How do function interactions work with a proxy

Can anyone here better explain something regarding this tutorial.... i thought the user interacts with the proxy contract so doesn't that mean when the Box contract is deployed, the TransparentUpgradeableProxy contract needs to include all the logic the Box contract has? I realize the calls are then forwarded to the Implementation (Box) contract via delegate call but doesn't the proxy contract need all the logic and functions that are in the Box contract since that is the one the users will be interacting with?

Hi @CryptJoe, TransparentUpgradeableProxy forwards ALL function calls (unless called by an admin) to the implementation contract. This means the proxy does not need to know about the logic or functions in the implementation, because every function selector would be delegated to the implementation.

Thanks for the response. I undestand what you are saying in regards to calls being forwarded to the implementation contract via delegate call but which contract is the user interacting with? Doesn't the user interact with TransparentUpgradeableProxy?

The user interacts with TransparentUpgradeableProxy but using the ABI of the implementation (which needs to be available. This kind of interaction is also possible on Etherscan if the proxy and implementation are verified and the proxy is marked as a proxy.)

Are you saying users can only interact with the TransparentUpgradeableProxy on etherscan? These contracts cannot be designed with the purpose/intent of being used with a front end like most traditional smart contract designs?

Putting that aside for a moment.... if users are interacting with the TransparentUpgradeableProxy contract than don't those contracts need the very same functions contained in the implementation contract?

To demonstrate with a very simple example (Similar to what we just did in this tutorial) if i create a contract for users to retrieve a value.... lets call it a "getValue" function.. doesn't the user need to be able to interact with the "getValue" function on the TransparentUpgradeableProxy contract?

I'm probs not explaning this too well, but if the proxy contract is the one users are interacting with than don't we need to have all the functions our Box contract has (referring to the tutorial in this case)? I realize the calls get routed to the implementation contract but how are those calls getting routed from the proxy if the proxy doesn't have those functions?

Hi @CryptJoe, to clarify:

  • For any contract interaction (whether upgradeable or not), you need the ABI of your contract in order to encode the call data, which includes the function selector and arguments.
  • When you have a proxy, users interact with the proxy using the implementation's ABI, not the proxy's ABI. So that they can encode call data using the implementation's functions. This also applies to a front end (the front end must provide the implementation's ABI).
  • So because the implementation ABI is available (e.g. in the front end), and you can encode function calls using that ABI, then you can just create a transaction to the proxy's address using that encoded function call.

In your example, you would encode a function call for "getValue" from Box's ABI, then you submit a transaction to the proxy address using that call data. Then the proxy delegates that call to the actual Box implementation.

Okay thanks for the clarification. So you are basically saying users have access to the implementations functions (Box contract functions) but when they interact with it they are dong so through the proxy? Meaning transactions are submitted through the proxy (not the implementation). Is that more or less the idea?

1 Like

Yes, that's correct.

Okay thanks. Greatly appreciate the help.

Came across this as I'm trying to understand.

To add my 0.02 to the above - my understanding so far is:

I think the issue that's not clear above, is that the function calls themselves are not proxied through, it's the raw data that you call with is passed on. So you can in fact call completely new functions that don't exist on the original proxy and that data - according to the new IMPL contract's ABI - will just get passed through.
This is why it's a bit confusing. You aren't over-riding or delegating specific function calls, but more generically setting up a gateway for any function and call signature to pass through.

The other point though is that all the data remains tied to the original proxy contract and address (or base contract?) so you have to be very careful with modifying data structures.

So my question is that when a contract is upgraded (with a new IMPL) should we make calls to the proxy or to the upgraded address?

Correct.

The other point though is that all the data remains tied to the original proxy contract and address (or base contract?) so you have to be very careful with modifying data structures.

Right, stored data remains tied to the original proxy contract and address.

So my question is that when a contract is upgraded (with a new IMPL) should we make calls to the proxy or to the upgraded address?

Make calls to the proxy. The proxy will pass through the calls to the new implementation.