-
-
Notifications
You must be signed in to change notification settings - Fork 802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VIP: Library Modules #2431
Comments
A "Safe" ERC20 built-in library could be a good example here
def transfer(token: ERC20, receiver: address, amount: uint256):
# Handle call return data inconsistencies in implementations...
def transferFrom(...):
... Usage: from vyper import safe_erc20
...
safe_erc20.transfer(self.token, msg.sender, self.token.balanceOf(msg.sender)) |
An importable module can define:
|
Events blocked initially and then we can revisit |
i want to extend this proposal with an idea based on #2852 (comment). we could allow importing events, and even storage variables(!) from a library, and in storage allocation / interface generation, only export those that are used. for instance # token_library.vy
balances: HashMap[address, uint256]
some_random_variable: public(uint256)
@internal
def _transfer(...):
self.balances[sender] -= amount
self.balances[receiver] += amount
log Transfer(...)
@internal
def _mint(...):
self.totalSupply += amount
self.balances[receiver] += amount
log Mint(...)
@external
def mint(...):
self._mint(...) import token_library as token
@external
def transfer(...):
token._transfer(...) # balances are pulled into this contract, so is the `Transfer` event
# no function that touches `token.some_random_variable` is referenced,
# so it does not get allocated in this contract.
@external
def burn(...): # custom burn function
# note ability to stomp all over token members
token.totalSupply -= amount # totalSupply is brought into scope here, it gets a storage slot
token.balances[sender] -= amount
# maybe to make it easy to re-export external function signatures:
from token export mint, totalSupply, balances note this results in no name collisions or reference ambiguities, since everything is namespaced. |
What is imported surely can be explicitly exported? have type production and type test pls to make which imports are relevant and help reduce unnecessary bloat. also if we can have import map such that (erc20lib)://([email protected]) for explicit version support or git tag maybe |
Any thoughts on priority/timeframe for this? I'm starting to see some layer2 EVMs that extend the VM by adding new built-in contract primitives. So they have Solidity functions that do asm calls against them. For Vyper we could wrap them in raw_calls it appears but we would, presently, have to put all those primitives in the same source file as our contract. Modules supporting types and stateless functions would make it much nicer to add Vyper support for these alternative chains. One in particular that I'm dealing with is providing homomorphic encrypted computations and is pretty interesting. Would love to make coding in Vyper practical on these kinds of platforms. |
Simple Summary
Allow contracts to be imported into other contracts and used like python modules.
Motivation
It's important to be able to break up contracts into logical sections, or have reusable modules which can be shared across deployed contracts. Several proposals have been created for Vyper, but they all get stuck on one of several points
A lot of problems with readability go away if we assume that imported modules cannot alter the contract's storage - or at least can only do so explicitly.
Similarly, I think Python's zero-syntactic-overhead for modules is a good thing to keep here.
One clear deficiency of this proposal is that it does not address the use case of reusable-code-which-can-operate-on-storage-variables (e.g. stack/queue). I think that this can be solved by allowing storage variables to be passed by reference and mutated by internal functions, which could be another VIP.
Specification
An importable module is structurally the same as a regular Vyper contract. It is automatically able to be imported as a module so long as it satisfies the following properties:
Importantly, there is no syntactic overhead to using an importable module. It can be thought of as just a bunch of internal function definitions and struct/event/interface definitions. Implementation-wise, all these definitions just get imported in the module namespace. Here's an example
Backwards Compatibility
N/A
Dependencies
References
#484
#584
#1954
#2273
Copyright
Copyright and related rights waived via CC0
The text was updated successfully, but these errors were encountered: