github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/vm/interpreter.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2014 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package vm
    26  
    27  import (
    28  	"fmt"
    29  	"sync/atomic"
    30  
    31  	"github.com/ethereum/go-ethereum/common/math"
    32  	"github.com/ethereum/go-ethereum/params"
    33  )
    34  
    35  //config是解释器的配置选项
    36  type Config struct {
    37  //启用调试的调试解释器选项
    38  	Debug bool
    39  //跟踪程序是操作代码记录器
    40  	Tracer Tracer
    41  //无加密禁用的解释程序调用,调用代码,
    42  //委派呼叫并创建。
    43  	NoRecursion bool
    44  //启用sha3/keccak preimages的录制
    45  	EnablePreimageRecording bool
    46  //JumpTable包含EVM指令表。这个
    47  //可能未初始化,并将设置为默认值
    48  //表。
    49  	JumpTable [256]operation
    50  }
    51  
    52  //解释器用于运行基于以太坊的合同,并将使用
    53  //已传递环境以查询外部源以获取状态信息。
    54  //解释器将根据传递的
    55  //配置。
    56  type Interpreter interface {
    57  //运行循环并使用给定的输入数据评估契约的代码并返回
    58  //返回字节切片,如果出现错误,则返回一个错误。
    59  	Run(contract *Contract, input []byte) ([]byte, error)
    60  //canrun告诉作为参数传递的契约是否可以
    61  //由当前解释器运行。这意味着
    62  //呼叫方可以执行以下操作:
    63  //
    64  //'Gangang'
    65  //对于u,解释器:=测距解释器
    66  //if explorer.canrun(contract.code)
    67  //解释器.run(contract.code,input)
    68  //}
    69  //}
    70  //` `
    71  	CanRun([]byte) bool
    72  //如果解释器处于只读模式,is read only将报告。
    73  	IsReadOnly() bool
    74  //setreadonly在解释器中设置(或取消设置)只读模式。
    75  	SetReadOnly(bool)
    76  }
    77  
    78  //evm interpreter表示evm解释器
    79  type EVMInterpreter struct {
    80  	evm      *EVM
    81  	cfg      Config
    82  	gasTable params.GasTable
    83  	intPool  *intPool
    84  
    85  readOnly   bool   //是否进行状态修改
    86  returnData []byte //最后一次调用的返回数据供后续重用
    87  }
    88  
    89  //NewEvminterPreter返回解释器的新实例。
    90  func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
    91  //我们使用停止指令是否看到
    92  //跳转表已初始化。如果不是
    93  //我们将设置默认跳转表。
    94  	if !cfg.JumpTable[STOP].valid {
    95  		switch {
    96  		case evm.ChainConfig().IsConstantinople(evm.BlockNumber):
    97  			cfg.JumpTable = constantinopleInstructionSet
    98  		case evm.ChainConfig().IsByzantium(evm.BlockNumber):
    99  			cfg.JumpTable = byzantiumInstructionSet
   100  		case evm.ChainConfig().IsHomestead(evm.BlockNumber):
   101  			cfg.JumpTable = homesteadInstructionSet
   102  		default:
   103  			cfg.JumpTable = frontierInstructionSet
   104  		}
   105  	}
   106  
   107  	return &EVMInterpreter{
   108  		evm:      evm,
   109  		cfg:      cfg,
   110  		gasTable: evm.ChainConfig().GasTable(evm.BlockNumber),
   111  	}
   112  }
   113  
   114  func (in *EVMInterpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error {
   115  	if in.evm.chainRules.IsByzantium {
   116  		if in.readOnly {
   117  //如果解释器在只读模式下工作,请确保否
   118  //执行状态修改操作。第三个堆栈项
   119  //对于一个调用操作来说是值。从一个转移价值
   120  //对其他人的帐户意味着状态被修改,并且应该
   121  //返回时出错。
   122  			if operation.writes || (op == CALL && stack.Back(2).BitLen() > 0) {
   123  				return errWriteProtection
   124  			}
   125  		}
   126  	}
   127  	return nil
   128  }
   129  
   130  //运行循环并使用给定的输入数据评估契约的代码并返回
   131  //返回字节切片,如果出现错误,则返回一个错误。
   132  //
   133  //需要注意的是,解释程序返回的任何错误都应该
   134  //被认为是一种还原和消耗除
   135  //errExecutionReverted,这意味着还原并保留气体。
   136  func (in *EVMInterpreter) Run(contract *Contract, input []byte) (ret []byte, err error) {
   137  	if in.intPool == nil {
   138  		in.intPool = poolOfIntPools.get()
   139  		defer func() {
   140  			poolOfIntPools.put(in.intPool)
   141  			in.intPool = nil
   142  		}()
   143  	}
   144  
   145  //增加限制为1024的调用深度
   146  	in.evm.depth++
   147  	defer func() { in.evm.depth-- }()
   148  
   149  //重置上一个呼叫的返回数据。保留旧的缓冲区并不重要
   150  //因为每次回电都会返回新的数据。
   151  	in.returnData = nil
   152  
   153  //如果没有代码,就不必费心执行。
   154  	if len(contract.Code) == 0 {
   155  		return nil, nil
   156  	}
   157  
   158  	var (
   159  op    OpCode        //当前操作码
   160  mem   = NewMemory() //绑定内存
   161  stack = newstack()  //本地栈
   162  //为了优化,我们使用uint64作为程序计数器。
   163  //理论上可以超过2^64。YP定义PC
   164  //为UIT2525。实际上不那么可行。
   165  pc   = uint64(0) //程序计数器
   166  		cost uint64
   167  //追踪器使用的副本
   168  pcCopy  uint64 //延期追踪器需要
   169  gasCopy uint64 //用于示踪剂记录执行前的剩余气体
   170  logged  bool   //延迟跟踪程序应忽略已记录的步骤
   171  	)
   172  	contract.Input = input
   173  
   174  //在执行停止时将堆栈作为int池回收
   175  	defer func() { in.intPool.put(stack.data...) }()
   176  
   177  	if in.cfg.Debug {
   178  		defer func() {
   179  			if err != nil {
   180  				if !logged {
   181  					in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err)
   182  				} else {
   183  					in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err)
   184  				}
   185  			}
   186  		}()
   187  	}
   188  //解释器主运行循环(上下文)。此循环运行到
   189  //执行显式停止、返回或自毁函数,期间发生错误
   190  //执行一个操作,或直到完成标志由
   191  //父上下文。
   192  	for atomic.LoadInt32(&in.evm.abort) == 0 {
   193  		if in.cfg.Debug {
   194  //捕获执行前的值以进行跟踪。
   195  			logged, pcCopy, gasCopy = false, pc, contract.Gas
   196  		}
   197  
   198  //从跳转表中获取操作并验证堆栈以确保
   199  //有足够的堆栈项可用于执行该操作。
   200  		op = contract.GetOp(pc)
   201  		operation := in.cfg.JumpTable[op]
   202  		if !operation.valid {
   203  			return nil, fmt.Errorf("invalid opcode 0x%x", int(op))
   204  		}
   205  		if err := operation.validateStack(stack); err != nil {
   206  			return nil, err
   207  		}
   208  //如果操作有效,则强制执行并写入限制
   209  		if err := in.enforceRestrictions(op, operation, stack); err != nil {
   210  			return nil, err
   211  		}
   212  
   213  		var memorySize uint64
   214  //计算新内存大小并展开内存以适应
   215  //手术
   216  		if operation.memorySize != nil {
   217  			memSize, overflow := bigUint64(operation.memorySize(stack))
   218  			if overflow {
   219  				return nil, errGasUintOverflow
   220  			}
   221  //内存以32字节的字扩展。气体
   222  //也用文字计算。
   223  			if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow {
   224  				return nil, errGasUintOverflow
   225  			}
   226  		}
   227  //如果没有足够的气体可用,则消耗气体并返回错误。
   228  //明确设置成本,以便捕获状态延迟方法可以获得适当的成本
   229  		cost, err = operation.gasCost(in.gasTable, in.evm, contract, stack, mem, memorySize)
   230  		if err != nil || !contract.UseGas(cost) {
   231  			return nil, ErrOutOfGas
   232  		}
   233  		if memorySize > 0 {
   234  			mem.Resize(memorySize)
   235  		}
   236  
   237  		if in.cfg.Debug {
   238  			in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err)
   239  			logged = true
   240  		}
   241  
   242  //执行操作
   243  		res, err := operation.execute(&pc, in, contract, mem, stack)
   244  //VerifyPool是一个生成标志。池验证确保完整性
   245  //通过将值与默认值进行比较来获得整数池的值。
   246  		if verifyPool {
   247  			verifyIntegerPool(in.intPool)
   248  		}
   249  //如果操作清除返回数据(例如,它有返回数据)
   250  //将最后一个返回设置为操作结果。
   251  		if operation.returns {
   252  			in.returnData = res
   253  		}
   254  
   255  		switch {
   256  		case err != nil:
   257  			return nil, err
   258  		case operation.reverts:
   259  			return res, errExecutionReverted
   260  		case operation.halts:
   261  			return res, nil
   262  		case !operation.jumps:
   263  			pc++
   264  		}
   265  	}
   266  	return nil, nil
   267  }
   268  
   269  //canrun告诉作为参数传递的契约是否可以
   270  //由当前解释器运行。
   271  func (in *EVMInterpreter) CanRun(code []byte) bool {
   272  	return true
   273  }
   274  
   275  //如果解释器处于只读模式,is read only将报告。
   276  func (in *EVMInterpreter) IsReadOnly() bool {
   277  	return in.readOnly
   278  }
   279  
   280  //setreadonly在解释器中设置(或取消设置)只读模式。
   281  func (in *EVMInterpreter) SetReadOnly(ro bool) {
   282  	in.readOnly = ro
   283  }