Question regarding TransparentUpgreadableProxy contracts

Hi everyone!
I'm trying to develop a TransparentUpgradeableContract but I'm facing many issues related to the contract itself. I'm currently using Remix IDE because it helps me to understand what's going on.
I took the code from the OpenZeppelin Github and I'm trying to understand it but I cannot understand some things. When I call the constructor of TransparentUpgreadbleProxy the third parameter is 'data' of type 'bytes' as shown here:

        address _logic,
        address admin_,
        bytes memory _data
    ) payable ERC1967Proxy(_logic, _data) {
        assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));

What is that parameter? I can't figure it out by myself.
Then, once I deployed the contract how can I call the functions of my logic contract?

Here I have all the functions of my proxy contract, what about the functions of the logic contract?
Then I've got another question about the relationship between the logic contract and the proxy:
1 - let's say that I call the transfer(_to, _value) function that is in my logic contract;
2 - the receiver balance is the one he had before plus '_value';
3 - I keep track of the balances with my variable that is declared in my ProxyAccount:

mapping(address => uint256) private balances

4 - how can I notify the Proxy smart contract that the balance of _to is changed?
5 - I ask this because I read that the state of my contract must reside in the proxy meanwhile the logic is in the logic contract. But doing this I cannot understand how to change the state of my proxy from the logic smart contract
I hope I was clear enough and that you understood my problem, if not: let me know!

  • N.V.

It's cool if you want to learn and understand things. Please note that the recommended way to use proxies and upgradeable contracts is through the OpenZeppelin Upgrades Plugins.

Refer to the documentation for the constructor.

The functions are in the contract, but they are not shown by Remix when you deploy like this. You can select your logic contract in the dropdown and use the "At Address" field/button pasting in the address of your newly deployed proxy to access your logic functions.


You never call a function in the logic contract. You and your users will interact with the proxy contract address. This is why in the "At Address" field you paste in the proxy address. And this is how the storage of the proxy is modified: by using the "logic" but in the context (including storage) of the proxy.

This is explained in our guide Learn: Upgrading smart contracts.

Please check out all of our upgrades resources as well.