In this document we define the Multi-chain account id. It is a compactly encoded account identifier that is blockchain agnostic.
mcai ::= <multibase_prefix><mcai_code><chain_namespace><id_size><chain_id><address_size><address><parity_byte>
where,
multibase_prefix
- the prefix which defines which multibase is used to encode the bytes, z
for base58btc
mcai_code
- a number registered on the multicodec table, makes the multi-chain account id upgradable, encoded as varintchain_namespace
- see table below, encoded as varintid_size
- the length in bytes of the chain_id
, encoded as varintchain_id
- the chain id, encoding is defined by the chain namespaceaddress_size
- the length of the address, encoded as varintaddress
- the address itself, encoding is defined by the chain namespaceparity_byte
- a checksum byte, see section belowShould be a number registered on the multicodec table. In the examples below we use 0xCA
but this is subject to change.
Each blockchain namespace needs to be properly defined.
Namespace | code |
---|---|
bip122 | 0x00 |
eip155 | 0x01 |
cosmos | 0x02 |
polkadot | 0x03 |
filecoin | 0x04 |
Chain ID: Convert from hex to bytes
Address: Convert from base58btc to bytes
In the exammple below we encode 128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6
on bitcoin mainnet.
This means that we use chain_id = 000000000019d6689c085ae165831e93
zEbYEtEFFMZvVzJK3AWU5R5egEj1ep1yMVEWiWJ2FARDz
Chain ID: Convert from integer to bytes
Address: Convert from hex to bytes
In the exammple below we encode 0xde30da39c46104798bb5aa3fe8b9e0e1f348163f
on ethereum mainnet.
This means that we use chain_id = 1
zUJWDxUnc8pZCfUtVKcAsRgxijaVqHyuMgeKKF
Using the algorithm described on Wikipedia: checksums. XOR each byte word in the mcai, the resulting byte is the parity byte.
We could easily build tools and UIs that decompose the encoded mcai similar to this: https://cid.ipfs.io/#bagcqcera6wh5laey5njuo2weun46wv4cn2jlbn6qio6mt3bwian4kbp76tdq
Below is a PoC implementation in javascript
const varint = require('varint')
const u8a = require('uint8arrays')
const mcai_code = 0xca
const namespaces = {
bip122: 0x00,
eip155: 0x01,
cosmos: 0x02,
polkadot: 0x03,
filecoin: 0x04
}
function checksum(bytes) {
let result = u8a.xor([bytes[0]], [bytes[1]])
for (let i = 2; i < bytes.length; i++) {
result = u8a.xor(result, [bytes[i]])
}
return result
}
function encodeMCAI(namespace, chain_id, address) {
const bytes = u8a.concat([
varint.encode(mcai_code),
Uint8Array.from([namespace]),
varint.encode(1), // chain_id below is just one byte
Uint8Array.from([chain_id]),
varint.encode(address.length),
address
])
const checksummedBytes = u8a.concat([bytes, checksum(bytes)])
return 'z' + u8a.toString(checksummedBytes, 'base58btc')
}
function encodeBtcMainnet() {
const chain_id = '000000000019d6689c085ae165831e93'
const chain_id_bytes = u8a.fromString(chain_id, 'base16')
const address = '128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6'
const address_bytes = u8a.fromString(address, 'base58btc')
return encodeMCAI(namespaces['bip122'], chain_id_bytes, address_bytes)
}
function encodeEthMainnet() {
const chain_id = 0x01
const address = '0xde30da39c46104798bb5aa3fe8b9e0e1f348163f'
const address_bytes = u8a.fromString(address.slice(2), 'base16')
return encodeMCAI(namespaces['eip155'], chain_id, address_bytes)
}
console.log('btc mainnet:', encodeBtcMainnet())
console.log('eth mainnet:', encodeEthMainnet())
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing