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.

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