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  }