Skip to content

Cheat Sheet

Reference Contract

Here is a reference contract showcasing many of the syntax and features of Contracting.

python
random.seed() # Seed the random number generator

# Variable is a way to define a state variable in the contract
simple_var = Variable() 
# Hash is a way to define a key-value store in the contract
storage = Hash(default_value=0)

submission_time = Variable()
submission_block_num = Variable()
submission_block_hash = Variable()
random_number = Variable()

# ForeignHash is a way to get a read-only view of
# a Hash object from another contract
xian_balances = ForeignHash(
    foreign_contract='currency', foreign_name='balances'
) 
# ForeignVariable is a way to get a read-only view of
# a Variable object from another contract
foundation_owner = ForeignVariable(
    foreign_contract='foundation', foreign_name='owner'
) 

# The construct decorator is optional and can be used to define
# initialization logic for the contract. It's called on contract submission
@construct 
def seed():
    # Initialize the contract with a variable
    simple_var.set(0)
    # now is a built-in variable that returns the current datetime
    submission_time.set(now) 
    random_number.set(random.randint(0, 100))
    # block_num is a built-in variable that returns the current block number
    submission_block_num.set(block_num) 
    # block_hash is a built-in variable that returns the current block hash
    submission_block_hash.set(block_hash) 

# This function is private and cannot be called from outside the contract
def private_function(): 
    return "This is a private function"

# The export decorator is used to define functions that can be called from 
# outside the contract
@export 
def call_private_function():
    # Call the private function
    return private_function()

# This function is public and can be called from outside the contract
@export
def public_function():
    return "This is a public function"

# Increment the variable by 1
@export
def increment():
    simple_var.set(simple_var.get() + 1)

# Decrement the variable by 1
@export
def decrement():
    simple_var.set(simple_var.get() - 1)

# Set a key-value pair in the storage
@export
def set_storage_pair(key: str, value: int):
    storage[key] = value

# Get the value of a key in the storage
@export
def get_storage_pair(key: str):
    return storage[key]

# Set a nested key-value pair in the storage
@export
def set_nested_storage_pair(key: str, nested_key: str, value: int):
    storage[key, nested_key] = value

@export
# Get the value of a nested key in the storage
def get_nested_storage_pair(key: str, nested_key: str):
    return storage[key, nested_key]

# Import another contract dynamically
@export
def interact_with_other_contract(contract: str, args: dict):
    c = importlib.import_module(contract) 

    forced_interface = [
        # Func is a way to enforce the existence of a function with specific 
        # arguments
        importlib.Func('do_something', args=('amount', 'to')), 
        # Var is a way to enforce the existence of a variable with a specific 
        # type
        importlib.Var('balances', Hash) 
    ] 

    # Enforce the interface of the other contract
    assert importlib.enforce_interface(c, forced_interface) 

    # Interact with another contract
    c.do_something(**args)

# Check if the submission time is older than a specific date
@export 
def is_older_than_date(date: datetime.datetime):
    return submission_time.get() < date

@export
def get_contract_name():
    return ctx.this

@export
def am_i_a_masternode():
    nodes = ForeignVariable(
        foreign_contract='masternodes', foreign_name='nodes'
    ) # nodes is a list
    return ctx.caller in nodes

@export
def xian_balance():
    # Return value from a previously retrieved Hash object
    return xian_balances[ctx.caller]

@export
def get_foundation_owner():
    # Return value from a previously retrieved Variable object
    return foundation_owner.get()

# The actual caller that called this function. Could be a contract or an account
@export
def who_am_i():
    return ctx.caller 

# First signer in the call chain (the original signer). This is the account that 
# initiated the transaction even if the transaction was forwarded by another 
# contract
@export
def get_top_level_signer():
    return ctx.signer 

# Exception handling
@export
def calculate():
    some_value = 0

    # This will not work. The transaction will result in an error because 
    # it's not allowed to use exceptions in smart contracts.
    try:
        return 100 / some_value
    except:
        return "Cannot divide by 0"

    # Instead, use asserts
    assert some_value != 0, "Cannot divide by 0"

    # Or use IF statements
    if some_value == 0:
        return "Cannot divide by 0"