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.

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