instructions.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package vm
  17. import (
  18. "fmt"
  19. "math/big"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/common/math"
  22. "github.com/ethereum/go-ethereum/core/types"
  23. "github.com/ethereum/go-ethereum/crypto"
  24. "github.com/ethereum/go-ethereum/params"
  25. )
  26. func opAdd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  27. x, y := stack.pop(), stack.pop()
  28. stack.push(U256(x.Add(x, y)))
  29. return nil, nil
  30. }
  31. func opSub(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  32. x, y := stack.pop(), stack.pop()
  33. stack.push(U256(x.Sub(x, y)))
  34. return nil, nil
  35. }
  36. func opMul(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  37. x, y := stack.pop(), stack.pop()
  38. stack.push(U256(x.Mul(x, y)))
  39. return nil, nil
  40. }
  41. func opDiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  42. x, y := stack.pop(), stack.pop()
  43. if y.Cmp(common.Big0) != 0 {
  44. stack.push(U256(x.Div(x, y)))
  45. } else {
  46. stack.push(new(big.Int))
  47. }
  48. return nil, nil
  49. }
  50. func opSdiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  51. x, y := S256(stack.pop()), S256(stack.pop())
  52. if y.Cmp(common.Big0) == 0 {
  53. stack.push(new(big.Int))
  54. return nil, nil
  55. } else {
  56. n := new(big.Int)
  57. if new(big.Int).Mul(x, y).Cmp(common.Big0) < 0 {
  58. n.SetInt64(-1)
  59. } else {
  60. n.SetInt64(1)
  61. }
  62. res := x.Div(x.Abs(x), y.Abs(y))
  63. res.Mul(res, n)
  64. stack.push(U256(res))
  65. }
  66. return nil, nil
  67. }
  68. func opMod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  69. x, y := stack.pop(), stack.pop()
  70. if y.Cmp(common.Big0) == 0 {
  71. stack.push(new(big.Int))
  72. } else {
  73. stack.push(U256(x.Mod(x, y)))
  74. }
  75. return nil, nil
  76. }
  77. func opSmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  78. x, y := S256(stack.pop()), S256(stack.pop())
  79. if y.Cmp(common.Big0) == 0 {
  80. stack.push(new(big.Int))
  81. } else {
  82. n := new(big.Int)
  83. if x.Cmp(common.Big0) < 0 {
  84. n.SetInt64(-1)
  85. } else {
  86. n.SetInt64(1)
  87. }
  88. res := x.Mod(x.Abs(x), y.Abs(y))
  89. res.Mul(res, n)
  90. stack.push(U256(res))
  91. }
  92. return nil, nil
  93. }
  94. func opExp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  95. base, exponent := stack.pop(), stack.pop()
  96. stack.push(math.Exp(base, exponent))
  97. return nil, nil
  98. }
  99. func opSignExtend(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  100. back := stack.pop()
  101. if back.Cmp(big.NewInt(31)) < 0 {
  102. bit := uint(back.Uint64()*8 + 7)
  103. num := stack.pop()
  104. mask := back.Lsh(common.Big1, bit)
  105. mask.Sub(mask, common.Big1)
  106. if common.BitTest(num, int(bit)) {
  107. num.Or(num, mask.Not(mask))
  108. } else {
  109. num.And(num, mask)
  110. }
  111. stack.push(U256(num))
  112. }
  113. return nil, nil
  114. }
  115. func opNot(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  116. x := stack.pop()
  117. stack.push(U256(x.Not(x)))
  118. return nil, nil
  119. }
  120. func opLt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  121. x, y := stack.pop(), stack.pop()
  122. if x.Cmp(y) < 0 {
  123. stack.push(big.NewInt(1))
  124. } else {
  125. stack.push(new(big.Int))
  126. }
  127. return nil, nil
  128. }
  129. func opGt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  130. x, y := stack.pop(), stack.pop()
  131. if x.Cmp(y) > 0 {
  132. stack.push(big.NewInt(1))
  133. } else {
  134. stack.push(new(big.Int))
  135. }
  136. return nil, nil
  137. }
  138. func opSlt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  139. x, y := S256(stack.pop()), S256(stack.pop())
  140. if x.Cmp(S256(y)) < 0 {
  141. stack.push(big.NewInt(1))
  142. } else {
  143. stack.push(new(big.Int))
  144. }
  145. return nil, nil
  146. }
  147. func opSgt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  148. x, y := S256(stack.pop()), S256(stack.pop())
  149. if x.Cmp(y) > 0 {
  150. stack.push(big.NewInt(1))
  151. } else {
  152. stack.push(new(big.Int))
  153. }
  154. return nil, nil
  155. }
  156. func opEq(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  157. x, y := stack.pop(), stack.pop()
  158. if x.Cmp(y) == 0 {
  159. stack.push(big.NewInt(1))
  160. } else {
  161. stack.push(new(big.Int))
  162. }
  163. return nil, nil
  164. }
  165. func opIszero(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  166. x := stack.pop()
  167. if x.Cmp(common.Big0) > 0 {
  168. stack.push(new(big.Int))
  169. } else {
  170. stack.push(big.NewInt(1))
  171. }
  172. return nil, nil
  173. }
  174. func opAnd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  175. x, y := stack.pop(), stack.pop()
  176. stack.push(x.And(x, y))
  177. return nil, nil
  178. }
  179. func opOr(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  180. x, y := stack.pop(), stack.pop()
  181. stack.push(x.Or(x, y))
  182. return nil, nil
  183. }
  184. func opXor(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  185. x, y := stack.pop(), stack.pop()
  186. stack.push(x.Xor(x, y))
  187. return nil, nil
  188. }
  189. func opByte(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  190. th, val := stack.pop(), stack.pop()
  191. if th.Cmp(big.NewInt(32)) < 0 {
  192. byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
  193. stack.push(byte)
  194. } else {
  195. stack.push(new(big.Int))
  196. }
  197. return nil, nil
  198. }
  199. func opAddmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  200. x, y, z := stack.pop(), stack.pop(), stack.pop()
  201. if z.Cmp(Zero) > 0 {
  202. add := x.Add(x, y)
  203. add.Mod(add, z)
  204. stack.push(U256(add))
  205. } else {
  206. stack.push(new(big.Int))
  207. }
  208. return nil, nil
  209. }
  210. func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  211. x, y, z := stack.pop(), stack.pop(), stack.pop()
  212. if z.Cmp(Zero) > 0 {
  213. mul := x.Mul(x, y)
  214. mul.Mod(mul, z)
  215. stack.push(U256(mul))
  216. } else {
  217. stack.push(new(big.Int))
  218. }
  219. return nil, nil
  220. }
  221. func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  222. offset, size := stack.pop(), stack.pop()
  223. data := memory.Get(offset.Int64(), size.Int64())
  224. hash := crypto.Keccak256(data)
  225. if env.vmConfig.EnablePreimageRecording {
  226. env.StateDB.AddPreimage(common.BytesToHash(hash), data)
  227. }
  228. stack.push(common.BytesToBig(hash))
  229. return nil, nil
  230. }
  231. func opAddress(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  232. stack.push(common.Bytes2Big(contract.Address().Bytes()))
  233. return nil, nil
  234. }
  235. func opBalance(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  236. addr := common.BigToAddress(stack.pop())
  237. balance := env.StateDB.GetBalance(addr)
  238. stack.push(new(big.Int).Set(balance))
  239. return nil, nil
  240. }
  241. func opOrigin(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  242. stack.push(env.Origin.Big())
  243. return nil, nil
  244. }
  245. func opCaller(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  246. stack.push(contract.Caller().Big())
  247. return nil, nil
  248. }
  249. func opCallValue(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  250. stack.push(new(big.Int).Set(contract.value))
  251. return nil, nil
  252. }
  253. func opCalldataLoad(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  254. stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
  255. return nil, nil
  256. }
  257. func opCalldataSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  258. stack.push(big.NewInt(int64(len(contract.Input))))
  259. return nil, nil
  260. }
  261. func opCalldataCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  262. var (
  263. mOff = stack.pop()
  264. cOff = stack.pop()
  265. l = stack.pop()
  266. )
  267. memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
  268. return nil, nil
  269. }
  270. func opExtCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  271. addr := common.BigToAddress(stack.pop())
  272. l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
  273. stack.push(l)
  274. return nil, nil
  275. }
  276. func opCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  277. l := big.NewInt(int64(len(contract.Code)))
  278. stack.push(l)
  279. return nil, nil
  280. }
  281. func opCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  282. var (
  283. mOff = stack.pop()
  284. cOff = stack.pop()
  285. l = stack.pop()
  286. )
  287. codeCopy := getData(contract.Code, cOff, l)
  288. memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
  289. return nil, nil
  290. }
  291. func opExtCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  292. var (
  293. addr = common.BigToAddress(stack.pop())
  294. mOff = stack.pop()
  295. cOff = stack.pop()
  296. l = stack.pop()
  297. )
  298. codeCopy := getData(env.StateDB.GetCode(addr), cOff, l)
  299. memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
  300. return nil, nil
  301. }
  302. func opGasprice(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  303. stack.push(new(big.Int).Set(env.GasPrice))
  304. return nil, nil
  305. }
  306. func opBlockhash(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  307. num := stack.pop()
  308. n := new(big.Int).Sub(env.BlockNumber, common.Big257)
  309. if num.Cmp(n) > 0 && num.Cmp(env.BlockNumber) < 0 {
  310. stack.push(env.GetHash(num.Uint64()).Big())
  311. } else {
  312. stack.push(new(big.Int))
  313. }
  314. return nil, nil
  315. }
  316. func opCoinbase(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  317. stack.push(env.Coinbase.Big())
  318. return nil, nil
  319. }
  320. func opTimestamp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  321. stack.push(U256(new(big.Int).Set(env.Time)))
  322. return nil, nil
  323. }
  324. func opNumber(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  325. stack.push(U256(new(big.Int).Set(env.BlockNumber)))
  326. return nil, nil
  327. }
  328. func opDifficulty(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  329. stack.push(U256(new(big.Int).Set(env.Difficulty)))
  330. return nil, nil
  331. }
  332. func opGasLimit(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  333. stack.push(U256(new(big.Int).Set(env.GasLimit)))
  334. return nil, nil
  335. }
  336. func opPop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  337. stack.pop()
  338. return nil, nil
  339. }
  340. func opMload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  341. offset := stack.pop()
  342. val := common.BigD(memory.Get(offset.Int64(), 32))
  343. stack.push(val)
  344. return nil, nil
  345. }
  346. func opMstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  347. // pop value of the stack
  348. mStart, val := stack.pop(), stack.pop()
  349. memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
  350. return nil, nil
  351. }
  352. func opMstore8(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  353. off, val := stack.pop().Int64(), stack.pop().Int64()
  354. memory.store[off] = byte(val & 0xff)
  355. return nil, nil
  356. }
  357. func opSload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  358. loc := common.BigToHash(stack.pop())
  359. val := env.StateDB.GetState(contract.Address(), loc).Big()
  360. stack.push(val)
  361. return nil, nil
  362. }
  363. func opSstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  364. loc := common.BigToHash(stack.pop())
  365. val := stack.pop()
  366. env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
  367. return nil, nil
  368. }
  369. func opJump(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  370. pos := stack.pop()
  371. if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
  372. nop := contract.GetOp(pos.Uint64())
  373. return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
  374. }
  375. *pc = pos.Uint64()
  376. return nil, nil
  377. }
  378. func opJumpi(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  379. pos, cond := stack.pop(), stack.pop()
  380. if cond.Cmp(common.BigTrue) >= 0 {
  381. if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
  382. nop := contract.GetOp(pos.Uint64())
  383. return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
  384. }
  385. *pc = pos.Uint64()
  386. } else {
  387. *pc++
  388. }
  389. return nil, nil
  390. }
  391. func opJumpdest(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  392. return nil, nil
  393. }
  394. func opPc(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  395. stack.push(new(big.Int).SetUint64(*pc))
  396. return nil, nil
  397. }
  398. func opMsize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  399. stack.push(big.NewInt(int64(memory.Len())))
  400. return nil, nil
  401. }
  402. func opGas(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  403. stack.push(new(big.Int).Set(contract.Gas))
  404. return nil, nil
  405. }
  406. func opCreate(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  407. var (
  408. value = stack.pop()
  409. offset, size = stack.pop(), stack.pop()
  410. input = memory.Get(offset.Int64(), size.Int64())
  411. gas = new(big.Int).Set(contract.Gas)
  412. )
  413. if env.ChainConfig().IsEIP150(env.BlockNumber) {
  414. gas.Div(gas, n64)
  415. gas = gas.Sub(contract.Gas, gas)
  416. }
  417. contract.UseGas(gas)
  418. _, addr, suberr := env.Create(contract, input, gas, value)
  419. // Push item on the stack based on the returned error. If the ruleset is
  420. // homestead we must check for CodeStoreOutOfGasError (homestead only
  421. // rule) and treat as an error, if the ruleset is frontier we must
  422. // ignore this error and pretend the operation was successful.
  423. if env.ChainConfig().IsHomestead(env.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
  424. stack.push(new(big.Int))
  425. } else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
  426. stack.push(new(big.Int))
  427. } else {
  428. stack.push(addr.Big())
  429. }
  430. return nil, nil
  431. }
  432. func opCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  433. gas := stack.pop()
  434. // pop gas and value of the stack.
  435. addr, value := stack.pop(), stack.pop()
  436. value = U256(value)
  437. // pop input size and offset
  438. inOffset, inSize := stack.pop(), stack.pop()
  439. // pop return size and offset
  440. retOffset, retSize := stack.pop(), stack.pop()
  441. address := common.BigToAddress(addr)
  442. // Get the arguments from the memory
  443. args := memory.Get(inOffset.Int64(), inSize.Int64())
  444. if len(value.Bytes()) > 0 {
  445. gas.Add(gas, params.CallStipend)
  446. }
  447. ret, err := env.Call(contract, address, args, gas, value)
  448. if err != nil {
  449. stack.push(new(big.Int))
  450. } else {
  451. stack.push(big.NewInt(1))
  452. memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
  453. }
  454. return nil, nil
  455. }
  456. func opCallCode(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  457. gas := stack.pop()
  458. // pop gas and value of the stack.
  459. addr, value := stack.pop(), stack.pop()
  460. value = U256(value)
  461. // pop input size and offset
  462. inOffset, inSize := stack.pop(), stack.pop()
  463. // pop return size and offset
  464. retOffset, retSize := stack.pop(), stack.pop()
  465. address := common.BigToAddress(addr)
  466. // Get the arguments from the memory
  467. args := memory.Get(inOffset.Int64(), inSize.Int64())
  468. if len(value.Bytes()) > 0 {
  469. gas.Add(gas, params.CallStipend)
  470. }
  471. ret, err := env.CallCode(contract, address, args, gas, value)
  472. if err != nil {
  473. stack.push(new(big.Int))
  474. } else {
  475. stack.push(big.NewInt(1))
  476. memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
  477. }
  478. return nil, nil
  479. }
  480. func opDelegateCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  481. // if not homestead return an error. DELEGATECALL is not supported
  482. // during pre-homestead.
  483. if !env.ChainConfig().IsHomestead(env.BlockNumber) {
  484. return nil, fmt.Errorf("invalid opcode %x", DELEGATECALL)
  485. }
  486. gas, to, inOffset, inSize, outOffset, outSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
  487. toAddr := common.BigToAddress(to)
  488. args := memory.Get(inOffset.Int64(), inSize.Int64())
  489. ret, err := env.DelegateCall(contract, toAddr, args, gas)
  490. if err != nil {
  491. stack.push(new(big.Int))
  492. } else {
  493. stack.push(big.NewInt(1))
  494. memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
  495. }
  496. return nil, nil
  497. }
  498. func opReturn(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  499. offset, size := stack.pop(), stack.pop()
  500. ret := memory.GetPtr(offset.Int64(), size.Int64())
  501. return ret, nil
  502. }
  503. func opStop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  504. return nil, nil
  505. }
  506. func opSuicide(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  507. balance := env.StateDB.GetBalance(contract.Address())
  508. env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
  509. env.StateDB.Suicide(contract.Address())
  510. return nil, nil
  511. }
  512. // following functions are used by the instruction jump table
  513. // make log instruction function
  514. func makeLog(size int) executionFunc {
  515. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  516. topics := make([]common.Hash, size)
  517. mStart, mSize := stack.pop(), stack.pop()
  518. for i := 0; i < size; i++ {
  519. topics[i] = common.BigToHash(stack.pop())
  520. }
  521. d := memory.Get(mStart.Int64(), mSize.Int64())
  522. env.StateDB.AddLog(&types.Log{
  523. Address: contract.Address(),
  524. Topics: topics,
  525. Data: d,
  526. // This is a non-consensus field, but assigned here because
  527. // core/state doesn't know the current block number.
  528. BlockNumber: env.BlockNumber.Uint64(),
  529. })
  530. return nil, nil
  531. }
  532. }
  533. // make push instruction function
  534. func makePush(size uint64, bsize *big.Int) executionFunc {
  535. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  536. byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
  537. stack.push(common.Bytes2Big(byts))
  538. *pc += size
  539. return nil, nil
  540. }
  541. }
  542. // make push instruction function
  543. func makeDup(size int64) executionFunc {
  544. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  545. stack.dup(int(size))
  546. return nil, nil
  547. }
  548. }
  549. // make swap instruction function
  550. func makeSwap(size int64) executionFunc {
  551. // switch n + 1 otherwise n would be swapped with n
  552. size += 1
  553. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  554. stack.swap(int(size))
  555. return nil, nil
  556. }
  557. }