Skip to main content
CKB scripts (smart contracts) for stealth address operations on the Nervos CKB network. Written in Rust and compiled to RISC-V binaries that run on CKB-VM.

The Cell Model — Why CKB Is Different

CKB uses a UTXO-based Cell model, not accounts. Every piece of on-chain state is a Cell:

No Separate Announcer

On EVM chains, stealth payments require two operations: transfer funds and emit an announcement event. On CKB, the Cell itself is the announcement. The lock script args contain both the ephemeral public key and the stealth address hash:
This 53-byte args field serves as both the lock condition and the announcement. No separate contract call, no event indexing infrastructure — just create a Cell and the recipient can find it.

Scanning = Querying Cells

CKB has a built-in indexer with an RPC method get_cells that filters by lock script code hash. To scan for incoming payments, query all live Cells using the stealth-lock code hash. Each Cell’s args contains the ephemeral key needed for the ECDH check.

Spending = Consuming Cells

To withdraw funds, build a transaction that:
  1. Inputs: The stealth Cell being consumed
  2. Outputs: A new Cell at the destination address
  3. Witness: secp256k1 signature with the stealth private key
The stealth lock script verifies the signature against the pubkey hash in the args.

Script Set

wraith-stealth-lock handles stealth payments. wraith-names-type handles .wraith name registration.

wraith-stealth-lock

A lock script that verifies secp256k1 signatures against the stealth public key hash embedded in the script args.

Args Format

53 bytes total:

Verification Flow

The script uses ckb-std crypto syscalls or ckb-auth for secp256k1 signature recovery and verification.

blake160

CKB’s standard address hashing:
The "ckb-default-hash" personalization is required. Without it, hashes won’t match CKB’s standard address format.

How It Differs from Standard CKB Locks

CKB’s default lock script (secp256k1-blake160-sighash-all) uses 20-byte blake160 args containing the owner’s pubkey hash. The stealth lock extends this to 53 bytes by prepending the ephemeral public key. The verification logic is the same — recover the public key from the signature and check the blake160 hash.

Usage


wraith-names-type

A Type Script for .wraith name registration on CKB. Each name is stored as a live Cell. The type script validates creation, update, and destruction of name Cells.

Deployed Code Hash

Cell Dep

Cell Layout

A .wraith name Cell has three meaningful fields: The type script args uniquely identify the name. Two Cells cannot have the same type script (same code hash + same args) because the type script enforces uniqueness at creation time.

How It Works

The type script runs on every transaction that creates, updates, or destroys a name Cell. It inspects the transaction’s inputs and outputs to determine the operation:
  • Create: The type script appears in an output but not in any input. A new name is being registered.
  • Update: The type script appears in both an input and an output. The name’s data is being changed.
  • Destroy: The type script appears in an input but not in any output. The name is being released.

Validation Rules

Data must be exactly 66 bytes. The data field holds two 33-byte compressed secp256k1 public keys (spending + viewing). The type script rejects any Cell with data that is not exactly 66 bytes. This applies to both creation and update. Create: When a new name Cell is created, the type script verifies:
  1. No existing live Cell has the same type script (same code hash and args). CKB enforces this natively — two live Cells cannot share the same type script.
  2. The output data is exactly 66 bytes.
Update: When a name Cell is consumed and recreated in the same transaction:
  1. The new output data must be exactly 66 bytes.
  2. The lock script on the input Cell must be satisfied (the owner authorized the transaction).
Destroy: When a name Cell is consumed without being recreated:
  1. The lock script on the input Cell must be satisfied (the owner authorized the destruction).
  2. No further validation — the name is released and can be re-registered.

Ownership Model

On EVM and Solana, name ownership is proven by a signature from the spending key embedded in the meta-address. The contract verifies this signature on every register/update/release call. On CKB, ownership is proven by the Cell’s lock script. The lock script determines who can spend (consume) the Cell. This is more flexible:
  • A standard secp256k1 lock means a single key controls the name.
  • A multisig lock means multiple parties must agree to update or transfer the name.
  • Any custom lock script can control a name.
To transfer a name, consume the name Cell and create a new one with the same type script but a different lock script. The new lock script’s owner now controls the name.

Verification Flow

Usage


Project Structure

Deployment

Build

Compile to RISC-V binary:

Deploy

Deploy the compiled binary as a Cell on CKB testnet. The Cell’s data hash becomes the code_hash used in stealth lock scripts.

Record Deployment Info

After deployment, record:
  • Code hash: The blake2b hash of the deployed binary (used as lock.code_hash in stealth Cells)
  • Cell dep: The transaction hash and index where the script binary Cell lives (required in every transaction that uses the lock)
Update the SDK’s deployments.ts:

Testing

Tests use CKB’s native testing framework with ckb-testtool: wraith-stealth-lock:
  • Args validation — rejects args that aren’t exactly 53 bytes
  • Signature verification — valid stealth key signature passes
  • Wrong key rejection — signature from a different key fails
  • blake160 correctness — hash matches CKB’s standard implementation
wraith-names-type:
  • Data validation — rejects data that isn’t exactly 66 bytes
  • Create — allows creating a name Cell with valid 66-byte data
  • Update — allows updating data when the owner’s lock is satisfied
  • Destroy — allows destroying a name Cell when the owner’s lock is satisfied
  • Invalid data on create — rejects Cell creation with wrong data length
  • Invalid data on update — rejects Cell update with wrong data length

Differences from Other Chains

The key architectural difference: CKB needs only two scripts to support stealth payments and names. The stealth lock handles payments (announcements are implicit in the Cell), and the names type script handles .wraith name registration. Other chains need 3-4 separate contracts for the same functionality.