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