Conflux 網路地址介紹

Conflux中文社群發表於2021-12-16

Conflux 最初使用同以太坊一樣的 hex40 格式地址,但對地址首位做了限制,只有 0x0, 0x1, 0x8 三種字首的地址是合法的,並且這三種字首可用於區分地址的型別:

  • 0x0 內建合約地址
  • 0x1 普通外部賬戶地址
  • 0x8 合約地址

但由於地址格式類似,又不能完全互相使用(因為Conflux限制了固定的字首),導致極易與以太坊地址混用,進而導致資產丟失。為了解決此問題,Conflux 通過CIP-37 引入了新的 Base32 格式的地址。
本文將對 Conflux 地址做一個詳細介紹。

以太坊 hex40 地址

以太坊賬戶私鑰是一個 256 位的字串(32 位元組),通常是隨機生成。

18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725

然後通過橢圓曲線演算法計算得到私鑰對應的 X 和 Y 值。04 + X + Y 即為公鑰(65位元組)

04
50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352
2cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6

最後對公鑰(不包含04字首)進行 Keccak-256 計算得到雜湊值,取最後 20 位元組作為以太坊地址

1016f75c54c607f082ae6b0881fac0abeda21781

即 0x1016f75c54c607f082ae6b0881fac0abeda21781

image.png

並且以太坊通過EIP-55引入了一個帶校驗的地址格式,它的實現非常簡單,即對地址做一個keccak256雜湊,然後按位對齊,將雜湊值>=8的字母變成大寫:

image.png

需要注意的是在 Solidity 智慧合約中,要求必須使用 checkSum 格式地址

Conflux Base32 地址

Conflux 的地址生成規則同以太坊一樣,只是地址生成後強制將地址首位換成了 0x1

  • 0x7defad05b632ba2cef7ea20731021657e20a7596
  • 0x1defad05b632ba2cef7ea20731021657e20a7596

然後對 0x1 開頭的地址進行 base32 編碼,得到 Conflux 目前使用的 base32 格式地址:

cfx:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg

兩種格式的地址只是編碼方式不同,但所表達的資訊相同,可以互相轉換

具體編碼規則

編碼使用32個字元:abcdefghjkmnprstuvwxyz0123456789 (i, l, o, q removed)

網路字首

根據 networkId 確定網路字首:

  • 1: cfxtest
  • 1029: cfx
  • N: netN

payload

使用固定的 0 作為 version byte, 然後加上 hex40 地址的 byte 資料,構造為 payload,然後對 payload 進行 base32 編碼。

checksum

構造計算 checksum 的 data:

  • 網路字首每個字元的低 5 位. "cfx..." 對應 0x03, 0x06, 0x18, ...
  • 一個 0 (5 個 0 bit) 作為連線符
  • payload
  • 8 個 0 (作為 checksum 的 template)

使用如下方法計算得到一個 40 bit 的數字,轉換為 8 個 base32 字元作為 checksum

uint64_t PolyMod(const data &v) {
    uint64_t c = 1;
    for (uint8_t d : v) {
        uint8_t c0 = c >> 35;
        c = ((c & 0x07ffffffff) << 5) ^ d;

        if (c0 & 0x01) c ^= 0x98f2bc8e61;
        if (c0 & 0x02) c ^= 0x79b76d99e2;
        if (c0 & 0x04) c ^= 0xf33e5fb3c4;
        if (c0 & 0x08) c ^= 0xae2eabe2a8;
        if (c0 & 0x10) c ^= 0x1e4f43e470;
    }
    return c ^ 1;
}

最終將所有資料連線到一起:

netprefix + ":" + payload + checksum

可選的地址型別資訊

base32 地址中可以包含一個可選的地址型別資訊, 該資訊不參與 checksum 計算,地址型別有如下四種:

  • type.contract 普通合約
  • type.user 普通使用者
  • type.builtin - 內建合約
  • type.null 零地址型別

通常帶型別資訊的地址使用大寫字母表示

CFX:TYPE.USER:AAKPBX01FZM1XP89CB7URF6YVYXH3GGX5E9HZ07B38

具體的地址規範參看 CIP-37規範

Base32 使用場景

Conflux-rustv1.1.1 開始所有涉及到地址的 RPC 方法均只接受 base32 格式地址,Portal 也同步進行了升級預設顯示和接受新格式的地址。主要場景均需使用新地址:

  • RPC 互動
  • 錢包轉賬
  • 使用 SDK 開發應用

目前只有一種場景需要使用 hex40 checksum 格式地址,即是在開發 Solidity 智慧合約時,在 Solidity 程式碼中只能使用 hex40 checksum 地址(受 Solidity 編譯器限制)

另外在跟合約方法進行互動時,涉及到傳參或返回結果的地方,本質也要求使用 ABI 編碼的 hex40 地址。但使用 Conflux 的 SDK 進行互動時,SDK 會自動進行地址格式轉換,因此可以說此種場景也是使用 base32 格式地址。

SDK address 方法 和 Scan 地址轉換工具

Conflux 各語言 SDK 均提供了兩種格式地址的轉換方法。官方開發的 JS, Go, Java, Python 語言 SDK,以及社群開發的 C++ SDK 等。
以 js-sdk 為例:

const {format} = require('js-conflux-sdk');

const hexAddress = "0x12c0ced72d5579b3df107b0697948d267c98d3d9";
const base32Address = "cfx:aakpbx01fzm1xp89cb7urf6yvyxh3ggx5e9hz07b38";
const netId = 1029;

// hex to base32
format.address(hexAddress, netId);
// cfx:aakpbx01fzm1xp89cb7urf6yvyxh3ggx5e9hz07b38
format.hexAddress(base32Address);
// 0x12c0ced72d5579b3df107b0697948d267c98d3d9

另外 JS-SDK 還提供了多個地址相關的 utilities 方法

const {address} = require('js-conflux-sdk');
/*
{
  encodeCfxAddress: [Function: encode],
  decodeCfxAddress: [Function: decode],
  ethChecksumAddress: [Function: ethChecksumAddress],
  ethAddressToCfxAddress: [Function: ethAddressToCfxAddress],
  ADDRESS_TYPES: {
    USER: 'user',
    CONTRACT: 'contract',
    BUILTIN: 'builtin',
    NULL: 'null'
  },
  isValidCfxAddress: [Function: isValidCfxAddress],
  verifyCfxAddress: [Function: verifyCfxAddress],
  hasNetworkPrefix: [Function: hasNetworkPrefix],
  simplifyCfxAddress: [Function: simplifyCfxAddress],
  shortenCfxAddress: [Function: shortenCfxAddress],
  isZeroAddress: [Function: isZeroAddress],
  isInternalContractAddress: [Function: isInternalContractAddress],
  isValidHexAddress: [Function: isValidHexAddress],
  isValidCfxHexAddress: [Function: isValidCfxHexAddress]
}
*/

address.encodeCfxAddress(hexAddress, netId, true);
// CFX:TYPE.USER:AAKPBX01FZM1XP89CB7URF6YVYXH3GGX5E9HZ07B38
address.decodeCfxAddress(base32Address);
/*
{
  hexAddress: <Buffer 12 c0 ce d7 2d 55 79 b3 df 10 7b 06 97 94 8d 26 7c 98 d3 d9>,
  netId: 1029,
  type: 'user'
}
*/

除此之外在 Scan 瀏覽器上面,也提供了一個地址轉換工具,方便兩種格式地址互相轉換

image.png

bip44 coin number

Conflux 同以太坊,比特幣一樣也遵循 bip32, bip44, bip39 所引進的賬戶體系。即可以使用助記詞生成 HD 錢包。

例如以太坊的錢包派生路徑為: m/44'/60'/0'/0/0 這裡 60 是 ETH 的 coin 編碼。

Conflux 的 Coin 編碼是 503, 其派生路徑為: m/44'/503'/0'/0/0

0x1 相容地址生成工具

目前以太坊網路中只有以 0x1 開頭的地址也能在 Conflux 網路中使用,如果想一個地址在兩個網路使用,可以嘗試生成一些 0x1 開頭的地址。可以使用 js-conflux-sdk 中的 cli 工具 cfxjs 來生成:

$ npx cfxjs genEthCMPTaccount  
PrivateKey:  0x6c6faf9644eafe16211ad6a222f7e2a22eb3b10f3145a6226ef0b4c9ef618413
Address:  0x15d4b49ffd7a75a86901cdfce54d85548d3698dd

另外還有一個網頁工具,可以從助記詞中快速查詢一個 0x1 賬號的索引和私鑰。安全起見使用時請斷網並開啟隱私模式.

image.png

相關文章