Smart Contract Development
  • Introduction
    • What is a Transaction
    • Accounts and Signing
    • What is a smart contract
  • Learning Solidity
    • Introduction
    • Module 1
      • Variable Types
      • Variable Scope: State & Local variables
      • Global variables
      • Functions
        • View and Pure
        • Shadowing in Fuctions
      • Mapping
      • Require
      • Events
    • Project #1: Simple Registry
    • Module 2
      • Constructor
      • Data Location: Value & Reference
      • Interface
      • Import
        • Importing in Foundry
      • Inheritance
      • ERC-20
      • Checks-effect-interaction pattern
    • Project #2: Basic Vault
    • Module 3
      • Payable
      • Receive
      • Fallback
      • Returns
    • Project #3: ERC20+ETH Wrapper
    • Module 4
      • Immutable and Constant
      • Fixed-point Math
      • Abstract contracts
      • ERC-4626
      • Modifier + Inheritance +Ownable
      • Type
    • Project #4: Fractional Wrapper
    • Module 5
      • If-else
      • Libraries
        • TransferHelper
      • Chainlink Oracle
    • Project #5: Collateralized Vault
  • Compendium
    • Solidity Basics
      • Variable Types
      • Value Types
        • address
        • enum
      • Reference Types
        • strings
        • mappings
        • struct
        • Arrays
        • Multi-Dimensional arrays
      • Global Objects
      • Functions
        • Function types
        • Constructor Function
        • Transaction vs Call
        • Require, Revert, Assert
      • Function signature + selectors
      • Payable
        • Payable + withdraw
        • msg.value & payable functions
      • Receive
      • Fallback function (sol v 0.8)
        • Fallback function (sol v 0.6)
      • call, staticcall, delegatecall
    • Return & Events
    • Control Variable Visibility
    • Local Variables (Storage v Memory)
    • Data Location and Assignment Behaviors
    • Modifiers & Inheritance & Import
      • import styles
    • Interface & Abstract Contracts
    • ABI & Debugging
    • Libraries
    • Conditional(ternary) operators
    • Smart Contract Life-cycle
      • Pausing Smart Contracts
      • Destroying Smart Contracts
    • Merkle Trie and MPT
    • Merkle Tree Airdrop
  • Try & catch
  • Ethereum Signatures
  • EVM, Storage, Opcodes
    • EVM
    • Wei, Ether, Gas
    • Storage
    • ByteCode and Opcodes
    • Transaction costs & Execution costs
  • Reading txn input data
  • Data Representation
  • Yul
    • Yul
      • Intro
      • Basic operations
      • Storage Slots
      • Storage of Arrays and Mappings
      • Memory Operations
      • Memory: how solidity uses memory
      • Memory: Return, Require, Tuples and Keccak256
      • Memory: Logs and Events
      • Inter-contract calls
      • calldata
      • free memory pointer
    • Yul Exercises
      • read state variable
      • read mapping
      • iterate Array, Return Sum
    • memory-safe
  • Upgradable Contracts
    • Upgradability & Proxies
    • UUPS Example
    • Minimal Proxy Example
    • TPP Example
    • 🚧Diamond
      • On Storage
  • Gas Opt
    • Block Limit
    • gasLimit & min cost
    • Solidity Optimiser
    • Memory v calldata
    • Memory caching vs direct storage vs pointers
    • < vs <=
    • reverting early
    • X && Y, ||
    • constant and immutable
    • caching sload into mload
    • Syntactic Sugar
    • using unchecked w/o require
    • Compact Strings
    • Calling a view function
    • Custom errors over require
    • usage of this.
      • multiple address(this)
  • ERCs & EIPs
    • ERC-20.sol
      • Core functions
      • transfer()
      • transferFrom()
      • TLDR transfer vs transferFrom
    • Landing
      • ERC721.sol
      • EIP-721
        • LooksRare
        • Page 1
      • ERC-1271
      • EIP-2981
      • ERC-165
      • EIP-1167: Minimal Proxy Contract
    • VRFConsumerBase
    • UniswapV2Library
  • Yield Mentorship 2022
    • Projects
      • #1 Simple Registry
      • #2 Basic Vault
      • #3 ERC20+ETH Wrapper
        • setFailTransferTrue
      • #4 Fractional Wrapper
      • #5 Collateralized Vault
        • Process
        • Vault.sol
        • Testing
        • Chainlink Oracles
        • Pricing + Decimal scaling
        • Refactor for Simplicity
      • #9 Flash Loan Vault
        • Implementing ERC3156
        • Full code for lender
        • Ex-rate calculation
    • State Inheritance Testing
    • Testing w/ Mocks
    • Yield Style Guide
    • Github Actions
    • TransferHelper.sol
    • math logic + internal fn
    • Interfaces: IERC20
  • Foundry
    • Overview
    • Importing Contracts
    • Testing
      • stdError.arithmeticError
      • assume vs bound
      • Traces
      • label & console2
      • std-storage
  • Smart Contract Security
    • Damn Vulnerable Defi
      • 1. Unstoppable
      • 2. Naive receiver
      • 3. Truster
      • 4. Side Entrance
      • 5. The Rewarder
      • 6. Selfie
      • 7. Compromised
      • 8. Puppet
      • 9. Puppet V2
      • 10 - Free Rider
    • Merkle Tree: shortened proof attack
  • Fixed-Point Math
    • AMM Math
  • Solidity Patterns
    • checks-effects-interactions pattern
    • Router // batch
    • claimDelegate: stack unique owners
    • claimDelegate: cache previous user
  • Array: dup/ascending check
  • Deployment
    • Behind the Scenes
    • Interacting with External Contracts
    • Logging, Events, Solidity, Bloom Filter
  • Misc
    • Mnemonic Phrases
    • Bidul Ideas
  • Archive
    • Brownie Framework
      • Brownie basics
        • storing wallets in .env
        • Deployment to ganache
        • Interacting with contract
        • Unit Testing
        • Testnet deployment
        • Interacting w/ deployed contract
        • Brownie console
      • Brownie Advanced
        • Dependencies: import contracts
        • helpful_scripts.py
        • verify and publish
        • Forking and Mocking
        • Mocking
        • Forking
      • Testing
      • Scripts Framework
        • deploy.py
        • get_accounts
        • deploy_mocks()
        • fund_with_<token>()
      • Brownie Networks
    • Brownie Projects
      • SharedWallet
        • Multiple Beneficiaries
        • Common Code Contract
        • Adding Events
        • Renounce Ownership
        • Separate Files
      • Supply Chain
        • ItemManager()
        • Adding Events
        • Adding unique address to each item
      • Lottery
      • Aave - Lending and Borrowing
        • Approve & Deposit
        • Borrow
      • NFT
      • Advanced Collectible
        • adv_deploy() + Testing
        • Create Metadata
        • Setting the TokenURI
    • node npm
    • Ganache
    • Truffle
    • Remix
    • Installing Env
Powered by GitBook
On this page
  • Call
  • Staticcall
  • Delegatecall
  1. Compendium
  2. Solidity Basics

call, staticcall, delegatecall

Call

  • call is a low level function to interact with other contracts.

bytes memory data = abi.encodeWithSignature(
            "approve(address,uint256)", address(this), type(uint256).max
        );
(bool success, bytes memory data) = target.call{value: 111, gas: 5000}(data)
  • value: amount of ETH to send to the target (in case you are calling a payable function).

  • gas: optional value for gas to pass in to limit how much gas you could spend on the entire call

Example


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract TestCall {
    string public message;
    uint public x;
    event Log(string message);

    fallback() external payable {
        emit Log("Fallback was called");
    }

    function foo(string memory _message, uint256 _x) public payable returns (bool, uint) {
        message = _message;
        x =  _x;
        return (true, 999);
    }
}

contract Call {
    bytes public data;
    
    function callFoo(address _test) external {
        (bool succes, bytes memory _data) = _test.call{value: 111, gas: 5000}(
            abi.encodedWithSignature("foo(string,uint256)", "call Foo", 123));
        require(success, "call failed");
        data = _data;
    }
}
  • value: how much ether to send

  • gas: how much gas to send

  • mark callFoo as payable so that we can send it ether when calling it

Read more:

Staticcall

method similar to call, but it does not allow changing the state of the blockchain. This means that we cannot use staticcall if the called function changes some state variable, for example.

  • can be declared as view, as staticcall does not allow changing the state of the blockchain.

  • If we use staticcall to invoke a function that changes the state of the blockchain, the function invocation will not be successful.

  • We can use staticcall to read state variables. The following line of code is perfectly valid.

    
    (, bytes memory data) = called.staticcall(abi.encodeWithSignature("number()"));
    

  • Like call, staticcall returns two values. A boolean, indicating the success or not of the call, and a value of type bytes, which is the return of the call.

  • As staticcall does not change the state of the blockchain, it only makes sense to execute this method when we want to retrieve some value; that is, when we expect some return.

Delegatecall

What is the difference between CALL and DELEGATECALL?

  • CALL executes the function in the context of the contract it was defined, while DELEGATECALL inherits the execution context, meaning that the function will behave as it was defined in the contract that’s using DELEGATECALL

contract Called {

  uint public number;

  function setNumber(uint _number) public {
    number = _number;
  }
}
contract Caller {

  uint public number;
  address public called = 0xd9145CCE52D386f254917e481eB44e9943F39138;
  
  function callSetNumber(uint _number) public {
    called.delegatecall(abi.encodeWithSignature("setNumber(uint256)",_number));
  }
}
  • The callSetNumber function will call the setNumber function on Called, which will change the number variable.

  • However, it will change the variable number of the contract Caller, and not of the contract where the function is defined.

  • Like call, delegatecall also returns two values. The first is a boolean that indicates whether the transaction was successful or not, and the second is of type bytes, which is the function’s return, if any return occurs.

  • In the example above, we used the same state variable name in both contracts, number, but it is not necessary. The name of the variable doesn’t matter, but where it is located in storage.

  • Using delegatecall, the execution that would be done in the storage of the called contract, is done in the storage of the calling contract. Thus, we need to make sure that the variables of both contracts are properly paired.

PreviousFallback function (sol v 0.6)NextReturn & Events

Last updated 2 years ago

https://ethereum.stackexchange.com/questions/136075/when-to-use-call-and-abi-encodewithsignature-when-calling-external-function-and
https://ethereum.stackexchange.com/questions/145345/all-about-call-usage