Skip to content

Syscalls

View as Markdown

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

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.

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.

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.

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.

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.

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.

ulong tsys_account_delete( ulong account_idx );

Delete an account. The account must be owned by the current program.

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.

ulong tsys_account_set_flags( ushort account_idx, uchar flags );

Update the account’s flags byte. See Accounts and Transaction Context for flag constants.

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.

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.

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.

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).

ulong tsys_emit_event( void const * data, ulong data_sz );

Emit an event payload that downstream consumers can read from the transaction result.

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.

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

ulong tsys_set_anonymous_segment_sz( void * addr );

Set the anonymous (heap) segment size to addr.

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.

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 );
}
  • 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.
  • 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.