github.com/devfans/go-ethereum@v1.5.10-0.20170326212234-7419d0c38291/cmd/evm/runner.go (about) 1 // Copyright 2017 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 package main 18 19 import ( 20 "bytes" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "time" 25 26 goruntime "runtime" 27 28 "github.com/ethereum/go-ethereum/cmd/evm/internal/compiler" 29 "github.com/ethereum/go-ethereum/cmd/utils" 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/ethereum/go-ethereum/core/state" 32 "github.com/ethereum/go-ethereum/core/vm" 33 "github.com/ethereum/go-ethereum/core/vm/runtime" 34 "github.com/ethereum/go-ethereum/ethdb" 35 "github.com/ethereum/go-ethereum/log" 36 cli "gopkg.in/urfave/cli.v1" 37 ) 38 39 var runCommand = cli.Command{ 40 Action: runCmd, 41 Name: "run", 42 Usage: "run arbitrary evm binary", 43 ArgsUsage: "<code>", 44 Description: `The run command runs arbitrary EVM code.`, 45 } 46 47 func runCmd(ctx *cli.Context) error { 48 glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) 49 glogger.Verbosity(log.Lvl(ctx.GlobalInt(VerbosityFlag.Name))) 50 log.Root().SetHandler(glogger) 51 52 var ( 53 db, _ = ethdb.NewMemDatabase() 54 statedb, _ = state.New(common.Hash{}, db) 55 sender = common.StringToAddress("sender") 56 logger = vm.NewStructLogger(nil) 57 ) 58 statedb.CreateAccount(sender) 59 60 var ( 61 code []byte 62 ret []byte 63 err error 64 ) 65 if fn := ctx.Args().First(); len(fn) > 0 { 66 src, err := ioutil.ReadFile(fn) 67 if err != nil { 68 return err 69 } 70 71 bin, err := compiler.Compile(fn, src, false) 72 if err != nil { 73 return err 74 } 75 code = common.Hex2Bytes(bin) 76 } else if ctx.GlobalString(CodeFlag.Name) != "" { 77 code = common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)) 78 } else { 79 var hexcode []byte 80 if ctx.GlobalString(CodeFileFlag.Name) != "" { 81 var err error 82 hexcode, err = ioutil.ReadFile(ctx.GlobalString(CodeFileFlag.Name)) 83 if err != nil { 84 fmt.Printf("Could not load code from file: %v\n", err) 85 os.Exit(1) 86 } 87 } else { 88 var err error 89 hexcode, err = ioutil.ReadAll(os.Stdin) 90 if err != nil { 91 fmt.Printf("Could not load code from stdin: %v\n", err) 92 os.Exit(1) 93 } 94 } 95 code = common.Hex2Bytes(string(bytes.TrimRight(hexcode, "\n"))) 96 } 97 98 runtimeConfig := runtime.Config{ 99 Origin: sender, 100 State: statedb, 101 GasLimit: ctx.GlobalUint64(GasFlag.Name), 102 GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), 103 Value: utils.GlobalBig(ctx, ValueFlag.Name), 104 EVMConfig: vm.Config{ 105 Tracer: logger, 106 Debug: ctx.GlobalBool(DebugFlag.Name), 107 DisableGasMetering: ctx.GlobalBool(DisableGasMeteringFlag.Name), 108 }, 109 } 110 111 tstart := time.Now() 112 if ctx.GlobalBool(CreateFlag.Name) { 113 input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...) 114 ret, _, err = runtime.Create(input, &runtimeConfig) 115 } else { 116 receiver := common.StringToAddress("receiver") 117 statedb.SetCode(receiver, code) 118 119 ret, err = runtime.Call(receiver, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtimeConfig) 120 } 121 execTime := time.Since(tstart) 122 123 if ctx.GlobalBool(DumpFlag.Name) { 124 statedb.Commit(true) 125 fmt.Println(string(statedb.Dump())) 126 } 127 128 if ctx.GlobalBool(DebugFlag.Name) { 129 fmt.Fprintln(os.Stderr, "#### TRACE ####") 130 vm.WriteTrace(os.Stderr, logger.StructLogs()) 131 fmt.Fprintln(os.Stderr, "#### LOGS ####") 132 vm.WriteLogs(os.Stderr, statedb.Logs()) 133 134 var mem goruntime.MemStats 135 goruntime.ReadMemStats(&mem) 136 fmt.Fprintf(os.Stderr, `evm execution time: %v 137 heap objects: %d 138 allocations: %d 139 total allocations: %d 140 GC calls: %d 141 142 `, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC) 143 } 144 145 fmt.Printf("0x%x", ret) 146 if err != nil { 147 fmt.Printf(" error: %v", err) 148 } 149 fmt.Println() 150 return nil 151 }