Open gabrielfior opened 1 month ago
This would take a larger refactor to move to a more functional, metaclass-style method for generating ContractContainer
singleton classes from ethpm_types.ContractType
models which can be instantiated (and enhanced with other information from ContractType
such as NatSpec docs, etc.)
@BobTheBuidler might find this idea interesting, he was looking for a way to avoid having multiple instances of ContractType
models to reduce the memory usage of Ape with large amounts of instances with the same contract type
cc @antazoey @bitwise-constructs who are thinking about overall improvements to contract ergonomics
I just want to have some things to visualize for us to discuss, as this might be something we want to consider for 0.9.
Currently:
>>> from ape import project
>>> project.MyContract
Note: currently, all contract-types are the same class and not individual classes (not generated at runtime via ABI)
Proposition:
>>> from ape.contracts import MyContract
The new MyContract
is something generated at runtime via the ABI. All methods are readidly available. Structs are the same, we already use meta-classes for those, same with errors.
^ That last sentence is a good point: we are already using metaclass / runtime type generation for errors and structs, so one more step to ContractType
feels right.
Anyway, the downside is the metaclass are weird, but I think one can just expect that... like you can't use issubclass
and some other stuff like that.
Proposition:
>>> from ape.contracts import MyContract
As an overall note, this level of change (migrating from using ape.project.MyContract
to ape.contracts.MyContract
) would be a v1.0 type of breaking change
Further, I don't think I like automatically generating imports. That's what Brownie used to do, and it's very difficult because you pollute the namespace of the module. It can be much more simple that project.__getattr__
uses keys from the current project's known contract types and generates custom classes using ContractContainer
more as a metaclass (or we can get rid of ContractContainer
entirely). Still, like you said it would be a breaking change to remove ContractContainer
from the class heirarchy (and ContractInstance
, which subclasses ape.api.address.BaseAddress
) but there are ways of just applying a common parent class when forming the metaclass to maintain that heirarchy for all the generated subclasses.
In a similar vein, we can probably do the same with MethodABI
objects to generate custom method handlers as metaclasses and insert them into the ContractInstance
objects (closer to what this issue's OP is talking about) This might also be a breaking v1.0 level change due to the change of metaclasses, type annotation support, etc. (I think I am using ContractMethodHandler
inside of ape-safe
and the multicall module)
Overview
I want to generate Python functions from a smart contract's ABI definitions.
Specification
I would expect this to be part of the
ape.contracts
package.Dependencies
For reference, I found some (old) implementations that don't actually do what I'm thinking. https://github.com/Consensys/python-solidity-parser/tree/master (last commit 3 years ago)
This also goes in the right direction -> https://github.com/ethereum/web3.py/issues/3016