Accounts & Keys
Every identifier on æternity carries a two-letter prefix that says what it is: a token sale
address is a ct_, a wallet is an ak_, a trade receipt is a th_.
Address prefixes
Identifiers are a raw byte array, base-encoded, with a prefix describing what the bytes are. Base58 with a checksum is used for short identifiers meant to be read and pasted; base64 for longer binary payloads.
Base58: the ones you paste
| Prefix | What it identifies | Where it shows up in Superhero |
|---|---|---|
ak_ | Account public key | Wallets, post authors, token holders, tip recipients |
ct_ | Contract public key | Token sale addresses, DAO addresses, the Tipping contract |
th_ | Transaction hash | Trade and post receipts; what you paste into an explorer |
kh_ | Key-block hash | Block references in explorer links |
mh_ | Micro-block hash | Block references in explorer links |
sg_ | Signature | Delegated-posting payloads, address-link claims |
nm_ | Name (AENS) | The on-chain object behind a .chain name |
cm_ | Commitment | The salted preclaim hash in AENS registration |
ok_ | Oracle public key | Not used by Superhero |
oq_ | Oracle query id | Not used by Superhero |
ch_ | Channel id | State channels; not used by Superhero |
pp_ | Peer public key | Node-to-node networking; never user-facing |
Base64: the ones that appear in payloads
| Prefix | What it identifies |
|---|---|
cb_ | Contract byte array (compiled bytecode, call data) |
tx_ | Serialised transaction |
st_ | State |
ss_ | State trees |
pi_ | Proof of inclusion |
ov_ | Oracle query |
or_ | Oracle response |
The full list is in the protocol's API encoding spec, linked below.
What Superhero accepts as input
When you paste an identifier into Superhero, it accepts ak_, ct_, nm_, th_ and ok_
and links each to the matching explorer page. A string ending in .chain is treated as a name
and passes without a prefix check. Other prefixes are not accepted as input.
Keys
æternity accounts are Ed25519 keypairs. The public key, base58-encoded with a checksum and the
ak_ prefix, is the address. There is no account-creation transaction, and an address is
valid the moment you generate the key. The same keypair signs delegated-posting messages, which
contracts verify with Crypto.verify_sig.
Secret-key encoding
Superhero's tooling uses @aeternity/aepp-sdk v14. From v14, MemoryAccount takes the secret
key as an sk_-prefixed encoded 32-byte secret, not raw hex. The web app's built-in wallet
normalises older persisted values (raw hex, or a longer keypair payload) by taking the first
32 bytes and encoding them as sk_. The agent skill does not: it passes AE_PRIVATE_KEY straight
to new MemoryAccount(privateKey), so give it the sk_ form.
# Generates a v14-shaped keypair and prints the sk_ secret once
node scripts/superhero-wallet.mjs generate
# What every other script reads
export AE_PRIVATE_KEY=sk_...
node scripts/superhero-wallet.mjs addressDerivation from a mnemonic
æternity's coin type in SLIP-0044 is 457, and AEX-10 standardises the derivation path for
deterministic æternity wallets as m/44'/457'/account'/0'/address_index'.
Superhero's built-in wallet, the Superhero browser extension and the mobile wallet all derive
m/44'/457'/index'/0'/0' with SLIP-0010 for Ed25519, through the SDK's AccountMnemonicFactory.
The account index varies; change and address index are pinned to 0'. The same mnemonic and
index therefore produce the same address in every Superhero wallet.
import { AccountMnemonicFactory } from '@aeternity/aepp-sdk';
const account = new AccountMnemonicFactory(mnemonic).initializeSync(index);
console.log(account.address); // ak_...Use the SDK's factory rather than reimplementing BIP32 or SLIP-0010 by hand. BIP32 was written for secp256k1 and does not apply unchanged to Ed25519. See Backup & recovery and Built-in wallet.
Practical rules
- Never truncate an address before comparing it. Superhero shortens addresses for display only, in the middle.
ct_addresses are case-sensitive base58. Uppercasing a sale address corrupts it; token symbols, by contrast, are uppercased for lookup.- A
.chainname is not an address. Resolve it to anak_through AENS before using it in a transaction. See AENS.
Related
- AENS: how
nm_andcm_come into existence, and how names resolve toak_. - Wallet & keys for agents: generating and storing
AE_PRIVATE_KEYfor the agent skill. - Wallet security: how to hold a key you care about.
- Explorers: where each prefix takes you on æScan.
- æternity API encoding spec (opens in a new tab): the authoritative list of every prefix and its base encoding.
- æternity JavaScript SDK quick start (opens in a new tab): creating an account and signing with the v14 SDK.