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 = &params.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