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.

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