Skip to main content
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

StepWhat normally happens
EnterThe VM jumps to a function marked with TSDK_ENTRYPOINT_FN.
Read inputsThe program reads transaction and account context through helpers like tsdk_get_txn, tsdk_get_account_meta, and tsdk_get_account_data_ptr.
DecodeInstruction bytes are read from the transaction body, usually through tsdk_txn_get_instr_data and tsdk_txn_get_instr_data_sz.
ValidatePrograms check instruction size, account indices, ownership, authorization, and any variable-length payload boundaries before mutating state.
Mutate or invokePrograms call syscalls such as tsys_account_resize, tsys_account_transfer, or tsys_invoke.
ExitPrograms terminate with tsdk_return(...) for success or tsdk_revert(...) for failure.
FilePurpose
your_program.hInstruction tags, error codes, packed payload structs, account-data structs, and local constants.
your_program.cEntry 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

GoalCommon choice
Small fixed instructionOne packed struct with a leading tag.
Variable-length instructionFixed header plus byte tail, with explicit size checks before casting or copying.
Stateful programOne or more packed account-data structs plus helper functions to read and write them.
CPI-heavy programEntry 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.