Skip to main content

Overview

The account_create_eoa syscall creates a new Externally Owned Account (EOA) by verifying a cryptographic signature that proves ownership of the accountโ€™s private key.

Syscall Code

Code: 0x0F (TN_SYSCALL_CODE_ACCOUNT_CREATE_EOA)

C SDK Function

ulong tsys_account_create_eoa(ulong account_idx,
                               tn_signature_t const* signature,
                               void const* proof,
                               ulong proof_sz);

Arguments

account_idx
ulong
required
Index of the account slot to create. The accountโ€™s public key address must be specified in the transaction at this index.
signature
tn_signature_t const*
required
Pointer to the Ed25519 signature (64 bytes). The signature must be created by signing the null owner address (32 bytes of zeros) with the private key corresponding to the accountโ€™s public key.
proof
void const*
required
Pointer to the state proof data verifying the account doesnโ€™t exist.
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) - EOA account created successfully
Error Codes
ulong
  • TN_VM_ERR_SYSCALL_INVALID_ACCOUNT_INDEX (-8) - Account index out of bounds
  • TN_VM_ERR_SYSCALL_ACCOUNT_ALREADY_EXISTS (-15) - Account already exists
  • TN_VM_ERR_SYSCALL_INVALID_ADDRESS (-22) - Invalid virtual address for signature or proof
  • TN_VM_ERR_SYSCALL_INVALID_SIGNATURE (-44) - Ed25519 signature verification failed
  • 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

Resource Consumption

Compute Units

  • Base cost: TN_VM_SYSCALL_BASE_COST (512 units)
  • Signature cost: Additional 64 units for signature verification
  • Proof cost: Additional units equal to proof size in bytes
  • Metadata cost: Additional units equal to sizeof(tn_account_meta_t)
  • Total formula: base_cost + 64 + proof_sz + sizeof(tn_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

Side Effects

  • Account creation: Creates a new account with NEW and EOA flags set
  • Ownership: Sets owner to null (00000โ€ฆ) for EOA accounts
  • Account metadata: Initializes writable metadata structure with EOA flag

Signature Verification

The signature verification process:
  1. Reads the Ed25519 signature (64 bytes) from the provided virtual address
  2. Verifies the signature by checking that it was created by signing the null owner address (32 bytes of zeros) with the private key
  3. Uses the accountโ€™s public key from the transaction to verify the signature
  4. The signature proves ownership of the private key corresponding to the account address

Signature Generation

To create a valid signature for EOA account creation:
message = null_owner_address  // 32 bytes of zeros (0x00000...000)
signature = ed25519_sign(private_key, message)
The verification confirms:
ed25519_verify(message=null_owner, signature, public_key=account_address) == SUCCESS

State Proof Requirements

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

EOA Properties

  • Owner: Always set to null address (00000โ€ฆ)
  • EOA Flag: TN_ACCOUNT_FLAG_EOA (0x80) is set
  • NEW Flag: TN_ACCOUNT_FLAG_NEW is set on first creation
  • External control: Account is controlled by the holder of the private key, not by a program

Usage Notes

  • The account address must correspond to the public key from which the signature is derived
  • Signature verification ensures only the private key holder can create the account
  • EOA accounts are distinguished from program-defined accounts by the EOA flag
  • State proof ensures global uniqueness of the address
  • Account is created with zero balance and zero data size

Example

#include "tn_sdk_syscall.h"
#include "tn_sdk_types.h"

// Create EOA for a specific public key address
ulong account_idx = 3;

// Ed25519 signature (64 bytes) - use tn_signature_t type
// The signature MUST be generated by signing the null owner (32 zeros)
tn_signature_t signature;
uchar null_owner[32] = {0}; // 32 bytes of zeros
// signature = ed25519_sign(private_key, null_owner, 32)
// ... populate signature using your Ed25519 signing library ...

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

ulong result = tsys_account_create_eoa(account_idx, &signature,
                                       proof_data, proof_size);

if (result == TN_VM_SYSCALL_SUCCESS) {
    // EOA account created successfully
    // Account has NEW and EOA flags set
    // Owner is null (00000...)
    // Account is controlled by private key holder
}