Пример #1
0
tuple<bool, uint64_t, string> CVmRunEvn::run(shared_ptr<CBaseTransaction>& Tx, CAccountViewCache& view, CScriptDBViewCache& VmDB, int nHeight,
		uint64_t nBurnFactor, uint64_t &uRunStep) {

	if(nBurnFactor == 0)
	{
//		assert(0);
		return std::make_tuple (false, 0, string("VmScript nBurnFactor == 0 \n"));
	}
	m_ScriptDBTip = &VmDB;

	CTransaction* tx = static_cast<CTransaction*>(Tx.get());
	if(tx->llFees <= CBaseTransaction::nMinTxFee) {
		return std::make_tuple (false, 0, string("vm run evn fee too litter\n"));
	}
	uint64_t maxstep = ((tx->llFees-CBaseTransaction::nMinTxFee)/ nBurnFactor) * 100;
	
	if(maxstep > MAX_BLOCK_RUN_STEP){
		maxstep = MAX_BLOCK_RUN_STEP;
	}
	LogPrint("vm", "tx hash:%s fees=%lld fuelrate=%lld maxstep:%d\n", Tx->GetHash().GetHex(), tx->llFees, nBurnFactor, maxstep);
	if (!intial(Tx, view, nHeight)) {
		return std::make_tuple (false, 0, string("VmScript inital Failed\n"));
	}

	int64_t step = pMcu.get()->run(maxstep,this);
	if (0 == step) {
		return std::make_tuple(false, 0, string("VmScript run Failed\n"));
	} else if (-1 == step) {
		return std::make_tuple(false, 0, string("execure tx contranct run step exceed the max step limit\n"));
	}else{
		uRunStep = step;
	}

	LogPrint("vm", "tx:%s,step:%ld\n", tx->ToString(view), uRunStep);

	if (!CheckOperate(m_output)) {
		return std::make_tuple (false, 0, string("VmScript CheckOperate Failed \n"));
	}

	if (!OpeatorAccount(m_output, view, nHeight)) {
		return std::make_tuple (false, 0, string("VmScript OpeatorAccount Failed\n"));
	}

	LogPrint("vm", "isCheckAccount:%d\n", isCheckAccount);
	if(isCheckAccount) {
		LogPrint("vm","isCheckAccount is true\n");
		if(!CheckAppAcctOperate(tx))
			return std::make_tuple (false, 0, string("VmScript CheckAppAcct Failed\n"));
	}

	if(!OpeatorAppAccount(MapAppOperate, *m_ScriptDBTip))
	{
		return std::make_tuple (false, 0, string("OpeatorApp Account Failed\n"));
	}

	if(SysCfg().GetOutPutLog() && m_output.size() > 0) {
		CScriptDBOperLog operlog;
		uint256 txhash = GetCurTxHash();
		if(!m_ScriptDBTip->WriteTxOutPut(txhash, m_output, operlog))
			return std::make_tuple (false, 0, string("write tx out put Failed \n"));
		m_dblog->push_back(operlog);
	}

	uint64_t spend = uRunStep * nBurnFactor;
		if((spend < uRunStep) || (spend < nBurnFactor)){
		return std::make_tuple (false, 0, string("mul error\n"));
	}
	return std::make_tuple (true, spend, string("VmScript Sucess\n"));

}
struct sBinaryRelation LexicalAnalyzer(char *pcSubName)//词法分析器
{
	static char fcFirst='Y';
	//初始化扫描指示器为第一个元素
	static char *fpcStart;
	char **fppcStart=&fpcStart;//取fpcstart的地址
	static char *fpcSerching;
	char **fppcfpcSerching=&fpcSerching;//取fpcSerching的地址
	static int iLine=1;//记录当前的行数
	int *piLine=&iLine;//指向行数的指针
	struct sBinaryRelation sTempResult;//存放返回结果

	if(fcFirst=='Y')//第一次调用装入bufferl
	{
		PreProcess(pcSubName);
		fcFirst='N';
		fpcStart=acScanBufL;//将start和serch都指向第一个地址
	}

	while(*fpcStart==0x20) 
	{
		if(!CheckEndBuffer(fppcStart,pcSubName)) fpcStart++;//检查是否越界,若没越界将start指针指向一个不为空格的字符
	}
	fpcSerching=fpcStart;//serching指向start
	//fpcSerching++;//serching指向start的下一个位置

	while(*fpcSerching!=0x00)
	{
		if(CheckNewLine(*fpcStart,piLine))//检查回车,记录行数加一
		{
			//待扩建是否将\n也算作标识符
			fpcStart++;
			fpcSerching=fpcStart;//serching指向start
		}
		else if(isalpha(*fpcStart))//第一个字符是字母,为关键字
		{
			char cTempResult[SBUFSIZE]={0};
			char *pcCurrent=cTempResult;

			//检查是否为变量或关键字
			while(isalnum(*fpcSerching))//下一个是字符或数字
			{
				//if(isspace(*fpcSerching)) break;//若为空格结束

				*(pcCurrent++)=*fpcSerching;//将字符保存到临时数组,并且指针后移

				if(!CheckEndBuffer(fppcfpcSerching,pcSubName)) fpcSerching++; //检查是否越界,若没越界将serching++
			}//循环完成时fpceSerching指向当前标识符的下一个位置	
			//将start和serching重合
			fpcStart=fpcSerching;

			//返回当前的标识符放到结构体中
			int KeyWordScript;//关键字的下标
			if((KeyWordScript=CheckKeyWords(cTempResult))!=0)//检查是否为关键字还是普通变量
			{
				sTempResult.iId=0;//标志符置为0,关键字的下标
				sTempResult.iSubScript=KeyWordScript;
				sTempResult.acTempValName[0]='\0';//赋值
			}
			else//普通变量
			{
				sTempResult.iId=1;//单词为变量
				int i=-1;
				while(cTempResult[++i]!='\0')//将变量的值赋给变量名字数组
				{
					sTempResult.acTempValName[i]=cTempResult[i];
				}
				sTempResult.acTempValName[i]=cTempResult[i];//赋值个'\0'
				sTempResult.iSubScript=0;//赋值
			}
			//返回结构体
			
			return sTempResult;
		}
		else if(isdigit(*fpcStart))//如果是数字常量
		{
			int iTemp=0;
			while(*fpcSerching!=0x20)//下面字符都要是数字
			{
				if((!isdigit(*fpcSerching))&&(isalpha(*fpcSerching)))//若后面是字幕或者不是操作符
				{
					printf("词法分析:");
					Error(iLine);//不是数字报错
					printf(" %d %c非法字符\n",iTemp,*fpcSerching);
				}
				iTemp=iTemp*10+int(*fpcSerching-0x30);//将数字字符转化为整形
				if(!CheckEndBuffer(fppcfpcSerching,pcSubName)) fpcSerching++; //检查是否越界,若没越界将serching++
				//判断是否是;若下一个字符是分号或者操作符就结束
				if(*fpcSerching==';') break;
				if(CheckOperate(*fpcSerching)) break;
			}
			//循环完成时fpceSerching指向当前标识符的下一个位置
			fpcStart=fpcSerching;//将start和serching重合

			//返回当前的标识符放到结构体中
			sTempResult.iId=2;
			sTempResult.iSubScript=iTemp;
			sTempResult.acTempValName[0]='\0';//赋值
			return sTempResult;

		}
		else if(CheckOperate(*fpcStart)) //判断运算符
		{
			int iTempOperateOffset;//记录标识符下标
			iTempOperateOffset=CheckOperate(*fpcStart);
			//不需要因为serching本来就在start的下一个fpceSerching++;
			if(!CheckEndBuffer(fppcStart,pcSubName)) fpcStart=++fpcSerching;//检查serching是否越界,若没越界将start和serching重合
			
			//返回当前的标识符放到结构体中
			sTempResult.iId=3;
			sTempResult.iSubScript=iTempOperateOffset;
			sTempResult.acTempValName[0]='\0';//赋值
			return sTempResult;

		}
		else
		{
			printf("词法分析:");
			Error(iLine);//不是数字报错
			printf(" %c非法字符\n",*fpcSerching);
			exit(1);//退出程序
		}
				 
	}
	if(*fpcSerching!=0) printf("词法分析:未知错误\n");//若不为结束符,显示未知错误
	exit(1);//失败返回空
}