I’m working with the proxy.sol contract in Remix. If I send a transaction with an encoded function call in the payload to my proxy contract, it will trigger the fallback function which will call the below _delegate function. The _delegate function will then send the encoded function call to the implementation contract.
However, the _delegate function doesn’t specify a return variable; only that it does return any returned data if the function call was successful. How do I access that returned data?
function _delegate(address implementation) internal {
assembly {
calldatacopy(0, 0, calldatasize)
let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
returndatacopy(0, 0, returndatasize)
switch result
case 0 { revert(0, returndatasize) }
default { return(0, returndatasize) }
}
}
I think when you use Proxy pattern, you can not determine the type of return value, such as, when calls transfer(), it will return bool, and when calls name(), it will return string.
You can use the ABI of the implementation contract with the address of the proxy to interact with the proxy contract.
In Remix I deployed the Box contract as my implementation contract and then deployed the TransparentUpgradeableProxy using the address of the Box contract, an other address as the admin and initializing with 0x6057361d000000000000000000000000000000000000000000000000000000000000002a
(which is calling store with the value 42).
I then used Remix to interact with a Box contract using the address of the proxy I just deployed.
Box.sol
// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Box {
uint256 private value;
// Emitted when the stored value changes
event ValueChanged(uint256 newValue);
// Stores a new value in the contract
function store(uint256 newValue) public {
value = newValue;
emit ValueChanged(newValue);
}
// Reads the last stored value
function retrieve() public view returns (uint256) {
return value;
}
}
OpenZeppelinContracts.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/proxy/TransparentUpgradeableProxy.sol";
MyContract
I used the following to encode the initialization 0x6057361d000000000000000000000000000000000000000000000000000000000000002a
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract MyContract {
function calculate() public pure returns (bytes memory) {
uint256 value = 42;
bytes memory payload = abi.encodeWithSignature("store(uint256)", value);
return payload;
}
}