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.

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