github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/core/vm/contract.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:35</date>
    10  //</624342621128495104>
    11  
    12  
    13  package vm
    14  
    15  import (
    16  	"math/big"
    17  
    18  	"github.com/ethereum/go-ethereum/common"
    19  )
    20  
    21  //contractRef是对合同支持对象的引用
    22  type ContractRef interface {
    23  	Address() common.Address
    24  }
    25  
    26  //accountRef执行contractRef。
    27  //
    28  //在EVM初始化和
    29  //它的主要用途是获取地址。删除此对象
    30  //由于缓存的跳转目的地
    31  //从父合同(即调用者)中提取,其中
    32  //是ContractRef。
    33  type AccountRef common.Address
    34  
    35  //地址将accountRef强制转换为地址
    36  func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
    37  
    38  //契约表示状态数据库中的以太坊契约。它包含
    39  //合同代码,调用参数。合同执行合同参考号
    40  type Contract struct {
    41  //CallerAddress是调用方初始化此项的结果
    42  //合同。但是,当“调用方法”被委托时,这个值
    43  //需要初始化为调用方的调用方的调用方。
    44  	CallerAddress common.Address
    45  	caller        ContractRef
    46  	self          ContractRef
    47  
    48  jumpdests destinations //JumpDest分析结果。
    49  
    50  	Code     []byte
    51  	CodeHash common.Hash
    52  	CodeAddr *common.Address
    53  	Input    []byte
    54  
    55  	Gas   uint64
    56  	value *big.Int
    57  
    58  	Args []byte
    59  
    60  	DelegateCall bool
    61  }
    62  
    63  //NewContract返回执行EVM的新合同环境。
    64  func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uint64) *Contract {
    65  	c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}
    66  
    67  	if parent, ok := caller.(*Contract); ok {
    68  //如果可用,请重新使用父上下文中的JumpDest分析。
    69  		c.jumpdests = parent.jumpdests
    70  	} else {
    71  		c.jumpdests = make(destinations)
    72  	}
    73  
    74  //气体应该是一个指针,这样可以在运行过程中安全地减少气体。
    75  //此指针将关闭状态转换
    76  	c.Gas = gas
    77  //确保设置了值
    78  	c.value = value
    79  
    80  	return c
    81  }
    82  
    83  //asdelegate将协定设置为委托调用并返回当前
    84  //合同(用于链接呼叫)
    85  func (c *Contract) AsDelegate() *Contract {
    86  	c.DelegateCall = true
    87  //注:呼叫者必须始终是合同。这不应该发生
    88  //打电话的不是合同。
    89  	parent := c.caller.(*Contract)
    90  	c.CallerAddress = parent.CallerAddress
    91  	c.value = parent.value
    92  
    93  	return c
    94  }
    95  
    96  //getop返回契约字节数组中的第n个元素
    97  func (c *Contract) GetOp(n uint64) OpCode {
    98  	return OpCode(c.GetByte(n))
    99  }
   100  
   101  //GetByte返回协定字节数组中的第n个字节
   102  func (c *Contract) GetByte(n uint64) byte {
   103  	if n < uint64(len(c.Code)) {
   104  		return c.Code[n]
   105  	}
   106  
   107  	return 0
   108  }
   109  
   110  //调用者返回合同的调用者。
   111  //
   112  //当协定是委托时,调用方将递归调用调用方
   113  //呼叫,包括呼叫者的呼叫。
   114  func (c *Contract) Caller() common.Address {
   115  	return c.CallerAddress
   116  }
   117  
   118  //use gas尝试使用气体并减去它,成功后返回true。
   119  func (c *Contract) UseGas(gas uint64) (ok bool) {
   120  	if c.Gas < gas {
   121  		return false
   122  	}
   123  	c.Gas -= gas
   124  	return true
   125  }
   126  
   127  //地址返回合同地址
   128  func (c *Contract) Address() common.Address {
   129  	return c.self.Address()
   130  }
   131  
   132  //value返回合同值(从调用方发送给它)
   133  func (c *Contract) Value() *big.Int {
   134  	return c.value
   135  }
   136  
   137  //setcode将代码设置为合同
   138  func (c *Contract) SetCode(hash common.Hash, code []byte) {
   139  	c.Code = code
   140  	c.CodeHash = hash
   141  }
   142  
   143  //setcallcode设置合同的代码和支持数据的地址
   144  //对象
   145  func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
   146  	c.Code = code
   147  	c.CodeHash = hash
   148  	c.CodeAddr = addr
   149  }
   150