opcodes.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. // Copyright 2014 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. )
  20. // OpCode is an EVM opcode
  21. type OpCode byte
  22. func (op OpCode) IsPush() bool {
  23. switch op {
  24. 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:
  25. return true
  26. }
  27. return false
  28. }
  29. func (op OpCode) IsStaticJump() bool {
  30. return op == JUMP
  31. }
  32. const (
  33. // 0x0 range - arithmetic ops
  34. STOP OpCode = iota
  35. ADD
  36. MUL
  37. SUB
  38. DIV
  39. SDIV
  40. MOD
  41. SMOD
  42. ADDMOD
  43. MULMOD
  44. EXP
  45. SIGNEXTEND
  46. )
  47. const (
  48. LT OpCode = iota + 0x10
  49. GT
  50. SLT
  51. SGT
  52. EQ
  53. ISZERO
  54. AND
  55. OR
  56. XOR
  57. NOT
  58. BYTE
  59. SHA3 = 0x20
  60. )
  61. const (
  62. // 0x30 range - closure state
  63. ADDRESS OpCode = 0x30 + iota
  64. BALANCE
  65. ORIGIN
  66. CALLER
  67. CALLVALUE
  68. CALLDATALOAD
  69. CALLDATASIZE
  70. CALLDATACOPY
  71. CODESIZE
  72. CODECOPY
  73. GASPRICE
  74. EXTCODESIZE
  75. EXTCODECOPY
  76. RETURNDATASIZE
  77. RETURNDATACOPY
  78. )
  79. const (
  80. // 0x40 range - block operations
  81. BLOCKHASH OpCode = 0x40 + iota
  82. COINBASE
  83. TIMESTAMP
  84. NUMBER
  85. DIFFICULTY
  86. GASLIMIT
  87. )
  88. const (
  89. // 0x50 range - 'storage' and execution
  90. POP OpCode = 0x50 + iota
  91. MLOAD
  92. MSTORE
  93. MSTORE8
  94. SLOAD
  95. SSTORE
  96. JUMP
  97. JUMPI
  98. PC
  99. MSIZE
  100. GAS
  101. JUMPDEST
  102. )
  103. const (
  104. // 0x60 range
  105. PUSH1 OpCode = 0x60 + iota
  106. PUSH2
  107. PUSH3
  108. PUSH4
  109. PUSH5
  110. PUSH6
  111. PUSH7
  112. PUSH8
  113. PUSH9
  114. PUSH10
  115. PUSH11
  116. PUSH12
  117. PUSH13
  118. PUSH14
  119. PUSH15
  120. PUSH16
  121. PUSH17
  122. PUSH18
  123. PUSH19
  124. PUSH20
  125. PUSH21
  126. PUSH22
  127. PUSH23
  128. PUSH24
  129. PUSH25
  130. PUSH26
  131. PUSH27
  132. PUSH28
  133. PUSH29
  134. PUSH30
  135. PUSH31
  136. PUSH32
  137. DUP1
  138. DUP2
  139. DUP3
  140. DUP4
  141. DUP5
  142. DUP6
  143. DUP7
  144. DUP8
  145. DUP9
  146. DUP10
  147. DUP11
  148. DUP12
  149. DUP13
  150. DUP14
  151. DUP15
  152. DUP16
  153. SWAP1
  154. SWAP2
  155. SWAP3
  156. SWAP4
  157. SWAP5
  158. SWAP6
  159. SWAP7
  160. SWAP8
  161. SWAP9
  162. SWAP10
  163. SWAP11
  164. SWAP12
  165. SWAP13
  166. SWAP14
  167. SWAP15
  168. SWAP16
  169. )
  170. const (
  171. LOG0 OpCode = 0xa0 + iota
  172. LOG1
  173. LOG2
  174. LOG3
  175. LOG4
  176. )
  177. // unofficial opcodes used for parsing
  178. const (
  179. PUSH OpCode = 0xb0 + iota
  180. DUP
  181. SWAP
  182. )
  183. const (
  184. // 0xf0 range - closures
  185. CREATE OpCode = 0xf0 + iota
  186. CALL
  187. CALLCODE
  188. RETURN
  189. DELEGATECALL
  190. STATICCALL = 0xfa
  191. REVERT = 0xfd
  192. SELFDESTRUCT = 0xff
  193. )
  194. // Since the opcodes aren't all in order we can't use a regular slice
  195. var opCodeToString = map[OpCode]string{
  196. // 0x0 range - arithmetic ops
  197. STOP: "STOP",
  198. ADD: "ADD",
  199. MUL: "MUL",
  200. SUB: "SUB",
  201. DIV: "DIV",
  202. SDIV: "SDIV",
  203. MOD: "MOD",
  204. SMOD: "SMOD",
  205. EXP: "EXP",
  206. NOT: "NOT",
  207. LT: "LT",
  208. GT: "GT",
  209. SLT: "SLT",
  210. SGT: "SGT",
  211. EQ: "EQ",
  212. ISZERO: "ISZERO",
  213. SIGNEXTEND: "SIGNEXTEND",
  214. // 0x10 range - bit ops
  215. AND: "AND",
  216. OR: "OR",
  217. XOR: "XOR",
  218. BYTE: "BYTE",
  219. ADDMOD: "ADDMOD",
  220. MULMOD: "MULMOD",
  221. // 0x20 range - crypto
  222. SHA3: "SHA3",
  223. // 0x30 range - closure state
  224. ADDRESS: "ADDRESS",
  225. BALANCE: "BALANCE",
  226. ORIGIN: "ORIGIN",
  227. CALLER: "CALLER",
  228. CALLVALUE: "CALLVALUE",
  229. CALLDATALOAD: "CALLDATALOAD",
  230. CALLDATASIZE: "CALLDATASIZE",
  231. CALLDATACOPY: "CALLDATACOPY",
  232. CODESIZE: "CODESIZE",
  233. CODECOPY: "CODECOPY",
  234. GASPRICE: "GASPRICE",
  235. EXTCODESIZE: "EXTCODESIZE",
  236. EXTCODECOPY: "EXTCODECOPY",
  237. RETURNDATASIZE: "RETURNDATASIZE",
  238. RETURNDATACOPY: "RETURNDATACOPY",
  239. // 0x40 range - block operations
  240. BLOCKHASH: "BLOCKHASH",
  241. COINBASE: "COINBASE",
  242. TIMESTAMP: "TIMESTAMP",
  243. NUMBER: "NUMBER",
  244. DIFFICULTY: "DIFFICULTY",
  245. GASLIMIT: "GASLIMIT",
  246. // 0x50 range - 'storage' and execution
  247. POP: "POP",
  248. //DUP: "DUP",
  249. //SWAP: "SWAP",
  250. MLOAD: "MLOAD",
  251. MSTORE: "MSTORE",
  252. MSTORE8: "MSTORE8",
  253. SLOAD: "SLOAD",
  254. SSTORE: "SSTORE",
  255. JUMP: "JUMP",
  256. JUMPI: "JUMPI",
  257. PC: "PC",
  258. MSIZE: "MSIZE",
  259. GAS: "GAS",
  260. JUMPDEST: "JUMPDEST",
  261. // 0x60 range - push
  262. PUSH1: "PUSH1",
  263. PUSH2: "PUSH2",
  264. PUSH3: "PUSH3",
  265. PUSH4: "PUSH4",
  266. PUSH5: "PUSH5",
  267. PUSH6: "PUSH6",
  268. PUSH7: "PUSH7",
  269. PUSH8: "PUSH8",
  270. PUSH9: "PUSH9",
  271. PUSH10: "PUSH10",
  272. PUSH11: "PUSH11",
  273. PUSH12: "PUSH12",
  274. PUSH13: "PUSH13",
  275. PUSH14: "PUSH14",
  276. PUSH15: "PUSH15",
  277. PUSH16: "PUSH16",
  278. PUSH17: "PUSH17",
  279. PUSH18: "PUSH18",
  280. PUSH19: "PUSH19",
  281. PUSH20: "PUSH20",
  282. PUSH21: "PUSH21",
  283. PUSH22: "PUSH22",
  284. PUSH23: "PUSH23",
  285. PUSH24: "PUSH24",
  286. PUSH25: "PUSH25",
  287. PUSH26: "PUSH26",
  288. PUSH27: "PUSH27",
  289. PUSH28: "PUSH28",
  290. PUSH29: "PUSH29",
  291. PUSH30: "PUSH30",
  292. PUSH31: "PUSH31",
  293. PUSH32: "PUSH32",
  294. DUP1: "DUP1",
  295. DUP2: "DUP2",
  296. DUP3: "DUP3",
  297. DUP4: "DUP4",
  298. DUP5: "DUP5",
  299. DUP6: "DUP6",
  300. DUP7: "DUP7",
  301. DUP8: "DUP8",
  302. DUP9: "DUP9",
  303. DUP10: "DUP10",
  304. DUP11: "DUP11",
  305. DUP12: "DUP12",
  306. DUP13: "DUP13",
  307. DUP14: "DUP14",
  308. DUP15: "DUP15",
  309. DUP16: "DUP16",
  310. SWAP1: "SWAP1",
  311. SWAP2: "SWAP2",
  312. SWAP3: "SWAP3",
  313. SWAP4: "SWAP4",
  314. SWAP5: "SWAP5",
  315. SWAP6: "SWAP6",
  316. SWAP7: "SWAP7",
  317. SWAP8: "SWAP8",
  318. SWAP9: "SWAP9",
  319. SWAP10: "SWAP10",
  320. SWAP11: "SWAP11",
  321. SWAP12: "SWAP12",
  322. SWAP13: "SWAP13",
  323. SWAP14: "SWAP14",
  324. SWAP15: "SWAP15",
  325. SWAP16: "SWAP16",
  326. LOG0: "LOG0",
  327. LOG1: "LOG1",
  328. LOG2: "LOG2",
  329. LOG3: "LOG3",
  330. LOG4: "LOG4",
  331. // 0xf0 range
  332. CREATE: "CREATE",
  333. CALL: "CALL",
  334. RETURN: "RETURN",
  335. CALLCODE: "CALLCODE",
  336. DELEGATECALL: "DELEGATECALL",
  337. STATICCALL: "STATICCALL",
  338. REVERT: "REVERT",
  339. SELFDESTRUCT: "SELFDESTRUCT",
  340. PUSH: "PUSH",
  341. DUP: "DUP",
  342. SWAP: "SWAP",
  343. }
  344. func (o OpCode) String() string {
  345. str := opCodeToString[o]
  346. if len(str) == 0 {
  347. return fmt.Sprintf("Missing opcode 0x%x", int(o))
  348. }
  349. return str
  350. }
  351. var stringToOp = map[string]OpCode{
  352. "STOP": STOP,
  353. "ADD": ADD,
  354. "MUL": MUL,
  355. "SUB": SUB,
  356. "DIV": DIV,
  357. "SDIV": SDIV,
  358. "MOD": MOD,
  359. "SMOD": SMOD,
  360. "EXP": EXP,
  361. "NOT": NOT,
  362. "LT": LT,
  363. "GT": GT,
  364. "SLT": SLT,
  365. "SGT": SGT,
  366. "EQ": EQ,
  367. "ISZERO": ISZERO,
  368. "SIGNEXTEND": SIGNEXTEND,
  369. "AND": AND,
  370. "OR": OR,
  371. "XOR": XOR,
  372. "BYTE": BYTE,
  373. "ADDMOD": ADDMOD,
  374. "MULMOD": MULMOD,
  375. "SHA3": SHA3,
  376. "ADDRESS": ADDRESS,
  377. "BALANCE": BALANCE,
  378. "ORIGIN": ORIGIN,
  379. "CALLER": CALLER,
  380. "CALLVALUE": CALLVALUE,
  381. "CALLDATALOAD": CALLDATALOAD,
  382. "CALLDATASIZE": CALLDATASIZE,
  383. "CALLDATACOPY": CALLDATACOPY,
  384. "DELEGATECALL": DELEGATECALL,
  385. "STATICCALL": STATICCALL,
  386. "CODESIZE": CODESIZE,
  387. "CODECOPY": CODECOPY,
  388. "GASPRICE": GASPRICE,
  389. "EXTCODESIZE": EXTCODESIZE,
  390. "EXTCODECOPY": EXTCODECOPY,
  391. "RETURNDATASIZE": RETURNDATASIZE,
  392. "RETURNDATACOPY": RETURNDATACOPY,
  393. "BLOCKHASH": BLOCKHASH,
  394. "COINBASE": COINBASE,
  395. "TIMESTAMP": TIMESTAMP,
  396. "NUMBER": NUMBER,
  397. "DIFFICULTY": DIFFICULTY,
  398. "GASLIMIT": GASLIMIT,
  399. "POP": POP,
  400. "MLOAD": MLOAD,
  401. "MSTORE": MSTORE,
  402. "MSTORE8": MSTORE8,
  403. "SLOAD": SLOAD,
  404. "SSTORE": SSTORE,
  405. "JUMP": JUMP,
  406. "JUMPI": JUMPI,
  407. "PC": PC,
  408. "MSIZE": MSIZE,
  409. "GAS": GAS,
  410. "JUMPDEST": JUMPDEST,
  411. "PUSH1": PUSH1,
  412. "PUSH2": PUSH2,
  413. "PUSH3": PUSH3,
  414. "PUSH4": PUSH4,
  415. "PUSH5": PUSH5,
  416. "PUSH6": PUSH6,
  417. "PUSH7": PUSH7,
  418. "PUSH8": PUSH8,
  419. "PUSH9": PUSH9,
  420. "PUSH10": PUSH10,
  421. "PUSH11": PUSH11,
  422. "PUSH12": PUSH12,
  423. "PUSH13": PUSH13,
  424. "PUSH14": PUSH14,
  425. "PUSH15": PUSH15,
  426. "PUSH16": PUSH16,
  427. "PUSH17": PUSH17,
  428. "PUSH18": PUSH18,
  429. "PUSH19": PUSH19,
  430. "PUSH20": PUSH20,
  431. "PUSH21": PUSH21,
  432. "PUSH22": PUSH22,
  433. "PUSH23": PUSH23,
  434. "PUSH24": PUSH24,
  435. "PUSH25": PUSH25,
  436. "PUSH26": PUSH26,
  437. "PUSH27": PUSH27,
  438. "PUSH28": PUSH28,
  439. "PUSH29": PUSH29,
  440. "PUSH30": PUSH30,
  441. "PUSH31": PUSH31,
  442. "PUSH32": PUSH32,
  443. "DUP1": DUP1,
  444. "DUP2": DUP2,
  445. "DUP3": DUP3,
  446. "DUP4": DUP4,
  447. "DUP5": DUP5,
  448. "DUP6": DUP6,
  449. "DUP7": DUP7,
  450. "DUP8": DUP8,
  451. "DUP9": DUP9,
  452. "DUP10": DUP10,
  453. "DUP11": DUP11,
  454. "DUP12": DUP12,
  455. "DUP13": DUP13,
  456. "DUP14": DUP14,
  457. "DUP15": DUP15,
  458. "DUP16": DUP16,
  459. "SWAP1": SWAP1,
  460. "SWAP2": SWAP2,
  461. "SWAP3": SWAP3,
  462. "SWAP4": SWAP4,
  463. "SWAP5": SWAP5,
  464. "SWAP6": SWAP6,
  465. "SWAP7": SWAP7,
  466. "SWAP8": SWAP8,
  467. "SWAP9": SWAP9,
  468. "SWAP10": SWAP10,
  469. "SWAP11": SWAP11,
  470. "SWAP12": SWAP12,
  471. "SWAP13": SWAP13,
  472. "SWAP14": SWAP14,
  473. "SWAP15": SWAP15,
  474. "SWAP16": SWAP16,
  475. "LOG0": LOG0,
  476. "LOG1": LOG1,
  477. "LOG2": LOG2,
  478. "LOG3": LOG3,
  479. "LOG4": LOG4,
  480. "CREATE": CREATE,
  481. "CALL": CALL,
  482. "RETURN": RETURN,
  483. "CALLCODE": CALLCODE,
  484. "REVERT": REVERT,
  485. "SELFDESTRUCT": SELFDESTRUCT,
  486. }
  487. func StringToOp(str string) OpCode {
  488. return stringToOp[str]
  489. }