# Sth about Solidity

By [Yuan](https://paragraph.com/@yuan90) · 2023-05-30

---

随便记录的草稿, 别看~

1\. About ABI
=============

> **ABI: Application Binary Interface**

**function selector:** use front 4 bytes as function selector to locate the function.

**how to calculate:** use `keccak256` to get front 4 bytes.。

    bytes4(keccak256("foo(uint32,bool)"))
    

**an example:**

**function:** function baz(uint32 x, bool y)

**call it:** baz(69, true)

    function selector:  0xcdcd77c0     bytes4(keccak256("baz(uint32,bool)"))
    
    0x0000000000000000000000000000000000000000000000000000000000000045
    + first param, uint32:69, should append 0 to get 32 bytes
    
    0x0000000000000000000000000000000000000000000000000000000000000001
    + second param, bool:true
    

[https://abi.hashex.org/](https://abi.hashex.org/)

use abi.hashex try it, will get:

cdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001

**another example:**

**function:** fn1(uint8\[\], bool, string)

**call it:** fn1(\[5,6\], true, “hello world!“)

    abi:  0dbb9c190000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c68656c6c6f20776f726c64210000000000000000000000000000000000000000
    

### \[analysis\]:

*   **front 4 bytes:** 0dbb9c19 **as** function selector.
    
*   **following 32 bytes:** 0000000000000000000000000000000000000000000000000000000000000060 **as** first param is non-fixed type, so record it’s offset(96, 3 x 32, the value’s location after third 32bytes)
    
*   **following 32 bytes:** 0000000000000000000000000000000000000000000000000000000000000001 **as** second param: bool value (fixed length param)
    
*   **following 32 bytes:** 00000000000000000000000000000000000000000000000000000000000000c0 **as** third param is non-fixed type, so record it’s offset(192, 6 x 32, the value’s location after 6th 32bytes)
    
*   **following 32 bytes:** 0000000000000000000000000000000000000000000000000000000000000002 **as** first param : array length (non-fixed length param)
    
*   **following 32 bytes:** 0000000000000000000000000000000000000000000000000000000000000005 **as** first param : array element\[0\]
    
*   **following 32 bytes:** 0000000000000000000000000000000000000000000000000000000000000006 **as** first param : array element\[1\]
    
*   **following 32 bytes:** 000000000000000000000000000000000000000000000000000000000000000c **as** third param: string length(12) (non-fixed length param)
    
*   **following 32 bytes:** 68656c6c6f20776f726c64210000000000000000000000000000000000000000 **as** third param: string value(hex 2 = 1 char, such as ‘h‘ is 0x68, 0x6c is ‘l‘)
    

* * *

1\. About Call/Callcode/Delegatecall/Staticcall
===============================================

differences among these approaches:

*   **call:** `call` is a low level function to interact with other contracts, is recommended.
    
*   **callcode:** CALL modifies the storage of the callee, and CALLCODE modifies the storage of the caller.
    
*   **delegatecall:** DELEGATECALL can be considered a bugfix version of CALLCODE, and CALLCODE is no longer officially recommended. The difference is that **MSG. SENDER** is different\*\*.\*\* DELEGATECALL WILL ALWAYS USE THE ADDRESS OF THE ORIGINAL CALLER, WHILE CALLCODE WILL NOT.
    
*   **staticcall:** is currently no low-level API in Solidity that can call it directly, but it is planned to compile functions calling view and pure types into STATIC call instructions at the compiler level in the future.
    

    pragma solidity ^0.8.0;
    
    contract A {
        int public x;
        
        function inc_call(address _contractAddress) public {
            _contractAddress.call(bytes4(keccak256("inc()")));
        }
        function inc_callcode(address _contractAddress) public {
            _contractAddress.callcode(bytes4(keccak256("inc()")));
        }
    }
    
    contract B {
        int public x;
        
        function inc() public {
            x++;
        }
    }
    

![](https://storage.googleapis.com/papyrus_images/89f93dec7eefa2b4b00730b7235abeb794786bcc097506a1c86a90ea94691c05.png)

    pragma solidity ^0.4.25;
    
    contract A {
        int public x;
        
        function inc_callcode(address _contractAddress) public {
            _contractAddress.callcode(bytes4(keccak256("inc()")));
        }
        function inc_delegatecall(address _contractAddress) public {
            _contractAddress.delegatecall(bytes4(keccak256("inc()")));
        }
    }
    
    contract B {
        int public x;
        
        event senderAddr(address);
        function inc() public {
            x++;
            emit senderAddr(msg.sender);
        }
    }
    

![](https://storage.googleapis.com/papyrus_images/cd7450a92655c56a83a42a55503b5b1d21293985517de7fd9fb0d319e5db38ad.png)

---

*Originally published on [Yuan](https://paragraph.com/@yuan90/sth-about-solidity)*
