Nano contracts flow
Introduction
This article is the reference material for the creation and execution flow of a nano contract, to consult while developing a blueprint. This flow can be divided into three phases:
- Validation
- Method execution
- Resolution
Validation
Every creation and execution of a nano contract results from a user submitting an NC (nano contract) transaction to Hathor Network. In other words, everything starts when a user submits an NC transaction to a full node. An NC transaction is a subtype of transaction that has three specific fields not present in other transactions:
nc_id
nc_method
nc_args
Hathor protocol then begins the validation phase of the transaction. First, the common validations applicable to all transactions are performed. If the transaction passes these validations, the specific validations for NC transactions are then conducted:
- Validation of
nc_id
- Validation of
nc_method
- Validation of withdrawals
Validation of nc_id
Hathor protocol verifies whether nc_id
identifies an existing blueprint on Hathor platform or a nano contract registered on chain. If it does not, the transaction is considered invalid and discarded. If nc_id
identifies a blueprint, Hathor protocol understands that the user wants to create a new contract. Conversely, if nc_id
identifies a nano contract registered on chain, Hathor protocol understands that the user wants to execute an existing contract.
Validation of nc_method
Hathor protocol verifies if nc_method
identifies a valid public method to be executed. In the case where nc_id
identifies a blueprint — that is, contract creation — nc_method
must be initialize
. For example, let’s take the case of the swap blueprint from our tutorial. To create a swap contract, a user must submit an NC transaction such that:
nc_id
: identifier of the blueprint on Hathor platform.nc_method
:'initialize'
In the case where nc_id
identifies a nano contract (registered on chain), nc_method
must be the name of an existing public method in the contract, different from initialize
. For example, to execute the swap
method in a contract created from the swap blueprint, a user must submit an NC transaction such that:
nc_id
: id of the transaction that registered the contract creation.nc_method
:'swap'
If it does not fit into either of these cases, the transaction is considered invalid and discarded. This will occur in the following cases:
nc_id
points to a blueprint andnc_method
is notinitialize
.nc_id
points to a nano contract andnc_method
isinitialize
.nc_id
points to a nano contract andnc_method
is not an existing public method in the contract other thaninitialize
.
Validation of withdrawals
To validate withdrawals, Hathor protocol first translates the set of inputs and outputs into a set of NCAction
(actions). An NCAction
object is a tuple that contains:
type
of the action, which can beDEPOSIT
orWITHDRAWAL
.token_uid
that identifies the token to which the deposit or withdrawal action refers.amount
that describes the quantity (amount) of tokens to be transferred to or from the contract's balance.
Hathor protocol then verifies if the contract has sufficient funds to perform all requested withdrawal actions. If the contract does not have enough funds to perform all withdrawals, the transaction is considered invalid and discarded. For example, suppose a nano contract with the following multi-token balance:
- Token A: 100
- Token B: 10
- Token C: 50
- Token D: 20
In this case, the following sets of actions will be considered valid (individually):
- Alice wants to: deposit 10 tokens A; withdraw 10 tokens B; withdraw 10 tokens C.
- Bob wants to: withdraw 10 tokens A; withdraw 10 tokens B; deposit 20 tokens E.
- Charlie wants to: withdraw 20 tokens D; deposit 10 tokens E; deposit 10 tokens F.
And the following sets of actions will be considered invalid (individually):
- Alice wants to: withdraw 120 tokens A; deposit 30 tokens F.
- Bob wants to: withdraw 10 tokens A; withdraw 15 tokens B.
- Charlie wants to: withdraw 10 tokens G.
Another case in which Hathor protocol will consider the request invalid is when a contract creation transaction contains a withdrawal request. Obviously, if a contract is being created now, its balance for any token will always be zero, and thus no withdrawal makes sense. Hathor protocol considers the transaction invalid and discards it. The following diagram shows a case in which this occurs:

Alice calls the initialize
method to create a contract from a blueprint but requests a withdrawal of 10 tokens B, which does not make sense since a newly created contract will always have an initial balance of zero for any token.
Note that Hathor protocol does not invalidate an NC transaction due to deposits. For Hathor protocol, if the user has sufficient funds in their wallet to make the deposit, then the deposit request is valid. It will be up to the contract, during its method execution, to decide whether or not to authorize this deposit request.
Awaiting in the mempool
Once the NC transaction passes the common checks, and the specific validations for nc_id
, nc_method
, and withdrawals, it is considered valid and sent to the mempool to await the arrival of the next block. When the next block arrives, all transactions waiting in the mempool will be added to the blockchain. At this point, the public method for creating or executing the nano contract will be called.
Hathor protocol calls the method defined in the NC transaction, passing as arguments a Context
object followed by all the arguments contained in nc_args
, in the same order they appear. A Context
object provides:
tx
: the transaction ID that called the method.address
: the wallet address that called the method.timestamp
: the timestamp of the first block confirming the transaction.actions
: a dictionary where the keys aretoken_uid
and the values areNCAction
objects.
Note that the set of deposits and withdrawals the user wants to perform with the transaction is found in actions
.
Method execution
The method call initialize
denotes contract creation, while the call of any other public method denotes contract execution.
Contract creation
Every blueprint must have the initialize
method. The initialize
method typically performs the following activities:
- Verify that the set of received arguments is valid.
- Authorize or deny the creation of a new contract.
- Define the initial state of the attributes for this new contract.
For example, suppose Alice wants to create a new nano contract from a certain blueprint called "ABC":
- She submits an NC transaction to Hathor Network that correctly describes the creation of this contract. This transaction has three deposits: 10 tokens A, 20 tokens B, and 30 tokens C, and no withdrawals.
- Hathor protocol considered the transaction valid, and upon the arrival of the next block, called the
initialize
method of the blueprint for execution. - The
initialize
method confirmed that the received arguments are valid for the creation of a new contract. initialize
will use the arguments passed by Alice innc_args
and theContext
to initialize the attributes of the new contract.initialize
executes to the end and returns nothing (None
). This indicates to Hathor protocol that the contract creation was successful.
On the other hand, suppose Bob wants to create another nano contract using this same blueprint "ABC":
- However, he submits an NC transaction to Hathor Network that does not correctly describe the creation of this contract. This transaction has no deposits (which is not what
initialize
expects) and no withdrawals. - Hathor protocol considered the transaction valid, and upon the arrival of the next block, called the
initialize
method of the blueprint for execution. - The
initialize
method was expecting exactly three deposits for tokens A, B, and C respectively (as Alice did). Since it did not receive exactly these three deposits,initialize
raises an exception. This indicates to Hathor protocol that the contract creation failed.
Contract execution
Executing a contract denotes that the public method (other than initialize
) typically performs the following activities:
- Verify that the set of received arguments is valid.
- Authorize or deny the execution of all deposits and withdrawals that the user wants to make.
- Update the contract's attributes.
For example, suppose Alice wants to execute a certain nano contract that was instantiated from the swap blueprint:
- She submits an NC transaction to Hathor Network that correctly describes the call to the public method
swap
of this contract. This transaction has a deposit of 10 tokens A and a withdrawal of 20 tokens B. - Hathor protocol considers the transaction valid, and upon the arrival of the next block, calls the
swap
method for execution. - The
swap
method confirms that the received arguments are valid. swap
make the checks to verify if the request should be authorized.swap
updates the contract's attributes.swap
executes to the end and returns nothing (None
). This indicates to Hathor protocol that the contract execution was successful, which means the set of all deposits and withdrawals of the NC transaction was authorized.
On the other hand, suppose Bob wants to execute the same contract, calling the same swap
method:
- He submits an NC transaction to Hathor Network that does not correctly describe the call to the public method
swap
. This transaction has a deposit of 100 tokens C and no withdrawal. - Hathor protocol considers the transaction valid, and upon the arrival of the next block, calls the
swap
method for execution. - The
swap
method was expecting exactly two actions, one for deposit and one for withdrawal. Since this did not occur,swap
raises an exception. This indicates to the Hathor protocol that the contract execution failed, and thus, the requested deposit was not authorized.
Resolution
Hathor protocol receives the method's return and completes the processing of the NC transaction. There are two possible outcomes for the creation/execution of a contract:
- Success
- Fail
Success
If the public method runs to completion without raising an exception, Hathor protocol understands that the creation/execution was successful and will carry out the following activities:
- In the case of contract creation, add it to the database (i.e., the ledger).
- In the case of contract execution, update the attributes as modified by the method.
- Perform all deposits and withdrawals contained in the NC transaction and update the contract's balance.
- Add the NC transaction to the blockchain marked as "success".
Fail
If the execution of the public method raises an exception, Hathor protocol understands that the creation/execution has failed and will carry out the following activities:
- In the case of contract creation, discard the created instance.
- In the case of contract execution, discard any modifications made to attributes.
- Do not perform any of the deposits and withdrawals contained in the NC transaction.
- Add the NC transaction to the blockchain marked as "fail" and with its "inputs/outputs" voided.
What's next?
- Blueprint development: main guidelines to consult while developing a blueprint.
- Blueprint development — API: to consult the API provided by the blueprint SDK for developers.
- Develop a blueprint — part 1: hands-on tutorial to assist developers to conceive and design a blueprint.
- Develop a blueprint — part 2: hands-on tutorial to assist developers to implement and test a blueprint.
- Set up a localnet: for integration testing of blueprints, nano contracts, and DApps.