The main goal of SRC5 is to support interoperability, allowing contracts to interact with each other with consistency and simplicity, knowing what behavior to expect from the target.
With the New Syntax interfaces, we have an important issue if try to support Ids of interfaces containing generic types (besides the TContractState
that is compiler-generated):
If we have this interface:
#[starknet::interface]
trait IMyContract<TContractState, TNumber> {
fn foo(self: @TContractState, some: TNumber) -> felt252;
}
A contract implementing it like this:
(...)
#[external(v0)]
impl IMyContractImpl of IMyContract<ContractState, felt252> {
fn foo(self: @ContractState, some: felt252) -> felt252 {
(...)
}
}
(...)
Would break if someone tries to call the external foo
method with a u256
instead of a felt252
as the second param, because the actual external method of the contract is not generic, but specific to the type set in the Impl block. Even worst, the call could not break if the calldata is serde-compatible, with potential unexpected bad outcomes.
With this in mind, I think we should NOT ALLOW these interfaces in the standard, so even when they are language supported, they won’t be SRC5 compliant.
For the SNIP terminology I will call these interfaces (with generic types) Interface Blueprints, and the ones without it just Interfaces, because an Interface Blueprint can translate into multiple interfaces for different contracts regarding the input types that will be accepted in the actual external methods of the contract (that can’t be generic at the time being). This naming convention is mostly for updating the SNIP specification.
Summary: I think Interface Blueprints should be NOT ALLOWED, while Interfaces SHOULD.
Interested in opinions and potential other solutions/thoughts around this.