delegatecall is similar to call, is a low level function in Solidity. delegate means entrust/represent, so what does delegatecall entrust?
When user A call contract C via contract B, the executed functions are from contract C, and the execution context (the environment including state and variable) is in contract C: msg.sender is contract B's address, and if state variables are changed due to function call, the affected state variables are in contract C.

And when user A delegatecall contract C via contract B, the executed functions are from contract C, the execution context is in contract B: msg.sender is user A's address, and if state variables are changed due to function call, the affected state variables are in contract B.

You can understand it like this: a rich businessman entrusts his asset (state variables) to a VC (functions of target contract) for management. The executed functions are from the VC, but the state variables get changed from the businessman.
The syntax of delegatecall is similar to call:
the binary code is generated by abi.encodeWithSignature:
function signature is "functionName(parameters separated by comma)". For example, abi.encodeWithSignature("f(uint256,address)", _x, _addr)。
Unlike call, delegatecall can specify the value of gas when calling a smart contract, but the value of ETH can't be specified.
Attention: using delegatecall could incur risk, make sure the storage layout of state variables of current contract and target contract is same, and target contract is safe, otherwise could cause loss of funds.
delegatecall use cases?
Currently, there are 2 major use cases for delegatecall:
Proxy Contract: separating the storage part and logic part of smart contract:proxy contractis used to store all related variables, and also store the address of logic contract; all functions are stored in thelogic contract, and called via delegatecall. When upgrading, you only need to redirectproxy contractto a newlogic contract.- EIP-2535 Diamonds: Diamond is a standard that supports building modular smart contract systems that can scale in production. Diamond is a proxy contract with multiple implementation contracts. For more information, check Introduction to EIP-2535 Diamonds.
delegatecall example
Call mechanism: you (A) call contract C via contract B.
Target Contract C
First, we create a target contract C with 2 public variables: num and sender which are uint256 and address respectively; and a function which sets num based on _num, and set sender as msg.sender.
Call Initialization Contract B
First, contract B must have the same state variable layout as target contract C, 2 variables and the order is num and sender.
Next, we use call and delegatecall respectively to call setVars from contract C, so we can understand the difference better.
The function callSetVars calls setVars via call. callSetVars has 2 parameters, _addr and _num, which correspond to contract C's address and the parameter of setVars.
While function delegatecallSetVars calls setVars via delegatecall. Similar to callSetVars, delegatecallSetVars has 2 parameters, _addr and _num, which correspond to contract C's address and the parameter of setVars.
Verify on Remix
- First we deploy Contract B and contract C

- After deployment, check the initial value of state variables in contract
C, also the initial value of state variables in contractB.

- Next, call
callSetVarsin contractBwith arguments of contractC's address and10

- After execution, the state variables in contract
Care changed:numis changed to 10,senderis changed to contract B's address

- Next, we call
delegatecallsetVarsin contractBwith arguments of contractC's address and100

- Because of
delegatecall, the execution context is contractB. After execution, the state variables of contractBare changed:numis changed to 100,senderis changed to your wallet's address. The state variables of contractCare unchanged.

Summary
In this lecture, we introduce another low-level function in Solidity, delegatecall. Similar to call, delegatecall can be used to call another contract; the difference between delegatecall and call is execution context, the execution context is C if B call C; but the execution context is B if B delegatecall C. The major use cases for delegatecall are proxy contract and EIP-2535 Diamonds.