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
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
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
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")
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")
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)