account_delete
Overview
Section titled “Overview”The account_delete syscall truncates account data to zero. For a permanent account with neither NEW nor EPHEMERAL set, it leaves DELETED clear and the account remains live and active. For a NEW or EPHEMERAL account, it also sets DELETED, leaving an inactive corpse that can be revived within the block or removed at block seal.
Creation sets NEW, and block finalization does not clear it. A created account stays in the NEW/corpse class until it has been compressed and decompressed, even if it is deleted much later. Decompression clears NEW, including the runtime’s fee-payer decompression path. Non-NEW accounts include decompressed accounts and genesis accounts provisioned without NEW.
The account must exist, have zero balance and nonce, be writable in the transaction, and be owned by the current program. If it has data, that data must also be writable by the current program.
Syscall Code
Section titled “Syscall Code”Code: 0x06 (TN_SYSCALL_CODE_ACCOUNT_DELETE)
C SDK Function
Section titled “C SDK Function”ulong tsys_account_delete( ulong account_idx, tn_signature_t const * signature );Arguments
Section titled “Arguments”account_idx · ulong · required
Index of the account to delete. Must satisfy the existence, ownership, write-access, zero-balance, and zero-nonce requirements above.
signature · tn_signature_t const * · optional
Pointer to an Ed25519 signature over the canonical delete message, verified against the account’s public key. Pass 0 or NULL for an ordinary program-owned account when no signature is required. The EOA program requires the account keyholder’s signature before deleting an EOA and passes it to this syscall. Supplying a signature does not bypass ownership or write-access checks.
The signed message concatenates the 16-byte ASCII domain tag tn_eoa_delete_v1 (without a terminating NUL), the two-byte little-endian chain ID, the 32-byte fee-payer public key, and the 32-byte account public key.
Return Value
Section titled “Return Value”Returns a syscall result code:
Success · ulong
TN_VM_SYSCALL_SUCCESS(0) - Account data truncated; DELETED set only for NEW or EPHEMERAL accounts
Error Codes · ulong
TN_VM_ERR_SYSCALL_INVALID_ACCOUNT_INDEX(-8) - Account index out of boundsTN_VM_ERR_SYSCALL_ACCOUNT_DOES_NOT_EXIST(-9) - Account does not existTN_VM_ERR_SYSCALL_ACCOUNT_NOT_WRITABLE(-10) - Account not writable by current programTN_VM_ERR_SYSCALL_INVALID_ACCOUNT(-27) - Account has non-zero balance or non-zero nonceTN_VM_ERR_SYSCALL_INVALID_SIGNATURE(-44) - Supplied Ed25519 signature fails verification against the account’s public key
Resource Consumption
Section titled “Resource Consumption”Compute Units
Section titled “Compute Units”- Base cost:
TN_VM_SYSCALL_BASE_COST(512 units) - Additional cost: 146 units when a signature is supplied (64 signature bytes + 82 canonical-message bytes)
- Total cost: 512 units without a signature; 658 units with a signature
Memory Pages
Section titled “Memory Pages”- Page usage: Frees currently allocated account data pages and sets
data_szto zero - Metadata impact: Makes account metadata writable if needed
- Record cleanup: Retains non-NEW, non-EPHEMERAL records; retains deleted-class corpse metadata until revival or block seal
State Counter Impact
Section titled “State Counter Impact”State units are metered from committed account endpoints after execution, not by unconditionally adding metadata and data bytes during this syscall. A truncated permanent account remains active and contributes one state unit. A NEW or EPHEMERAL deleted corpse is inactive and contributes no active state units.
Side Effects
Section titled “Side Effects”- Non-NEW, non-EPHEMERAL accounts: Preserve flags and remain live with empty data
- NEW or EPHEMERAL accounts: Set DELETED and become inactive, non-existing corpses
- Data: Truncate immediately; old data is not available after deletion
- Metadata: Retain the record for non-NEW, non-EPHEMERAL accounts and for corpses awaiting revival or block seal
Usage Notes
Section titled “Usage Notes”- Account balance and nonce must both be zero
- Only the account owner program can call this syscall successfully, with the required transaction and data write access
- A truncated permanent account still exists; creation and decompression at that address return
TN_VM_ERR_SYSCALL_ACCOUNT_ALREADY_EXISTS, subject to their other preconditions - Deletion does not restore an old compressed preimage or make an old proof usable again
- The matching creation syscall can revive a deleted-class corpse at the same address within the block under its normal checks, preserving sequence continuity:
account_createoraccount_create_eoafor a non-ephemeral NEW|DELETED corpse, andaccount_create_ephemeralfor an EPHEMERAL|DELETED corpse. Ephemeral addresses use a different derivation; decompression cannot revive a corpse - Corpses that remain deleted are removed at block seal, not after each transaction
- Legacy plain-DELETED tombstones remain persisted and active for state accounting but do not exist for most account operations; the matching
account_createoraccount_create_eoacall revives one in place without a creation proof, subject to its other checks, and decompression rejects it withTN_VM_ERR_SYSCALL_ACCOUNT_ALREADY_EXISTS. Current permanent deletion does not produce these tombstones
Deletion vs Compression
Section titled “Deletion vs Compression”| Operation | Purpose | Requirements | Effect |
|---|---|---|---|
| Delete non-NEW, non-EPHEMERAL account | Clear account data | Zero balance and nonce, ownership, write access | Truncates data; account remains live and active |
| Delete NEW or EPHEMERAL account (includes created accounts until compressed and decompressed, regardless of age) | Deactivate account | Zero balance and nonce, ownership, write access | Sets DELETED and truncates data; retains corpse until revival or block seal |
| Compress account (normal compression path) | Move account out of active state | State proof and compression eligibility checks | Sets COMPRESSED; removes live record at save time |
Compression of an EPHEMERAL account, or a NEW account with zero balance, nonce, and data size, instead follows the deleted-corpse path. See tsys_account_compress() and the account lifecycle.
Example
Section titled “Example”#include <thru-sdk/c/tn_sdk_syscall.h>
/* Delete or truncate an ordinary program-owned account with zero balance and nonce. The caller must have ownership and write access. Return the syscall result so the caller can handle failure. */ulongtn_example_delete_account( ulong account_idx ) { /* No signature required for an ordinary program-owned account. */ return tsys_account_delete( account_idx, NULL );}