Skip to main content
Use this page when you need the low-level mutation and control operations exposed by tn_sdk_syscall.h.

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

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

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

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

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

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

ulong tsys_account_delete( ulong account_idx );
Delete an account. The account must be owned by the current program.

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

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

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

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

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

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

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

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

These are lower-level memory-management syscalls that most programs will not need immediately.

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

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

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

  • Call tsys_set_account_data_writable before 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_printf for human-readable debugging and tsys_emit_event for machine-consumed event payloads.

Notes

  • tsys_invoke is 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.