4 Methods for Inter-Contract Calls in Solidity

ยท

In large-scale blockchain projects, implementing all functionalities within a single smart contract is impractical and counterproductive for teamwork. Code is typically organized into libraries or separate contracts with interfaces for cross-contract communication.

Understanding Contract Interactions

Solidity offers two primary approaches for code reuse:

  1. Libraries: Deploy reusable logic as libraries (similar to C/Java libraries). However, libraries cannot modify contract states since they prohibit storage variables.
  2. New Contracts: When state modification is required, deploy new contracts and use inter-contract calls.

Here are the 4 methods for contract-to-contract calls in Solidity:

  1. CALL
  2. CALLCODE (Deprecated)
  3. DELEGATECALL
  4. STATICCALL

1. CALL vs. CALLCODE

FeatureCALLCALLCODE
ContextModifies callee's storageModifies caller's storage
Use CaseCross-contract state changesLibrary-like behavior within caller

๐Ÿ‘‰ Master Solidity with real-world examples

Verification Code Example

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++; }
}

Outcome:


2. CALLCODE vs. DELEGATECALL

FeatureCALLCODEDELEGATECALL
msg.senderUses caller contract addressPreserves original EOA address
StatusDeprecatedRecommended alternative

Key Insight

DELEGATECALL maintains the original transaction sender's address, making it essential for proxy contracts and upgradeable patterns.

contract B {
    event senderAddr(address);
    function inc() public {
        emit senderAddr(msg.sender); 
        // CALLCODE: emits Contract A's address
        // DELEGATECALL: emits EOA address
    }
}

3. STATICCALL

Currently, Solidity compiles view and pure functions with runtime checks. Future implementations may use STATICCALL opcode to enforce read-only behavior at runtime.

Characteristics:


Summary Table

MethodContextState Changemsg.senderUse Case
CALLCalleeYesCaller contractGeneral cross-contract calls
CALLCODECallerYesCaller contract(Deprecated)
DELEGATECALLCallerYesOriginal EOAProxy patterns
STATICCALLCalleeNoCaller contractRead-only queries

๐Ÿ‘‰ Explore advanced Solidity techniques


FAQ

Q1: When should I use DELEGATECALL?

A: Use it for proxy contracts or upgradeable designs where you need to preserve the original sender's context.

Q2: Why is CALLCODE deprecated?

A: It doesn't preserve msg.sender consistency, which can cause security issues. DELEGATECALL is the safer alternative.

Q3: Can STATICCALL modify state?

A: No. It enforces read-only operations and reverts on state modification attempts.

Q4: What's the gas cost difference between these methods?

A: CALL and DELEGATECALL incur higher costs due to state changes, while STATICCALL is cheaper for read-only operations.