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