opcodes.go 9.0 KB

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