币安Binance交易所-币安官网注册-币安HT行情价格

Go语言+区块链入门教程eth源码分析core-vm源码分析

作者:小雷 2021-09-28

  ## contract.go

  contract 代表了eth state database里面的一个合约。包含了合约代码,调用参数。

  结构

  // ContractRef is a reference to the contract's backing object

  type ContractRef interface {

  Address() common.Address

  // AccountRef implements ContractRef.

  // Account references are used during EVM initialisation and

  // it's primary use is to fetch addresses. Removing this object

  // proves difficult because of the cached jump destinations which

  // are fetched from the parent contract (i.e. the caller), which

  // is a ContractRef.

  type AccountRef common.Address

  // Address casts AccountRef to a Address

  func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }

  // Contract represents an ethereum contract in the state database. It contains

  // the the contract code, calling arguments. Contract implements ContractRef

  type Contract struct {

  // CallerAddress is the result of the caller which initialised this

  // contract. However when the "call method" is delegated this value

  // needs to be initialised to that of the caller's caller.

  // CallerAddress是初始化这个合约的人。 如果是delegate,这个值被设置为调用者的调用者。

  CallerAddress common.Address

  caller ContractRef

  self ContractRef

  jumpdests destinations // result of JUMPDEST analysis. JUMPDEST指令的分析

  Code []byte //代码

  CodeHash common.Hash //代码的HASH

  CodeAddr *common.Address //代码地址

  Input []byte // 入参

  Gas uint64 // 合约还有多少Gas

  value *big.Int

  Args []byte //好像没有使用

  DelegateCall bool

  构造

  // NewContract returns a new contract environment for the execution of EVM.

  func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uint64) *Contract {

  c := Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}

  if parent, ok := caller.(*Contract); ok {

  // Reuse JUMPDEST analysis from parent context if available.

  // 如果 caller 是一个合约,说明是合约调用了我们。 jumpdests设置为caller的jumpdests

  c.jumpdests = parent.jumpdests

  } else {

  c.jumpdests = make(destinations)

  // Gas should be a pointer so it can safely be reduced through the run

  // This pointer will be off the state transition

  c.Gas = gas

  // ensures a value is set

  c.value = value

  return c

  AsDelegate将合约设置为委托调用并返回当前合同(用于链式调用)

  // AsDelegate sets the contract to be a delegate call and returns the current

  // contract (for chaining calls)

  func (c *Contract) AsDelegate() *Contract {

  c.DelegateCall = true

  // NOTE: caller must, at all times be a contract. It should never happen

  // that caller is something other than a Contract.

  parent := c.caller.(*Contract)

  c.CallerAddress = parent.CallerAddress

  c.value = parent.value

  return c

  GetOp 用来获取下一跳指令

  // GetOp returns the n'th element in the contract's byte array

  func (c *Contract) GetOp(n uint64) OpCode {

  return OpCode(c.GetByte(n))

  // GetByte returns the n'th byte in the contract's byte array

  func (c *Contract) GetByte(n uint64) byte {

  if n uint64(len(c.Code)) {

  return c.Code[n]

  return 0

  // Caller returns the caller of the contract.

  // Caller will recursively call caller when the contract is a delegate

  // call, including that of caller's caller.

  func (c *Contract) Caller() common.Address {

  return c.CallerAddress

  UseGas使用Gas。

  // UseGas attempts the use gas and subtracts it and returns true on success

  func (c *Contract) UseGas(gas uint64) (ok bool) {

  if c.Gas gas {

  return false

  c.Gas -= gas

  return true

  // Address returns the contracts address

  func (c *Contract) Address() common.Address {

  return c.self.Address()

  // Value returns the contracts value (sent to it from it's caller)

  func (c *Contract) Value() *big.Int {

  return c.value

  SetCode ,SetCallCode 设置代码。

  // SetCode sets the code to the contract

  func (self *Contract) SetCode(hash common.Hash, code []byte) {

  self.Code = code

  self.CodeHash = hash

  // SetCallCode sets the code of the contract and address of the backing data

  // object

  func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {

  self.Code = code

  self.CodeHash = hash

  self.CodeAddr = addr

  ## evm.go

  结构

  // Context provides the EVM with auxiliary information. Once provided

  // it shouldn't be modified.

  // 上下文为EVM提供辅助信息。 一旦提供,不应该修改。

  type Context struct {

  // CanTransfer returns whether the account contains

  // sufficient ether to transfer the value

  // CanTransfer 函数返回账户是否有足够的ether用来转账

  CanTransfer CanTransferFunc

  // Transfer transfers ether from one account to the other

  // Transfer 用来从一个账户给另一个账户转账

  Transfer TransferFunc

  // GetHash returns the hash corresponding to n

  // GetHash用来返回入参n对应的hash值

  GetHash GetHashFunc

  // Message information

  // 用来提供Origin的信息 sender的地址

  Origin common.Address // Provides information for ORIGIN

  // 用来提供GasPrice信息

  GasPrice *big.Int // Provides information for GASPRICE

  // Block information

  Coinbase common.Address // Provides information for COINBASE

  GasLimit *big.Int // Provides information for GASLIMIT

  BlockNumber *big.Int // Provides information for NUMBER

  Time *big.Int // Provides information for TIME

  Difficulty *big.Int // Provides information for DIFFICULTY

  // EVM is the Ethereum Virtual Machine base object and provides

  // the necessary tools to run a contract on the given state with

  // the provided context. It should be noted that any error

  // generated through any of the calls should be considered a

  // revert-state-and-consume-all-gas operation, no checks on

  // specific errors should ever be performed. The interpreter makes

  // sure that any errors generated are to be considered faulty code.

  // EVM是eth虚拟机基础对象,并提供必要的工具,以使用提供的上下文运行给定状态的合约。

  // 应该指出的是,任何调用产生的任何错误都应该被认为是一种回滚修改状态和消耗所有GAS操作,

  // 不应该执行对具体错误的检查。 解释器确保生成的任何错误都被认为是错误的代码。

  // The EVM should never be reused and is not thread safe.

  type EVM struct {

  // Context provides auxiliary blockchain related information

  Context

  // StateDB gives access to the underlying state

  StateDB StateDB

  // Depth is the current call stack

  // 当前的调用堆栈

  depth int

  // chainConfig contains information about the current chain

  // 包含了当前的区块链的信息

  chainConfig *params.ChainConfig

  // chain rules contains the chain rules for the current epoch

  chainRules params.Rules

  // virtual machine configuration options used to initialise the

  // evm.

  vmConfig Config

  // global (to this context) ethereum virtual machine

  // used throughout the execution of the tx.

  interpreter *Interpreter

  // abort is used to abort the EVM calling operations

  // NOTE: must be set atomically

  abort int32

  构造函数

  // NewEVM retutrns a new EVM . The returned EVM is not thread safe and should

  // only ever be used *once*.

  func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {

  evm := EVM{

  Context: ctx,

  StateDB: statedb,

  vmConfig: vmConfig,

  chainConfig: chainConfig,

  chainRules: chainConfig.Rules(ctx.BlockNumber),

  evm.interpreter = NewInterpreter(evm, vmConfig)

  return evm

  // Cancel cancels any running EVM operation. This may be called concurrently and

  // it's safe to be called multiple times.

  func (evm *EVM) Cancel() {

  atomic.StoreInt32(evm.abort, 1)

目前有 0 条留言

发表留言

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。