what is a general rule of thumb for creating interfaces? Why would I want an interface i.e. IAugur.sol instead of the entire Augur.sol file? Can someone shed light on interface best practices and pros/cons.
2 Answers
There are two main reasons.
- To minimize contract size
- To ensure compliance
If you make the smallest possible contract and use Augor.sol
, then your contract will be at least as big as Augor.sol
.
contract Mine {
Augor a;
}
You have defined a
as an instance of Augor
and that means all of the Augor
bytecode is rolled up into yours. It's not evaluated for usefulness, so the fact it isn't used doesn't reduce the size of your contract.
If you, instead say:
IAugor a;
Your contract will include the code for the interface which should be much smaller. The interface is all that is required. It's a black box and its internal workings are not relevant. Only the function signatures and expected responses.
Interfaces are also useful for ensuring and demonstrating compliance. For example, one might say "My contract is an ERC20 token." Is it? Does it implement all the required functions?
You can say:
contract MyIncompleteToken is ERC20 {} // where ERC20 is the standard interface
It will compile but it will not deploy. It won't deploy because the interface laid out some functions and they have no implementation. This can help catch developer oversight. The inherited interface is a commitment to implement all the promised functions. It is not a catch-all for every compatibility concern, but it is helpful.
Hope it helps.
-
I think the 1 part of this answer is not correct, the size of your compiled contracts does not change whether you use and interface or the whole contract. Jun 28, 2022 at 14:15
-
Interfaces are always smaller than the contracts they describe. Importing either will tell a client contract how to connect. Importing the smaller of the two options, the interface, will make the client contract as small as possible. Importing the larger of the two options means that the internal logic of the functions, including the internal and private functions is all imported into the client contract. Most of it will be unreachable code, but it will be there. Jun 28, 2022 at 22:40
-
Maybe we're talking of different things, I'm talking about the file bytecode, the part that actually makes it into the Tx. I've, tried both scenarios and, for example using "hardhat size-contracts" yields the same size. I think the compiler is "intelligent" enough to only include the minimum required to fulfill the necessary interactions, no more. You can also try importing many contracts and not using them, the size doesn't change. Sep 2, 2022 at 15:13
Because often when you're writing contracts which interact with other contracts, the internal workings of those contracts are not relevant, just the externally exposed functions. By providing an Interface, other developers can write code that interacts perfectly with yours, without needing to see/include your entire codebase.