OpCodes.sol 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. pragma solidity >=0.4.21 <0.6.0;
  2. contract Test1 {
  3. function isSameAddress(address a, address b) public returns(bool){ //Simply add the two arguments and return
  4. if (a == b) return true;
  5. return false;
  6. }
  7. }
  8. contract OpCodes {
  9. Test1 test1;
  10. constructor() public { //Constructor function
  11. test1 = new Test1(); //Create new "Test1" function
  12. }
  13. modifier onlyOwner(address _owner) {
  14. require(msg.sender == _owner);
  15. _;
  16. }
  17. // Add a todo to the list
  18. function test() public {
  19. //simple_instructions
  20. /*assembly { pop(sub(dup1, mul(dup1, dup1))) }*/
  21. //keywords
  22. assembly { pop(address) return(2, byte(2,1)) }
  23. //label_complex
  24. /*assembly { 7 abc: 8 eq jump(abc) jumpi(eq(7, 8), abc) pop }
  25. assembly { pop(jumpi(eq(7, 8), abc)) jump(abc) }*/
  26. //functional
  27. /*assembly { let x := 2 add(7, mul(6, x)) mul(7, 8) add =: x }*/
  28. //for_statement
  29. assembly { for { let i := 1 } lt(i, 5) { i := add(i, 1) } {} }
  30. assembly { for { let i := 6 } gt(i, 5) { i := add(i, 1) } {} }
  31. assembly { for { let i := 1 } slt(i, 5) { i := add(i, 1) } {} }
  32. assembly { for { let i := 6 } sgt(i, 5) { i := add(i, 1) } {} }
  33. //no_opcodes_in_strict
  34. assembly { pop(callvalue()) }
  35. //no_dup_swap_in_strict
  36. /*assembly { swap1() }*/
  37. //print_functional
  38. assembly { let x := mul(sload(0x12), 7) }
  39. //print_if
  40. assembly { if 2 { pop(mload(0)) }}
  41. //function_definitions_multiple_args
  42. assembly { function f(a, d){ mstore(a, d) } function g(a, d) -> x, y {}}
  43. //sstore
  44. assembly { function f(a, d){ sstore(a, d) } function g(a, d) -> x, y {}}
  45. //mstore8
  46. assembly { function f(a, d){ mstore8(a, d) } function g(a, d) -> x, y {}}
  47. //calldatacopy
  48. assembly {
  49. let a := mload(0x40)
  50. let b := add(a, 32)
  51. calldatacopy(a, 4, 32)
  52. /*calldatacopy(b, add(4, 32), 32)*/
  53. /*result := add(mload(a), mload(b))*/
  54. }
  55. //codecopy
  56. assembly {
  57. let a := mload(0x40)
  58. let b := add(a, 32)
  59. codecopy(a, 4, 32)
  60. }
  61. //codecopy
  62. assembly {
  63. let a := mload(0x40)
  64. let b := add(a, 32)
  65. extcodecopy(0, a, 4, 32)
  66. }
  67. //for_statement
  68. assembly { let x := calldatasize() for { let i := 0} lt(i, x) { i := add(i, 1) } { mstore(i, 2) } }
  69. //keccak256
  70. assembly { pop(keccak256(0,0)) }
  71. //returndatasize
  72. assembly { let r := returndatasize }
  73. //returndatacopy
  74. assembly { returndatacopy(64, 32, 0) }
  75. //byzantium vs const Constantinople
  76. //staticcall
  77. assembly { pop(staticcall(10000, 0x123, 64, 0x10, 128, 0x10)) }
  78. /*//create2 Constantinople
  79. assembly { pop(create2(10, 0x123, 32, 64)) }*/
  80. //create Constantinople
  81. assembly { pop(create(10, 0x123, 32)) }
  82. //shift Constantinople
  83. /*assembly { pop(shl(10, 32)) }
  84. assembly { pop(shr(10, 32)) }
  85. assembly { pop(sar(10, 32)) }*/
  86. //not
  87. assembly { pop( not(0x1f)) }
  88. //exp
  89. assembly { pop( exp(2, 226)) }
  90. //mod
  91. assembly { pop( mod(3, 9)) }
  92. //smod
  93. assembly { pop( smod(3, 9)) }
  94. //div
  95. assembly { pop( div(4, 2)) }
  96. //sdiv
  97. assembly { pop( sdiv(4, 2)) }
  98. //iszero
  99. assembly { pop(iszero(1)) }
  100. //and
  101. assembly { pop(and(2,3)) }
  102. //or
  103. assembly { pop(or(3,3)) }
  104. //xor
  105. assembly { pop(xor(3,3)) }
  106. //addmod
  107. assembly { pop(addmod(3,3,6)) }
  108. //mulmod
  109. assembly { pop(mulmod(3,3,3)) }
  110. //signextend
  111. assembly { pop(signextend(1, 10)) }
  112. //sha3
  113. assembly { pop(calldataload(0)) }
  114. //blockhash
  115. assembly { pop(blockhash(sub(number(), 1))) }
  116. //balance
  117. assembly { pop(balance(0x0)) }
  118. //caller
  119. assembly { pop(caller()) }
  120. //codesize
  121. assembly { pop(codesize()) }
  122. //extcodesize
  123. assembly { pop(extcodesize(0x1)) }
  124. //origin
  125. assembly { pop(origin()) }
  126. //gas
  127. assembly { pop(gas())}
  128. //msize
  129. assembly { pop(msize())}
  130. //pc
  131. assembly { pop(pc())}
  132. //gasprice
  133. assembly { pop(gasprice())}
  134. //coinbase
  135. assembly { pop(coinbase())}
  136. //timestamp
  137. assembly { pop(timestamp())}
  138. //number
  139. assembly { pop(number())}
  140. //difficulty
  141. assembly { pop(difficulty())}
  142. //gaslimit
  143. assembly { pop(gaslimit())}
  144. //call
  145. address contractAddr = address(test1);
  146. bytes4 sig = bytes4(keccak256("isSameAddress(address,address)")); //Function signature
  147. address a = msg.sender;
  148. assembly {
  149. let x := mload(0x40) //Find empty storage location using "free memory pointer"
  150. mstore(x,sig) //Place signature at begining of empty storage
  151. mstore(add(x,0x04),a) // first address parameter. just after signature
  152. mstore(add(x,0x24),a) // 2nd address parameter - first padded. add 32 bytes (not 20 bytes)
  153. mstore(0x40,add(x,0x64)) // this is missing in other examples. Set free pointer before function call. so it is used by called function.
  154. // new free pointer position after the output values of the called function.
  155. let success := call(
  156. 5000, //5k gas
  157. contractAddr, //To addr
  158. 0, //No wei passed
  159. x, // Inputs are at location x
  160. 0x44, //Inputs size two padded, so 68 bytes
  161. x, //Store output over input
  162. 0x20) //Output is 32 bytes long
  163. }
  164. //callcode
  165. assembly {
  166. let x := mload(0x40) //Find empty storage location using "free memory pointer"
  167. mstore(x,sig) //Place signature at begining of empty storage
  168. mstore(add(x,0x04),a) // first address parameter. just after signature
  169. mstore(add(x,0x24),a) // 2nd address parameter - first padded. add 32 bytes (not 20 bytes)
  170. mstore(0x40,add(x,0x64)) // this is missing in other examples. Set free pointer before function call. so it is used by called function.
  171. // new free pointer position after the output values of the called function.
  172. let success := callcode(
  173. 5000, //5k gas
  174. contractAddr, //To addr
  175. 0, //No wei passed
  176. x, // Inputs are at location x
  177. 0x44, //Inputs size two padded, so 68 bytes
  178. x, //Store output over input
  179. 0x20) //Output is 32 bytes long
  180. }
  181. //delegatecall
  182. assembly {
  183. let x := mload(0x40) //Find empty storage location using "free memory pointer"
  184. mstore(x,sig) //Place signature at begining of empty storage
  185. mstore(add(x,0x04),a) // first address parameter. just after signature
  186. mstore(add(x,0x24),a) // 2nd address parameter - first padded. add 32 bytes (not 20 bytes)
  187. mstore(0x40,add(x,0x64)) // this is missing in other examples. Set free pointer before function call. so it is used by called function.
  188. // new free pointer position after the output values of the called function.
  189. let success := delegatecall(
  190. 5000, //5k gas
  191. contractAddr, //To addr
  192. x, // Inputs are at location x
  193. 0x44, //Inputs size two padded, so 68 bytes
  194. x, //Store output over input
  195. 0x20) //Output is 32 bytes long
  196. }
  197. uint256 _id = 0x420042;
  198. //log0
  199. log0(
  200. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20)
  201. );
  202. //log1
  203. log1(
  204. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
  205. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20)
  206. );
  207. //log2
  208. log2(
  209. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
  210. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
  211. bytes32(uint256(msg.sender))
  212. );
  213. //log3
  214. log3(
  215. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
  216. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
  217. bytes32(uint256(msg.sender)),
  218. bytes32(_id)
  219. );
  220. //log4
  221. log4(
  222. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
  223. bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
  224. bytes32(uint256(msg.sender)),
  225. bytes32(_id),
  226. bytes32(_id)
  227. );
  228. //selfdestruct
  229. assembly { selfdestruct(0x02) }
  230. }
  231. function test_revert() public {
  232. //revert
  233. assembly{ revert(0, 0) }
  234. }
  235. function test_invalid() public {
  236. //revert
  237. assembly{ invalid() }
  238. }
  239. function test_stop() public {
  240. //revert
  241. assembly{ stop() }
  242. }
  243. }