Chains

Waves

Waves addresses decode to 26 bytes. The validator checks the mainnet byte and checksum.
IDwaves38 / 38waves · WAVES
Chain / Waves

Waves

"waves""Waves""Waves"

Symbol
WAVES · 8 decimals
Coin type
5741564
CAIP-2
waves:087
Checks
address · txid
fields set 6 / 9

Network

CAIP-2waves:087
Magicnone
PoWnone
RPCnodes.wavesnodes.com
Explorerwavesexplorer.com

Access

Createcreate("waves")
ResolvegetChain("Waves")
CLIchains info Waves
Tryplayground with a sample address

Waves address format

What's under a Waves address? Base58 hides 26 bytes, using the Bitcoin alphabet.

  • One entity type byte, set to 1.
  • One chain ID byte.
  • A 20-byte account public key hash.
  • A 4-byte checksum.

The public key hash is the first 20 bytes of Keccak256(Blake2b256(publicKey)). Waves uses original Keccak-256, not FIPS SHA3-256. The address binary format documents the layout.

The check decodes base58, with a limit of 36 characters. It checks the byte count, entity type, mainnet byte and checksum. It reports every broken rule together. A length window would be a fragile substitute.

It doesn't check whether the account exists. The address contains a public key hash, not the public key. Transaction recipients can also use aliases such as alias:W:name. Those aren't addresses and the check refuses them.

ts
import { getChain } from "@agntn/chains";

const chain = getChain("waves");
chain.assertAddress("3PPbMwqLtwBGcJrTA5whqJfY95GqnNnFMDX"); // returned unchanged
chain.caip2; // "waves:087"
chain.bip44; // 5741564

That address is a documented Waves test vector. Its public key is HBqhfdFASRQ5eBBpu2y6c6KKi1az6bMx8v1JxX4iW1Q8. decodeAddress returns { kind: "account" }.

Waves has 8 decimals. One WAVES is 100,000,000 wavelets.

Why mainnet addresses start with 3P

Every mainnet address carries byte 87, ASCII W. That makes every mainnet address start with 3P.

Testnet uses byte 84, ASCII T. Its addresses start with 3M or 3N. Stagenet uses byte 83, ASCII S. Its addresses start with 3M. Both networks are refused.

For example, 3N9Q2sdkkhAnbR4XCveuRaSMLiVtvebZ3wp fails with chain byte "T", Waves testnet, where mainnet writes "W".

The CAIP-2 ID is waves:087. The namespace writes the chain byte as a padded signed integer.

Waves checksum and Base58Check

The checksum covers the first 22 bytes. It's the first four bytes of Keccak256(Blake2b256(first 22 bytes)). Two different hashes for four bytes. Fair enough.

This isn't Base58Check. Base58Check runs one hash twice. Waves stacks two different hashes once. The Waves class computes its checksum itself.

Change the last character and the checksum fails. The reason says the checksum does not hold, so a character is wrong.

Identifying a Waves address

What about 3PBitcoinAVGJvpSe6jevepPbT3M8SoMZjb? It's a real Waves mainnet sender. identify returns Waves alone, with the key waves. The Bitcoin validator refuses it. The name inside the address doesn't get a vote.

Waves transaction IDs

Transaction IDs are base58 decoded to 32 or 64 bytes. Other widths fail.

A 32-byte ID is a hash, such as kD9ahh6vk5AQKQnnAGW797Qxwadidzf6Jty6r4imDQX.

Why accept 64 bytes? Genesis and payment transactions, the oldest kinds Waves has, still use their signatures as IDs. The first genesis transaction is 2DVtfgXjpMeFf2PQCqvwxAiaGbiDsxDjSdNQkc5JQ74eWxjWFYgwvqzC4dn7iB1AhuM32WxEiVi1SGijsBtYQwn8. The node's TransactionId path reads exactly these two widths.

Waves chain spellings

Use waves or Waves with getChain. Case doesn't matter. There are no other aliases.