Hi Craig (@cjd9s),
I am still either not understanding what you are trying to do, or I haven’t explained properly how Transparent upgradeable proxies work.
I recommend reading (if you haven’t already):
I am going to walk through the example using Remix to hopefully make it clearer
- Deploy the implementation contract (Box.sol). I deployed to Rinkeby.
// 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;
}
}
Transaction deploying the contract:
Implementation contract (Box): https://rinkeby.etherscan.io/address/0xd8400192f5f7b2bdba6ec3b5f6a838aa2b5b5b5e#code
- Deploy the proxy contract
I used GitHub imports to get the contract.
// 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";
Using the parameters of:
_LOGIC: 0xd8400192f5f7b2bdba6ec3b5f6a838aa2b5b5b5e
(implementation contract - Box)
_ADMIN: 0x4924b7e51F71f2D3a57711C7a2Ac8a5ca3b2DBED
(an account I control, we could also deploy a ProxyAdmin and use that)
_DATA: 0x6057361d000000000000000000000000000000000000000000000000000000000000002a
(call store(uint256)
with a value of 42)
Transaction deploying the contract: https://rinkeby.etherscan.io/tx/0xa8cfc31ef0e4c7c34277f258b0ed618fb5cb58325a3d54d86831ca37a2089183
Proxy: https://rinkeby.etherscan.io/address/0xfc38e2f5cf00dbab4884abb26bf21fe23d8af803#code
- Interact with the upgradeable contract
Interact using the ABI of the implementation contract with the address of the proxy
Use the Box contract with the address of the proxy: 0xfc38e2f5cf00dbab4884abb26bf21fe23d8af803
Then press retrieve to get the initialized value
We can then store a value e.g. 23
(https://rinkeby.etherscan.io/tx/0xedf7ac46f8270301215cdf58c2615ee546690f0ec0ab8dd43760f2ae44ac26f0) and retrieve it.
A. (Optional) Verify the implementation contract on Etherscan
If you use Rinkeby you won’t need to do this as I have already done this.
B. (Optional) Verify the proxy contract on Etherscan
If you use Rinkeby you won’t need to do this as I have already done this.
I used Hardhat but used similar to this: Verify Upgrades Plugins proxy on Etherscan
arguments.js
// arguments.js
module.exports = [
"0xd8400192f5f7b2bdba6ec3b5f6a838aa2b5b5b5e",
"0x4924b7e51F71f2D3a57711C7a2Ac8a5ca3b2DBED",
"0x6057361d000000000000000000000000000000000000000000000000000000000000002a"
];
Verify using Hardhat
$ npx hardhat verify --constructor-args arguments.js --network rinkeby 0xfc38e2f5cf00dbab4884abb26bf21fe23d8af803
Nothing to compile
Successfully submitted source code for contract
contracts/proxy/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy at 0xfc38e2f5cf00dbab4884abb26bf21fe23d8af803
for verification on etherscan. Waiting for verification result...
Successfully verified contract on etherscan
C. (Optional) Flag on Etherscan as a proxy
You would need to do this for your contract
D. (Optional) Interact using Etherscan
Read: https://rinkeby.etherscan.io/address/0xfc38e2f5cf00dbab4884abb26bf21fe23d8af803#readProxyContract
Press retrieve to read the value set earlier.