Documentation Index
Fetch the complete documentation index at: https://docs.thru.org/llms.txt
Use this file to discover all available pages before exploring further.
Use this page when you need the smallest reliable mental model for how a C program starts, reads input, mutates state, and exits.
Minimal program shape
#include <thru-sdk/c/tn_sdk.h>
TSDK_ENTRYPOINT_FN void
start( void ) {
tsdk_txn_t const * txn = tsdk_get_txn( );
if( tsdk_txn_get_instr_data_sz( txn ) == 0UL ) {
tsdk_revert( 1UL );
}
tsdk_return( TSDK_SUCCESS );
}
Execution model
| Step | What normally happens |
|---|
| Enter | The VM jumps to a function marked with TSDK_ENTRYPOINT_FN. |
| Read inputs | The program reads transaction and account context through helpers like tsdk_get_txn, tsdk_get_account_meta, and tsdk_get_account_data_ptr. |
| Decode | Instruction bytes are read from the transaction body, usually through tsdk_txn_get_instr_data and tsdk_txn_get_instr_data_sz. |
| Validate | Programs check instruction size, account indices, ownership, authorization, and any variable-length payload boundaries before mutating state. |
| Mutate or invoke | Programs call syscalls such as tsys_account_resize, tsys_account_transfer, or tsys_invoke. |
| Exit | Programs terminate with tsdk_return(...) for success or tsdk_revert(...) for failure. |
Recommended file split
| File | Purpose |
|---|
your_program.h | Instruction tags, error codes, packed payload structs, account-data structs, and local constants. |
your_program.c | Entry point, validation, instruction dispatch, syscall usage, and local helper functions. |
This split keeps payload layout definitions easy to reuse without forcing an agent to reread the whole implementation file.
Typical instruction dispatch pattern
#include <thru-sdk/c/tn_sdk.h>
typedef struct __attribute__(( packed )) {
uint instruction_type;
} my_instr_hdr_t;
TSDK_ENTRYPOINT_FN void
start( void ) {
tsdk_txn_t const * txn = tsdk_get_txn( );
uchar const * instr = tsdk_txn_get_instr_data( txn );
ulong instr_sz = tsdk_txn_get_instr_data_sz( txn );
if( instr_sz < sizeof( my_instr_hdr_t ) ) tsdk_revert( 0x1000UL );
my_instr_hdr_t const * hdr = (my_instr_hdr_t const *)instr;
switch( hdr->instruction_type ) {
case 0U:
/* handle create */
break;
case 1U:
/* handle update */
break;
default:
tsdk_revert( 0x1001UL );
}
tsdk_return( TSDK_SUCCESS );
}
Control-flow rules
tsdk_return does not come back.
tsdk_revert does not come back.
tsys_exit underlies both helpers and is also terminal.
- If you need cleanup, do it before calling either exit helper.
Common structure choices
| Goal | Common choice |
|---|
| Small fixed instruction | One packed struct with a leading tag. |
| Variable-length instruction | Fixed header plus byte tail, with explicit size checks before casting or copying. |
| Stateful program | One or more packed account-data structs plus helper functions to read and write them. |
| CPI-heavy program | Entry point plus small helpers to build invoke payloads and auth descriptors. |
Notes
- Prefer
tsdk_get_txn() as the root of most program reads.
- Prefer a local header for your instruction/account layouts so the implementation page can stay focused on logic.
- Keep the entrypoint thin: validate, dispatch, return.