void ExecuteScript(State runstate, SmartContract.Debug.LogScript script)
 {
     runstate.PushExe(script.hash);
     foreach (var op in script.ops)
     {
         if (op.op == VM.OpCode.APPCALL)//不造成栈影响,由目标script影响
         {
             ExecuteScript(runstate, op.subScript);
             mapState[op] = runstate.StateID;
         }
         else if (op.op == VM.OpCode.CALL)//不造成栈影响 就是个jmp
         {
             runstate.PushExe(script.hash);
             mapState[op] = runstate.StateID;
         }
         else if (op.op == VM.OpCode.RET)
         {
             mapState[op] = runstate.StateID;
         }
         else
         {
             if (op.op == VM.OpCode.SYSCALL)//syscall比较独特,有些syscall 可以产生独立的log
             {
                 var name = System.Text.Encoding.ASCII.GetString(op.param);
                 careinfo.Add(new CareItem(name, runstate));
                 //runstate.DoSysCall(op.op);
             }
             if (runstate.CalcCalcStack(op.op) == false)
             {
                 if (op.stack != null)
                 {
                     for (var i = 0; i < op.stack.Length; i++)
                     {
                         if (i == op.stack.Length - 1)
                         {
                             runstate.CalcCalcStack(op.stack[i], op.opresult);
                         }
                         else
                         {
                             runstate.CalcCalcStack(op.stack[i], null);
                         }
                     }
                 }
             }
             if (stateClone.ContainsKey(runstate.StateID) == false)
             {
                 stateClone[runstate.StateID] = (Debug.State)runstate.Clone();
             }
             mapState[op] = runstate.StateID;
         }
     }
 }
Beispiel #2
0
        public void Execute(SmartContract.Debug.FullLog FullLog)
        {
            State runstate = new State();

            runstate.SetId(0);

            stateClone = new Dictionary <int, State>();
            mapState   = new Dictionary <SmartContract.Debug.LogOp, int>();
            careinfo   = new List <CareItem>();

            regenScript = new SmartContract.Debug.LogScript(FullLog.script.hash);
            lastScript  = regenScript;

            ExecuteScript(runstate, FullLog.script);
        }
Beispiel #3
0
        //加入outputscript,做一個補救,以前導出的log樹層次可能是錯的
        void ExecuteScript(State runstate, SmartContract.Debug.LogScript script)
        {
            try
            {
                runstate.PushExe(script.hash);
                foreach (var op in script.ops)
                {
                    var _nop = op.Clone();
                    lastScript.ops.Add(_nop);
                    try
                    {
                        if (op.op == VM.OpCode.APPCALL)//不造成栈影响,由目标script影响
                        {
                            var _script   = op.subScript;
                            var outscript = new SmartContract.Debug.LogScript(op.subScript.hash);
                            outscript.parent = lastScript;
                            _nop.subScript   = outscript;
                            lastScript       = outscript;
                            //有可能造成影响
                            if (op.stack != null)
                            {
                                for (var i = 0; i < op.stack.Length; i++)
                                {
                                    if (i == op.stack.Length - 1)
                                    {
                                        runstate.CalcCalcStack(op.stack[i], op.opresult);
                                    }
                                    else
                                    {
                                        runstate.CalcCalcStack(op.stack[i], null);
                                    }
                                }
                            }
                            runstate.PushExe(script.hash);
                            if (stateClone.ContainsKey(runstate.StateID) == false)
                            {
                                stateClone[runstate.StateID] = (Debug.State)runstate.Clone();
                            }
                            ExecuteScript(runstate, _script);
                            mapState[_nop] = runstate.StateID;
                        }
                        else if (op.op == VM.OpCode.CALL)//造成栈影响 就是个jmp
                        {
                            var _lastScript = new SmartContract.Debug.LogScript(lastScript.hash);
                            _lastScript.parent = lastScript;
                            _nop.subScript     = _lastScript;

                            lastScript = _lastScript;
                            runstate.PushExe(lastScript.hash);
                            mapState[_nop] = runstate.StateID;

                            //runstate.callcount++;
                        }
                        else if (op.op == VM.OpCode.RET)
                        {
                            runstate.PopExe();

                            //mapState[op] = runstate.StateID;
                            //if (runstate.callcount > 0)
                            //{
                            //    runstate.callcount--;
                            //}
                            //if (runstate.callcount == 0)
                            {
                                lastScript = lastScript.parent;
                            }
                            if (stateClone.ContainsKey(runstate.StateID) == false)
                            {
                                stateClone[runstate.StateID] = (Debug.State)runstate.Clone();
                            }
                            mapState[_nop] = runstate.StateID;
                        }
                        else
                        {
                            if (op.op == VM.OpCode.SYSCALL)//syscall比较独特,有些syscall 可以产生独立的log
                            {
                                var name = System.Text.Encoding.ASCII.GetString(op.param);
                                careinfo.Add(new CareItem(name, runstate));
                                //runstate.DoSysCall(op.op);
                            }
                            if (runstate.CalcCalcStack(op.op) == false)
                            {
                                if (op.stack != null)
                                {
                                    for (var i = 0; i < op.stack.Length; i++)
                                    {
                                        if (i == op.stack.Length - 1)
                                        {
                                            runstate.CalcCalcStack(op.stack[i], op.opresult);
                                        }
                                        else
                                        {
                                            runstate.CalcCalcStack(op.stack[i], null);
                                        }
                                    }
                                }
                            }
                            if (stateClone.ContainsKey(runstate.StateID) == false)
                            {
                                stateClone[runstate.StateID] = (Debug.State)runstate.Clone();
                            }
                            mapState[_nop] = runstate.StateID;
                        }
                    }
                    catch (Exception err1)
                    {
                        _nop.error = true;
                    }
                }
            }
            catch (Exception err)
            {
                throw new Exception("error in:" + err.Message);
            }
        }