You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

721 lines
18 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package vm
  2. import (
  3. "errors"
  4. "fmt"
  5. "math"
  6. . "github.com/tendermint/tendermint/common"
  7. "github.com/tendermint/tendermint/vm/sha3"
  8. )
  9. var (
  10. ErrInsufficientBalance = errors.New("Insufficient balance")
  11. ErrInvalidJumpDest = errors.New("Invalid jump dest")
  12. ErrInsufficientGas = errors.New("Insuffient gas")
  13. ErrMemoryOutOfBounds = errors.New("Memory out of bounds")
  14. ErrCodeOutOfBounds = errors.New("Code out of bounds")
  15. ErrInputOutOfBounds = errors.New("Input out of bounds")
  16. ErrCallStackOverflow = errors.New("Call stack overflow")
  17. ErrCallStackUnderflow = errors.New("Call stack underflow")
  18. ErrDataStackOverflow = errors.New("Data stack overflow")
  19. ErrDataStackUnderflow = errors.New("Data stack underflow")
  20. ErrInvalidContract = errors.New("Invalid contract")
  21. )
  22. const (
  23. dataStackCapacity = 1024
  24. callStackCapacity = 100 // TODO ensure usage.
  25. memoryCapacity = 1024 * 1024 // 1 MB
  26. )
  27. type VM struct {
  28. appState AppState
  29. params VMParams
  30. callDepth int
  31. }
  32. type VMParams struct {
  33. BlockHeight uint64
  34. BlockHash Word
  35. BlockTime int64
  36. GasLimit uint64
  37. CallStackLimit uint64
  38. Origin Word
  39. }
  40. func NewVM(appState AppState, params VMParams) *VM {
  41. return &VM{
  42. appState: appState,
  43. params: params,
  44. callDepth: 0,
  45. }
  46. }
  47. /*
  48. // When running a transaction, the caller the pays for the fees.
  49. // Check caller's account balance vs feeLimit and value
  50. if caller.Balance < (feeLimit + value) {
  51. return nil, ErrInsufficientBalance
  52. }
  53. caller.Balance -= (feeLimit + value)
  54. */
  55. // gas: the maximum gas that will be run.
  56. // When the function returns, *gas will be the amount of remaining gas.
  57. func (vm *VM) Call(caller, callee *Account, code, input []byte, value uint64, gas *uint64) (output []byte, err error) {
  58. if len(code) == 0 {
  59. panic("Call() requires code")
  60. }
  61. fmt.Printf("(%d) (%X) %X (code=%d) gas: %v (d) %X\n", vm.callDepth, caller.Address[:4], callee.Address, len(callee.Code), *gas, input)
  62. var (
  63. pc uint64 = 0
  64. stack = NewStack(dataStackCapacity, gas, &err)
  65. memory = make([]byte, memoryCapacity)
  66. ok = false // convenience
  67. )
  68. for {
  69. var op = codeGetOp(code, pc)
  70. fmt.Printf("(pc) %-3d (op) %-14s (st) %-4d ", pc, op.String(), stack.Len())
  71. switch op {
  72. case STOP: // 0x00
  73. return nil, nil
  74. case ADD: // 0x01
  75. x, y := stack.Pop64(), stack.Pop64()
  76. stack.Push64(x + y)
  77. fmt.Printf(" %v + %v = %v\n", x, y, x+y)
  78. case MUL: // 0x02
  79. x, y := stack.Pop64(), stack.Pop64()
  80. stack.Push64(x * y)
  81. fmt.Printf(" %v * %v = %v\n", x, y, x*y)
  82. case SUB: // 0x03
  83. x, y := stack.Pop64(), stack.Pop64()
  84. stack.Push64(x - y)
  85. fmt.Printf(" %v - %v = %v\n", x, y, x-y)
  86. case DIV: // 0x04
  87. x, y := stack.Pop64(), stack.Pop64()
  88. if y == 0 { // TODO
  89. stack.Push(Zero)
  90. fmt.Printf(" %v / %v = %v (TODO)\n", x, y, 0)
  91. } else {
  92. stack.Push64(x / y)
  93. fmt.Printf(" %v / %v = %v\n", x, y, x/y)
  94. }
  95. case SDIV: // 0x05
  96. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  97. if y == 0 { // TODO
  98. stack.Push(Zero)
  99. fmt.Printf(" %v / %v = %v (TODO)\n", x, y, 0)
  100. } else {
  101. stack.Push64(uint64(x / y))
  102. fmt.Printf(" %v / %v = %v\n", x, y, x/y)
  103. }
  104. case MOD: // 0x06
  105. x, y := stack.Pop64(), stack.Pop64()
  106. if y == 0 { // TODO
  107. stack.Push(Zero)
  108. fmt.Printf(" %v %% %v = %v (TODO)\n", x, y, 0)
  109. } else {
  110. stack.Push64(x % y)
  111. fmt.Printf(" %v %% %v = %v\n", x, y, x%y)
  112. }
  113. case SMOD: // 0x07
  114. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  115. if y == 0 { // TODO
  116. stack.Push(Zero)
  117. fmt.Printf(" %v %% %v = %v (TODO)\n", x, y, 0)
  118. } else {
  119. stack.Push64(uint64(x % y))
  120. fmt.Printf(" %v %% %v = %v\n", x, y, x%y)
  121. }
  122. case ADDMOD: // 0x08
  123. x, y, z := stack.Pop64(), stack.Pop64(), stack.Pop64()
  124. if z == 0 { // TODO
  125. stack.Push(Zero)
  126. fmt.Printf(" (%v + %v) %% %v = %v (TODO)\n", x, y, z, 0)
  127. } else {
  128. stack.Push64(x % y)
  129. fmt.Printf(" (%v + %v) %% %v = %v\n", x, y, z, (x+y)%z)
  130. }
  131. case MULMOD: // 0x09
  132. x, y, z := stack.Pop64(), stack.Pop64(), stack.Pop64()
  133. if z == 0 { // TODO
  134. stack.Push(Zero)
  135. fmt.Printf(" (%v + %v) %% %v = %v (TODO)\n", x, y, z, 0)
  136. } else {
  137. stack.Push64(x % y)
  138. fmt.Printf(" (%v + %v) %% %v = %v\n", x, y, z, (x*y)%z)
  139. }
  140. case EXP: // 0x0A
  141. x, y := stack.Pop64(), stack.Pop64()
  142. stack.Push64(ExpUint64(x, y))
  143. fmt.Printf(" %v ** %v = %v\n", x, y, uint64(math.Pow(float64(x), float64(y))))
  144. case SIGNEXTEND: // 0x0B
  145. x, y := stack.Pop64(), stack.Pop64()
  146. res := (y << uint(x)) >> x
  147. stack.Push64(res)
  148. fmt.Printf(" (%v << %v) >> %v = %v\n", y, x, x, res)
  149. case LT: // 0x10
  150. x, y := stack.Pop64(), stack.Pop64()
  151. if x < y {
  152. stack.Push64(1)
  153. } else {
  154. stack.Push(Zero)
  155. }
  156. fmt.Printf(" %v < %v = %v\n", x, y, x < y)
  157. case GT: // 0x11
  158. x, y := stack.Pop64(), stack.Pop64()
  159. if x > y {
  160. stack.Push64(1)
  161. } else {
  162. stack.Push(Zero)
  163. }
  164. fmt.Printf(" %v > %v = %v\n", x, y, x > y)
  165. case SLT: // 0x12
  166. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  167. if x < y {
  168. stack.Push64(1)
  169. } else {
  170. stack.Push(Zero)
  171. }
  172. fmt.Printf(" %v < %v = %v\n", x, y, x < y)
  173. case SGT: // 0x13
  174. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  175. if x > y {
  176. stack.Push64(1)
  177. } else {
  178. stack.Push(Zero)
  179. }
  180. fmt.Printf(" %v > %v = %v\n", x, y, x > y)
  181. case EQ: // 0x14
  182. x, y := stack.Pop64(), stack.Pop64()
  183. if x > y {
  184. stack.Push64(1)
  185. } else {
  186. stack.Push(Zero)
  187. }
  188. fmt.Printf(" %v == %v = %v\n", x, y, x == y)
  189. case ISZERO: // 0x15
  190. x := stack.Pop64()
  191. if x == 0 {
  192. stack.Push64(1)
  193. } else {
  194. stack.Push(Zero)
  195. }
  196. fmt.Printf(" %v == 0 = %v\n", x, x == 0)
  197. case AND: // 0x16
  198. x, y := stack.Pop64(), stack.Pop64()
  199. stack.Push64(x & y)
  200. fmt.Printf(" %v & %v = %v\n", x, y, x&y)
  201. case OR: // 0x17
  202. x, y := stack.Pop64(), stack.Pop64()
  203. stack.Push64(x | y)
  204. fmt.Printf(" %v | %v = %v\n", x, y, x|y)
  205. case XOR: // 0x18
  206. x, y := stack.Pop64(), stack.Pop64()
  207. stack.Push64(x ^ y)
  208. fmt.Printf(" %v ^ %v = %v\n", x, y, x^y)
  209. case NOT: // 0x19
  210. x := stack.Pop64()
  211. stack.Push64(^x)
  212. fmt.Printf(" !%v = %v\n", x, ^x)
  213. case BYTE: // 0x1A
  214. idx, val := stack.Pop64(), stack.Pop()
  215. res := byte(0)
  216. if idx < 32 {
  217. res = val[idx]
  218. }
  219. stack.Push64(uint64(res))
  220. fmt.Printf(" => 0x%X\n", res)
  221. case SHA3: // 0x20
  222. if ok = useGas(gas, GasSha3); !ok {
  223. return nil, firstErr(err, ErrInsufficientGas)
  224. }
  225. offset, size := stack.Pop64(), stack.Pop64()
  226. data, ok := subslice(memory, offset, size)
  227. if !ok {
  228. return nil, firstErr(err, ErrMemoryOutOfBounds)
  229. }
  230. data = sha3.Sha3(data)
  231. stack.PushBytes(data)
  232. fmt.Printf(" => (%v) %X\n", size, data)
  233. case ADDRESS: // 0x30
  234. stack.Push(callee.Address)
  235. fmt.Printf(" => %X\n", callee.Address)
  236. case BALANCE: // 0x31
  237. addr := stack.Pop()
  238. if ok = useGas(gas, GasGetAccount); !ok {
  239. return nil, firstErr(err, ErrInsufficientGas)
  240. }
  241. account, err_ := vm.appState.GetAccount(addr) // TODO ensure that 20byte lengths are supported.
  242. if err = firstErr(err, err_); err != nil {
  243. return nil, err
  244. }
  245. balance := account.Balance
  246. stack.Push64(balance)
  247. fmt.Printf(" => %v (%X)\n", balance, addr)
  248. case ORIGIN: // 0x32
  249. origin := vm.params.Origin
  250. stack.Push(origin)
  251. fmt.Printf(" => %X\n", origin)
  252. case CALLER: // 0x33
  253. stack.Push(caller.Address)
  254. fmt.Printf(" => %X\n", caller.Address)
  255. case CALLVALUE: // 0x34
  256. stack.Push64(value)
  257. fmt.Printf(" => %v\n", value)
  258. case CALLDATALOAD: // 0x35
  259. offset := stack.Pop64()
  260. data, ok := subslice(input, offset, 32)
  261. if !ok {
  262. return nil, firstErr(err, ErrInputOutOfBounds)
  263. }
  264. stack.Push(RightPadWord(data))
  265. fmt.Printf(" => 0x%X\n", data)
  266. case CALLDATASIZE: // 0x36
  267. stack.Push64(uint64(len(input)))
  268. fmt.Printf(" => %d\n", len(input))
  269. case CALLDATACOPY: // 0x37
  270. memOff := stack.Pop64()
  271. inputOff := stack.Pop64()
  272. length := stack.Pop64()
  273. data, ok := subslice(input, inputOff, length)
  274. if !ok {
  275. return nil, firstErr(err, ErrInputOutOfBounds)
  276. }
  277. dest, ok := subslice(memory, memOff, length)
  278. if !ok {
  279. return nil, firstErr(err, ErrMemoryOutOfBounds)
  280. }
  281. copy(dest, data)
  282. fmt.Printf(" => [%v, %v, %v] %X\n", memOff, inputOff, length, data)
  283. case CODESIZE: // 0x38
  284. l := uint64(len(code))
  285. stack.Push64(l)
  286. fmt.Printf(" => %d\n", l)
  287. case CODECOPY: // 0x39
  288. memOff := stack.Pop64()
  289. codeOff := stack.Pop64()
  290. length := stack.Pop64()
  291. data, ok := subslice(code, codeOff, length)
  292. if !ok {
  293. return nil, firstErr(err, ErrCodeOutOfBounds)
  294. }
  295. dest, ok := subslice(memory, memOff, length)
  296. if !ok {
  297. return nil, firstErr(err, ErrMemoryOutOfBounds)
  298. }
  299. copy(dest, data)
  300. fmt.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
  301. case GASPRICE_DEPRECATED: // 0x3A
  302. stack.Push(Zero)
  303. fmt.Printf(" => %X (GASPRICE IS DEPRECATED)\n")
  304. case EXTCODESIZE: // 0x3B
  305. addr := stack.Pop()
  306. if ok = useGas(gas, GasGetAccount); !ok {
  307. return nil, firstErr(err, ErrInsufficientGas)
  308. }
  309. account, err_ := vm.appState.GetAccount(addr)
  310. if err = firstErr(err, err_); err != nil {
  311. return nil, err
  312. }
  313. code := account.Code
  314. l := uint64(len(code))
  315. stack.Push64(l)
  316. fmt.Printf(" => %d\n", l)
  317. case EXTCODECOPY: // 0x3C
  318. addr := stack.Pop()
  319. if ok = useGas(gas, GasGetAccount); !ok {
  320. return nil, firstErr(err, ErrInsufficientGas)
  321. }
  322. account, err_ := vm.appState.GetAccount(addr)
  323. if err = firstErr(err, err_); err != nil {
  324. return nil, err
  325. }
  326. code := account.Code
  327. memOff := stack.Pop64()
  328. codeOff := stack.Pop64()
  329. length := stack.Pop64()
  330. data, ok := subslice(code, codeOff, length)
  331. if !ok {
  332. return nil, ErrCodeOutOfBounds
  333. }
  334. dest, ok := subslice(memory, memOff, length)
  335. if !ok {
  336. return nil, ErrMemoryOutOfBounds
  337. }
  338. copy(dest, data)
  339. fmt.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
  340. case BLOCKHASH: // 0x40
  341. stack.Push(Zero)
  342. fmt.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes())
  343. case COINBASE: // 0x41
  344. stack.Push(Zero)
  345. fmt.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes())
  346. case TIMESTAMP: // 0x42
  347. time := vm.params.BlockTime
  348. stack.Push64(uint64(time))
  349. fmt.Printf(" => 0x%X\n", time)
  350. case BLOCKHEIGHT: // 0x43
  351. number := uint64(vm.params.BlockHeight)
  352. stack.Push64(number)
  353. fmt.Printf(" => 0x%X\n", number)
  354. case GASLIMIT: // 0x45
  355. stack.Push64(vm.params.GasLimit)
  356. fmt.Printf(" => %v\n", vm.params.GasLimit)
  357. case POP: // 0x50
  358. stack.Pop()
  359. fmt.Printf(" => %v\n", vm.params.GasLimit)
  360. case MLOAD: // 0x51
  361. offset := stack.Pop64()
  362. data, ok := subslice(memory, offset, 32)
  363. if !ok {
  364. return nil, ErrMemoryOutOfBounds
  365. }
  366. stack.Push(RightPadWord(data))
  367. fmt.Printf(" => 0x%X\n", data)
  368. case MSTORE: // 0x52
  369. offset, data := stack.Pop64(), stack.Pop()
  370. dest, ok := subslice(memory, offset, 32)
  371. if !ok {
  372. return nil, ErrMemoryOutOfBounds
  373. }
  374. copy(dest, data[:])
  375. fmt.Printf(" => 0x%X\n", data)
  376. case MSTORE8: // 0x53
  377. offset, val := stack.Pop64(), byte(stack.Pop64()&0xFF)
  378. if len(memory) <= int(offset) {
  379. return nil, ErrMemoryOutOfBounds
  380. }
  381. memory[offset] = val
  382. fmt.Printf(" => [%v] 0x%X\n", offset, val)
  383. case SLOAD: // 0x54
  384. loc := stack.Pop()
  385. data, _ := vm.appState.GetStorage(callee.Address, loc)
  386. stack.Push(data)
  387. fmt.Printf(" {0x%X : 0x%X}\n", loc, data)
  388. case SSTORE: // 0x55
  389. loc, data := stack.Pop(), stack.Pop()
  390. updated, err_ := vm.appState.SetStorage(callee.Address, loc, data)
  391. if err = firstErr(err, err_); err != nil {
  392. return nil, err
  393. }
  394. if updated {
  395. useGas(gas, GasStorageUpdate)
  396. } else {
  397. useGas(gas, GasStorageCreate)
  398. }
  399. fmt.Printf(" {0x%X : 0x%X}\n", loc, data)
  400. case JUMP: // 0x56
  401. err = jump(code, stack.Pop64())
  402. continue
  403. case JUMPI: // 0x57
  404. pos, cond := stack.Pop64(), stack.Pop64()
  405. if cond >= 1 {
  406. err = jump(code, pos)
  407. continue
  408. }
  409. fmt.Printf(" ~> false\n")
  410. case PC: // 0x58
  411. stack.Push64(pc)
  412. case MSIZE: // 0x59
  413. stack.Push64(uint64(len(memory)))
  414. case GAS: // 0x5A
  415. stack.Push64(*gas)
  416. fmt.Printf(" => %X\n", *gas)
  417. case JUMPDEST: // 0x5B
  418. // Do nothing
  419. 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:
  420. a := uint64(op - PUSH1 + 1)
  421. codeSegment, ok := subslice(code, pc+1, a)
  422. if !ok {
  423. return nil, firstErr(err, ErrCodeOutOfBounds)
  424. }
  425. res := RightPadWord(codeSegment)
  426. stack.Push(res)
  427. pc += a
  428. fmt.Printf(" => 0x%X\n", res)
  429. case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
  430. n := int(op - DUP1 + 1)
  431. stack.Dup(n)
  432. fmt.Printf(" => [%d] 0x%X\n", n, stack.Peek().Bytes())
  433. case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
  434. n := int(op - SWAP1 + 2)
  435. stack.Swap(n)
  436. fmt.Printf(" => [%d]\n", n)
  437. case LOG0, LOG1, LOG2, LOG3, LOG4:
  438. n := int(op - LOG0)
  439. topics := make([]Word, n)
  440. offset, size := stack.Pop64(), stack.Pop64()
  441. for i := 0; i < n; i++ {
  442. topics[i] = stack.Pop()
  443. }
  444. data, ok := subslice(memory, offset, size)
  445. if !ok {
  446. return nil, firstErr(err, ErrMemoryOutOfBounds)
  447. }
  448. log := &Log{
  449. callee.Address,
  450. topics,
  451. data,
  452. vm.params.BlockHeight,
  453. }
  454. vm.appState.AddLog(log)
  455. fmt.Printf(" => %v\n", log)
  456. case CREATE: // 0xF0
  457. value := stack.Pop64()
  458. offset, size := stack.Pop64(), stack.Pop64()
  459. input, ok := subslice(memory, offset, size)
  460. if !ok {
  461. return nil, firstErr(err, ErrMemoryOutOfBounds)
  462. }
  463. // Check balance
  464. if caller.Balance < value {
  465. return nil, firstErr(err, ErrInsufficientBalance)
  466. } else {
  467. caller.Balance -= value
  468. }
  469. // Create a new address
  470. nonce := caller.Nonce
  471. addr := createAddress(caller.Address, nonce)
  472. caller.Nonce += 1
  473. // TODO charge for gas to create account _ the code length * GasCreateByte
  474. newAccount, err := vm.appState.CreateAccount(addr, value)
  475. if err != nil {
  476. stack.Push(Zero)
  477. fmt.Printf(" (*) 0x0 %v\n", err)
  478. } else {
  479. // Run the input to get the contract code.
  480. // The code as well as the input to the code are the same.
  481. ret, err_ := vm.Call(callee, newAccount, input, input, value, gas)
  482. if err_ != nil {
  483. caller.Balance += value // Return the balance
  484. stack.Push(Zero)
  485. } else {
  486. newAccount.Code = ret // Set the code
  487. stack.Push(newAccount.Address)
  488. }
  489. }
  490. case CALL, CALLCODE: // 0xF1, 0xF2
  491. gasLimit := stack.Pop64()
  492. addr, value := stack.Pop(), stack.Pop64()
  493. inOffset, inSize := stack.Pop64(), stack.Pop64() // inputs
  494. retOffset, retSize := stack.Pop64(), stack.Pop64() // outputs
  495. fmt.Printf(" => %X\n", addr)
  496. // Get the arguments from the memory
  497. args, ok := subslice(memory, inOffset, inSize)
  498. if !ok {
  499. return nil, firstErr(err, ErrMemoryOutOfBounds)
  500. }
  501. // Ensure that gasLimit is reasonable
  502. if *gas < gasLimit {
  503. return nil, firstErr(err, ErrInsufficientGas)
  504. } else {
  505. *gas -= gasLimit
  506. // NOTE: we will return any used gas later.
  507. }
  508. // Begin execution
  509. var ret []byte
  510. var err error
  511. // If addr is in nativeContracts
  512. if nativeContract := nativeContracts[addr]; nativeContract != nil {
  513. ret, err = nativeContract(args, &gasLimit)
  514. } else {
  515. if ok = useGas(gas, GasGetAccount); !ok {
  516. return nil, firstErr(err, ErrInsufficientGas)
  517. }
  518. account, err_ := vm.appState.GetAccount(addr)
  519. if err = firstErr(err, err_); err != nil {
  520. return nil, err
  521. }
  522. if op == CALLCODE {
  523. ret, err = vm.Call(callee, callee, account.Code, args, value, gas)
  524. } else {
  525. ret, err = vm.Call(callee, account, account.Code, args, value, gas)
  526. }
  527. }
  528. // Push result
  529. if err != nil {
  530. stack.Push(Zero)
  531. } else {
  532. stack.Push(One)
  533. dest, ok := subslice(memory, retOffset, retSize)
  534. if !ok {
  535. return nil, firstErr(err, ErrMemoryOutOfBounds)
  536. }
  537. copy(dest, ret)
  538. }
  539. // Handle remaining gas.
  540. *gas += gasLimit
  541. fmt.Printf("resume %X (%v)\n", callee.Address, gas)
  542. case RETURN: // 0xF3
  543. offset, size := stack.Pop64(), stack.Pop64()
  544. ret, ok := subslice(memory, offset, size)
  545. if !ok {
  546. return nil, firstErr(err, ErrMemoryOutOfBounds)
  547. }
  548. fmt.Printf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(ret), ret)
  549. return ret, nil
  550. case SUICIDE: // 0xFF
  551. addr := stack.Pop()
  552. if ok = useGas(gas, GasGetAccount); !ok {
  553. return nil, firstErr(err, ErrInsufficientGas)
  554. }
  555. receiver, err_ := vm.appState.GetAccount(addr)
  556. if err = firstErr(err, err_); err != nil {
  557. return nil, err
  558. }
  559. balance := callee.Balance
  560. receiver.Balance += balance
  561. vm.appState.UpdateAccount(receiver)
  562. vm.appState.DeleteAccount(callee)
  563. fmt.Printf(" => (%X) %v\n", addr[:4], balance)
  564. fallthrough
  565. default:
  566. fmt.Printf("(pc) %-3v Invalid opcode %X\n", pc, op)
  567. panic(fmt.Errorf("Invalid opcode %X", op))
  568. }
  569. pc++
  570. // If there is an error, return
  571. if err != nil {
  572. return nil, err
  573. }
  574. }
  575. }
  576. func subslice(data []byte, offset, length uint64) ([]byte, bool) {
  577. size := uint64(len(data))
  578. if size < offset {
  579. return nil, false
  580. } else if size < offset+length {
  581. return data[offset:], false
  582. } else {
  583. return data[offset : offset+length], true
  584. }
  585. }
  586. func codeGetOp(code []byte, n uint64) OpCode {
  587. if uint64(len(code)) <= n {
  588. return OpCode(0) // stop
  589. } else {
  590. return OpCode(code[n])
  591. }
  592. }
  593. func jump(code []byte, to uint64) (err error) {
  594. dest := codeGetOp(code, to)
  595. if dest != JUMPDEST {
  596. return ErrInvalidJumpDest
  597. }
  598. fmt.Printf(" ~> %v\n", to)
  599. return nil
  600. }
  601. func firstErr(errA, errB error) error {
  602. if errA != nil {
  603. return errA
  604. } else {
  605. return errB
  606. }
  607. }
  608. func useGas(gas *uint64, gasToUse uint64) bool {
  609. if *gas > gasToUse {
  610. *gas -= gasToUse
  611. return true
  612. } else {
  613. return false
  614. }
  615. }
  616. // Creates a 20 byte address from the creatorAddr and nonce.
  617. func createAddress(creatorAddr Word, nonce uint64) Word {
  618. temp := make([]byte, 32+8)
  619. copy(temp, creatorAddr[:])
  620. PutUint64(temp[32:], nonce)
  621. return RightPadWord(sha3.Sha3(temp)[:20])
  622. }