You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Allow breaking up a Vyper contract into separate files based on sensible boundaries.
Motivation
Once more complex Vyper contracts are being written, there are often very natural boundary divisions in the code where it would be more readable if the code where broken apart at those boundaries. This is an often-cited "weakness" of Vyper, and it would be good to have a design for how larger contract types can be written using Vyper.
Specification
In order to break up a contract type into multiple files, a file structure is used to organize the hierarchy of which file is ultimately the "build file" and imports the functionality from others. Borrowing the Python module layout, a contract type can become a "composite" contract type if the __contract__.vy file is added underneath a folder bearing the contract's type name (e.g. MyType). This name is what will be used by the compiler to generate the contract type when compiling, and the __contract__.vy file will be considered the "build file" for that type, meaning any modular components written in other files at that same level must be imported in to be considered a part of the contract type's implementation.
# Import the functionality from the modular implementation filesfrom .tokenimport*from .stakingimport*from .vestingimport*
... # Other code to make it work
There are a lot of considerations to make this work, mostly "what are the boundary conditions?" for the import. It would make most sense to limit modular code files from using state variables from other modular code files, as that could create some unnecessary complexity to readers. Also, since Vyper can't call public-facing methods, it makes sense not to be able to call those either in modular code files, and the import statement in the "build file" imports those in as final methods for the contract to represent in the build. Internal methods are possible to call in Vyper, so allowing modular components (including the "build file") to call internal methods of other modular components seems like a reasonable point of abstraction.
Using the example above, token would probably implement the basic ERC20 methods, making the internal methods _transfer, _mint, and _burn available to staking and vesting to perform more complex logic using their own stateful variables. When finally imported into __contract__.vy, the import * shows that everything is being imported from those files, including all state variables and internal and external methods (including public state variables). If there is a conflict during the import (any file uses the same state variable or defines the same internal/external method), the conflict should raise an error during compilation. This ensures that the strict boundary conditions are respected.
Backwards Compatibility
This VIP is fully backwards compatible.
Dependencies
No dependencies
References
Consideration should be taken in reference to #2152, #1954, and #1347 with this feature
Simple Summary
Allow breaking up a Vyper contract into separate files based on sensible boundaries.
Motivation
Once more complex Vyper contracts are being written, there are often very natural boundary divisions in the code where it would be more readable if the code where broken apart at those boundaries. This is an often-cited "weakness" of Vyper, and it would be good to have a design for how larger contract types can be written using Vyper.
Specification
In order to break up a contract type into multiple files, a file structure is used to organize the hierarchy of which file is ultimately the "build file" and imports the functionality from others. Borrowing the Python module layout, a contract type can become a "composite" contract type if the
__contract__.vy
file is added underneath a folder bearing the contract's type name (e.g.MyType
). This name is what will be used by the compiler to generate the contract type when compiling, and the__contract__.vy
file will be considered the "build file" for that type, meaning any modular components written in other files at that same level must be imported in to be considered a part of the contract type's implementation.The file hierarchy:
The "build file" (
__contract__.vy
):There are a lot of considerations to make this work, mostly "what are the boundary conditions?" for the import. It would make most sense to limit modular code files from using state variables from other modular code files, as that could create some unnecessary complexity to readers. Also, since Vyper can't call public-facing methods, it makes sense not to be able to call those either in modular code files, and the import statement in the "build file" imports those in as final methods for the contract to represent in the build. Internal methods are possible to call in Vyper, so allowing modular components (including the "build file") to call internal methods of other modular components seems like a reasonable point of abstraction.
Using the example above,
token
would probably implement the basic ERC20 methods, making the internal methods_transfer
,_mint
, and_burn
available tostaking
andvesting
to perform more complex logic using their own stateful variables. When finally imported into__contract__.vy
, theimport *
shows that everything is being imported from those files, including all state variables and internal and external methods (including public state variables). If there is a conflict during the import (any file uses the same state variable or defines the same internal/external method), the conflict should raise an error during compilation. This ensures that the strict boundary conditions are respected.Backwards Compatibility
This VIP is fully backwards compatible.
Dependencies
No dependencies
References
Consideration should be taken in reference to #2152, #1954, and #1347 with this feature
Copyright
Copyright and related rights waived via CC0
The text was updated successfully, but these errors were encountered: