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 }