DelegateCall in Solidity — With Some Code Examples
Tags: delegatecall, solidity, example, security
Published: 2023-04-06 22:24:37

# DelegateCall Solidity

DelegateCall is a unique feature in Solidity, which allows `contract A` to execute code in `contract B` with `contract A` storage, and the preserving the `msg` (`msg.sender`, `msg.value`, etc..). 

Today, we will discuss how DelegateCall works and provide some code samples.

## Understanding DelegateCall

DelegateCall is a low-level Solidity opcode that allows a contract to execute code from another contract, but it using the state and the storage of the calling contract.

The syntax for DelegateCall is as follows:

```solidity
(bool success, bytes memory returnData) = address.delegatecall(bytes memory data);
```

The `address` parameter is the address of the contract to execute, and the `data` parameter is the encoded function call to execute.

## DelegateCall vs. Call

The primary distinction between `call` and `delegateCall` is how they handle the execution context of the function. When you use `call`, the called function executes within the context of the calling contract. This means that the called function has access to the calling contract's storage and code.

On the other hand, when you use `delegateCall`, the called function executes in the context of the calling contract's caller. This means that the called function has access to the caller's storage and code, not the calling contract's storage and code.

In simple terms, `delegatecCall` enables the called contract to access the storage and code of the calling contract's caller, whereas `call` only permits the called contract to use the storage and code of the calling contract.

The difference between `call` and `delegateCall` is crucial when upgrading smart contracts. By using `delegateCall`, you can create a separate contract that contains the upgraded logic, and then call that contract from your main contract using `delegateCall`. This way, your main contract retains its storage, and the upgraded logic is executed in the context of the calling contract's caller. This allows for seamless upgrades without losing any data.

## DelegateCall Security

As you continue to learn about delegateCall, it's important to gain hands-on experience and training to fully understand the potential risks and vulnerabilities of smart contracts. That's where my [smart contract hacking and auditing course](http://bit.ly/3KB1vlL) comes in.

This course offers high-quality **video content** and **practical hands-on exercises** to help you gain valuable knowledge and skills. You will learn how to identify potential security risks and vulnerabilities in smart contracts, as well as best practices for preventing and mitigating those risks. 

By completing this course, you will become a more knowledgeable and skilled auditor, increasing your chances of landing a job in the growing field of smart contract auditing.

But the benefits don't stop there. Upon completion of the course, you'll receive a certificate to showcase your newly acquired expertise. 

This certificate can be a powerful tool when seeking employment opportunities, demonstrating to potential employers that you have the necessary skills and knowledge to be a successful smart contract auditor.

Whether you're looking to advance your career or simply improve your understanding of smart contract security, this course is the perfect solution. Take your first step toward becoming a top-notch smart contract auditor:

[http://bit.ly/3KB1vlL](http://bit.ly/3KB1vlL)

## DelegateCall Use Cases

Here are some of the most common use cases for the `delegateCall` opcode:

1. Proxy Contracts: `delegateCall` is often used in proxy contracts, which forward function calls to an implementation contract. By using `delegateCall`, the implementation contract can be upgraded without changing the address of the proxy contract, since the proxy contract's storage and state will remain unchanged.
2. Modular Contracts: `delegateCall` can be used to create modular contracts. In this design, each module is a separate contract that can be upgraded independently. The modules can use `delegateCall` to interact with each other and with the main contract, allowing for greater flexibility and modularity.
3. Gas Efficiency: `delegateCall` can be used to reduce gas costs. It allows multiple contracts to share the same code without having to copy it into each contract. This can be particularly useful for large contracts that would otherwise exceed the gas limit.
4. Library Contracts: `delegateCall` can be used to implement library contracts that contain reusable code that can be called from multiple contracts. The library contract's functions are executed in the context of the calling contract's caller, allowing the library code to access the caller's storage.
5. Cross-Chain Communication: The `delegateCall` function can be used to enable cross-chain communication between different blockchain networks. By using `delegateCall` to interact with a bridge contract on another blockchain, contracts on one chain can call functions on the other chain, allowing for interoperability between different blockchain networks.

## DelegateCall Examples

Let's look at some code samples to better understand how `delegateCall` works:

### Example 1: How delegateCall works

In the following example, we have two smart contracts, `Contract A` and `Contract B`

```solidity
contract A {
    uint public a;
    function setA(uint _a) public {
        a = _a;
    }
}

contract B {
    address public aAddress;
    uint public b;
    
    constructor(address _aAddress) {
        aAddress = _aAddress;
    }
    
    function setA(uint _a) public {
        (bool success, bytes memory result) = aAddress.delegatecall(
            abi.encodeWithSignature("setA(uint256)", _a)
        );
        require(success, "delegatecall failed");
    }
    
    function setB(uint _b) public {
        b = _b;
    }
}
```

In this example, `contract B` has a state variable `aAddress` that stores the address of `contract A`, which has a state variable `a`. 

The `setA` function in `contract B` uses `delegatecall` to call the `setA` function in `contract A` with the context of `contract B`. 

This allows `contract A` to access the storage variables and state of `contract B`.

### Example 2: Gas-efficient Upgradeable Contracts

One common use case for `delegatecall` is to implement proxy contracts that can be upgraded (upgradeable contracts) in a gas-efficient way. 

The basic idea is to separate the contract state from the contract logic so that the contract logic can be upgraded without affecting the state.

Here's an example of a proxy upgradable contract that uses `delegatecall`:

```solidity
pragma solidity ^0.8.0;

contract Proxy {
    address private _implementation;

    function setImplementation(address implementation) external {
        _implementation = implementation;
    }

    fallback() external payable {
        address impl = _implementation;
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }
}
```

In this example, we define a contract called `Proxy` that contains a private `_implementation` variable. This variable stores the address of the contract that contains the contract logic. We also define a `setImplementation` function that allows the contract owner to update the `_implementation` variable.

The `fallback` function is where the magic happens. It uses `delegatecall` to execute the function call in the context of the contract that contains the contract logic. This means that the contract state is still stored in the `Proxy` contract, but the contract logic is executed in the context of the `_implementation` contract.

## Conclusion

- We learned what is the DelegateCall opcode in Solidity, an important feature for smart contract developers.
- DelegateCall allows a contract to execute code from another contract while using the state and storage of the calling contract.
- We explained the fundamental differences between DelegateCall and Call and discussed the risks and vulnerabilities of smart contracts.
- DelegateCall can be used to upgrade smart contracts without losing any data. By creating a separate contract containing the upgraded logic and calling that contract from the main contract, developers can upgrade their contracts while retaining the main contract's storage.
- We saw some code samples to better understand how DelegateCall works and its most common use cases. Examples include creating proxy contracts, modular contracts, implementing library contracts, and enabling cross-chain communication between different blockchain networks.