Skip to main content

Blueprint SDK — API

Introduction

This article is the reference for the Python API provided by the blueprint SDK. The blueprint SDK Python API comprises all names from package hathor that can be imported in a blueprint module.

This API reference is divided into the following sections:

  • Constants: utility constants.
  • Types: types used in the development of contracts.
  • Decorators: used to define a blueprint and the type of methods in it.
  • Functions: utility functions.
  • Objects: describe the interface of internal objects from the available types. That is, you can use them through instances of available types, but you cannot import and use them directly.
tip

Not all names from the hathor package can be imported into a blueprint module. Only strictly allowed names may be imported. For the list of these names, see Imports at Blueprint SDK — guidelines.

Constants

HATHOR_TOKEN_UID

The TokenUid for Hathor's native token, HTR (equivalent to TokenUid(b'\x00'), or 00 in hexadecimal).

Usage:

from hathor import public, Context, HATHOR_TOKEN_UID
...
@public
def some_method(self, ctx: Context) -> None:
action = ctx.get_single_action(HATHOR_TOKEN_UID)
...

Source code:
hathor.HATHOR_TOKEN_UID

Types

Source code: types in hathor

Address

  • Description: wallet address
  • Wrapper for: bytes
  • Constraint: 25 bytes
  • Example: Address(b'(\xf3\xb5}\xf3\xf6\xa2"\x80\x8eWr\xa9\x08\xbd\xfb\xa1\xfc\xd3-R\xd2d\x16\x95')
  • Usage:
    from hathor import Address
    ...
    address: Address
    ...
    address = Address.from_str('HUjk1F977H9Ct8UEx3Zgc4yFw5VEkmdGJY')

Amount

  • Description: denotes an amount of tokens, a non-negative integer where the last two digits represent decimals.
  • Wrapper for: int
  • Constraints:
    • Max value: 2**(32 * 7) - 1 = 26959946667150639794667015087019630673637144422540572481103610249215
    • Min value: 0
  • Example: 1025 represents 10.25 tokens
  • Usage:
    from hathor import Amount
    ...
    amount: Amount
    ...
    amount = Amount(1025)

BlueprintId

  • Description: identifier of a blueprint which is the hash of the transaction that deployed it.
  • Wrapper for: bytes
  • Constraint: 32 bytes
  • Example: BlueprintId(bytes.fromhex("3cb032600bdf7db784800e4ea911b10676fa2f67591f82bb62628c234e771595"))
  • Usage:
    from hathor import BlueprintId
    ...
    blueprint: BlueprintId
    ...
    blueprint = BlueprintId(bytes.fromhex("3cb032600bdf7db784800e4ea911b10676fa2f67591f82bb62628c234e771595"))

ContractId

  • Description: identifier of a contract. It is recorded in the transaction where it was created.
  • Wrapper for: bytes
  • Constraint: 32 bytes
  • Example: bytes.fromhex("000063f99b133c7630bc9d0117919f5b8726155412ad063dbbd618bdc7f85d7a")
  • Usage:
    from hathor import ContractId
    ...
    contract: ContractId
    ...
    contract = ContractId(bytes.fromhex("000063f99b133c7630bc9d0117919f5b8726155412ad063dbbd618bdc7f85d7a"))

Timestamp

  • Description: non-negative integer representing the number of seconds elapsed since January 1st, 1970 00:00:00 UTC (Unix epoch standard).
  • Wrapper for: int
  • Constraints:
    • Max value: 2**(4 * 8) - 1 = 4294967295
    • Min value: 0
  • Example: timestamp for January 3, 2020, at noon UTC is Timestamp(1578052800)
  • Usage:
    from hathor import Timestamp
    ...
    timestamp: Timestamp
    ...
    timestamp = Timestamp(1578052800)

TokenUid

  • Description: identifier of a token. It is recorded in the transaction where it was created.
  • Wrapper for: bytes
  • Constraint: 32 bytes
  • Example: TokenUid(bytes.fromhex("00000943573723a28e3dd980c10e08419d0e00bc647a95f4ca9671ebea7d5669"))
  • Usage:
    from hathor import TokenUid
    ...
    token: TokenUid
    ...
    token = TokenUid(bytes.fromhex("00000943573723a28e3dd980c10e08419d0e00bc647a95f4ca9671ebea7d5669"))

TxOutputScript

  • Description: lock script of a transaction output
  • Wrapper for: bytes
  • Constraint: maximum of 2**16 = 65536 bytes
  • Usage:
    from hathor import TxOutputScript
    ...
    oracle: TxOutputScript

VertexId

  • Description: identifier of a transaction in the ledger (blockchain). It is the hash of the transaction.
  • Wrapper for: bytes
  • Constraint: 32 bytes
  • Example: VertexId(bytes.fromhex("00000943573723a28e3dd980c10e08419d0e00bc647a95f4ca9671ebea7d5669"))
  • Usage:
    from hathor import VertexId
    ...
    tx: VertexId
    ...
    tx = VertexId(bytes.fromhex("00000943573723a28e3dd980c10e08419d0e00bc647a95f4ca9671ebea7d5669"))

NCAction

  • Description: union type alias representing any of the four possible action types. Use for type annotations when a parameter, variable, or attribute can accept any action type.
  • Union for one of the possible action classes: NCDepositAction, NCWithdrawalAction, NCGrantAuthorityAction, or NCAcquireAuthorityAction.
  • Constraint: must be an instance of one of the classes above.
  • Usage:
    from hathor import NCAction
    ...
    actions: list[NCAction] = []
    ...
    def fail_if_invalid_action(self, action: NCAction) -> None:
    if action.token_uid != VALID_TOKEN:
    ...
  • Source code: hathor.nanocontracts.types.NCAction

CallerId

  • Description: union type alias representing one of the possible caller types. Use for type annotations when a parameter, variable, or attribute can accept any caller type.
  • Union for one of the possible caller types: Address or ContractId.
  • Constraint: must be an instance of one of the classes above.
  • Usage:
from hathor import CallerId, public, Context
...
caller: CallerId
...
@public
def some_method(self, ctx: Context) -> None:
self.caller = ctx.caller_id
...

NCArgs, NCRawArgs, and NCParsedArgs

NCArgs is an union type alias representing one of the possible args types to be used in fallback methods:

  • NCRawArgs: raw bytes representing args that could not be parsed given the method signature.
  • NCParsedArgs: parsed args and kwargs.

Usage:

from hathor import fallback, Context, NCArgs
...

@fallback(allow_deposit=True)
def fallback(self, ctx: Context, method_name: str, nc_args: NCArgs) -> None:
match nc_args:
case NCRawArgs():
a, b = nc_args.try_parse_as((str, int))
...
case NCParsedArgs(args, kwargs):
...
case _:
raise NCFail('unexpected')

NCFee

A dataclass representing a fee payment for operations that require fees, such as minting fee-based tokens.

Data attributes:

  • token_uid: TokenUid that denotes the token used to pay the fee.
  • amount: int that denotes the amount of tokens to be used as fee payment.

Usage:

from hathor import NCFee, TokenUid, HATHOR_TOKEN_UID
...

# Create a fee payment using HTR
htr_fee = NCFee(token_uid=HATHOR_TOKEN_UID, amount=100)

# Use fees when calling another contract's public method
contract.public(deposit_action, fees=[htr_fee]).some_method()

Source code:
hathor.nanocontracts.types.NCFee

Blueprint

Serves as the base class for all blueprints. You must subclass Blueprint exactly once in your blueprint module.

Usage:

from hathor import Blueprint, export
...
# Define your blueprint class as subclass of Blueprint:
@export
class Bet(Blueprint):
...

Objects:

Blueprint provides contracts the following objects:

  • syscall: instance attribute used for all external interactions outside the contract itself — e.g., reading and writing to the ledger, calling other contracts, etc. See Blueprint.syscall at section Objects.
  • log: instance attribute used to record contract execution logs. Useful during development for debugging and testing, and in production for audits. See Blueprint.log at section Objects.

Source code:
hathor.nanocontracts.blueprint.Blueprint

VertexData

A dataclass containing information about the vertex that originated the nano method call chain. It can be obtained from a Context, via ctx.vertex.

Data attributes:

  • version: the TxVersion, which is an integer representing the vertex's version.
  • hash: the vertex's hash (its ID).
  • nonce: the vertex's nonce.
  • signal_bits: the vertex's signal bits.
  • weight: the vertex's weight.
  • inputs: a tuple of TxInputData containing data about each input of this vertex.
  • outputs: a tuple of TxOutputDatacontaining data about each output of this vertex.
  • tokens: a tuple of TokenUid containing hashes of this vertex's tokens.
  • parents: a tuple of VertexId containing hashes of this vertex's parents.
  • headers: a tuple of HeaderData containing data about each header of this vertex.

Source code:
hathor.nanocontracts.vertex_data.VertexData

TxVersion

An integer enumeration (IntEnum) representing the version of a vertex (transaction or block). It can be one of the following:

  • REGULAR_BLOCK = 0: A regular block.
  • REGULAR_TRANSACTION = 1: A regular transaction.
  • TOKEN_CREATION_TRANSACTION = 2: A transaction that creates a new custom token.
  • MERGE_MINED_BLOCK = 3: A merge-mined block.
  • ON_CHAIN_BLUEPRINT = 6: An on-chain blueprint.

Source code:
hathor.transaction.base_transaction.TxVersion

TxInputData

A dataclass containing information about a transaction input. It can be obtained from a VertexData, via vertex.inputs.

Data attributes:

  • tx_id: VertexId of the transaction containing the output being spent.
  • index: the index of the output being spent within that transaction.
  • data: the unlocking script data as bytes.
  • info: a TxOutputData containing information about the output being spent.

Source code:
hathor.nanocontracts.vertex_data.TxInputData

TxOutputData

A dataclass containing information about a transaction output. It can be obtained from a VertexData via vertex.outputs, or from a TxInputData via input.info.

Data attributes:

  • value: the output value as an integer.
  • raw_script: the locking script as raw bytes.
  • parsed_script: a ScriptInfo object with parsed script details, or None if the script could not be parsed.
  • token_data: the token data byte, which encodes the token index and authority flags.

Source code:
hathor.nanocontracts.vertex_data.TxOutputData

ScriptInfo

A dataclass containing parsed information from a transaction output script. It can be obtained from a TxOutputData via output.parsed_script.

Data attributes:

  • type: a ScriptType indicating the type of script (P2PKH or MultiSig).
  • address: the destination address as a string.
  • timelock: the timelock timestamp as an integer, or None if no timelock is present.

Source code:
hathor.nanocontracts.vertex_data.ScriptInfo

ScriptType

A string enumeration (StrEnum) representing the type of an output script. It can be one of the following:

  • P2PKH = 'P2PKH': Pay-to-Public-Key-Hash script.
  • MULTI_SIG = 'MultiSig': Multi-signature script (P2SH).

Source code:
hathor.nanocontracts.vertex_data.ScriptType

BlockData

A dataclass containing information about the block that confirmed and executed the nano method call. It can be obtained from a Context, via ctx.block.

Data attributes:

  • hash: the VertexId (hash) of the block.
  • timestamp: the block's timestamp as an integer (Unix epoch) — this may be used for time-based operations on blueprints.
  • height: the block's height in the blockchain.

Source code:
hathor.nanocontracts.vertex_data.BlockData

HeaderData

A marker class representing an arbitrary vertex header. It serves as a base class for specific header types. It can be obtained from a VertexData, via vertex.headers.

Source code:
hathor.nanocontracts.vertex_data.HeaderData

NanoHeaderData

A dataclass (subclass of HeaderData) containing information about the nano contract header of a transaction. This header contains the nano contract call information.

Data attributes:

  • nc_seqnum: the sequence number of the vertex.
  • nc_id: the nc_id of the vertex.
  • nc_method: the name of the method being called as a string.
  • nc_args_bytes: the serialized method arguments as bytes.

Source code:
hathor.nanocontracts.vertex_data.NanoHeaderData

Context

Provides the public method with the context in which it was called — namely, who called it, when it was called, and what the origin transaction is. The origin transaction is the transaction that originated the current call chain; in other words, it contains the entry point call.

When Hathor engine invokes a public method, it always passes a Context object as the first argument. Therefore, every public method must have a Context object as its second parameter (after self).

The Context object is immutable, and what is passed is only a copy of the original maintained by Hathor engine. As such, you cannot, and should not attempt to, modify the call context in your blueprint's code.

Data attributes:

  • vertex: VertexData that contains the origin transaction.
  • block: BlockData that contains information about the block that confirmed (and therefore executed) the origin transaction.
  • caller_id: A CallerId which is either an Address or a ContractId that denotes who called the method.
  • actions: Immutable dict where the keys are TokenUid and the values are tuples of NCAction objects. All actions requested in the current call. It may contain zero, one, or more elements.
  • actions_list: The same as actions, but organized in a list with all actions for convenience.
tip

Note that a token is associated with a tuple of actions. However, not all combinations of actions are possible for the same token. For example, Hathor engine will never pass to a public method a Context.actions in which, for the same token UID (TokenUid), there are:

  • Two actions (NCAction) of the same type (NCActionType) — e.g., two deposits for the same token.
  • One DEPOSIT action and one WITHDRAWAL action.
  • One GRANT_AUTHORITY action and one ACQUIRE_AUTHORITY action.

Methods:

  • get_single_action
  • get_caller_address
  • get_caller_contract_id

The following subsection describes the methods of this class that are available to use in your blueprint.

Context.get_single_action

Given a token UID, returns the single NCAction from actions that should be associated with it — i.e., the action whose key matches the token. Otherwise, raises an exception.

get_single_action(self, token_uid: TokenUid) -> NCAction:

Parameter:

  • token_uid: TokenUid that identifies the single action.

Return: NCAction if there is one and only one action associated with the token UID. If no action is found, raises an NCFail exception. If more than one action is found, also raises an NCFail exception.

Usage:

from hathor import Context, public
...
# Second parameter of a public method is always a Context object:
@public(allow_deposit=True, allow_withdrawal=True)
def swap(self, ctx: Context) -> None:
"""Execute a token swap."""

# Check if there is exactly one action related to each token:
# You should use the method get_single_action for it:
action_a = ctx.get_single_action(self.token_a)
action_b = ctx.get_single_action(self.token_b)
...

Source code:
hathor.nanocontracts.context.Context

Context.get_caller_address

Given a CallerId, extracts an Address if the caller is a wallet address (that is, the method was called directly by a transaction), or None if it's a ContractId (that is, the method was called by another contract).

get_caller_address(self) -> Address | None:

Return: Address if the caller is a wallet address, and None otherwise.

Usage:

from hathor import Context, public
...
@public
def swap(self, ctx: Context) -> None:
address_or_none = ctx.get_caller_address()
...

Source code:
hathor.nanocontracts.context.Context

Context.get_caller_contract_id

Given a CallerId, extracts a ContractId if the caller is a another contract, or None if it's a wallet address (that is, the method was called directly by a transaction).

get_caller_contract_id(self) -> ContractId | None:

Return: ContractId if the caller is a contract, and None otherwise.

Usage:

from hathor import Context, public
...
@public
def swap(self, ctx: Context) -> None:
contract_id_or_none = ctx.get_caller_contract_id()
...

Source code:
hathor.nanocontracts.context.Context

NCActionType

An enumeration (Enum) that defines the possible types of actions a contract user (wallet or another contract) can perform on a contract's multi-token balance. Can be one of the following:

  • DEPOSIT: deposit tokens into contract.
  • WITHDRAWAL: withdrawal tokens from contract.
  • GRANT_AUTHORITY: grant mint/melt authority to contract.
  • ACQUIRE_AUTHORITY: acquire mint/melt authority from contract.

For more about it, see Actions section at Nano contracts: how it works.

Usage:

from hathor import NCActionType
...
# Checking the type of a given action
# You can use:
if not isinstance(action, NCDepositAction):
raise InvalidAction

# OR with NCActionType the equivalent:
if action.type != NCActionType.DEPOSIT:
raise InvalidAction

# Defining what actions a public method shall receive:
# You can use in the decorator:
@public(allow_deposit=True, allow_withdrawal=True)

# OR with NCActionType the equivalent:
@public(allow_actions=[NCActionType.DEPOSIT, NCActionType.WITHDRAWAL])

Source code:
hathor.nanocontracts.types.NCActionType

NCDepositAction

Used to create or validate actions of type DEPOSIT.

Data attributes:

  • name: always "DEPOSIT"
  • type: always NCActionType.DEPOSIT
  • token_uid: TokenUid that denotes the token the caller wants to deposit.
  • amount: Amount that denotes the amount of tokens to be deposited.

Usage:

from hathor import NCDepositAction
...

# Use it whenever you want to represent the specific deposit action:
# For example, to check if a given action is a deposit:
if not isinstance(action, NCDepositAction):
...

Source code:
hathor.nanocontracts.types.NCDepositAction

NCWithdrawalAction

Used to create or validate actions of type WITHDRAWAL.

Data attributes:

  • name: always "WITHDRAWAL"
  • type: always NCActionType.WITHDRAWAL
  • token_uid: TokenUid that denotes the token the caller wants to withdraw.
  • amount: Amount that denotes the amount of tokens to be withdrawn.

Usage:

from hathor import NCWithdrawalAction
...
# Use it whenever you want to represent the specific withdrawal action:
# For example, to check if a given action is a withdrawal:
if not isinstance(action, NCWithdrawalAction):
...

Source code:
hathor.nanocontracts.types.NCWithdrawalAction

NCGrantAuthorityAction

Used to create or validate actions of type GRANT_AUTHORITY.

Data attributes:

  • name: always "GRANT_AUTHORITY".
  • type: always NCActionType.GRANT_AUTHORITY.
  • token_uid: TokenUid that denotes the token the caller wants to grant authority to contract.
  • mint: bool; if True, the contract will be allowed to issue new amounts of the token, increasing its total supply.
  • melt: bool; if True, the contract will be allowed to destroy amounts of the token, decreasing its total supply.

Usage:

from hathor import NCGrantAuthorityAction
...
# Use it whenever you want to represent the specific grant authority action:
# For example, to check if a given action is a grant authority:
if not isinstance(action, NCGrantAuthorityAction):
...

Source code:
hathor.nanocontracts.types.NCGrantAuthorityAction

NCAcquireAuthorityAction

Used to create or validate actions of type ACQUIRE_AUTHORITY.

Data attributes:

  • name: always "ACQUIRE_AUTHORITY".
  • type: always NCActionType.ACQUIRE_AUTHORITY.
  • token_uid: TokenUid that denotes the token the caller wants to grant authority to contract.
  • mint: bool; if True, the caller will be allowed to issue new amounts of the token, increasing its total supply.
  • melt: bool; if True, the caller will be allowed to destroy amounts of the token, decreasing its total supply.

Usage:

from hathor import NCAcquireAuthorityAction
...
# Use it whenever you want to represent the specific acquire authority action:
# For example, to check if a given action is an acquire authority:
if not isinstance(action, NCAcquireAuthorityAction):
...

Source code:
hathor.nanocontracts.types.NCAcquireAuthorityAction

NCFail

An NCFail exception signals to Hathor engine that a contract's creation or execution has failed. Use it in your blueprint's methods to indicate execution failures. Also, define subclasses of NCFail to provide more specific and clearer failure reasons for contract users (wallets and other contracts).

Usage:

from hathor import NCFail
...
# Raise a generic NCFail exception.
if len(ctx.actions) != 0:
raise NCFail('must be a single call')
...
# Define specific exception classes.
class WithdrawalNotAllowed(NCFail):
pass
...
# Raise a specific exception.
if action.type != NCActionType.DEPOSIT:
raise WithdrawalNotAllowed('must be deposit')
...

Source code:
hathor.nanocontracts.exception.NCFail

SignedData

Out-of-the-box support for oracles in blueprints. To achieve this, the blueprint should have a public method exclusively for oracle use, which receives a SignedData as a parameter.

Data attributes:

  • data: off-chain data that the oracle wants to feed into the contract. The type of data is defined in the SignedData generic parameter which is defined in the public method that uses it.
  • script_input: bytes denoting the script used to authenticate the oracle.

Examples:

Suppose a sports betting contract in which an oracle should submit the result of a game after it has ended. In this scenario, SignedData[str] specifies that the result in data must be passed as a string. For example:

  data: "Barcelona2x1Real-Madrid"
script_input: <unlock_script_to_auth_oracle_as_bytes>

Now, suppose an oracle needs to submit the exchange rate of 1 BTC in US dollars (USD) every minute. In this scenario, SignedData[int] specifies that the result in data must be passed as an integer, with the last two digits representing cents. For example:

  data: 9654292
script_input: <unlock_script_to_auth_oracle_as_bytes>

Methods:

  • checksig
  • get_data_bytes

The following subsections describe each of these methods.

SignedData.checksig

Called in the oracle's public method to authenticate the oracle. That is, checks if this object's script_input attribute resolves the oracle script registered in the contract state.

checksig(self, contract_id: ContractId, script: bytes) -> bool:

Parameter:

  • contract_id: ContractId denoting the contract that was intended to authenticate this signed data.
  • script: bytes that denotes the oracle script. That is, a script from the contract state used to authenticate the oracle.

Return: True if this object's script_input attribute successfully unlocks the script received as parameter. That is, the oracle is authenticated.

SignedData.get_data_bytes

Given a contract ID, returns a serialized version of data as bytes. Useful to perform unit tests on your blueprint.

get_data_bytes(self, contract_id: ContractId) -> bytes:

Parameter:

  • contract_id: ContractId denoting the contract that was intended to authenticate this signed data.

Return: bytes that denotes the serialized version of the attribute data. Useful to generate the script_input during unit tests.

Usage:

The following snippet presents how to write a public method that allows an oracle to feed off-chain data to a contract:

from hathor import TxOutputScript, SignedData, public, Context, NCFail

# Script that must be resolved to authenticate oracle.
oracle_script: TxOutputScript
# Data to be fed by oracle
offchain_data: str | None

# SignedData[str] specifies that off-chain data being passed is of type string.
@public
def provide_offchain_data(self, ctx: Context, signed_data: SignedData[str]) -> None:
"""Called by oracle to input off-chain data into contract."""

# Check if script_input resolves oracle_script, to authenticate oracle.
if not signed_data.checksig(self.syscall.get_contract_id(), self.oracle_script):
raise NCFail('Oracle not authenticated')

# Once oracle authenticated, off-chain data can be saved in the contract.
self.offchain_data = signed_data.data

Source code:
hathor.nanocontracts.types.SignedData

Decorators

export

Decorator that marks a class in your blueprint module as the Blueprint. It must only be used once, decorating a class that inherits from Blueprint.

Usage:

from hathor import export, Blueprint
...

@export
class MyBlueprint(Blueprint):
...

Source code:
hathor.nanocontracts.types.export

public

Decorator that marks a method in your blueprint class as 'public'. All public methods must be marked with the public decorator. In addition, you must explicitly specify which types of actions the public method can receive, if any. This should be done using one of the following keyword arguments:

  • Option 1: pass True for each action type you want to allow:
"""
- allow_deposit=True for DEPOSIT
- allow_withdrawal=True for WITHDRAWAL
- allow_grant_authority=True for GRANT_AUTHORITY
- allow_acquire_authority=True for ACQUIRE_AUTHORITY
"""
  • Option 2: use allow_actions to provide the list of allowed NCActionType values. Example: allow_actions=[NCActionType.DEPOSIT, NCActionType.WITHDRAWAL]).

You cannot use allow_actions (option 2) together with the other keyword arguments (option 1). Doing so will always raise a BlueprintSyntaxError exception.

You can also use allow_reentrancy=True to allow the method to be called again during its own execution (reentrancy). By default, reentrancy is not allowed (allow_reentrancy=False).

tip

If an action type is not explicitly allowed using the keyword arguments in the @public decorator, the public method will not be able to receive or handle that type of action. If you use the @public decorator with no keyword arguments, the method will not be allowed to receive any actions. Finally, calling a public method with actions it is not allowed to handle will cause the method call to fail.

Usage:

from hathor import public, NCActionType, SignedData, Context
...

# Mark all your public methods:
@public
def set_result(self, ctx: Context, result: SignedData[Result]) -> None:
"""Public method that CANNOT receive any type of action.

This is because you didn't explicitly allow any type
alongside the public decorator.
"""
...

# If you want your method to receive any type of action
# You must do it explicitly:
@public(allow_actions=[NCActionType.DEPOSIT, NCActionType.WITHDRAWAL])
def swap(self, ctx: Context) -> None:
"""Public method that works with deposits and withdrawals.

It can receive ANY number of deposits and withdrawals
of any token. It is up to your code to validate these
actions.
We used the allow_actions arg to pass a list of enabled
actions, and we needed to use the NCActionTypes.
"""
...

# There are two alternative syntaxes to state the types of actions
# You either pass the allow_actions arg or:
@public(allow_deposit=True, allow_withdrawal=True)
def swap(self, ctx: Context) -> None:
"""Decorator using the other keyword args of public.

Both work the same way.
Here we do the same we did above but using one keyword arg
for each specific type of action.
"""
...

# It is not required to pass one of them as False:
@public(allow_grant_authority=False, allow_acquire_authority=False)
def foo(self, ctx: Context) -> None:
"""False with <allow_some_action_type> arg changes nothing.

You may decide to use it just for human-reading purposes if you prefer.
"""
...

Source code:
hathor.nanocontracts.types.public

view

Decorator that marks a method in your blueprint class as 'view'. All view methods must be marked with the view decorator.

Usage:

from hathor import view, Address
...
# Mark all your view methods.
@view
def get_max_withdrawal(self, address: Address) -> int:
"""Return the maximum amount available for withdrawal."""
...

Source code:
hathor.nanocontracts.types.view

fallback

Decorator that marks the method named 'fallback' in your blueprint class. That is, you can only use the @fallback decorator once in the entire blueprint class, and only to mark a method named fallback.

Just like with public methods, you must explicitly specify the allowed action types. You can also use allow_reentrancy=True to allow the fallback method to be called again during its own execution (reentrancy). By default, reentrancy is not allowed (allow_reentrancy=False). For more on it, see Method fallback at Blueprint development guidelines

Usage:

from hathor import fallback, Context, NCArgs
...

# Mark your fallback method:
@fallback(allow_deposit=True)
def fallback(self, ctx: Context, method_name: str, nc_args: NCArgs) -> None:
"""THE only fallback method of your blueprint class.

You can only use this decorator with the method named 'fallback'.
Whenever a caller calls a non-existent PUBLIC method, Hathor engine
will invoke the fallback method.
Thus: just like any public method, you must explicitly state
what action types the method works with.
"""
...

Source code:
hathor.nanocontracts.types.fallback

Functions

sha3

Calculate the SHA3-256 of some data.

Usage:

from hathor import sha3, public, Context
...
@public
def some_method(self, ctx: Context, data: bytes) -> None:
my_hash = sha3(data)
...

Source code:
hathor.nanocontracts.utils.sha3

verify_ecdsa

Verify a cryptographic signature using a compressed public key for a SECP256K1 curve.

Usage:

from hathor import verify_ecdsa, public, Context
...
@public
def some_method(self, ctx: Context, public_key: bytes, data: bytes, signature: bytes) -> None:
is_valid = verify_ecdsa(public_key, data, signature)
...

Source code:
hathor.nanocontracts.utils.verify_ecdsa

Objects

Blueprint.syscall

For all interactions outside the scope of the blueprint itself (external interactions). That is, whenever you need to perform reads and writes to the ledger, call methods from other contracts, or access special features provided by Hathor engine.

Methods:

  • get_contract_id
  • get_blueprint_id
  • get_current_code_blueprint_id
  • get_balance_before_current_call
  • get_current_balance
  • can_mint_before_current_call
  • can_mint
  • can_melt_before_current_call
  • can_melt
  • revoke_authorities
  • mint_tokens
  • melt_tokens
  • create_deposit_token
  • create_fee_token
  • emit_event
  • change_blueprint
  • get_contract
  • get_proxy
  • setup_new_contract

The following subsections describe each of these methods.

syscall.get_contract_id

Returns the contract's own ID.

get_contract_id(self) -> ContractId:

syscall.get_blueprint_id

Returns the blueprint ID of the current nano contract. Note that during a proxy call, this method returns the blueprint ID of the caller's contract, not the blueprint ID of the blueprint that owns the running code.

get_blueprint_id(self) -> BlueprintId:

syscall.get_current_code_blueprint_id

Returns the blueprint ID of the blueprint that owns the currently running code. This is useful during proxy calls, where get_blueprint_id returns the caller's blueprint ID, and this method returns the blueprint ID of the code being executed.

get_current_code_blueprint_id(self) -> BlueprintId:

syscall.get_balance_before_current_call

Returns the balance of a token held by this contract; it does not take into account the effects of the current call.

get_balance_before_current_call(self, token_uid: TokenUid | None = None) -> Amount:

Parameter:

  • token_uid: TokenUid to check balance; defaults to HTR.

Return: Amount, such that:

  • It takes into account:
    • Everything that happened in the call chain before this call, including any actions.
  • It does not take into account:
    • Actions or changes that occurred during the current call.
    • Actions or changes that will occur later in this call or in subsequent calls (since they haven't happened yet, by definition).

Example: if a contract holds 50 HTR and the current call is requesting to withdraw 3 HTR, this method still returns 50 HTR.

syscall.get_current_balance

Returns the balance of a token held by this contract; it does take into account the actions and changes already performed in the current call.

get_current_balance(self, token_uid: TokenUid | None = None) -> Amount:

Parameter:

  • token_uid: TokenUid to check balance; defaults to HTR.

Return: Amount, such that:

  • It takes into account:
    • Everything that happened in the call chain before this call, including any actions.
    • All actions and changes that occurred during the current call.
  • It does not take into account:
    • Actions or changes that will occur later in this call or in subsequent calls (since they haven't happened yet, by definition).

Example: if a contract holds 50 HTR and the current call is requesting to withdraw 3 HTR, this method returns 47 HTR.

syscall.can_mint_before_current_call

Returns whether this contract has mint authority over a token; it does not take into account the actions and changes already performed in the current call.

can_mint_before_current_call(self, token_uid: TokenUid) -> bool:

Parameter:

  • token_uid: TokenUid to check authority.

Return: bool, such that:

  • True means the contract has mint authority over the token.
  • It takes into account:
    • Everything that happened in the call chain before this call, including any actions.
  • It does not take into account:
    • All actions and changes that occurred during the current call.
    • Actions or changes that will occur later in this call or in subsequent calls (since they haven't happened yet, by definition).

Example: if a contract has mint authority over a token and the current call revokes it before invoking this method, it still returns True.

syscall.can_mint

Returns whether this contract has mint authority over a token; it does take into account the actions and changes already performed in the current call.

can_mint(self, token_uid: TokenUid) -> bool:

Parameter:

  • token_uid: TokenUid to check authority.

Return: bool, such that:

  • True means the contract has mint authority over the token.
  • It takes into account:
    • Everything that happened in the call chain before this call, including any actions.
    • All actions and changes that occurred during the current call.
  • It does not take into account:
    • Actions or changes that will occur later in this call or in subsequent calls (since they haven't happened yet, by definition).

Example: if a contract has mint authority over a token and the current call revokes it before invoking this method, it returns False.

syscall.can_melt_before_current_call

Returns whether this contract has melt authority over a token; it does not take into account the actions and changes already performed in the current call.

can_melt_before_current_call(self, token_uid: TokenUid) -> bool:

Parameter:

  • token_uid: TokenUid to check authority.

Return: bool, such that:

  • True means the contract has melt authority over the token.
  • It takes into account:
    • Everything that happened in the call chain before this call, including any actions.
  • It does not take into account:
    • All actions and changes that occurred during the current call.
    • Actions or changes that will occur later in this call or in subsequent calls (since they haven't happened yet, by definition).

Example: if a contract has melt authority over a token and the current call revokes it before invoking this method, it still returns True.

syscall.can_melt

Returns whether this contract has melt authority over a token; it does take into account the actions and changes already performed in the current call.

can_melt(self, token_uid: TokenUid) -> bool:

Parameter:

  • token_uid: TokenUid to check authority.

Return: bool, such that:

  • True means the contract has melt authority over the token.
  • It takes into account:
    • Everything that happened in the call chain before this call, including any actions.
    • All actions and changes that occurred during the current call.
  • It does not take into account:
    • Actions or changes that will occur later in this call or in subsequent calls (since they haven't happened yet, by definition).

Example: if a contract has melt authority over a token and the current call revokes it before invoking this method, it returns False.

syscall.revoke_authorities

Revokes the contract's own mint/melt authorities over a token.

revoke_authorities(
self,
token_uid: TokenUid,
*,
revoke_mint: bool,
revoke_melt: bool
) -> None:

Parameters:

  • token_uid: TokenUid to revoke authorities over.
  • revoke_mint: bool; if True, will revoke mint authority.
  • revoke_melt: bool; if True, will revoke melt authority.

syscall.mint_tokens

Mints a new amount of a given token and adds it to the contract balance.

mint_tokens(
self,
token_uid: TokenUid,
amount: int,
*,
fee_payment_token: TokenUid = TokenUid(HATHOR_TOKEN_UID)
) -> None:

Parameters:

  • token_uid: TokenUid to mint; contract must have mint authority over it.
  • amount: Amount to mint.
  • fee_payment_token: TokenUid used to pay the minting fee; defaults to HTR.

syscall.melt_tokens

Melts an amount of a given token by removing it from the contract balance.

melt_tokens(
self,
token_uid: TokenUid,
amount: int,
*,
fee_payment_token: TokenUid = TokenUid(HATHOR_TOKEN_UID)
) -> None:

Parameters:

  • token_uid: TokenUid to melt; contract must have melt authority over it.
  • amount: Amount to melt.
  • fee_payment_token: TokenUid used to pay the melting fee; defaults to HTR.

syscall.create_deposit_token

Creates a new deposit-based fungible token and adds its initial supply to the contract balance.

create_deposit_token(
self,
*,
token_name: str,
token_symbol: str,
amount: int,
mint_authority: bool = True,
melt_authority: bool = True,
salt: bytes = b'',
) -> TokenUid:

Parameters:

  • token_name: str; 1-30 UTF-8 characters.
  • token_symbol: str; 1-5 UTF-8 characters.
  • amount: Amount that denotes initial supply of the token; contract must hold enough HTR in its balance to be consumed in minting initial supply.
  • mint_authority: bool; if True, creates a mint authority for the contract over the new token.
  • melt_authority: bool; if True, creates a melt authority for the contract over the new token.
  • salt: bytes used to generate a unique TokenUid; defaults to empty bytes.

Return: TokenUid that uniquely identifies the token on the ledger (blockchain).

syscall.create_fee_token

Creates a new fee-based fungible token and adds its initial supply to the contract balance.

create_fee_token(
self,
*,
token_name: str,
token_symbol: str,
amount: int,
mint_authority: bool = True,
melt_authority: bool = True,
salt: bytes = b'',
fee_payment_token: TokenUid = TokenUid(HATHOR_TOKEN_UID)
) -> TokenUid:

Parameters:

  • token_name: str; 1-30 UTF-8 characters.
  • token_symbol: str; 1-5 UTF-8 characters.
  • amount: Amount that denotes initial supply of the token.
  • mint_authority: bool; if True, creates a mint authority for the contract over the new token.
  • melt_authority: bool; if True, creates a melt authority for the contract over the new token.
  • salt: bytes used to generate a unique TokenUid; defaults to empty bytes.
  • fee_payment_token: TokenUid used to pay the token creation fee; defaults to HTR.

Return: TokenUid that uniquely identifies the token on the ledger (blockchain).

syscall.emit_event

Registers an event related to the current contract execution. The event is recorded by all full nodes configured to produce events — i.e., with the ledger events producer feature enabled — and can be consumed by client applications connected to them. For more on ledger events, see Ledger events at Highlighted configurations.

emit_event(self, data: bytes) -> None:

Parameter:

  • data: bytes that denotes the event to be registered; limited to 1 KiB. The event is marked as type NC_EVENT in the event database of each full node. Its content data consists of raw bytes, intended for client applications that know how to interpret it.

syscall.change_blueprint

Changes the contract blueprint. Use it for upgradeable contracts.

change_blueprint(self, blueprint_id: BlueprintId) -> None:

Parameter:

  • blueprint_id: BlueprintId; denotes the new blueprint for the contract.

syscall.get_contract

Returns a ContractAccessor for interacting with another contract. Use this to call view or public methods on other contracts.

get_contract(
self,
contract_id: ContractId,
*,
blueprint_id: BlueprintId | Collection[BlueprintId] | None,
) -> ContractAccessor:

Parameters:

  • contract_id: ContractId of the contract to interact with.
  • blueprint_id: the expected BlueprintId of the contract, or a collection of accepted blueprints, or None if any blueprint is accepted. If the contract's actual blueprint doesn't match, an NCFail exception is raised.

Return: a ContractAccessor object. See ContractAccessor for usage details.

Usage:

from hathor import public, Context, ContractId, BlueprintId, NCDepositAction

@public(allow_withdrawal=True)
def call_another_contract(self, ctx: Context, target: ContractId) -> None:
# Get a contract accessor, accepting any blueprint
contract = self.syscall.get_contract(target, blueprint_id=None)

# Call a view method
result = contract.view().get_value()

# Call a public method with actions
deposit = NCDepositAction(token_uid=HATHOR_TOKEN_UID, amount=100)
contract.public(deposit).deposit()

syscall.get_proxy

Returns a ProxyAccessor for invoking methods from another blueprint as if this contract had that method. This is useful for contracts that delegate functionality to other blueprints.

get_proxy(self, blueprint_id: BlueprintId) -> ProxyAccessor:

Parameter:

  • blueprint_id: BlueprintId of the blueprint to use.

Return: a ProxyAccessor object. See ProxyAccessor for usage details.

Usage:

from hathor import public, Context, BlueprintId

@public
def proxy_call(self, ctx: Context, target_blueprint: BlueprintId) -> None:
# Get a proxy accessor
proxy = self.syscall.get_proxy(target_blueprint)

# Call a view method from the target blueprint
result = proxy.view().some_view_method()

# Call a public method from the target blueprint
proxy.public().some_public_method(arg1, arg2)

syscall.setup_new_contract

Sets up the creation of a new contract. Returns an InitializeMethodAccessor that must be used to call the initialize method of the new contract.

setup_new_contract(
self,
blueprint_id: BlueprintId,
*actions: NCAction,
fees: Sequence[NCFee] | None = None,
salt: bytes,
) -> InitializeMethodAccessor:

Parameters:

  • blueprint_id: BlueprintId to instantiate the new contract from.
  • *actions: NCAction objects to be performed during initialization.
  • fees: optional sequence of NCFee objects for fee payment.
  • salt: bytes used to generate the ContractId for the new contract. This value must be unique for each contract created by this contract. You can use UUIDs generated via a pseudo-random number generator, or even a simple counter.

Return: an InitializeMethodAccessor object. See InitializeMethodAccessor for usage details.

Usage:

from hathor import public, Context, BlueprintId, NCDepositAction

@public(allow_deposit=True)
def create_child_contract(self, ctx: Context, blueprint: BlueprintId) -> ContractId:
# Setup new contract creation with initial deposit
deposit = NCDepositAction(token_uid=HATHOR_TOKEN_UID, amount=1000)
accessor = self.syscall.setup_new_contract(blueprint, deposit, salt=b'unique_salt')

# Call initialize to actually create the contract
contract_id, result = accessor.initialize(param1="value1", param2=42)

return contract_id

Blueprint.syscall.log

Use it to record method execution logs. Useful during development for debugging and testing, and in production for audits. Then, at runtime, use the full node HTTP API to retrieve the logs.

Methods:

  • debug
  • info
  • warn
  • error

The following subsections describe each of these methods.

log.debug

Create a new DEBUG log entry.

debug(self, message: str, **kwargs: Any) -> None:

log.info

Create a new INFO log entry.

info(self, message: str, **kwargs: Any) -> None:

log.warn

Create a new WARN log entry.

warn(self, message: str, **kwargs: Any) -> None:

log.error

Create a new ERROR log entry.

error(self, message: str, **kwargs: Any) -> None:
info

In addition to the log message (argument message), all methods accept arbitrary arguments via **kwargs: Any. These arguments will be recorded as key/value pairs. bytes will be represented as hexadecimals, and all values will be recorded as strings.

Source code:
hathor.nanocontracts.nc_exec_logs.NCLogger

Blueprint.syscall.rng

Random number generator (RNG) for use cases that require randomness. This RNG is deterministic based on the hash of the block that executes the contract. As a result, all nodes on the network will generate the same number. However, since it is virtually impossible to know this value beforehand, true randomness is achieved at the time of contract execution. It is based on the ChaCha20 algorithm.

Data attribute:

  • seed: bytes; seed used to create the RNG object. The seed is the double hash of the first block validating the transaction.

Methods:

  • randbytes
  • randbits
  • randbelow
  • randrange
  • randint
  • choice
  • random

The following subsections describe each of these methods.

rng.randbytes

Returns a random string of bytes of the specified size, where sizesize is an integer and 1\geq 1.

randbytes(self, size: int) -> bytes:

rng.randbits

Returns a random integer in the range [0,2bits)[0,2^{bits}), where bitsbits is integer and 1\geq 1. In other words, a random non-negative integer with size bitsbits.

randbits(self, bits: int) -> int:

rng.randbelow

Returns a random integer in the range [0,n)[0, n), where nn is integer and 1\geq 1.

randbelow(self, n: int) -> int:

rng.randrange

Returns a random integer in the range [start,stop)[start, stop) with step size stepstep, where startstart, stopstop, and stepstep are integers such that start<stopstart < stop and step1step \geq 1. The result will always be within the given interval, and of the form start+kstepstart + k \cdot step for a random integer kk. For example: randrange(start=10, stop=20, step=2) may return any of the following values: 10, 12, 14, 16, or 18.

randrange(self, start: int, stop: int, step: int = 1) -> int:

rng.randint

Returns a random integer in the range [a,b][a, b], where aa and bb are integers such that bab \geq a.

randint(self, a: int, b: int) -> int:

rng.choice

Chooses a random element from the non-empty Sequence.

choice(self, seq: Sequence[T]) -> T:

Parameter:

rng.random

Returns a random float in the range [0,1)[0,1).

random(self) -> float:

Source code:
hathor.nanocontracts.rng.NanoRNG

ContractAccessor

An accessor object for interacting with another contract. Returned by syscall.get_contract. It provides methods to call view and public methods on the target contract, and to query its balance and authorities.

Methods:

  • get_contract_id: returns the ContractId of the target contract.
  • get_blueprint_id: returns the BlueprintId of the target contract.
  • get_current_balance: returns the current balance for a given token on the target contract.
  • can_mint: returns whether the target contract has mint authority over a token.
  • can_melt: returns whether the target contract has melt authority over a token.
  • view: prepares a call to a view method. Returns an object where calling any attribute as a method will invoke that view method on the target contract.
  • public: prepares a call to a public method with the given actions. Returns an object where calling any attribute as a method will invoke that public method on the target contract.
  • get_view_method: returns a callable for a view method with a dynamic name.
  • get_public_method: returns a callable for a public method with a dynamic name.

ContractAccessor.view

Prepares a call to a view method on the target contract. Returns an intermediate object that allows calling any view method by name.

view(self) -> Any:

Return: an object where you can call any method name, which will invoke the corresponding view method on the target contract.

Usage:

# Call a view method named 'get_balance' on another contract
contract = self.syscall.get_contract(target_id, blueprint_id=None)
balance = contract.view().get_balance(address)

ContractAccessor.public

Prepares a call to a public method on the target contract with the specified actions. Returns an intermediate object that allows calling any public method by name.

public(
self,
*actions: NCAction,
fees: Sequence[NCFee] | None = None,
forbid_fallback: bool = False
) -> Any:

Parameters:

  • *actions: NCAction objects to be performed during the call. The caller contract must have sufficient funds for deposits, and the target contract must have sufficient funds for withdrawals.
  • fees: optional sequence of NCFee objects for fee payment.
  • forbid_fallback: if True, the call will fail if the method is not found instead of invoking the fallback method.

Return: an object where you can call any method name, which will invoke the corresponding public method on the target contract. Note that each prepared public call can only be used once because it consumes the provided actions.

Usage:

# Call a public method named 'deposit' on another contract
contract = self.syscall.get_contract(target_id, blueprint_id=None)
deposit_action = NCDepositAction(token_uid=HATHOR_TOKEN_UID, amount=100)
contract.public(deposit_action).deposit()

ContractAccessor.get_view_method

Returns a callable accessor for a view method with a dynamic name. Useful when the method name is stored in a variable.

get_view_method(self, method_name: str) -> ViewMethodAccessor:

Parameter:

  • method_name: the name of the view method to call.

Return: a ViewMethodAccessor that can be called multiple times with different arguments.

Usage:

contract = self.syscall.get_contract(target_id, blueprint_id=None)
method = contract.get_view_method("get_balance")
balance = method(address)

ContractAccessor.get_public_method

Returns a callable accessor for a public method with a dynamic name. Useful when the method name is stored in a variable.

get_public_method(
self,
method_name: str,
*actions: NCAction,
fees: Sequence[NCFee] | None = None,
forbid_fallback: bool = False,
) -> PublicMethodAccessor:

Parameters:

  • method_name: the name of the public method to call.
  • *actions: NCAction objects to be performed during the call.
  • fees: optional sequence of NCFee objects for fee payment.
  • forbid_fallback: if True, the call will fail if the method is not found.

Return: a PublicMethodAccessor that can only be called once because it consumes the provided actions.

Usage:

contract = self.syscall.get_contract(target_id, blueprint_id=None)
deposit_action = NCDepositAction(token_uid=HATHOR_TOKEN_UID, amount=100)
method = contract.get_public_method("deposit", deposit_action)
method()

Source code:
hathor.nanocontracts.contract_accessor.ContractAccessor

ProxyAccessor

An accessor object for invoking methods from another blueprint as if the current contract had that method. Returned by syscall.get_proxy. This is useful for contracts that delegate functionality to other blueprints.

Methods:

  • get_blueprint_id: returns the BlueprintId of the proxy blueprint.
  • view: prepares a proxy call to a view method.
  • public: prepares a proxy call to a public method with the given actions.
  • get_view_method: returns a callable for a proxy view method with a dynamic name.
  • get_public_method: returns a callable for a proxy public method with a dynamic name.

ProxyAccessor.view

Prepares a proxy call to a view method. Returns an intermediate object that allows calling any view method by name.

view(self) -> Any:

Return: an object where you can call any method name, which will invoke the corresponding view method from the proxy blueprint on the current contract.

Usage:

proxy = self.syscall.get_proxy(blueprint_id)
result = proxy.view().some_view_method(arg1, arg2)

ProxyAccessor.public

Prepares a proxy call to a public method with the specified actions. Returns an intermediate object that allows calling any public method by name.

public(
self,
*actions: NCAction,
fees: Sequence[NCFee] | None = None,
forbid_fallback: bool = False
) -> Any:

Parameters:

  • *actions: NCAction objects to be performed during the call.
  • fees: optional sequence of NCFee objects for fee payment.
  • forbid_fallback: if True, the call will fail if the method is not found instead of invoking the fallback method.

Return: an object where you can call any method name, which will invoke the corresponding public method from the proxy blueprint. Note that each prepared proxy call can only be used once.

Usage:

proxy = self.syscall.get_proxy(blueprint_id)
proxy.public().some_public_method(arg1, arg2)

ProxyAccessor.get_view_method

Returns a callable accessor for a proxy view method with a dynamic name.

get_view_method(self, method_name: str) -> ProxyViewMethodAccessor:

Parameter:

  • method_name: the name of the view method to call.

Return: a ProxyViewMethodAccessor that can be called multiple times with different arguments.

ProxyAccessor.get_public_method

Returns a callable accessor for a proxy public method with a dynamic name.

get_public_method(
self,
method_name: str,
*actions: NCAction,
fees: Sequence[NCFee] | None = None,
forbid_fallback: bool = False,
) -> ProxyPublicMethodAccessor:

Parameters:

  • method_name: the name of the public method to call.
  • *actions: NCAction objects to be performed during the call.
  • fees: optional sequence of NCFee objects for fee payment.
  • forbid_fallback: if True, the call will fail if the method is not found.

Return: a ProxyPublicMethodAccessor that can only be called once. It also supports call_with_nc_args(nc_args: NCArgs) for use within fallback methods.

Source code:
hathor.nanocontracts.proxy_accessor.ProxyAccessor

InitializeMethodAccessor

An accessor object for creating a new contract. Returned by syscall.setup_new_contract. It provides the initialize method to actually create the contract.

Methods:

  • initialize: creates the new contract by calling its initialize method with the provided arguments.

InitializeMethodAccessor.initialize

Creates the new contract by calling its initialize method.

initialize(self, *args: Any, **kwargs: Any) -> tuple[ContractId, object]:

Parameters:

  • Use *args or **kwargs to pass the arguments required by the initialize method of the chosen blueprint.

Return: a tuple where:

  • The first item is the ContractId that uniquely identifies the newly created contract.
  • The second item is the return value of the initialize method. You should know the chosen blueprint API to properly handle this return value.
warning

Each InitializeMethodAccessor can only be used once. Attempting to call initialize again will raise an NCFail exception. To create another contract, you must call syscall.setup_new_contract again.

Usage:

from hathor import public, Context, BlueprintId, NCDepositAction, HATHOR_TOKEN_UID

@public(allow_deposit=True)
def create_child(self, ctx: Context, blueprint: BlueprintId) -> ContractId:
# Setup the new contract with an initial deposit
deposit = NCDepositAction(token_uid=HATHOR_TOKEN_UID, amount=1000)
accessor = self.syscall.setup_new_contract(
blueprint,
deposit,
salt=b'unique_salt_for_this_contract'
)

# Create the contract by calling initialize
contract_id, init_result = accessor.initialize(owner=ctx.caller_id)

return contract_id

Source code:
hathor.nanocontracts.initialize_method_accessor.InitializeMethodAccessor