Syscalls
Use this page when you need the low-level mutation and control operations exposed by tn_sdk_syscall.h.
Return convention
Section titled “Return convention”Most syscall wrappers return a ulong status code in a0.
The main exception is tsys_invoke, which has two result channels:
- return value: syscall-level success or failure
invoke_err_code: callee-level success or failure
tsys_exit never returns.
Account and balance syscalls
Section titled “Account and balance syscalls”tsys_set_account_data_writable
Section titled “tsys_set_account_data_writable”ulong tsys_set_account_data_writable( ulong account_idx );Mark an account’s data segment as writable. Must be called before writing to tsdk_get_account_data_ptr(...). Returns TSDK_SUCCESS on success.
tsys_account_transfer
Section titled “tsys_account_transfer”ulong tsys_account_transfer( ulong from_account_idx, ulong to_account_idx, ulong amount );Transfer amount native tokens from one account to another. Both indices must be valid and the source account must be authorized.
tsys_account_create
Section titled “tsys_account_create”ulong tsys_account_create( ulong account_idx, uchar const seed[TN_SEED_SIZE], void const * proof, ulong proof_sz );Create a program-defined account. The 32-byte seed determines the account address deterministically. The proof is a state proof validating the account does not already exist.
tsys_account_create_ephemeral
Section titled “tsys_account_create_ephemeral”ulong tsys_account_create_ephemeral( ulong account_idx, uchar const seed[TN_SEED_SIZE] );Create a transaction-scoped ephemeral account. No state proof required because ephemeral accounts do not persist across transactions.
tsys_account_create_eoa
Section titled “tsys_account_create_eoa”ulong tsys_account_create_eoa( ulong account_idx, tn_signature_t const * signature, void const * proof, ulong proof_sz );Create an externally owned account (EOA). Requires a valid signature and state proof.
tsys_account_delete
Section titled “tsys_account_delete”ulong tsys_account_delete( ulong account_idx );Delete an account. The account must be owned by the current program.
tsys_account_resize
Section titled “tsys_account_resize”ulong tsys_account_resize( ulong account_idx, ulong new_size );Resize an account’s data region to new_size bytes. Maximum size is TSDK_ACCOUNT_DATA_SZ_MAX (16 MB). The account must already be writable.
tsys_account_set_flags
Section titled “tsys_account_set_flags”ulong tsys_account_set_flags( ushort account_idx, uchar flags );Update the account’s flags byte. See Accounts and Transaction Context for flag constants.
tsys_account_compress
Section titled “tsys_account_compress”ulong tsys_account_compress( ulong account_idx, void const * proof, ulong proof_sz );Compress an account’s state, removing it from the active ledger while preserving a proof of its existence.
tsys_account_decompress
Section titled “tsys_account_decompress”ulong tsys_account_decompress( ulong account_idx, void const * meta, void const * data, void const * proof, ulong proof_sz );Decompress a previously compressed account by providing its metadata, data payload, and validity proof.
Invocation, logging, and exit
Section titled “Invocation, logging, and exit”tsys_invoke
Section titled “tsys_invoke”ulong tsys_invoke( void const * instr_data, ulong instr_data_sz, ushort program_account_idx, tsdk_invoke_auth_t const * auth, ulong * invoke_err_code );Cross-program invocation. Returns a syscall-level status in the return value and a callee-level status in invoke_err_code. Pass NULL for auth when no explicit authorization is needed. See Cross-Program Invocation for details.
tsys_log
Section titled “tsys_log”ulong tsys_log( void const * data, ulong data_len );Emit raw log bytes. tsdk_printf is a formatted wrapper around this (capped at 1024 bytes per call).
tsys_emit_event
Section titled “tsys_emit_event”ulong tsys_emit_event( void const * data, ulong data_sz );Emit an event payload that downstream consumers can read from the transaction result.
tsys_exit
Section titled “tsys_exit”ulong __attribute__(( noreturn )) tsys_exit( ulong exit_code, ulong revert );Terminate execution. If revert is non-zero, the transaction state is rolled back. Prefer tsdk_return or tsdk_revert unless you need direct control.
Anonymous segment syscalls
Section titled “Anonymous segment syscalls”These are lower-level memory-management syscalls that most programs will not need immediately.
tsys_set_anonymous_segment_sz
Section titled “tsys_set_anonymous_segment_sz”ulong tsys_set_anonymous_segment_sz( void * addr );Set the anonymous (heap) segment size to addr.
tsys_increment_anonymous_segment_sz
Section titled “tsys_increment_anonymous_segment_sz”ulong tsys_increment_anonymous_segment_sz( void * segment_addr, ulong delta, void ** addr );Grow an anonymous segment by delta bytes and optionally receive the resulting address in addr.
Typical mutation flow
Section titled “Typical mutation flow”ushort account_idx = 2U;
if( !tsdk_is_account_idx_valid( account_idx ) ) tsdk_revert( 1UL );
if( tsys_set_account_data_writable( account_idx ) != TSDK_SUCCESS ) { tsdk_revert( 2UL );}
if( tsys_account_resize( account_idx, 128UL ) != TSDK_SUCCESS ) { tsdk_revert( 3UL );}Practical guidance
Section titled “Practical guidance”- Call
tsys_set_account_data_writablebefore writing account bytes. - Validate account indices before every syscall that takes an index from instruction data.
- Treat proof-carrying syscalls as layout-sensitive. Validate sizes before forwarding raw payload tails.
- Use
tsdk_printffor human-readable debugging andtsys_emit_eventfor machine-consumed event payloads.
tsys_invokeis the only wrapper here that can both return a syscall status and a callee status.- The C wrapper performs extra auth validation before issuing the CPI syscall, so bad auth descriptors can revert locally before the callee runs.