ICAN
We are introducing a standard for regular Core account and contract addresses — ICAN — with HRP and checksum, similar to what we are all using for current financial transactions. ICAN stands for International Crypto Account Number. Only hexadecimal characters are used to minimize the size of the address in blockchain storage.
Abstract
The ICAN facilitates the communication and processing of transactions. It allows exchanging account identification details in a machine-readable form.
Motivation
Finding reliable and financially friendly blockchain addresses for the community. Easy to understand and easy to interpret, but still compatible with modern financial solutions. The checksum is applied in this structure to ensure minimum risk of mistyping the address. ICAN is based on the financial standards that people are using already to simplify the matter for them.
Specification
A regular ICAN address consists of:
- Crypto Identifier - CID (HRP)
- Checksum
- BCAN - Account address (Hexadecimal)
Crypto Identifier (CID)
The Crypto Identifier (human-readable part) uniquely identifies the network. This part must contain 2 hexadecimal characters. In the 22-byte binary address, the two hexadecimal characters encode a one-byte network prefix. Currently unassigned and deleted ISO 3166-1 alpha-2 codes are available.
Checksum
The checksum consists of 2 decimal digits calculated from both CID and BCAN using the ISO 7064 MOD-97-10 algorithm. In the 22-byte binary address, these digits are stored as one packed BCD byte. For example, checksum 54 is stored as 0x54, not as the integer value 54 (0x36).
Why did we choose modulo 97 (IBAN format)?
- This gives us the possibility to detect ~99% of mistakes.
- Easy to process/calculate.
- Well known by financial institutions.
Generation steps:
- Remove spaces and convert CID and BCAN to uppercase.
- Construct
BCAN || CID || "00". - Replace hexadecimal letters with their decimal values:
A = 10,B = 11, ...,F = 15. - Interpret the result as a decimal integer and calculate its remainder modulo 97.
- Subtract the remainder from 98.
- If one digit is returned, prefix it with
0.
Validation steps:
- Remove spaces and convert the complete ICAN to uppercase.
- Move the first four characters (
CID || checksum) to the end. - Replace hexadecimal letters with their decimal values.
- Interpret the result as a decimal integer. The ICAN is valid if its remainder modulo 97 equals 1.
BCAN
BCAN (Basic Crypto Account Number) is the 20-byte raw account or contract identifier, represented by 40 hexadecimal characters.
For an externally owned account, BCAN is derived by applying SHA3-256 to the 57-byte public key and taking the last 20 bytes of the hash:
BCAN = SHA3-256(publicKey)[12:]
Contract BCAN values are produced by the corresponding contract-address derivation scheme rather than from a public key.
Network classification
ISO 3166-1 alpha-2 codes
| CID | Network | Network id |
|---|---|---|
| cb | mainnet | 1 |
| ab | testnet (Devín) | 3 |
| ce | private/enterprise | >3 |
Tickers
Tickers are composed of CID prefixed with the "X" character. They can be suffixed with assets running on the network.
This is a technical recommendation. From the perspective of marketing and usability, the asset can be used without prefix and network.
Example:
XCB XABTKN XCBCTN
Address structure
| Symbol | Explanation |
|---|---|
| n | Digits (numeric characters 0 to 9 only). |
| a | Uppercase letters (alphabetic characters A-Z only). |
| c | Uppercase and lowercase alphanumeric characters (A-Z, a-z, and 0-9). |
| h | Hexadecimal characters (A-F, a-f, 0-9). |
| e | Blank space. |
| k | Check digits. |
| nn! | Fixed length. |
| nn | Maximum length. |
Format
hh!kk!hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh!
Binary representation
A regular ICAN address occupies 22 bytes:
| Byte range | Contents |
|---|---|
0 | One-byte CID/network prefix |
1 | Two decimal checksum digits encoded as BCD |
2..21 | 20-byte BCAN |
System address exceptions
Core also uses raw 22-byte system values, including the real zero address address(0) and precompiled-contract addresses address(1) through address(9). These values do not contain a valid CID and checksum and are not regular ICAN addresses.
The real zero address address(0) is distinct from a checksummed ICAN whose BCAN is zero. The corresponding checksummed zero addresses are CB540000000000000000000000000000000000000000 for mainnet, AB720000000000000000000000000000000000000000 for Devín, and CE450000000000000000000000000000000000000000 for private networks.
Human and machine representation
Human representation has all letters uppercase and each group of 4 characters is divided into spaces. The machine address is composed without any spaces.
Human address example:
AB18 AB12 CD45 EF78 0369 0101 ABAB FFFF 0000 1234 5678
Machine address example:
AB18AB12CD45EF7803690101ABABFFFF000012345678 ab18ab12cd45ef7803690101ababffff000012345678
Note: With QR codes, capital letters in Alphanumeric mode are a must.
Conversion table
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Rationale
We use hexadecimal characters to minimize the size of the addresses in blockchain. The first part — CID — reflects the type of the network to avoid misunderstanding of the type of address. We choose two-digit checksum because it is already in use and it is easier to interpret while delivering the address in several cases. The third part contains the 20-byte raw account or contract identifier. For an externally owned account, it is derived from the last 20 bytes of the SHA3-256 hash of the public key.
Implementation
Validators:
- Golang — go-ican
- JavaScript — ican.js
- Bash — ican-validate.sh
- .Net — IcanNet
- Elixir — ican
Security Considerations
40 characters (20 bytes) of blockchain address.
Why 20 bytes?
- Heuristic aimed to simplify the management of the key; that is, copying and pasting, checksums, or confirmations over the phone in large transfers.
- Pre-empting security mechanisms. Hashing functions are broken every other decade or so, hence cutting the full public key is a great extra layer of defense.
Copyright
Copyright and related rights waived via CC0.