Skip to content

Cheat Sheet ​

Quick reference for Xian contract development.

State Primitives ​

python
owner = Variable()
balances = Hash(default_value=0)
metadata = Hash()

foreign_owner = ForeignVariable(
    foreign_contract="currency",
    foreign_name="owner",
)

foreign_balances = ForeignHash(
    foreign_contract="currency",
    foreign_name="balances",
)

Events ​

python
TransferEvent = LogEvent("Transfer", {
    "from": indexed(str),
    "to": indexed(str),
    "amount": (int, float, decimal),
})

Decorators ​

python
@construct
def seed():
    owner.set(ctx.caller)

@export
def transfer(amount: float, to: str):
    pass

def helper():
    pass

Export Signature Types ​

Allowed for exported arguments and exported return annotations:

python
str, int, float, bool, bytes, bytearray, dict, list, set, frozenset, Any
datetime.datetime, datetime.timedelta

Context ​

NameMeaning
ctx.callerimmediate caller
ctx.signeroriginal transaction signer
ctx.thiscurrent contract name
ctx.ownercurrent contract owner
ctx.entry(contract, function) entry point
ctx.submission_namechild contract name during deployment

Environment Values ​

NameMeaning
nowdeterministic block time
block_numcurrent block height
block_hashcurrent block hash
chain_idnetwork id

Imports ​

python
import currency

Only deployed contracts are imported explicitly.

Runtime modules such as hashlib, datetime, random, importlib, crypto, zk, and decimal are available directly in contract scope.

Do not use from x import y.

For dynamic function dispatch, prefer the explicit helper:

python
importlib.call(
    "con_token",
    "balance_of",
    {"address": "alice"},
)

The helper only resolves exported functions. It does not expose generic attribute lookup.

Probe helpers:

python
importlib.exists("con_token")
importlib.has_export("con_token", "balance_of")
importlib.owner_of("con_token")
importlib.contract_info("con_token")
importlib.code_hash("con_token")
importlib.code_hash("con_token", kind="source")

ZK verification:

python
# public_inputs must be exact 32-byte canonical BN254 field encodings
zk.is_available()
zk.has_verifying_key("shielded-deposit-v4")
zk.verify_groth16("shielded-deposit-v4", proof_hex, public_inputs)
zk.verify_groth16_bn254(vk_hex, proof_hex, public_inputs)

Prefer the registry-backed vk_id path for contract integrations. If a contract stores a verifier binding, pin the registry vk_hash alongside the vk_id.

importlib.enforce_interface(...), importlib.owner_of(...), and importlib.contract_info(...) also accept an imported contract module if you already resolved one.

Factory deployments use the built-in submission contract. Deployment takes contract source; validators derive the stored VM IR:

python
import submission

@export
def deploy_child(
    name: str,
    source: str,
    owner: str = None,
    constructor_args: dict = None,
):
    if constructor_args is None:
        constructor_args = {}

    submission.submit_contract(
        name=name,
        code=source,
        owner=owner,
        constructor_args=constructor_args,
    )

Validators compile child source with the canonical compiler. Submitted deployment artifacts are rejected.

Deployed contracts record immutable provenance in state:

  • __deployer__: immediate deployer
  • __initiator__: original external signer
  • __developer__: current mutable developer field used for runtime developer-reward attribution

Runtime ownership can be transferred through submission.change_owner(...). That updates __owner__ / ctx.owner, not a contract's own owner = Variable() pattern.

Runtime metadata changes stay on the built-in submission surface:

  • submission.change_owner(...)
  • submission.change_developer(...)

Ordinary contracts do not get direct low-level mutation access to another contract's runtime metadata.

Read / Write Patterns ​

python
owner.set("alice")
current_owner = owner.get()

balances["alice"] = 100
approvals["alice", "con_dex"] = 25

bal = balances["alice"]
allowance = approvals["alice", "con_dex"]

Local ContractingClient inspection and test setup:

python
client.get_var("con_token", "balances", arguments=["alice"])
client.set_var("con_token", "balances", arguments=["alice"], value=500)

Common Assertions ​

python
assert amount > 0, "Amount must be positive"
assert balances[ctx.caller] >= amount, "Insufficient balance"
assert ctx.caller == owner.get(), "Only owner"
assert ctx.caller == ctx.signer, "Direct calls only"

Common Token Surface ​

python
@export
def transfer(amount: float, to: str):
    ...

@export
def approve(amount: float, to: str):
    ...

@export
def transfer_from(amount: float, to: str, main_account: str):
    ...

@export
def balance_of(address: str) -> float:
    ...

Disallowed Patterns ​

  • classes
  • nested functions
  • try/except
  • lambda
  • async
  • generators / yield
  • stdlib imports
  • names starting or ending with _