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.

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