github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/vm/runtime/runtime.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 19:16:36</date> 10 //</624450083227701248> 11 12 13 package runtime 14 15 import ( 16 "math" 17 "math/big" 18 "time" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/core/state" 22 "github.com/ethereum/go-ethereum/core/vm" 23 "github.com/ethereum/go-ethereum/crypto" 24 "github.com/ethereum/go-ethereum/ethdb" 25 "github.com/ethereum/go-ethereum/params" 26 ) 27 28 //config是一种基本类型,指定运行的某些配置标志 29 //EVM。 30 type Config struct { 31 ChainConfig *params.ChainConfig 32 Difficulty *big.Int 33 Origin common.Address 34 Coinbase common.Address 35 BlockNumber *big.Int 36 Time *big.Int 37 GasLimit uint64 38 GasPrice *big.Int 39 Value *big.Int 40 Debug bool 41 EVMConfig vm.Config 42 43 State *state.StateDB 44 GetHashFn func(n uint64) common.Hash 45 } 46 47 //设置配置的默认值 48 func setDefaults(cfg *Config) { 49 if cfg.ChainConfig == nil { 50 cfg.ChainConfig = ¶ms.ChainConfig{ 51 ChainID: big.NewInt(1), 52 HomesteadBlock: new(big.Int), 53 DAOForkBlock: new(big.Int), 54 DAOForkSupport: false, 55 EIP150Block: new(big.Int), 56 EIP155Block: new(big.Int), 57 EIP158Block: new(big.Int), 58 } 59 } 60 61 if cfg.Difficulty == nil { 62 cfg.Difficulty = new(big.Int) 63 } 64 if cfg.Time == nil { 65 cfg.Time = big.NewInt(time.Now().Unix()) 66 } 67 if cfg.GasLimit == 0 { 68 cfg.GasLimit = math.MaxUint64 69 } 70 if cfg.GasPrice == nil { 71 cfg.GasPrice = new(big.Int) 72 } 73 if cfg.Value == nil { 74 cfg.Value = new(big.Int) 75 } 76 if cfg.BlockNumber == nil { 77 cfg.BlockNumber = new(big.Int) 78 } 79 if cfg.GetHashFn == nil { 80 cfg.GetHashFn = func(n uint64) common.Hash { 81 return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String()))) 82 } 83 } 84 } 85 86 //在执行期间,Execute使用输入作为调用数据来执行代码。 87 //它返回EVM的返回值、新状态以及失败时的错误。 88 // 89 //执行为执行设置内存中的临时环境 90 //给定的代码。它确保之后它恢复到原来的状态。 91 func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { 92 if cfg == nil { 93 cfg = new(Config) 94 } 95 setDefaults(cfg) 96 97 if cfg.State == nil { 98 cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 99 } 100 var ( 101 address = common.BytesToAddress([]byte("contract")) 102 vmenv = NewEnv(cfg) 103 sender = vm.AccountRef(cfg.Origin) 104 ) 105 cfg.State.CreateAccount(address) 106 //设置要执行的接收方(执行合同)代码。 107 cfg.State.SetCode(address, code) 108 //使用给定的配置调用代码。 109 ret, _, err := vmenv.Call( 110 sender, 111 common.BytesToAddress([]byte("contract")), 112 input, 113 cfg.GasLimit, 114 cfg.Value, 115 ) 116 117 return ret, cfg.State, err 118 } 119 120 //create使用evm create方法执行代码 121 func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { 122 if cfg == nil { 123 cfg = new(Config) 124 } 125 setDefaults(cfg) 126 127 if cfg.State == nil { 128 cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 129 } 130 var ( 131 vmenv = NewEnv(cfg) 132 sender = vm.AccountRef(cfg.Origin) 133 ) 134 135 //使用给定的配置调用代码。 136 code, address, leftOverGas, err := vmenv.Create( 137 sender, 138 input, 139 cfg.GasLimit, 140 cfg.Value, 141 ) 142 return code, address, leftOverGas, err 143 } 144 145 //调用执行由合同地址给定的代码。它将返回 146 //EVM的返回值或失败时的错误。 147 // 148 //与execute不同,call需要config,还需要state字段 149 //被设定。 150 func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) { 151 setDefaults(cfg) 152 153 vmenv := NewEnv(cfg) 154 155 sender := cfg.State.GetOrNewStateObject(cfg.Origin) 156 //使用给定的配置调用代码。 157 ret, leftOverGas, err := vmenv.Call( 158 sender, 159 address, 160 input, 161 cfg.GasLimit, 162 cfg.Value, 163 ) 164 165 return ret, leftOverGas, err 166 } 167