Skip to main content

Overview

The account_create syscall creates a new permanent account using a program-defined address derived from a seed. The account creation requires a state proof to verify the address doesn’t already exist in the global state.

Syscall Code

Code: 0x04 (TN_SYSCALL_CODE_ACCOUNT_CREATE)

C SDK Function

ulong tsys_account_create( ulong account_idx, uchar const seed[TN_SEED_SIZE],
                           void const * proof, ulong proof_sz );

Arguments

account_idx
ulong
required
Index of the account slot to create. Must be writable in the transaction and currently non-existent.
seed
uchar const[TN_SEED_SIZE]
required
Fixed 32-byte seed used for address derivation.
proof
void const*
required
Pointer to the state proof data.
proof_sz
ulong
required
Size of the state proof data in bytes.

Return Value

Returns a syscall result code:
Success
ulong
  • TN_VM_SYSCALL_SUCCESS (0) - Account created successfully
Error Codes
ulong
  • TN_VM_ERR_SYSCALL_INVALID_ACCOUNT_INDEX (-8) - Account index out of bounds
  • TN_VM_ERR_SYSCALL_ACCOUNT_NOT_WRITABLE (-10) - Account not writable in transaction
  • TN_VM_ERR_SYSCALL_ACCOUNT_ALREADY_EXISTS (-15) - Account already exists
  • TN_VM_ERR_SYSCALL_INVALID_ADDRESS (-22) - Invalid virtual address for seed or proof
  • TN_VM_ERR_SYSCALL_BAD_ACCOUNT_ADDRESS (-16) - Computed address doesn’t match expected
  • TN_VM_ERR_SYSCALL_INVALID_PROOF_LEN (-32) - Proof size mismatch
  • TN_VM_ERR_SYSCALL_INVALID_PROOF_SLOT (-33) - Proof references invalid block slot
  • TN_VM_ERR_SYSCALL_INVALID_STATE_PROOF (-23) - State proof verification failed
  • TN_VM_ERR_SYSCALL_EPHEMERAL_ACCOUNT_CANNOT_CREATE_PERSISTENT (-42) - Ephemeral account cannot create persistent account
  • TN_VM_ERR_SYSCALL_STATE_BYTES_ADDED_OVERFLOW (-47) - State bytes counter overflow during activation

Resource Consumption

Compute Units

  • Base cost: TN_VM_SYSCALL_BASE_COST (512 units)
  • Seed cost: Additional units equal to TN_SEED_SIZE bytes
  • Proof cost: Additional units equal to proof size in bytes
  • Metadata cost: Additional units equal to sizeof(tsdk_account_meta_t)
  • Total formula: base_cost + TN_SEED_SIZE + proof_sz + sizeof(tsdk_account_meta_t)

Memory Pages

  • Page usage: No direct page allocation (account data starts at size 0)
  • Metadata pages: Allocates pages for account metadata structure
  • State proof validation: Temporary memory usage for proof verification

State Counter Impact

  • GASC (Global Activated State Counter): Incremented by TSDK_ACCOUNT_META_FOOTPRINT bytes
  • Purpose: Tracks activated state for the account creation in the global state counter
  • Overflow protection: Returns TN_VM_ERR_SYSCALL_STATE_BYTES_ADDED_OVERFLOW if counter would overflow

Side Effects

  • Account creation: Creates a new account with NEW flag set
  • Ownership: Sets the current program as the account owner
  • Account metadata: Initializes writable metadata structure

Address Derivation

The account address is computed as:
SHA256(current_program_pubkey || is_ephemeral(0) || seed)

State Proof Requirements

  • New accounts: Requires a creation-type state proof showing the address doesn’t exist
  • Deleted accounts: Can recreate without proof (removes DELETED flag)
  • Proof verification: Must reference a valid block slot and verify against state root

Usage Notes

  • The computed account address must match the transaction’s expected address
  • Seed must be exactly TN_SEED_SIZE (32 bytes)
  • State proof ensures global uniqueness of the address
  • Created accounts are owned by the calling program
  • Account is implicitly marked as writable by the creating program

Example

#include <thru-sdk/c/tn_sdk_syscall.h>
#include <string.h>

// Create account with seed "my_account"
ulong account_idx = 5;
uchar seed[TN_SEED_SIZE] = { 0 };
memcpy( seed, "my_account", 10 );

// Prepare state proof data
uchar proof_data[1024];
ulong proof_size = prepare_creation_proof(proof_data);

ulong result = tsys_account_create( account_idx, seed, proof_data, proof_size );

if (result == TN_VM_SYSCALL_SUCCESS) {
    // Account created successfully
    // Account is owned by current program
    // Account has NEW flag set
}