DEV Community

Muwawu Moses
Muwawu Moses

Posted on

How to use 'initializes' and 'exports' in vyper: Modular Vyper code arrangement.

As vyper is evolving, a lot of new exciting changes have been introduced in version 0.4.0. Today, we are going to put our focus on two built-in functions: initializes and exports.

initializes

This mainly is useful when you need to initialize a module's state.

exports

In Vyper, @external functions are not automatically exposed (i.e., included in the runtime code) in the importing contract. This means that any externally facing functionality must be explicitly defined in the top-level of the compilation target.
So, exporting external functions from modules is accomplished using the exports keyword.

Anyway, to better understand these, we shall use a code example.
I am going to illustrate using three contracts i.e A.vy, B.vy and C.vy where A.vy is the module we gonna be utilizing.
A.vy

#pragma version >0.3.10  x: public(uint256) y: public(uint256) z: public(uint256) @deploy def __init__(_x: uint256, _y: uint256): self.x = _x self.y = _y @external def add(_x: uint256, _y: uint256): self._add(_x, _y) @internal def _add(_x: uint256, _y: uint256): _z: uint256 = _x + _y self.z = _z 
Enter fullscreen mode Exit fullscreen mode

B.vy

#pragma version >0.3.10  from . import A initializes: A @deploy def __init__(_x: uint256, _y: uint256): A.__init__(_x, _y) @external def set_value(_x: uint256, _y: uint256): A._add(_x, _y) @view @external def get_x() -> uint256: _x: uint256 = A.x return _x @view @external def get_y() -> uint256: _y: uint256 = A.y return _y @view @external def get_z() -> uint256: result: uint256 = A.z return result 
Enter fullscreen mode Exit fullscreen mode

C.vy

#pragma version >0.3.10  from . import A initializes: A exports: A.add @deploy def __init__(_x: uint256, _y: uint256): A.__init__(_x, _y) @view @external def get_x() -> uint256: _x: uint256 = A.x return _x @view @external def get_y() -> uint256: _y: uint256 = A.y return _y @view @external def get_z() -> uint256: result: uint256 = A.z return result 
Enter fullscreen mode Exit fullscreen mode

From the above code examples in contract B.vy, we can see that we use A.vy's state by initializing using the initializes: A magic. Also, i can access all @internal functions of the initialized contract. For example, I can call A._add(_x, _y). However, it's not possible to call external functions at this moment. A.add(_x, _y) will throw. To archive this, we need to use exports: A.add just like it's done in C.vy.
With exports, the external function is now available in the initializing contract. We are going to witness this later when it comes to interacting with the code.
scripts/deploy_B.py

from ape import project, accounts def main(): account = accounts.load('meta_wallet') # Replace with your actual account alias  _x = 3 _y = 4 # Deploy the contract  contract = account.deploy(project.B, _x, _y) # Initial values for x and y  # Display initial values  print(f"Initial x: {contract.get_x()} \u2705") print(f"Initial y: {contract.get_y()} \u2705") # Call the add method  contract.set_value(5, 15, sender=account) # Fetch and display the result  result = contract.get_z() print(f"Result (z): {result} \u2705") 
Enter fullscreen mode Exit fullscreen mode

ape with smart-contracts

From the image above, we see that we get exactly what we expect from the way how initializes and exports operate.✅
scripts/deploy_C.py

from ape import project, accounts def main(): account = accounts.load('meta_wallet') # Replace with your actual account name  _x = 5 _y = 10 # Deploy the contract  contract = account.deploy(project.C, _x, _y) # Initial values for x and y  # Display initial values  print(f"Initial x: {contract.get_x()} \u2705") print(f"Initial y: {contract.get_y()} \u2705") # Call the add method  contract.add(5, 15, sender=account) # Fetch and display the result  result = contract.get_z() print(f"Result (z): {result} \u2705") 
Enter fullscreen mode Exit fullscreen mode

modular vyper
Here also, you see that we can access the contract state of A just buy initializing and exporting it's external functions.✅ Therefore, one can just call from C, contract.add().

Thanks for reading. Let me hope my efforts help you at some stage. If you find the post helpful, please don't forget to give a like, and comment below if you need any help.

Top comments (0)