github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/cmd/evm/main.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 // evm executes EVM code snippets. 18 package main 19 20 import ( 21 "fmt" 22 "io/ioutil" 23 "os" 24 goruntime "runtime" 25 "time" 26 27 "github.com/atheioschain/go-atheios/cmd/utils" 28 "github.com/atheioschain/go-atheios/common" 29 "github.com/atheioschain/go-atheios/core/state" 30 "github.com/atheioschain/go-atheios/core/vm" 31 "github.com/atheioschain/go-atheios/core/vm/runtime" 32 "github.com/atheioschain/go-atheios/crypto" 33 "github.com/atheioschain/go-atheios/ethdb" 34 "github.com/atheioschain/go-atheios/logger/glog" 35 "gopkg.in/urfave/cli.v1" 36 ) 37 38 var gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) 39 40 var ( 41 app = utils.NewApp(gitCommit, "the evm command line interface") 42 43 DebugFlag = cli.BoolFlag{ 44 Name: "debug", 45 Usage: "output full trace logs", 46 } 47 CodeFlag = cli.StringFlag{ 48 Name: "code", 49 Usage: "EVM code", 50 } 51 CodeFileFlag = cli.StringFlag{ 52 Name: "codefile", 53 Usage: "file containing EVM code", 54 } 55 GasFlag = cli.StringFlag{ 56 Name: "gas", 57 Usage: "gas limit for the evm", 58 Value: "10000000000", 59 } 60 PriceFlag = cli.StringFlag{ 61 Name: "price", 62 Usage: "price set for the evm", 63 Value: "0", 64 } 65 ValueFlag = cli.StringFlag{ 66 Name: "value", 67 Usage: "value set for the evm", 68 Value: "0", 69 } 70 DumpFlag = cli.BoolFlag{ 71 Name: "dump", 72 Usage: "dumps the state after the run", 73 } 74 InputFlag = cli.StringFlag{ 75 Name: "input", 76 Usage: "input for the EVM", 77 } 78 SysStatFlag = cli.BoolFlag{ 79 Name: "sysstat", 80 Usage: "display system stats", 81 } 82 VerbosityFlag = cli.IntFlag{ 83 Name: "verbosity", 84 Usage: "sets the verbosity level", 85 } 86 CreateFlag = cli.BoolFlag{ 87 Name: "create", 88 Usage: "indicates the action should be create rather than call", 89 } 90 DisableGasMeteringFlag = cli.BoolFlag{ 91 Name: "nogasmetering", 92 Usage: "disable gas metering", 93 } 94 ) 95 96 func init() { 97 app.Flags = []cli.Flag{ 98 CreateFlag, 99 DebugFlag, 100 VerbosityFlag, 101 SysStatFlag, 102 CodeFlag, 103 CodeFileFlag, 104 GasFlag, 105 PriceFlag, 106 ValueFlag, 107 DumpFlag, 108 InputFlag, 109 DisableGasMeteringFlag, 110 } 111 app.Action = run 112 } 113 114 func run(ctx *cli.Context) error { 115 glog.SetToStderr(true) 116 glog.SetV(ctx.GlobalInt(VerbosityFlag.Name)) 117 118 db, _ := ethdb.NewMemDatabase() 119 statedb, _ := state.New(common.Hash{}, db) 120 sender := statedb.CreateAccount(common.StringToAddress("sender")) 121 122 logger := vm.NewStructLogger(nil) 123 124 tstart := time.Now() 125 126 var ( 127 code []byte 128 ret []byte 129 err error 130 ) 131 132 if ctx.GlobalString(CodeFlag.Name) != "" { 133 code = common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)) 134 } else { 135 var hexcode []byte 136 if ctx.GlobalString(CodeFileFlag.Name) != "" { 137 var err error 138 hexcode, err = ioutil.ReadFile(ctx.GlobalString(CodeFileFlag.Name)) 139 if err != nil { 140 fmt.Printf("Could not load code from file: %v\n", err) 141 os.Exit(1) 142 } 143 } else { 144 var err error 145 hexcode, err = ioutil.ReadAll(os.Stdin) 146 if err != nil { 147 fmt.Printf("Could not load code from stdin: %v\n", err) 148 os.Exit(1) 149 } 150 } 151 code = common.Hex2Bytes(string(hexcode[:])) 152 } 153 154 if ctx.GlobalBool(CreateFlag.Name) { 155 input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...) 156 ret, _, err = runtime.Create(input, &runtime.Config{ 157 Origin: sender.Address(), 158 State: statedb, 159 GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)), 160 GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)), 161 Value: common.Big(ctx.GlobalString(ValueFlag.Name)), 162 EVMConfig: vm.Config{ 163 Tracer: logger, 164 Debug: ctx.GlobalBool(DebugFlag.Name), 165 DisableGasMetering: ctx.GlobalBool(DisableGasMeteringFlag.Name), 166 }, 167 }) 168 } else { 169 receiver := statedb.CreateAccount(common.StringToAddress("receiver")) 170 receiver.SetCode(crypto.Keccak256Hash(code), code) 171 172 ret, err = runtime.Call(receiver.Address(), common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtime.Config{ 173 Origin: sender.Address(), 174 State: statedb, 175 GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)), 176 GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)), 177 Value: common.Big(ctx.GlobalString(ValueFlag.Name)), 178 EVMConfig: vm.Config{ 179 Tracer: logger, 180 Debug: ctx.GlobalBool(DebugFlag.Name), 181 DisableGasMetering: ctx.GlobalBool(DisableGasMeteringFlag.Name), 182 }, 183 }) 184 } 185 vmdone := time.Since(tstart) 186 187 if ctx.GlobalBool(DumpFlag.Name) { 188 statedb.Commit(true) 189 fmt.Println(string(statedb.Dump())) 190 } 191 vm.StdErrFormat(logger.StructLogs()) 192 193 if ctx.GlobalBool(SysStatFlag.Name) { 194 var mem goruntime.MemStats 195 goruntime.ReadMemStats(&mem) 196 fmt.Printf("vm took %v\n", vmdone) 197 fmt.Printf(`alloc: %d 198 tot alloc: %d 199 no. malloc: %d 200 heap alloc: %d 201 heap objs: %d 202 num gc: %d 203 `, mem.Alloc, mem.TotalAlloc, mem.Mallocs, mem.HeapAlloc, mem.HeapObjects, mem.NumGC) 204 } 205 206 fmt.Printf("OUT: 0x%x", ret) 207 if err != nil { 208 fmt.Printf(" error: %v", err) 209 } 210 fmt.Println() 211 return nil 212 } 213 214 func main() { 215 if err := app.Run(os.Args); err != nil { 216 fmt.Fprintln(os.Stderr, err) 217 os.Exit(1) 218 } 219 }