github.com/teleloco/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  }