github.com/datachainlab/burrow@v0.25.0/execution/evm/vm.go (about)

     1  // Copyright 2017 Monax Industries Limited
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package evm
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"io/ioutil"
    21  	"math/big"
    22  	"strings"
    23  
    24  	"github.com/hyperledger/burrow/execution/evm/abi"
    25  
    26  	"github.com/hyperledger/burrow/acm"
    27  	"github.com/hyperledger/burrow/acm/acmstate"
    28  	. "github.com/hyperledger/burrow/binary"
    29  	"github.com/hyperledger/burrow/crypto"
    30  	"github.com/hyperledger/burrow/crypto/sha3"
    31  	"github.com/hyperledger/burrow/execution/errors"
    32  	. "github.com/hyperledger/burrow/execution/evm/asm"
    33  	"github.com/hyperledger/burrow/execution/exec"
    34  	"github.com/hyperledger/burrow/logging"
    35  	"github.com/hyperledger/burrow/permission"
    36  	"github.com/hyperledger/burrow/txs"
    37  )
    38  
    39  const (
    40  	DataStackInitialCapacity    = 1024
    41  	MaximumAllowedBlockLookBack = 256
    42  	uint64Length                = 8
    43  )
    44  
    45  type Params struct {
    46  	BlockHeight              uint64
    47  	BlockTime                int64
    48  	GasLimit                 uint64
    49  	CallStackMaxDepth        uint64
    50  	DataStackInitialCapacity uint64
    51  	DataStackMaxDepth        uint64
    52  }
    53  
    54  type VM struct {
    55  	memoryProvider func(errors.Sink) Memory
    56  	params         Params
    57  	origin         crypto.Address
    58  	nonce          []byte
    59  	stackDepth     uint64
    60  	logger         *logging.Logger
    61  	debugOpcodes   bool
    62  	dumpTokens     bool
    63  	sequence       uint64
    64  }
    65  
    66  // Create a new EVM instance. Nonce is required to be globally unique (nearly almost surely) to avoid duplicate
    67  // addresses for EVM created accounts. In Burrow we use TxHash for this but a random nonce or sequence number could be
    68  // used.
    69  func NewVM(params Params, origin crypto.Address, nonce []byte, logger *logging.Logger, options ...func(*VM)) *VM {
    70  	vm := &VM{
    71  		memoryProvider: DefaultDynamicMemoryProvider,
    72  		params:         params,
    73  		origin:         origin,
    74  		stackDepth:     0,
    75  		nonce:          nonce,
    76  		logger:         logger.WithScope("NewVM"),
    77  	}
    78  	for _, option := range options {
    79  		option(vm)
    80  	}
    81  	return vm
    82  }
    83  
    84  func (vm *VM) Debugf(format string, a ...interface{}) {
    85  	// Uncomment for quick and dirty debug
    86  	//fmt.Printf(format, a...)
    87  	if vm.debugOpcodes {
    88  		vm.logger.TraceMsg(fmt.Sprintf(format, a...), "tag", "DebugOpcodes")
    89  	}
    90  }
    91  
    92  // CONTRACT: it is the duty of the contract writer to call known permissions
    93  // we do not convey if a permission is not set
    94  // (unlike in state/execution, where we guarantee HasPermission is called
    95  // on known permissions and panics else)
    96  // If the perm is not defined in the acc nor set by default in GlobalPermissions,
    97  // this function returns false.
    98  func HasPermission(st Interface, address crypto.Address, perm permission.PermFlag) bool {
    99  	globalPerms := st.GetPermissions(acm.GlobalPermissionsAddress)
   100  	accPerms := st.GetPermissions(address)
   101  	perms := accPerms.Base.Compose(globalPerms.Base)
   102  	value, err := perms.Get(perm)
   103  	if err != nil {
   104  		return false
   105  	}
   106  	return value
   107  }
   108  
   109  func EnsurePermission(st Interface, address crypto.Address, perm permission.PermFlag) {
   110  	if !HasPermission(st, address, perm) {
   111  		st.PushError(errors.PermissionDenied{
   112  			Address: address,
   113  			Perm:    perm,
   114  		})
   115  	}
   116  }
   117  
   118  func (vm *VM) fireCallEvent(eventSink EventSink, callType exec.CallType, errProvider errors.Provider, output *[]byte,
   119  	callerAddress, calleeAddress crypto.Address, input []byte, value uint64, gas *uint64, errSink errors.Sink) {
   120  	// fire the post call event (including exception if applicable)
   121  	eventErr := eventSink.Call(&exec.CallEvent{
   122  		CallType: callType,
   123  		CallData: &exec.CallData{
   124  			Caller: callerAddress,
   125  			Callee: calleeAddress,
   126  			Data:   input,
   127  			Value:  value,
   128  			Gas:    *gas,
   129  		},
   130  		Origin:     vm.origin,
   131  		StackDepth: vm.stackDepth,
   132  		Return:     *output,
   133  	}, errors.AsException(errProvider.Error()))
   134  	errSink.PushError(eventErr)
   135  }
   136  
   137  // CONTRACT state is aware of caller and callee, so we can just mutate them.
   138  // CONTRACT code and input are not mutated.
   139  // CONTRACT returned 'ret' is a new compact slice.
   140  // value: To be transferred from caller to callee. Refunded upon errors.CodedError.
   141  // gas:   Available gas. No refunds for gas.
   142  // code: May be nil, since the CALL opcode may be used to send value from contracts to accounts
   143  func (vm *VM) Call(callState Interface, eventSink EventSink, caller, callee crypto.Address, code,
   144  	input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
   145  
   146  	// Always return output - we may have a reverted exception for which the return is meaningful
   147  	output, err = vm.call(callState, eventSink, caller, callee, code, input, value, gas, exec.CallTypeCall)
   148  	if err == nil {
   149  		err = callState.Error()
   150  	}
   151  	return
   152  }
   153  
   154  func (vm *VM) call(callState Interface, eventSink EventSink, caller, callee crypto.Address, code,
   155  	input []byte, value uint64, gas *uint64, callType exec.CallType) (output []byte, err errors.CodedError) {
   156  
   157  	// fire the post call event (including exception if applicable) and make sure we return the accumulated call error
   158  	defer func() {
   159  		vm.fireCallEvent(eventSink, callType, callState, &output, caller, callee, input, value, gas, callState)
   160  		err = callState.Error()
   161  	}()
   162  
   163  	callState.PushError(transfer(callState, caller, callee, value))
   164  	callState.PushError(vm.ensureStackDepth())
   165  
   166  	// Early exit
   167  	if callState.Error() != nil {
   168  		return
   169  	}
   170  
   171  	if len(code) > 0 {
   172  		vm.stackDepth += 1
   173  		output = vm.execute(callState, eventSink, caller, callee, code, input, value, gas)
   174  		vm.stackDepth -= 1
   175  		if err != nil {
   176  			callState.PushError(err)
   177  			callState.PushError(transfer(callState, callee, caller, value))
   178  		}
   179  	}
   180  
   181  	return
   182  }
   183  
   184  // DelegateCall is executed by the DELEGATECALL opcode, introduced as off Ethereum Homestead.
   185  // The intent of delegate call is to run the code of the callee in the storage context of the caller;
   186  // while preserving the original caller to the previous callee.
   187  // Different to the normal CALL or CALLCODE, the value does not need to be transferred to the callee.
   188  func (vm *VM) delegateCall(callState Interface, eventSink EventSink, caller, callee crypto.Address,
   189  	code, input []byte, value uint64, gas *uint64,
   190  	callType exec.CallType) (output []byte, err errors.CodedError) {
   191  
   192  	// fire the post call event (including exception if applicable) and make sure we return the accumulated call error
   193  	defer func() {
   194  		vm.fireCallEvent(eventSink, callType, callState, &output, caller, callee, input, value, gas, callState)
   195  		err = callState.Error()
   196  	}()
   197  
   198  	// DelegateCall does not transfer the value to the callee.
   199  
   200  	callState.PushError(vm.ensureStackDepth())
   201  
   202  	// Early exit
   203  	if callState.Error() != nil {
   204  		return
   205  	}
   206  
   207  	if len(code) > 0 {
   208  		vm.stackDepth += 1
   209  		output = vm.execute(callState, eventSink, caller, callee, code, input, value, gas)
   210  		vm.stackDepth -= 1
   211  	}
   212  	return
   213  }
   214  
   215  // Try to deduct gasToUse from gasLeft.  If ok return false, otherwise
   216  // set err and return true.
   217  func useGasNegative(gasLeft *uint64, gasToUse uint64, err errors.Sink) {
   218  	if *gasLeft >= gasToUse {
   219  		*gasLeft -= gasToUse
   220  	} else {
   221  		err.PushError(errors.ErrorCodeInsufficientGas)
   222  	}
   223  }
   224  
   225  // Executes the EVM code passed in the appropriate context
   226  func (vm *VM) execute(callState Interface, eventSink EventSink, caller, callee crypto.Address,
   227  	code, input []byte, value uint64, gas *uint64) (returnData []byte) {
   228  	vm.Debugf("(%d) (%s) %s (code=%d) gas: %v (d) %X\n", vm.stackDepth, caller, callee, len(code), *gas, input)
   229  
   230  	logger := vm.logger.With("evm_nonce", vm.nonce)
   231  
   232  	if vm.dumpTokens {
   233  		dumpTokens(vm.nonce, caller, callee, code)
   234  	}
   235  
   236  	// Program counter - the index into code that tracks current instruction
   237  	pc := int64(0)
   238  	// Provide stack and memory storage - passing in the callState as an error provider
   239  	stack := NewStack(vm.params.DataStackInitialCapacity, vm.params.DataStackMaxDepth, gas, callState)
   240  	memory := vm.memoryProvider(callState)
   241  
   242  	for {
   243  		// Check for any error accrued to state
   244  		if callState.Error() != nil {
   245  			return
   246  		}
   247  
   248  		var op = codeGetOp(code, pc)
   249  		vm.Debugf("(pc) %-3d (op) %-14s (st) %-4d (gas) %d", pc, op.String(), stack.Len(), *gas)
   250  		// Use BaseOp gas.
   251  		useGasNegative(gas, GasBaseOp, callState)
   252  
   253  		switch op {
   254  
   255  		case ADD: // 0x01
   256  			x, y := stack.PopBigInt(), stack.PopBigInt()
   257  			sum := new(big.Int).Add(x, y)
   258  			res := stack.PushBigInt(sum)
   259  			vm.Debugf(" %v + %v = %v (%X)\n", x, y, sum, res)
   260  
   261  		case MUL: // 0x02
   262  			x, y := stack.PopBigInt(), stack.PopBigInt()
   263  			prod := new(big.Int).Mul(x, y)
   264  			res := stack.PushBigInt(prod)
   265  			vm.Debugf(" %v * %v = %v (%X)\n", x, y, prod, res)
   266  
   267  		case SUB: // 0x03
   268  			x, y := stack.PopBigInt(), stack.PopBigInt()
   269  			diff := new(big.Int).Sub(x, y)
   270  			res := stack.PushBigInt(diff)
   271  			vm.Debugf(" %v - %v = %v (%X)\n", x, y, diff, res)
   272  
   273  		case DIV: // 0x04
   274  			x, y := stack.PopBigInt(), stack.PopBigInt()
   275  			if y.Sign() == 0 {
   276  				stack.Push(Zero256)
   277  				vm.Debugf(" %x / %x = %v\n", x, y, 0)
   278  			} else {
   279  				div := new(big.Int).Div(x, y)
   280  				res := stack.PushBigInt(div)
   281  				vm.Debugf(" %v / %v = %v (%X)\n", x, y, div, res)
   282  			}
   283  
   284  		case SDIV: // 0x05
   285  			x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned()
   286  			if y.Sign() == 0 {
   287  				stack.Push(Zero256)
   288  				vm.Debugf(" %x / %x = %v\n", x, y, 0)
   289  			} else {
   290  				div := new(big.Int).Div(x, y)
   291  				res := stack.PushBigInt(div)
   292  				vm.Debugf(" %v / %v = %v (%X)\n", x, y, div, res)
   293  			}
   294  
   295  		case MOD: // 0x06
   296  			x, y := stack.PopBigInt(), stack.PopBigInt()
   297  			if y.Sign() == 0 {
   298  				stack.Push(Zero256)
   299  				vm.Debugf(" %v %% %v = %v\n", x, y, 0)
   300  			} else {
   301  				mod := new(big.Int).Mod(x, y)
   302  				res := stack.PushBigInt(mod)
   303  				vm.Debugf(" %v %% %v = %v (%X)\n", x, y, mod, res)
   304  			}
   305  
   306  		case SMOD: // 0x07
   307  			x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned()
   308  			if y.Sign() == 0 {
   309  				stack.Push(Zero256)
   310  				vm.Debugf(" %v %% %v = %v\n", x, y, 0)
   311  			} else {
   312  				mod := new(big.Int).Mod(x, y)
   313  				res := stack.PushBigInt(mod)
   314  				vm.Debugf(" %v %% %v = %v (%X)\n", x, y, mod, res)
   315  			}
   316  
   317  		case ADDMOD: // 0x08
   318  			x, y, z := stack.PopBigInt(), stack.PopBigInt(), stack.PopBigInt()
   319  			if z.Sign() == 0 {
   320  				stack.Push(Zero256)
   321  				vm.Debugf(" %v %% %v = %v\n", x, y, 0)
   322  			} else {
   323  				add := new(big.Int).Add(x, y)
   324  				mod := add.Mod(add, z)
   325  				res := stack.PushBigInt(mod)
   326  				vm.Debugf(" %v + %v %% %v = %v (%X)\n", x, y, z, mod, res)
   327  			}
   328  
   329  		case MULMOD: // 0x09
   330  			x, y, z := stack.PopBigInt(), stack.PopBigInt(), stack.PopBigInt()
   331  			if z.Sign() == 0 {
   332  				stack.Push(Zero256)
   333  				vm.Debugf(" %v %% %v = %v\n", x, y, 0)
   334  			} else {
   335  				mul := new(big.Int).Mul(x, y)
   336  				mod := mul.Mod(mul, z)
   337  				res := stack.PushBigInt(mod)
   338  				vm.Debugf(" %v * %v %% %v = %v (%X)\n", x, y, z, mod, res)
   339  			}
   340  
   341  		case EXP: // 0x0A
   342  			x, y := stack.PopBigInt(), stack.PopBigInt()
   343  			pow := new(big.Int).Exp(x, y, nil)
   344  			res := stack.PushBigInt(pow)
   345  			vm.Debugf(" %v ** %v = %v (%X)\n", x, y, pow, res)
   346  
   347  		case SIGNEXTEND: // 0x0B
   348  			back := stack.PopU64()
   349  			if back < Word256Length-1 {
   350  				stack.PushBigInt(SignExtend(back, stack.PopBigInt()))
   351  			}
   352  
   353  		case LT: // 0x10
   354  			x, y := stack.PopBigInt(), stack.PopBigInt()
   355  			if x.Cmp(y) < 0 {
   356  				stack.Push(One256)
   357  				vm.Debugf(" %v < %v = %v\n", x, y, 1)
   358  			} else {
   359  				stack.Push(Zero256)
   360  				vm.Debugf(" %v < %v = %v\n", x, y, 0)
   361  			}
   362  
   363  		case GT: // 0x11
   364  			x, y := stack.PopBigInt(), stack.PopBigInt()
   365  			if x.Cmp(y) > 0 {
   366  				stack.Push(One256)
   367  				vm.Debugf(" %v > %v = %v\n", x, y, 1)
   368  			} else {
   369  				stack.Push(Zero256)
   370  				vm.Debugf(" %v > %v = %v\n", x, y, 0)
   371  			}
   372  
   373  		case SLT: // 0x12
   374  			x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned()
   375  			if x.Cmp(y) < 0 {
   376  				stack.Push(One256)
   377  				vm.Debugf(" %v < %v = %v\n", x, y, 1)
   378  			} else {
   379  				stack.Push(Zero256)
   380  				vm.Debugf(" %v < %v = %v\n", x, y, 0)
   381  			}
   382  
   383  		case SGT: // 0x13
   384  			x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned()
   385  			if x.Cmp(y) > 0 {
   386  				stack.Push(One256)
   387  				vm.Debugf(" %v > %v = %v\n", x, y, 1)
   388  			} else {
   389  				stack.Push(Zero256)
   390  				vm.Debugf(" %v > %v = %v\n", x, y, 0)
   391  			}
   392  
   393  		case EQ: // 0x14
   394  			x, y := stack.Pop(), stack.Pop()
   395  			if bytes.Equal(x[:], y[:]) {
   396  				stack.Push(One256)
   397  				vm.Debugf(" %X == %X = %v\n", x, y, 1)
   398  			} else {
   399  				stack.Push(Zero256)
   400  				vm.Debugf(" %X == %X = %v\n", x, y, 0)
   401  			}
   402  
   403  		case ISZERO: // 0x15
   404  			x := stack.Pop()
   405  			if x.IsZero() {
   406  				stack.Push(One256)
   407  				vm.Debugf(" %X == 0 = %v\n", x, 1)
   408  			} else {
   409  				stack.Push(Zero256)
   410  				vm.Debugf(" %X == 0 = %v\n", x, 0)
   411  			}
   412  
   413  		case AND: // 0x16
   414  			x, y := stack.Pop(), stack.Pop()
   415  			z := [32]byte{}
   416  			for i := 0; i < 32; i++ {
   417  				z[i] = x[i] & y[i]
   418  			}
   419  			stack.Push(z)
   420  			vm.Debugf(" %X & %X = %X\n", x, y, z)
   421  
   422  		case OR: // 0x17
   423  			x, y := stack.Pop(), stack.Pop()
   424  			z := [32]byte{}
   425  			for i := 0; i < 32; i++ {
   426  				z[i] = x[i] | y[i]
   427  			}
   428  			stack.Push(z)
   429  			vm.Debugf(" %X | %X = %X\n", x, y, z)
   430  
   431  		case XOR: // 0x18
   432  			x, y := stack.Pop(), stack.Pop()
   433  			z := [32]byte{}
   434  			for i := 0; i < 32; i++ {
   435  				z[i] = x[i] ^ y[i]
   436  			}
   437  			stack.Push(z)
   438  			vm.Debugf(" %X ^ %X = %X\n", x, y, z)
   439  
   440  		case NOT: // 0x19
   441  			x := stack.Pop()
   442  			z := [32]byte{}
   443  			for i := 0; i < 32; i++ {
   444  				z[i] = ^x[i]
   445  			}
   446  			stack.Push(z)
   447  			vm.Debugf(" !%X = %X\n", x, z)
   448  
   449  		case BYTE: // 0x1A
   450  			idx := stack.Pop64()
   451  			val := stack.Pop()
   452  			res := byte(0)
   453  			if idx < 32 {
   454  				res = val[idx]
   455  			}
   456  			stack.Push64(int64(res))
   457  			vm.Debugf(" => 0x%X\n", res)
   458  
   459  		case SHL: //0x1B
   460  			shift, x := stack.PopBigInt(), stack.PopBigInt()
   461  
   462  			if shift.Cmp(Big256) >= 0 {
   463  				reset := big.NewInt(0)
   464  				stack.PushBigInt(reset)
   465  				vm.Debugf(" %v << %v = %v\n", x, shift, reset)
   466  			} else {
   467  				shiftedValue := x.Lsh(x, uint(shift.Uint64()))
   468  				stack.PushBigInt(shiftedValue)
   469  				vm.Debugf(" %v << %v = %v\n", x, shift, shiftedValue)
   470  			}
   471  
   472  		case SHR: //0x1C
   473  			shift, x := stack.PopBigInt(), stack.PopBigInt()
   474  
   475  			if shift.Cmp(Big256) >= 0 {
   476  				reset := big.NewInt(0)
   477  				stack.PushBigInt(reset)
   478  				vm.Debugf(" %v << %v = %v\n", x, shift, reset)
   479  			} else {
   480  				shiftedValue := x.Rsh(x, uint(shift.Uint64()))
   481  				stack.PushBigInt(shiftedValue)
   482  				vm.Debugf(" %v << %v = %v\n", x, shift, shiftedValue)
   483  			}
   484  
   485  		case SAR: //0x1D
   486  			shift, x := stack.PopBigInt(), stack.PopBigIntSigned()
   487  
   488  			if shift.Cmp(Big256) >= 0 {
   489  				reset := big.NewInt(0)
   490  				if x.Sign() < 0 {
   491  					reset.SetInt64(-1)
   492  				}
   493  				stack.PushBigInt(reset)
   494  				vm.Debugf(" %v << %v = %v\n", x, shift, reset)
   495  			} else {
   496  				shiftedValue := x.Rsh(x, uint(shift.Uint64()))
   497  				stack.PushBigInt(shiftedValue)
   498  				vm.Debugf(" %v << %v = %v\n", x, shift, shiftedValue)
   499  			}
   500  
   501  		case SHA3: // 0x20
   502  			useGasNegative(gas, GasSha3, callState)
   503  			offset, size := stack.PopBigInt(), stack.PopBigInt()
   504  			data := memory.Read(offset, size)
   505  			data = sha3.Sha3(data)
   506  			stack.PushBytes(data)
   507  			vm.Debugf(" => (%v) %X\n", size, data)
   508  
   509  		case ADDRESS: // 0x30
   510  			stack.Push(callee.Word256())
   511  			vm.Debugf(" => %X\n", callee)
   512  
   513  		case BALANCE: // 0x31
   514  			address := stack.PopAddress()
   515  			useGasNegative(gas, GasGetAccount, callState)
   516  			balance := callState.GetBalance(address)
   517  			stack.PushU64(balance)
   518  			vm.Debugf(" => %v (%X)\n", balance, address)
   519  
   520  		case ORIGIN: // 0x32
   521  			stack.Push(vm.origin.Word256())
   522  			vm.Debugf(" => %X\n", vm.origin)
   523  
   524  		case CALLER: // 0x33
   525  			stack.Push(caller.Word256())
   526  			vm.Debugf(" => %X\n", caller)
   527  
   528  		case CALLVALUE: // 0x34
   529  			stack.PushU64(value)
   530  			vm.Debugf(" => %v\n", value)
   531  
   532  		case CALLDATALOAD: // 0x35
   533  			offset := stack.Pop64()
   534  			data := subslice(input, offset, 32, callState)
   535  			res := LeftPadWord256(data)
   536  			stack.Push(res)
   537  			vm.Debugf(" => 0x%X\n", res)
   538  
   539  		case CALLDATASIZE: // 0x36
   540  			stack.Push64(int64(len(input)))
   541  			vm.Debugf(" => %d\n", len(input))
   542  
   543  		case CALLDATACOPY: // 0x37
   544  			memOff := stack.PopBigInt()
   545  			inputOff := stack.Pop64()
   546  			length := stack.Pop64()
   547  			data := subslice(input, inputOff, length, callState)
   548  			memory.Write(memOff, data)
   549  			vm.Debugf(" => [%v, %v, %v] %X\n", memOff, inputOff, length, data)
   550  
   551  		case CODESIZE: // 0x38
   552  			l := int64(len(code))
   553  			stack.Push64(l)
   554  			vm.Debugf(" => %d\n", l)
   555  
   556  		case CODECOPY: // 0x39
   557  			memOff := stack.PopBigInt()
   558  			codeOff := stack.Pop64()
   559  			length := stack.Pop64()
   560  			data := subslice(code, codeOff, length, callState)
   561  			memory.Write(memOff, data)
   562  			vm.Debugf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
   563  
   564  		case GASPRICE_DEPRECATED: // 0x3A
   565  			stack.Push(Zero256)
   566  			vm.Debugf(" => %X (GASPRICE IS DEPRECATED)\n", Zero256)
   567  
   568  		case EXTCODESIZE: // 0x3B
   569  			address := stack.PopAddress()
   570  			useGasNegative(gas, GasGetAccount, callState)
   571  			if callState.Exists(address) {
   572  				code := callState.GetCode(address)
   573  				l := int64(len(code))
   574  				stack.Push64(l)
   575  				vm.Debugf(" => %d\n", l)
   576  			} else {
   577  				if _, ok := registeredNativeContracts[address]; !ok {
   578  					callState.PushError(errors.ErrorCodeUnknownAddress)
   579  					continue
   580  				}
   581  				vm.Debugf(" => returning code size of 1 to indicated existence of native contract at %X\n", address)
   582  				stack.Push(One256)
   583  			}
   584  		case EXTCODECOPY: // 0x3C
   585  			address := stack.PopAddress()
   586  			useGasNegative(gas, GasGetAccount, callState)
   587  			if !callState.Exists(address) {
   588  				if _, ok := registeredNativeContracts[address]; ok {
   589  					vm.Debugf(" => attempted to copy native contract at %v but this is not supported\n", address)
   590  					callState.PushError(errors.ErrorCodeNativeContractCodeCopy)
   591  				}
   592  				callState.PushError(errors.ErrorCodeUnknownAddress)
   593  				continue
   594  			}
   595  			code := callState.GetCode(address)
   596  			memOff := stack.PopBigInt()
   597  			codeOff := stack.Pop64()
   598  			length := stack.Pop64()
   599  			data := subslice(code, codeOff, length, callState)
   600  			memory.Write(memOff, data)
   601  			vm.Debugf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
   602  
   603  		case RETURNDATASIZE: // 0x3D
   604  			stack.Push64(int64(len(returnData)))
   605  			vm.Debugf(" => %d\n", len(returnData))
   606  
   607  		case RETURNDATACOPY: // 0x3E
   608  			memOff, outputOff, length := stack.PopBigInt(), stack.PopBigInt(), stack.PopBigInt()
   609  			end := new(big.Int).Add(outputOff, length)
   610  
   611  			if end.BitLen() > 64 || uint64(len(returnData)) < end.Uint64() {
   612  				callState.PushError(errors.ErrorCodeReturnDataOutOfBounds)
   613  				continue
   614  			}
   615  
   616  			memory.Write(memOff, returnData)
   617  			vm.Debugf(" => [%v, %v, %v] %X\n", memOff, outputOff, length, returnData)
   618  
   619  		case EXTCODEHASH: // 0x3F
   620  			address := stack.PopAddress()
   621  
   622  			if !callState.Exists(address) {
   623  				// In case the account does not exist 0 is pushed to the stack.
   624  				stack.PushU64(0)
   625  			} else {
   626  				code := callState.GetCode(address)
   627  				if code == nil {
   628  					// In case the account does not have code the keccak256 hash of empty data
   629  					code = acm.Bytecode{}
   630  				}
   631  
   632  				// keccak256 hash of a contract's code
   633  				var extcodehash Word256
   634  				hash := sha3.NewKeccak256()
   635  				hash.Write(code)
   636  				copy(extcodehash[:], hash.Sum(nil))
   637  
   638  				stack.Push(extcodehash)
   639  			}
   640  
   641  		case BLOCKHASH: // 0x40
   642  			blockNumber := stack.PopU64()
   643  
   644  			if blockNumber >= vm.params.BlockHeight {
   645  				vm.Debugf(" => attempted to get block hash of a non-existent block: %v", blockNumber)
   646  				callState.PushError(errors.ErrorCodeInvalidBlockNumber)
   647  			} else if vm.params.BlockHeight-blockNumber > MaximumAllowedBlockLookBack {
   648  				vm.Debugf(" => attempted to get block hash of a block %d outside of the allowed range "+
   649  					"(must be within %d blocks)", blockNumber, MaximumAllowedBlockLookBack)
   650  				callState.PushError(errors.ErrorCodeBlockNumberOutOfRange)
   651  			} else {
   652  				blockHash, err := callState.GetBlockHash(blockNumber)
   653  				if err != nil {
   654  					vm.Debugf(" => error attempted to get block hash: %v, %v", blockNumber, err)
   655  					callState.PushError(errors.ErrorCodeInvalidBlockNumber)
   656  				} else {
   657  					stack.Push(blockHash)
   658  					vm.Debugf(" => 0x%X\n", blockHash)
   659  				}
   660  			}
   661  
   662  		case COINBASE: // 0x41
   663  			stack.Push(Zero256)
   664  			vm.Debugf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes())
   665  
   666  		case TIMESTAMP: // 0x42
   667  			time := vm.params.BlockTime
   668  			stack.Push64(int64(time))
   669  			vm.Debugf(" => 0x%X\n", time)
   670  
   671  		case BLOCKHEIGHT: // 0x43
   672  			number := vm.params.BlockHeight
   673  			stack.PushU64(number)
   674  			vm.Debugf(" => 0x%X\n", number)
   675  
   676  		case GASLIMIT: // 0x45
   677  			stack.PushU64(vm.params.GasLimit)
   678  			vm.Debugf(" => %v\n", vm.params.GasLimit)
   679  
   680  		case POP: // 0x50
   681  			popped := stack.Pop()
   682  			vm.Debugf(" => 0x%X\n", popped)
   683  
   684  		case MLOAD: // 0x51
   685  			offset := stack.PopBigInt()
   686  			data := memory.Read(offset, BigWord256Length)
   687  			stack.Push(LeftPadWord256(data))
   688  			vm.Debugf(" => 0x%X @ 0x%X\n", data, offset)
   689  
   690  		case MSTORE: // 0x52
   691  			offset, data := stack.PopBigInt(), stack.Pop()
   692  			memory.Write(offset, data.Bytes())
   693  			vm.Debugf(" => 0x%X @ 0x%X\n", data, offset)
   694  
   695  		case MSTORE8: // 0x53
   696  			offset := stack.PopBigInt()
   697  			val64 := stack.Pop64()
   698  			val := byte(val64 & 0xFF)
   699  			memory.Write(offset, []byte{val})
   700  			vm.Debugf(" => [%v] 0x%X\n", offset, val)
   701  
   702  		case SLOAD: // 0x54
   703  			loc := stack.Pop()
   704  			data := callState.GetStorage(callee, loc)
   705  			stack.Push(data)
   706  			vm.Debugf("%s {0x%X = 0x%X}\n", callee, loc, data)
   707  
   708  		case SSTORE: // 0x55
   709  			loc, data := stack.Pop(), stack.Pop()
   710  			useGasNegative(gas, GasStorageUpdate, callState)
   711  			callState.SetStorage(callee, loc, data)
   712  			vm.Debugf("%s {0x%X := 0x%X}\n", callee, loc, data)
   713  
   714  		case JUMP: // 0x56
   715  			to := stack.Pop64()
   716  			vm.jump(code, to, &pc, callState)
   717  			continue
   718  
   719  		case JUMPI: // 0x57
   720  			pos := stack.Pop64()
   721  			cond := stack.Pop()
   722  			if !cond.IsZero() {
   723  				vm.jump(code, pos, &pc, callState)
   724  				continue
   725  			}
   726  			vm.Debugf(" ~> false\n")
   727  
   728  		case PC: // 0x58
   729  			stack.Push64(pc)
   730  
   731  		case MSIZE: // 0x59
   732  			// Note: Solidity will write to this offset expecting to find guaranteed
   733  			// free memory to be allocated for it if a subsequent MSTORE is made to
   734  			// this offset.
   735  			capacity := memory.Capacity()
   736  			stack.PushBigInt(capacity)
   737  			vm.Debugf(" => 0x%X\n", capacity)
   738  
   739  		case GAS: // 0x5A
   740  			stack.PushU64(*gas)
   741  			vm.Debugf(" => %X\n", *gas)
   742  
   743  		case JUMPDEST: // 0x5B
   744  			vm.Debugf("\n")
   745  			// Do nothing
   746  
   747  		case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
   748  			a := int64(op - PUSH1 + 1)
   749  			codeSegment := subslice(code, pc+1, a, callState)
   750  			res := LeftPadWord256(codeSegment)
   751  			stack.Push(res)
   752  			pc += a
   753  			vm.Debugf(" => 0x%X\n", res)
   754  
   755  		case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
   756  			n := int(op - DUP1 + 1)
   757  			stack.Dup(n)
   758  			vm.Debugf(" => [%d] 0x%X\n", n, stack.Peek().Bytes())
   759  
   760  		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
   761  			n := int(op - SWAP1 + 2)
   762  			stack.Swap(n)
   763  			vm.Debugf(" => [%d] %X\n", n, stack.Peek())
   764  
   765  		case LOG0, LOG1, LOG2, LOG3, LOG4:
   766  			n := int(op - LOG0)
   767  			topics := make([]Word256, n)
   768  			offset, size := stack.PopBigInt(), stack.PopBigInt()
   769  			for i := 0; i < n; i++ {
   770  				topics[i] = stack.Pop()
   771  			}
   772  			data := memory.Read(offset, size)
   773  			callState.PushError(eventSink.Log(&exec.LogEvent{
   774  				Address: callee,
   775  				Topics:  topics,
   776  				Data:    data,
   777  			}))
   778  			vm.Debugf(" => T:%X D:%X\n", topics, data)
   779  
   780  		case CREATE, CREATE2: // 0xF0, 0xFB
   781  			returnData = nil
   782  			contractValue := stack.PopU64()
   783  			offset, size := stack.PopBigInt(), stack.PopBigInt()
   784  			input := memory.Read(offset, size)
   785  
   786  			// TODO charge for gas to create account _ the code length * GasCreateByte
   787  			useGasNegative(gas, GasCreateAccount, callState)
   788  
   789  			var newAccount crypto.Address
   790  			if op == CREATE {
   791  				vm.sequence++
   792  				nonce := make([]byte, txs.HashLength+uint64Length)
   793  				copy(nonce, vm.nonce)
   794  				PutUint64BE(nonce[txs.HashLength:], vm.sequence)
   795  				newAccount = crypto.NewContractAddress(callee, nonce)
   796  			} else if op == CREATE2 {
   797  				salt := stack.Pop()
   798  				newAccount = crypto.NewContractAddress2(callee, salt, callState.GetCode(callee))
   799  			}
   800  
   801  			// Check the CreateContract permission for this account
   802  			EnsurePermission(callState, callee, permission.CreateContract)
   803  			if callState.Error() != nil {
   804  				continue
   805  			}
   806  
   807  			// Establish a frame in which the putative account exists
   808  			childCallState := callState.NewCache()
   809  			create(childCallState, newAccount)
   810  
   811  			// Run the input to get the contract code.
   812  			// NOTE: no need to copy 'input' as per Call contract.
   813  			ret, callErr := vm.Call(childCallState, eventSink, callee, newAccount, input, input, contractValue, gas)
   814  			if callErr != nil {
   815  				stack.Push(Zero256)
   816  				// Note we both set the return buffer and return the result normally
   817  				returnData = ret
   818  			} else {
   819  				// Update the account with its initialised contract code
   820  				childCallState.InitCode(newAccount, ret)
   821  				callState.PushError(childCallState.Sync())
   822  				stack.PushAddress(newAccount)
   823  			}
   824  
   825  		case CALL, CALLCODE, DELEGATECALL, STATICCALL: // 0xF1, 0xF2, 0xF4, 0xFA
   826  			returnData = nil
   827  
   828  			EnsurePermission(callState, callee, permission.Call)
   829  			if callState.Error() != nil {
   830  				continue
   831  			}
   832  			gasLimit := stack.PopU64()
   833  			address := stack.PopAddress()
   834  			// NOTE: for DELEGATECALL value is preserved from the original
   835  			// caller, as such it is not stored on stack as an argument
   836  			// for DELEGATECALL and should not be popped.  Instead previous
   837  			// caller value is used.  for CALL and CALLCODE value is stored
   838  			// on stack and needs to be overwritten from the given value.
   839  			if op != DELEGATECALL && op != STATICCALL {
   840  				value = stack.PopU64()
   841  			}
   842  			// inputs
   843  			inOffset, inSize := stack.PopBigInt(), stack.PopBigInt()
   844  			// outputs
   845  			retOffset := stack.PopBigInt()
   846  			retSize := stack.Pop64()
   847  			vm.Debugf(" => %v\n", address)
   848  
   849  			// Get the arguments from the memory
   850  			args := memory.Read(inOffset, inSize)
   851  
   852  			// Ensure that gasLimit is reasonable
   853  			if *gas < gasLimit {
   854  				// EIP150 - the 63/64 rule - rather than errors.CodedError we pass this specified fraction of the total available gas
   855  				gasLimit = *gas - *gas/64
   856  			}
   857  			// NOTE: we will return any used gas later.
   858  			*gas -= gasLimit
   859  
   860  			// Begin execution
   861  			var callErr errors.CodedError
   862  			// Establish a stack frame and perform the call
   863  			var childCallState Interface
   864  			if IsRegisteredNativeContract(address) {
   865  				// Native contract
   866  				childCallState = callState.NewCache()
   867  				returnData, callErr = ExecuteNativeContract(address, childCallState, callee, args, &gasLimit, logger)
   868  				childCallState.PushError(callErr)
   869  				// for now we fire the Call event. maybe later we'll fire more particulars
   870  				// NOTE: these fire call go_events and not particular go_events for eg name reg or permissions
   871  				vm.fireCallEvent(eventSink, exec.CallTypeSNative, childCallState, &returnData, callee, address, args, value,
   872  					&gasLimit, childCallState)
   873  			} else {
   874  				// EVM contract
   875  				useGasNegative(gas, GasGetAccount, callState)
   876  				// since CALL is used also for sending funds,
   877  				// acc may not exist yet. This is an errors.CodedError for
   878  				// CALLCODE, but not for CALL, though I don't think
   879  				// ethereum actually cares
   880  				if !callState.Exists(address) {
   881  					if op != CALL {
   882  						callState.PushError(errors.ErrorCodeUnknownAddress)
   883  						continue
   884  					}
   885  					// We're sending funds to a new account so we must create it first
   886  					createAccount(callState, callee, address)
   887  					if callState.Error() != nil {
   888  						continue
   889  					}
   890  				}
   891  				switch op {
   892  				case CALL:
   893  					childCallState = callState.NewCache()
   894  					returnData, callErr = vm.call(childCallState, eventSink, callee, address, callState.GetCode(address),
   895  						args, value, &gasLimit, exec.CallTypeCall)
   896  
   897  				case CALLCODE:
   898  					childCallState = callState.NewCache()
   899  					returnData, callErr = vm.call(childCallState, eventSink, callee, callee, callState.GetCode(address),
   900  						args, value, &gasLimit, exec.CallTypeCode)
   901  
   902  				case DELEGATECALL:
   903  					childCallState = callState.NewCache()
   904  					returnData, callErr = vm.delegateCall(childCallState, eventSink, caller, callee,
   905  						callState.GetCode(address), args, value, &gasLimit, exec.CallTypeDelegate)
   906  
   907  				case STATICCALL:
   908  					childCallState = callState.NewCache(acmstate.ReadOnly)
   909  					returnData, callErr = vm.delegateCall(childCallState, NewLogFreeEventSink(eventSink),
   910  						callee, address, callState.GetCode(address), args, value, &gasLimit, exec.CallTypeStatic)
   911  
   912  				default:
   913  					panic(fmt.Errorf("switch statement should be exhaustive so this should not have been reached"))
   914  				}
   915  
   916  			}
   917  
   918  			if callErr == nil {
   919  				// Sync error is a hard stop
   920  				callState.PushError(childCallState.Sync())
   921  			}
   922  
   923  			// Push result
   924  			if callErr != nil {
   925  				vm.Debugf("error from nested sub-call (depth: %v): %s\n", vm.stackDepth, callErr.Error())
   926  				// So we can return nested errors.CodedError if the top level return is an errors.CodedError
   927  				stack.Push(Zero256)
   928  
   929  				if callErr.ErrorCode() == errors.ErrorCodeExecutionReverted {
   930  					memory.Write(retOffset, RightPadBytes(returnData, int(retSize)))
   931  				}
   932  			} else {
   933  				stack.Push(One256)
   934  
   935  				// Should probably only be necessary when there is no return value and
   936  				// returnData is empty, but since EVM expects retSize to be respected this will
   937  				// defensively pad or truncate the portion of returnData to be returned.
   938  				memory.Write(retOffset, RightPadBytes(returnData, int(retSize)))
   939  			}
   940  
   941  			// Handle remaining gas.
   942  			*gas += gasLimit
   943  
   944  			vm.Debugf("resume %s (%v)\n", callee, gas)
   945  
   946  		case RETURN: // 0xF3
   947  			offset, size := stack.PopBigInt(), stack.PopBigInt()
   948  			output := memory.Read(offset, size)
   949  			vm.Debugf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(output), output)
   950  			return output
   951  
   952  		case REVERT: // 0xFD
   953  			offset, size := stack.PopBigInt(), stack.PopBigInt()
   954  			output := memory.Read(offset, size)
   955  			vm.Debugf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(output), output)
   956  			callState.PushError(newRevertException(output))
   957  			return output
   958  
   959  		case INVALID: // 0xFE
   960  			callState.PushError(errors.ErrorCodeExecutionAborted)
   961  			return nil
   962  
   963  		case SELFDESTRUCT: // 0xFF
   964  			receiver := stack.PopAddress()
   965  			useGasNegative(gas, GasGetAccount, callState)
   966  			if !callState.Exists(receiver) {
   967  				// If receiver address doesn't exist, try to create it
   968  				useGasNegative(gas, GasCreateAccount, callState)
   969  				createAccount(callState, callee, receiver)
   970  				if callState.Error() != nil {
   971  					continue
   972  				}
   973  			}
   974  			balance := callState.GetBalance(callee)
   975  			callState.AddToBalance(receiver, balance)
   976  			callState.RemoveAccount(callee)
   977  			vm.Debugf(" => (%X) %v\n", receiver[:4], balance)
   978  			return nil
   979  
   980  		case STOP: // 0x00
   981  			return nil
   982  
   983  		default:
   984  			vm.Debugf("(pc) %-3v Unknown opcode %v\n", pc, op)
   985  			callState.PushError(errors.Errorf("unknown opcode %v", op))
   986  			return nil
   987  		}
   988  		pc++
   989  	}
   990  	return
   991  }
   992  
   993  func createAccount(st Interface, creator, address crypto.Address) {
   994  	EnsurePermission(st, creator, permission.CreateAccount)
   995  	create(st, address)
   996  }
   997  
   998  func create(st Interface, address crypto.Address) {
   999  	if IsRegisteredNativeContract(address) {
  1000  		st.PushError(errors.ErrorCodef(errors.ErrorCodeReservedAddress,
  1001  			"cannot create account at %v because that address is reserved for a native contract", address))
  1002  	}
  1003  	st.CreateAccount(address)
  1004  }
  1005  
  1006  // Returns a subslice from offset of length length and a bool
  1007  // (true iff slice was possible). If the subslice
  1008  // extends past the end of data it returns A COPY of the segment at the end of
  1009  // data padded with zeroes on the right. If offset == len(data) it returns all
  1010  // zeroes. if offset > len(data) it returns a false
  1011  func subslice(data []byte, offset, length int64, err errors.Sink) []byte {
  1012  	size := int64(len(data))
  1013  	if size < offset || offset < 0 || length < 0 {
  1014  		err.PushError(errors.ErrorCodef(errors.ErrorCodeInputOutOfBounds,
  1015  			"subslice could not slice data of size %d at offset %d for length %d", size, offset, length))
  1016  		return nil
  1017  	}
  1018  	if size < offset+length {
  1019  		// Extract slice from offset to end padding to requested length
  1020  		ret := make([]byte, length)
  1021  		copy(ret, data[offset:])
  1022  		return ret
  1023  	}
  1024  	return data[offset : offset+length]
  1025  }
  1026  
  1027  func codeGetOp(code []byte, n int64) OpCode {
  1028  	if int64(len(code)) <= n {
  1029  		return OpCode(0) // stop
  1030  	} else {
  1031  		return OpCode(code[n])
  1032  	}
  1033  }
  1034  
  1035  func (vm *VM) jump(code []byte, to int64, pc *int64, err errors.Sink) {
  1036  	dest := codeGetOp(code, to)
  1037  	if dest != JUMPDEST {
  1038  		vm.Debugf(" ~> %v invalid jump dest %v\n", to, dest)
  1039  		err.PushError(errors.ErrorCodeInvalidJumpDest)
  1040  		return
  1041  	}
  1042  	vm.Debugf(" ~> %v\n", to)
  1043  	*pc = to
  1044  }
  1045  
  1046  func transfer(st Interface, from, to crypto.Address, amount uint64) errors.CodedError {
  1047  	if amount == 0 {
  1048  		return nil
  1049  	}
  1050  	if st.GetBalance(from) < amount {
  1051  		return errors.ErrorCodeInsufficientBalance
  1052  	} else {
  1053  		st.SubtractFromBalance(from, amount)
  1054  		st.AddToBalance(to, amount)
  1055  	}
  1056  	err := st.Error()
  1057  	if err != nil {
  1058  		return err
  1059  	}
  1060  	return nil
  1061  }
  1062  
  1063  // Dump the bytecode being sent to the EVM in the current working directory
  1064  func dumpTokens(nonce []byte, caller, callee crypto.Address, code []byte) {
  1065  	var tokensString string
  1066  	tokens, err := acm.Bytecode(code).Tokens()
  1067  	if err != nil {
  1068  		tokensString = fmt.Sprintf("error generating tokens from bytecode: %v", err)
  1069  	} else {
  1070  		tokensString = strings.Join(tokens, "\n")
  1071  	}
  1072  	txHashString := "nil-nonce"
  1073  	if len(nonce) >= 4 {
  1074  		txHashString = fmt.Sprintf("nonce-%X", nonce[:4])
  1075  	}
  1076  	callerString := "caller-none"
  1077  	if caller != crypto.ZeroAddress {
  1078  		callerString = fmt.Sprintf("caller-%v", caller)
  1079  	}
  1080  	calleeString := "callee-none"
  1081  	if callee != crypto.ZeroAddress {
  1082  		calleeString = fmt.Sprintf("callee-%v", caller)
  1083  	}
  1084  	ioutil.WriteFile(fmt.Sprintf("tokens_%s_%s_%s.asm", txHashString, callerString, calleeString),
  1085  		[]byte(tokensString), 0777)
  1086  }
  1087  
  1088  func (vm *VM) ensureStackDepth() errors.CodedError {
  1089  	if vm.params.CallStackMaxDepth > 0 && vm.stackDepth == vm.params.CallStackMaxDepth {
  1090  		return errors.ErrorCodeCallStackOverflow
  1091  	}
  1092  	return nil
  1093  }
  1094  
  1095  func newRevertException(ret []byte) errors.CodedError {
  1096  	code := errors.ErrorCodeExecutionReverted
  1097  	if len(ret) > 0 {
  1098  		// Attempt decode
  1099  		reason, err := abi.UnpackRevert(ret)
  1100  		if err == nil {
  1101  			return errors.ErrorCodef(code, "with reason '%s'", *reason)
  1102  		}
  1103  	}
  1104  	return code
  1105  }