On dynamic interface (Basic design - Contract ABI Specification)

I’m bit of a puzzled by following phrase reading Contract ABI Specification. “This specification does not address contracts whose interface is dynamic or otherwise known only at run-time.”

Are there contracts with dynamic interface in Eth? Or is it added to those who want adapt Solidity to another block-chain systems? In any case it would help to have some comment on this in the docs. And I couldn’t find any additional relevant info in that chapter.

This refers to the fact that external functions do not exist at the EVM level and are only high-level abstractions provided by Solidity.

When you call an external contract, what really happens is that your contract uses the CALL opcode to run the other contract, giving it a blob of data. That other contract is just an unstructured string of opcodes and can interpret that blob however it likes.

Contract ABI is a convention that says how to structure that blob to simulate function invocations. It says that the first 4 bytes contain the hash of the signature of the function and this is followed by serialized arguments. A contract with a static interface basically looks at the selector in the input and goes over a big list of its own selectors. Once it finds a match, it jumps to the code corresponding to that selector (i.e. the function you called), which then decodes the parameters according to the function signature.

Since this is just a convention, you can write a contract that ignores all that and does wild things. For example you could create one that has two completely different sets of functions depending on whether you call it on a weekday or during the weekend. Or one that has functions that change their return type based on input. A more practical example are proxies - contracts that pretend to have the same functions as some other contract and only delegate the calls.

You can do these things in Solidity with fallback() or by writing your contract in something more low-level, like Yul or even EVM assembly.

Not sure if explaining this is in scope for the ABI spec. It kinda assumes you know a bit about the EVM. Maybe we could link to some external resource about the EVM though…

1 Like

So, basically it says that there is no common ABI specification for EVM, so everybody follows this one, provided by Solidity. But 1) things may change, and 2) when somebody goes low-level they may not need ABI (or implement it differently), so these contracts wouldn’t behave not as high-level developers used to.

Thank you for explanation! I’m just trying to check if I got it right essentially.

The ABI specification is actually older than Solidity. It changed during the development of Solidity (the function selector for example) but it was designed in conjunction with the earlier languages (mutan, lll, serpent).

The comment is very old, from a time where it was not clear yet if all contracts will follow the ABI or if there are more dynamic ones.

On the other hand, there are contracts whose interface is dynamic and only known at run-time: Proxy contracts are a good example, especially if you can change the address of the contract they point to.
ERC165 tries to address this fact in a way.

1 Like

I see, thank you! Thought that proxy contracts have static ABI too, which in turn calls other contracts’ ABI (which is static too) based on transferred parameters and state, so only dynamic is in parameters/variables. It’s an important note, a new angle for me!

You technically could have a proxy contract with a static ABI but it would proxy only to the functions you explicitly define in it. It’s much more common to do it dynamically because proxy is usually the part you can’t update.

1 Like