github.com/karalabe/go-ethereum@v0.8.5/vm/vm.go (about)

     1  package vm
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  
     7  	"github.com/ethereum/go-ethereum/crypto"
     8  	"github.com/ethereum/go-ethereum/ethutil"
     9  	"github.com/ethereum/go-ethereum/state"
    10  )
    11  
    12  type Vm struct {
    13  	env Environment
    14  
    15  	logTy  byte
    16  	logStr string
    17  
    18  	err error
    19  
    20  	Dbg Debugger
    21  
    22  	BreakPoints []int64
    23  	Stepping    bool
    24  	Fn          string
    25  
    26  	Recoverable bool
    27  }
    28  
    29  func New(env Environment) *Vm {
    30  	lt := LogTyPretty
    31  	if ethutil.Config.Diff {
    32  		lt = LogTyDiff
    33  	}
    34  
    35  	return &Vm{env: env, logTy: lt, Recoverable: true}
    36  }
    37  
    38  func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
    39  	self.env.SetDepth(self.env.Depth() + 1)
    40  
    41  	context := NewContext(caller, me, code, gas, price)
    42  
    43  	vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData)
    44  
    45  	if self.Recoverable {
    46  		// Recover from any require exception
    47  		defer func() {
    48  			if r := recover(); r != nil {
    49  				self.Printf(" %v", r).Endl()
    50  
    51  				context.UseGas(context.Gas)
    52  
    53  				ret = context.Return(nil)
    54  
    55  				err = fmt.Errorf("%v", r)
    56  
    57  			}
    58  		}()
    59  	}
    60  
    61  	if p := Precompiled[string(me.Address())]; p != nil {
    62  		return self.RunPrecompiled(p, callData, context)
    63  	}
    64  
    65  	var (
    66  		op OpCode
    67  
    68  		destinations        = analyseJumpDests(context.Code)
    69  		mem                 = NewMemory()
    70  		stack               = NewStack()
    71  		pc           uint64 = 0
    72  		step                = 0
    73  		prevStep            = 0
    74  		statedb             = self.env.State()
    75  
    76  		jump = func(from uint64, to *big.Int) {
    77  			p := to.Uint64()
    78  
    79  			nop := context.GetOp(p)
    80  			if !destinations.Has(p) {
    81  				panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
    82  			}
    83  
    84  			self.Printf(" ~> %v", to)
    85  			pc = to.Uint64()
    86  
    87  			self.Endl()
    88  		}
    89  	)
    90  
    91  	// Don't bother with the execution if there's no code.
    92  	if len(code) == 0 {
    93  		return context.Return(nil), nil
    94  	}
    95  
    96  	for {
    97  		prevStep = step
    98  		// The base for all big integer arithmetic
    99  		base := new(big.Int)
   100  
   101  		step++
   102  		// Get the memory location of pc
   103  		op = context.GetOp(pc)
   104  
   105  		self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len())
   106  		if self.Dbg != nil {
   107  			//self.Dbg.Step(self, op, mem, stack, context)
   108  		}
   109  
   110  		newMemSize, gas := self.calculateGasAndSize(context, caller, op, statedb, mem, stack)
   111  
   112  		self.Printf("(g) %-3v (%v)", gas, context.Gas)
   113  
   114  		if !context.UseGas(gas) {
   115  			self.Endl()
   116  
   117  			tmp := new(big.Int).Set(context.Gas)
   118  
   119  			context.UseGas(context.Gas)
   120  
   121  			return context.Return(nil), OOG(gas, tmp)
   122  		}
   123  
   124  		mem.Resize(newMemSize.Uint64())
   125  
   126  		switch op {
   127  		// 0x20 range
   128  		case ADD:
   129  			x, y := stack.Popn()
   130  			self.Printf(" %v + %v", y, x)
   131  
   132  			base.Add(y, x)
   133  
   134  			U256(base)
   135  
   136  			self.Printf(" = %v", base)
   137  			// Pop result back on the stack
   138  			stack.Push(base)
   139  		case SUB:
   140  			x, y := stack.Popn()
   141  			self.Printf(" %v - %v", y, x)
   142  
   143  			base.Sub(y, x)
   144  
   145  			U256(base)
   146  
   147  			self.Printf(" = %v", base)
   148  			// Pop result back on the stack
   149  			stack.Push(base)
   150  		case MUL:
   151  			x, y := stack.Popn()
   152  			self.Printf(" %v * %v", y, x)
   153  
   154  			base.Mul(y, x)
   155  
   156  			U256(base)
   157  
   158  			self.Printf(" = %v", base)
   159  			// Pop result back on the stack
   160  			stack.Push(base)
   161  		case DIV:
   162  			x, y := stack.Pop(), stack.Pop()
   163  			self.Printf(" %v / %v", x, y)
   164  
   165  			if y.Cmp(ethutil.Big0) != 0 {
   166  				base.Div(x, y)
   167  			}
   168  
   169  			U256(base)
   170  
   171  			self.Printf(" = %v", base)
   172  			// Pop result back on the stack
   173  			stack.Push(base)
   174  		case SDIV:
   175  			x, y := S256(stack.Pop()), S256(stack.Pop())
   176  
   177  			self.Printf(" %v / %v", x, y)
   178  
   179  			if y.Cmp(ethutil.Big0) == 0 {
   180  				base.Set(ethutil.Big0)
   181  			} else {
   182  				n := new(big.Int)
   183  				if new(big.Int).Mul(x, y).Cmp(ethutil.Big0) < 0 {
   184  					n.SetInt64(-1)
   185  				} else {
   186  					n.SetInt64(1)
   187  				}
   188  
   189  				base.Div(x.Abs(x), y.Abs(y)).Mul(base, n)
   190  
   191  				U256(base)
   192  			}
   193  
   194  			self.Printf(" = %v", base)
   195  			stack.Push(base)
   196  		case MOD:
   197  			x, y := stack.Pop(), stack.Pop()
   198  
   199  			self.Printf(" %v %% %v", x, y)
   200  
   201  			if y.Cmp(ethutil.Big0) == 0 {
   202  				base.Set(ethutil.Big0)
   203  			} else {
   204  				base.Mod(x, y)
   205  			}
   206  
   207  			U256(base)
   208  
   209  			self.Printf(" = %v", base)
   210  			stack.Push(base)
   211  		case SMOD:
   212  			x, y := S256(stack.Pop()), S256(stack.Pop())
   213  
   214  			self.Printf(" %v %% %v", x, y)
   215  
   216  			if y.Cmp(ethutil.Big0) == 0 {
   217  				base.Set(ethutil.Big0)
   218  			} else {
   219  				n := new(big.Int)
   220  				if x.Cmp(ethutil.Big0) < 0 {
   221  					n.SetInt64(-1)
   222  				} else {
   223  					n.SetInt64(1)
   224  				}
   225  
   226  				base.Mod(x.Abs(x), y.Abs(y)).Mul(base, n)
   227  
   228  				U256(base)
   229  			}
   230  
   231  			self.Printf(" = %v", base)
   232  			stack.Push(base)
   233  
   234  		case EXP:
   235  			x, y := stack.Popn()
   236  
   237  			self.Printf(" %v ** %v", y, x)
   238  
   239  			base.Exp(y, x, Pow256)
   240  
   241  			U256(base)
   242  
   243  			self.Printf(" = %v", base)
   244  
   245  			stack.Push(base)
   246  		case SIGNEXTEND:
   247  			back := stack.Pop().Uint64()
   248  			if back < 31 {
   249  				bit := uint(back*8 + 7)
   250  				num := stack.Pop()
   251  				mask := new(big.Int).Lsh(ethutil.Big1, bit)
   252  				mask.Sub(mask, ethutil.Big1)
   253  				if ethutil.BitTest(num, int(bit)) {
   254  					num.Or(num, mask.Not(mask))
   255  				} else {
   256  					num.And(num, mask)
   257  				}
   258  
   259  				num = U256(num)
   260  
   261  				self.Printf(" = %v", num)
   262  
   263  				stack.Push(num)
   264  			}
   265  		case NOT:
   266  			base.Sub(Pow256, stack.Pop()).Sub(base, ethutil.Big1)
   267  
   268  			// Not needed
   269  			base = U256(base)
   270  
   271  			stack.Push(base)
   272  		case LT:
   273  			x, y := stack.Popn()
   274  			self.Printf(" %v < %v", y, x)
   275  			// x < y
   276  			if y.Cmp(x) < 0 {
   277  				stack.Push(ethutil.BigTrue)
   278  			} else {
   279  				stack.Push(ethutil.BigFalse)
   280  			}
   281  		case GT:
   282  			x, y := stack.Popn()
   283  			self.Printf(" %v > %v", y, x)
   284  
   285  			// x > y
   286  			if y.Cmp(x) > 0 {
   287  				stack.Push(ethutil.BigTrue)
   288  			} else {
   289  				stack.Push(ethutil.BigFalse)
   290  			}
   291  
   292  		case SLT:
   293  			y, x := S256(stack.Pop()), S256(stack.Pop())
   294  			self.Printf(" %v < %v", y, x)
   295  			// x < y
   296  			if y.Cmp(S256(x)) < 0 {
   297  				stack.Push(ethutil.BigTrue)
   298  			} else {
   299  				stack.Push(ethutil.BigFalse)
   300  			}
   301  		case SGT:
   302  			y, x := S256(stack.Pop()), S256(stack.Pop())
   303  			self.Printf(" %v > %v", y, x)
   304  
   305  			// x > y
   306  			if y.Cmp(x) > 0 {
   307  				stack.Push(ethutil.BigTrue)
   308  			} else {
   309  				stack.Push(ethutil.BigFalse)
   310  			}
   311  
   312  		case EQ:
   313  			x, y := stack.Popn()
   314  			self.Printf(" %v == %v", y, x)
   315  
   316  			// x == y
   317  			if x.Cmp(y) == 0 {
   318  				stack.Push(ethutil.BigTrue)
   319  			} else {
   320  				stack.Push(ethutil.BigFalse)
   321  			}
   322  		case ISZERO:
   323  			x := stack.Pop()
   324  			if x.Cmp(ethutil.BigFalse) > 0 {
   325  				stack.Push(ethutil.BigFalse)
   326  			} else {
   327  				stack.Push(ethutil.BigTrue)
   328  			}
   329  
   330  			// 0x10 range
   331  		case AND:
   332  			x, y := stack.Popn()
   333  			self.Printf(" %v & %v", y, x)
   334  
   335  			stack.Push(base.And(y, x))
   336  		case OR:
   337  			x, y := stack.Popn()
   338  			self.Printf(" %v | %v", y, x)
   339  
   340  			stack.Push(base.Or(y, x))
   341  		case XOR:
   342  			x, y := stack.Popn()
   343  			self.Printf(" %v ^ %v", y, x)
   344  
   345  			stack.Push(base.Xor(y, x))
   346  		case BYTE:
   347  			val, th := stack.Popn()
   348  
   349  			if th.Cmp(big.NewInt(32)) < 0 {
   350  				byt := big.NewInt(int64(ethutil.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
   351  
   352  				base.Set(byt)
   353  			} else {
   354  				base.Set(ethutil.BigFalse)
   355  			}
   356  
   357  			self.Printf(" => 0x%x", base.Bytes())
   358  
   359  			stack.Push(base)
   360  		case ADDMOD:
   361  
   362  			x := stack.Pop()
   363  			y := stack.Pop()
   364  			z := stack.Pop()
   365  
   366  			add := new(big.Int).Add(x, y)
   367  			if len(z.Bytes()) > 0 { // NOT 0x0
   368  				base.Mod(add, z)
   369  
   370  				U256(base)
   371  			}
   372  
   373  			self.Printf(" %v + %v %% %v = %v", x, y, z, base)
   374  
   375  			stack.Push(base)
   376  		case MULMOD:
   377  
   378  			x := stack.Pop()
   379  			y := stack.Pop()
   380  			z := stack.Pop()
   381  
   382  			mul := new(big.Int).Mul(x, y)
   383  			if len(z.Bytes()) > 0 { // NOT 0x0
   384  				base.Mod(mul, z)
   385  
   386  				U256(base)
   387  			}
   388  
   389  			self.Printf(" %v + %v %% %v = %v", x, y, z, base)
   390  
   391  			stack.Push(base)
   392  
   393  			// 0x20 range
   394  		case SHA3:
   395  			size, offset := stack.Popn()
   396  			data := crypto.Sha3(mem.Get(offset.Int64(), size.Int64()))
   397  
   398  			stack.Push(ethutil.BigD(data))
   399  
   400  			self.Printf(" => %x", data)
   401  			// 0x30 range
   402  		case ADDRESS:
   403  			stack.Push(ethutil.BigD(context.Address()))
   404  
   405  			self.Printf(" => %x", context.Address())
   406  		case BALANCE:
   407  
   408  			addr := stack.Pop().Bytes()
   409  			balance := statedb.GetBalance(addr)
   410  
   411  			stack.Push(balance)
   412  
   413  			self.Printf(" => %v (%x)", balance, addr)
   414  		case ORIGIN:
   415  			origin := self.env.Origin()
   416  
   417  			stack.Push(ethutil.BigD(origin))
   418  
   419  			self.Printf(" => %x", origin)
   420  		case CALLER:
   421  			caller := context.caller.Address()
   422  			stack.Push(ethutil.BigD(caller))
   423  
   424  			self.Printf(" => %x", caller)
   425  		case CALLVALUE:
   426  			stack.Push(value)
   427  
   428  			self.Printf(" => %v", value)
   429  		case CALLDATALOAD:
   430  			var (
   431  				offset  = stack.Pop()
   432  				data    = make([]byte, 32)
   433  				lenData = big.NewInt(int64(len(callData)))
   434  			)
   435  
   436  			if lenData.Cmp(offset) >= 0 {
   437  				length := new(big.Int).Add(offset, ethutil.Big32)
   438  				length = ethutil.BigMin(length, lenData)
   439  
   440  				copy(data, callData[offset.Int64():length.Int64()])
   441  			}
   442  
   443  			self.Printf(" => 0x%x", data)
   444  
   445  			stack.Push(ethutil.BigD(data))
   446  		case CALLDATASIZE:
   447  			l := int64(len(callData))
   448  			stack.Push(big.NewInt(l))
   449  
   450  			self.Printf(" => %d", l)
   451  		case CALLDATACOPY:
   452  			var (
   453  				size = uint64(len(callData))
   454  				mOff = stack.Pop().Uint64()
   455  				cOff = stack.Pop().Uint64()
   456  				l    = stack.Pop().Uint64()
   457  			)
   458  
   459  			if cOff > size {
   460  				cOff = 0
   461  				l = 0
   462  			} else if cOff+l > size {
   463  				l = 0
   464  			}
   465  
   466  			code := callData[cOff : cOff+l]
   467  
   468  			mem.Set(mOff, l, code)
   469  
   470  			self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, callData[cOff:cOff+l])
   471  		case CODESIZE, EXTCODESIZE:
   472  			var code []byte
   473  			if op == EXTCODESIZE {
   474  				addr := stack.Pop().Bytes()
   475  
   476  				code = statedb.GetCode(addr)
   477  			} else {
   478  				code = context.Code
   479  			}
   480  
   481  			l := big.NewInt(int64(len(code)))
   482  			stack.Push(l)
   483  
   484  			self.Printf(" => %d", l)
   485  		case CODECOPY, EXTCODECOPY:
   486  			var code []byte
   487  			if op == EXTCODECOPY {
   488  				code = statedb.GetCode(stack.Pop().Bytes())
   489  			} else {
   490  				code = context.Code
   491  			}
   492  			context := NewContext(nil, nil, code, ethutil.Big0, ethutil.Big0)
   493  			var (
   494  				mOff = stack.Pop().Uint64()
   495  				cOff = stack.Pop().Uint64()
   496  				l    = stack.Pop().Uint64()
   497  			)
   498  			codeCopy := context.GetCode(cOff, l)
   499  
   500  			mem.Set(mOff, l, codeCopy)
   501  
   502  			self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy)
   503  		case GASPRICE:
   504  			stack.Push(context.Price)
   505  
   506  			self.Printf(" => %x", context.Price)
   507  
   508  			// 0x40 range
   509  		case BLOCKHASH:
   510  			num := stack.Pop()
   511  
   512  			n := new(big.Int).Sub(self.env.BlockNumber(), ethutil.Big257)
   513  			if num.Cmp(n) > 0 && num.Cmp(self.env.BlockNumber()) < 0 {
   514  				stack.Push(ethutil.BigD(self.env.GetHash(num.Uint64())))
   515  			} else {
   516  				stack.Push(ethutil.Big0)
   517  			}
   518  
   519  			self.Printf(" => 0x%x", stack.Peek().Bytes())
   520  		case COINBASE:
   521  			coinbase := self.env.Coinbase()
   522  
   523  			stack.Push(ethutil.BigD(coinbase))
   524  
   525  			self.Printf(" => 0x%x", coinbase)
   526  		case TIMESTAMP:
   527  			time := self.env.Time()
   528  
   529  			stack.Push(big.NewInt(time))
   530  
   531  			self.Printf(" => 0x%x", time)
   532  		case NUMBER:
   533  			number := self.env.BlockNumber()
   534  
   535  			stack.Push(U256(number))
   536  
   537  			self.Printf(" => 0x%x", number.Bytes())
   538  		case DIFFICULTY:
   539  			difficulty := self.env.Difficulty()
   540  
   541  			stack.Push(difficulty)
   542  
   543  			self.Printf(" => 0x%x", difficulty.Bytes())
   544  		case GASLIMIT:
   545  			self.Printf(" => %v", self.env.GasLimit())
   546  
   547  			stack.Push(self.env.GasLimit())
   548  
   549  			// 0x50 range
   550  		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:
   551  			a := uint64(op - PUSH1 + 1)
   552  			byts := context.GetRangeValue(pc+1, a)
   553  			// Push value to stack
   554  			stack.Push(ethutil.BigD(byts))
   555  			pc += a
   556  
   557  			step += int(op) - int(PUSH1) + 1
   558  
   559  			self.Printf(" => 0x%x", byts)
   560  		case POP:
   561  			stack.Pop()
   562  		case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
   563  			n := int(op - DUP1 + 1)
   564  			stack.Dupn(n)
   565  
   566  			self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
   567  		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
   568  			n := int(op - SWAP1 + 2)
   569  			x, y := stack.Swapn(n)
   570  
   571  			self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
   572  		case LOG0, LOG1, LOG2, LOG3, LOG4:
   573  			n := int(op - LOG0)
   574  			topics := make([][]byte, n)
   575  			mSize, mStart := stack.Popn()
   576  			for i := 0; i < n; i++ {
   577  				topics[i] = ethutil.LeftPadBytes(stack.Pop().Bytes(), 32)
   578  			}
   579  
   580  			data := mem.Get(mStart.Int64(), mSize.Int64())
   581  			log := &Log{context.Address(), topics, data, self.env.BlockNumber().Uint64()}
   582  			self.env.AddLog(log)
   583  
   584  			self.Printf(" => %v", log)
   585  		case MLOAD:
   586  			offset := stack.Pop()
   587  			val := ethutil.BigD(mem.Get(offset.Int64(), 32))
   588  			stack.Push(val)
   589  
   590  			self.Printf(" => 0x%x", val.Bytes())
   591  		case MSTORE: // Store the value at stack top-1 in to memory at location stack top
   592  			// Pop value of the stack
   593  			val, mStart := stack.Popn()
   594  			mem.Set(mStart.Uint64(), 32, ethutil.BigToBytes(val, 256))
   595  
   596  			self.Printf(" => 0x%x", val)
   597  		case MSTORE8:
   598  			off := stack.Pop()
   599  			val := stack.Pop()
   600  
   601  			mem.store[off.Int64()] = byte(val.Int64() & 0xff)
   602  
   603  			self.Printf(" => [%v] 0x%x", off, val)
   604  		case SLOAD:
   605  			loc := stack.Pop()
   606  			val := ethutil.BigD(statedb.GetState(context.Address(), loc.Bytes()))
   607  			stack.Push(val)
   608  
   609  			self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
   610  		case SSTORE:
   611  			val, loc := stack.Popn()
   612  			statedb.SetState(context.Address(), loc.Bytes(), val)
   613  
   614  			self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
   615  		case JUMP:
   616  			jump(pc, stack.Pop())
   617  
   618  			continue
   619  		case JUMPI:
   620  			cond, pos := stack.Popn()
   621  
   622  			if cond.Cmp(ethutil.BigTrue) >= 0 {
   623  				jump(pc, pos)
   624  
   625  				continue
   626  			}
   627  
   628  			self.Printf(" ~> false")
   629  
   630  		case JUMPDEST:
   631  		case PC:
   632  			stack.Push(big.NewInt(int64(pc)))
   633  		case MSIZE:
   634  			stack.Push(big.NewInt(int64(mem.Len())))
   635  		case GAS:
   636  			stack.Push(context.Gas)
   637  
   638  			self.Printf(" => %x", context.Gas)
   639  			// 0x60 range
   640  		case CREATE:
   641  
   642  			var (
   643  				value        = stack.Pop()
   644  				size, offset = stack.Popn()
   645  				input        = mem.Get(offset.Int64(), size.Int64())
   646  				gas          = new(big.Int).Set(context.Gas)
   647  				addr         []byte
   648  			)
   649  			self.Endl()
   650  
   651  			context.UseGas(context.Gas)
   652  			ret, suberr, ref := self.env.Create(context, nil, input, gas, price, value)
   653  			if suberr != nil {
   654  				stack.Push(ethutil.BigFalse)
   655  
   656  				self.Printf(" (*) 0x0 %v", suberr)
   657  			} else {
   658  
   659  				// gas < len(ret) * CreateDataGas == NO_CODE
   660  				dataGas := big.NewInt(int64(len(ret)))
   661  				dataGas.Mul(dataGas, GasCreateByte)
   662  				if context.UseGas(dataGas) {
   663  					ref.SetCode(ret)
   664  				}
   665  				addr = ref.Address()
   666  
   667  				stack.Push(ethutil.BigD(addr))
   668  
   669  			}
   670  
   671  			// Debug hook
   672  			if self.Dbg != nil {
   673  				self.Dbg.SetCode(context.Code)
   674  			}
   675  		case CALL, CALLCODE:
   676  			gas := stack.Pop()
   677  			// Pop gas and value of the stack.
   678  			value, addr := stack.Popn()
   679  			value = U256(value)
   680  			// Pop input size and offset
   681  			inSize, inOffset := stack.Popn()
   682  			// Pop return size and offset
   683  			retSize, retOffset := stack.Popn()
   684  
   685  			address := ethutil.Address(addr.Bytes())
   686  			self.Printf(" => %x", address).Endl()
   687  
   688  			// Get the arguments from the memory
   689  			args := mem.Get(inOffset.Int64(), inSize.Int64())
   690  
   691  			var (
   692  				ret []byte
   693  				err error
   694  			)
   695  			if op == CALLCODE {
   696  				ret, err = self.env.CallCode(context, address, args, gas, price, value)
   697  			} else {
   698  				ret, err = self.env.Call(context, address, args, gas, price, value)
   699  			}
   700  
   701  			if err != nil {
   702  				stack.Push(ethutil.BigFalse)
   703  
   704  				vmlogger.Debugln(err)
   705  			} else {
   706  				stack.Push(ethutil.BigTrue)
   707  
   708  				mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   709  			}
   710  			self.Printf("resume %x (%v)", context.Address(), context.Gas)
   711  
   712  			// Debug hook
   713  			if self.Dbg != nil {
   714  				self.Dbg.SetCode(context.Code)
   715  			}
   716  
   717  		case RETURN:
   718  			size, offset := stack.Popn()
   719  			ret := mem.Get(offset.Int64(), size.Int64())
   720  
   721  			self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl()
   722  
   723  			return context.Return(ret), nil
   724  		case SUICIDE:
   725  			receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
   726  			balance := statedb.GetBalance(context.Address())
   727  
   728  			self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
   729  
   730  			receiver.AddAmount(balance)
   731  			statedb.Delete(context.Address())
   732  
   733  			fallthrough
   734  		case STOP: // Stop the context
   735  			self.Endl()
   736  
   737  			return context.Return(nil), nil
   738  		default:
   739  			vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
   740  
   741  			panic(fmt.Errorf("Invalid opcode %x", op))
   742  		}
   743  
   744  		pc++
   745  
   746  		self.Endl()
   747  
   748  		if self.Dbg != nil {
   749  			for _, instrNo := range self.Dbg.BreakPoints() {
   750  				if pc == uint64(instrNo) {
   751  					self.Stepping = true
   752  
   753  					if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
   754  						return nil, nil
   755  					}
   756  				} else if self.Stepping {
   757  					if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
   758  						return nil, nil
   759  					}
   760  				}
   761  			}
   762  		}
   763  
   764  	}
   765  }
   766  
   767  func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
   768  	gas := new(big.Int)
   769  	addStepGasUsage := func(amount *big.Int) {
   770  		if amount.Cmp(ethutil.Big0) >= 0 {
   771  			gas.Add(gas, amount)
   772  		}
   773  	}
   774  
   775  	addStepGasUsage(GasStep)
   776  
   777  	var newMemSize *big.Int = ethutil.Big0
   778  	var additionalGas *big.Int = new(big.Int)
   779  	// Stack Check, memory resize & gas phase
   780  	switch op {
   781  	// Stack checks only
   782  	case ISZERO, CALLDATALOAD, POP, JUMP, NOT: // 1
   783  		stack.require(1)
   784  	case JUMPI, ADD, SUB, DIV, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2
   785  		stack.require(2)
   786  	case ADDMOD, MULMOD: // 3
   787  		stack.require(3)
   788  	case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
   789  		n := int(op - SWAP1 + 2)
   790  		stack.require(n)
   791  	case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
   792  		n := int(op - DUP1 + 1)
   793  		stack.require(n)
   794  	case LOG0, LOG1, LOG2, LOG3, LOG4:
   795  		n := int(op - LOG0)
   796  		stack.require(n + 2)
   797  
   798  		gas.Set(GasLog)
   799  		addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
   800  
   801  		mSize, mStart := stack.Peekn()
   802  		addStepGasUsage(mSize)
   803  
   804  		newMemSize = calcMemSize(mStart, mSize)
   805  	case EXP:
   806  		stack.require(2)
   807  
   808  		gas.Set(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()) + 1)))
   809  	// Gas only
   810  	case STOP:
   811  		gas.Set(ethutil.Big0)
   812  	case SUICIDE:
   813  		stack.require(1)
   814  
   815  		gas.Set(ethutil.Big0)
   816  	case SLOAD:
   817  		stack.require(1)
   818  
   819  		gas.Set(GasSLoad)
   820  	// Memory resize & Gas
   821  	case SSTORE:
   822  		stack.require(2)
   823  
   824  		var mult *big.Int
   825  		y, x := stack.Peekn()
   826  		val := statedb.GetState(context.Address(), x.Bytes())
   827  		if len(val) == 0 && len(y.Bytes()) > 0 {
   828  			// 0 => non 0
   829  			mult = ethutil.Big3
   830  		} else if len(val) > 0 && len(y.Bytes()) == 0 {
   831  			statedb.Refund(caller.Address(), GasSStoreRefund)
   832  
   833  			mult = ethutil.Big0
   834  		} else {
   835  			// non 0 => non 0 (or 0 => 0)
   836  			mult = ethutil.Big1
   837  		}
   838  		gas.Set(new(big.Int).Mul(mult, GasSStore))
   839  	case BALANCE:
   840  		stack.require(1)
   841  		gas.Set(GasBalance)
   842  	case MSTORE:
   843  		stack.require(2)
   844  		newMemSize = calcMemSize(stack.Peek(), u256(32))
   845  	case MLOAD:
   846  		stack.require(1)
   847  
   848  		newMemSize = calcMemSize(stack.Peek(), u256(32))
   849  	case MSTORE8:
   850  		stack.require(2)
   851  		newMemSize = calcMemSize(stack.Peek(), u256(1))
   852  	case RETURN:
   853  		stack.require(2)
   854  
   855  		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
   856  	case SHA3:
   857  		stack.require(2)
   858  		gas.Set(GasSha)
   859  		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
   860  		additionalGas.Set(stack.data[stack.Len()-2])
   861  	case CALLDATACOPY:
   862  		stack.require(2)
   863  
   864  		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
   865  		additionalGas.Set(stack.data[stack.Len()-3])
   866  	case CODECOPY:
   867  		stack.require(3)
   868  
   869  		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
   870  		additionalGas.Set(stack.data[stack.Len()-3])
   871  	case EXTCODECOPY:
   872  		stack.require(4)
   873  
   874  		newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
   875  		additionalGas.Set(stack.data[stack.Len()-4])
   876  	case CALL, CALLCODE:
   877  		stack.require(7)
   878  		gas.Set(GasCall)
   879  		addStepGasUsage(stack.data[stack.Len()-1])
   880  
   881  		x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
   882  		y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
   883  
   884  		newMemSize = ethutil.BigMax(x, y)
   885  	case CREATE:
   886  		stack.require(3)
   887  		gas.Set(GasCreate)
   888  
   889  		newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
   890  	}
   891  
   892  	switch op {
   893  	case CALLDATACOPY, CODECOPY, EXTCODECOPY:
   894  		additionalGas.Add(additionalGas, u256(31))
   895  		additionalGas.Div(additionalGas, u256(32))
   896  		addStepGasUsage(additionalGas)
   897  	case SHA3:
   898  		additionalGas.Add(additionalGas, u256(31))
   899  		additionalGas.Div(additionalGas, u256(32))
   900  		additionalGas.Mul(additionalGas, GasSha3Byte)
   901  		addStepGasUsage(additionalGas)
   902  	}
   903  
   904  	if newMemSize.Cmp(ethutil.Big0) > 0 {
   905  		newMemSize.Add(newMemSize, u256(31))
   906  		newMemSize.Div(newMemSize, u256(32))
   907  		newMemSize.Mul(newMemSize, u256(32))
   908  
   909  		if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
   910  			memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
   911  			memGasUsage.Mul(GasMemory, memGasUsage)
   912  			memGasUsage.Div(memGasUsage, u256(32))
   913  
   914  			addStepGasUsage(memGasUsage)
   915  		}
   916  
   917  	}
   918  
   919  	return newMemSize, gas
   920  }
   921  
   922  func (self *Vm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context *Context) (ret []byte, err error) {
   923  	gas := p.Gas(len(callData))
   924  	if context.UseGas(gas) {
   925  		ret = p.Call(callData)
   926  		self.Printf("NATIVE_FUNC => %x", ret)
   927  		self.Endl()
   928  
   929  		return context.Return(ret), nil
   930  	} else {
   931  		self.Printf("NATIVE_FUNC => failed").Endl()
   932  
   933  		tmp := new(big.Int).Set(context.Gas)
   934  
   935  		panic(OOG(gas, tmp).Error())
   936  	}
   937  }
   938  
   939  func (self *Vm) Printf(format string, v ...interface{}) VirtualMachine {
   940  	if self.logTy == LogTyPretty {
   941  		self.logStr += fmt.Sprintf(format, v...)
   942  	}
   943  
   944  	return self
   945  }
   946  
   947  func (self *Vm) Endl() VirtualMachine {
   948  	if self.logTy == LogTyPretty {
   949  		vmlogger.Debugln(self.logStr)
   950  		self.logStr = ""
   951  	}
   952  
   953  	return self
   954  }
   955  
   956  func (self *Vm) Env() Environment {
   957  	return self.env
   958  }