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);//失败返回空 }