Symbolでアプリを作ったり一歩踏み込んだノード運営しているとよく目につくNetworkTypeという設定値
役割としてはとても単純で、メインネットなのかテストネットなのかを区別するもの
・・・なのですが、気になるのがその中身。
- MAINNET:104
- TESTNET:152
うん、わからん。
何だこの数字?
ちょっと気になるので調べてみよう
今わかってること
- MAINNET:メインネットとして認識される。Nから始まるアドレスが生成される。
- TESTNET:テストネットとして認識される。Tから始まるアドレスが生成される。
もしかして:文字コード説
アドレスの先頭文字を文字コードで表してる説
JavaScriptで検証してみる
// MainNet
String.fromCharCode(104)
// 結果:h
// TestNet
String.fromCharCode(152)
// 結果: \x14(文字化け)
・・・ちがうな
16進数なのかな?
String.fromCharCode(parseInt("0x104",16))
// 'Ą'
String.fromCharCode(parseInt("0x152",16))
// 'Œ'
あー、8進数?
String.fromCharCode(parseInt("0104",8))
// 'D'
String.fromCharCode(parseInt("0152",8))
// 'j'
惜しい気がする。。。
SDKを使って生成してみる
調べるよりもやってみるほうが早いと判断
symbol-sdkを使ってNetworkTypeを0から順に設定してアドレスを生成してみます。
import { Account } from "symbol-sdk";
(() => {
// NetworkType0~256まで生成
for (let i = 0; i < 256; i++) {
const account = Account.generateNewAccount(i);
console.log(`NetworkType: ${i} Address: ${account.address.pretty()}`);
}
})();
結果
NetworkType: 0 Address: AAB3DW-2XZLTF-WYSRZ5-56TLZF-GOZGRX-OAEQGL-PQI
(省略)
NetworkType: 7 Address: A7CCR3-DTLAWV-MOQBKU-XMRTHB-LQF2RO-XYOGRW-5UI
NetworkType: 8 Address: BCKHNV-4EQVHT-2SANTH-S37CXP-RVB5AY-VSTNHM-GXY
(省略)
NetworkType: 15 Address: B4ZMDO-34CH4J-N5XCBY-M35F3E-W5POLV-4SBJZT-KTA
NetworkType: 16 Address: CD7KPJ-OM57H2-ISXZTQ-DDDM4G-ZN6DHD-OD7TK2-IFQ
(省略)
NetworkType: 23 Address: C4ZPGS-PQC3YM-TT63MT-BOSQJA-QTJH4M-ILU3AJ-OZY
NetworkType: 24 Address: DAJH4T-QCK4HJ-VY7EAC-NIOH5V-HK5UBJ-XSZTWN-TTA
(省略)
NetworkType: 31 Address: D4BLKL-TN6S2S-2PKOBV-KQ2MIL-3BRI4C-5T2SWO-BKA
NetworkType: 32 Address: EBQUYU-X33SIH-XO2T6G-UYT6OL-SISBJU-IYIZFS-5JA
(省略)
NetworkType: 103 Address: M6774I-NOGZPY-2UBWHW-D4BSCW-MFV5L5-2MMP2V-F3A
NetworkType: 104 Address: NCLCSU-6LAK4D-KCHN3S-T5KT33-3N5IIY-E2J65I-WEQ // メインネット
NetworkType: 152 Address: TAHOSO-LVGZVD-GAN2NU-UCXEUK-QOLZI4-IA6OJF-PTA // テストネット
(省略)
NetworkType: 207 Address: Z55XIL-LVPYRU-ICGQXG-AEU7ZY-O2NMAX-AMJLBB-J5Q
(省略)
NetworkType: 208 Address: 2C3XJL-G6LHMC-NZVGGM-Q26UHX-WAYONO-O27D55-O2Y
104,152以外でも一応はアドレスが生成できることが判明。
Aから始まって8個同じアドレスで生成したら次はB・・・のように進んでいき、
208以降は数値になることが判明。
メインネットはNで生成されるアドレスの1番目、テストネットはTで生成されるアドレスの1番目に生成されるアドレスの番号であることもわかりました。
SDKの処理を追う
次に、アドレスを生成するロジックを追ってみます。
結論から言うと、addressToStringメソッドの最後のほうでBase32に変換した際にアドレスの最初の文字が確定します。
// 引数decodedにはランダムに生成された公開鍵の値が入っている
// decoded[0]にNetworkTypeで指定した値が入ってる
public static addressToString = (decoded: Uint8Array): string => {
if (RawAddress.constants.sizes.addressDecoded !== decoded.length) {
throw Error(`${Convert.uint8ToHex(decoded)} does not represent a valid decoded address`);
}
const padded = new Uint8Array(RawAddress.constants.sizes.addressDecoded + 1);
padded.set(decoded);
// 下記でUTF32の文字列に変換している
return Base32.Base32Encode(padded).slice(0, -1);
};
Wikipediaによると、以下のように説明されています。
Base32 は 40 ビットを 8 文字に変換するエンコード方式である[1]。Base64 と異なり、大文字、小文字の違いが無視される環境においても正しく処理できる。以下に Base32 で用いる文字を示す。O, I と紛らわしい 0, 1 はない。 -- 引用元:Wikipedia
0~7をBase32形式で表すとAとなるので、NetworkTypeに0を指定するとAから始まるアドレスとなるわけですね。
また、Base32には0,1が存在しないので、207で"Z"を生成した次の208は"2"から始まるアドレスになるわけです。
以下のサイトで数値→Base32への変換ができますので、こちらでも気軽に試せますね。
※試す際はInput typeを"HEX"に設定し、16進数で入力して下さい。
Base32 Encode Online
結論
- NetworkTypeによってアドレスの最初の文字が変わる
- 最初の文字はNetworkTypeに指定した数値をBase32で表したもの
- プライベートチェーンを実装する際は好きな値が設定できる?
- ただし、104,152以外はSDK内で不正なアドレスと判断されエラーとなる可能性もある。
他にもなにか意味があるのかもしれませんが、普段React使ってJSONに色つけてる私ではここまでが限界でしたw
ちょっと疑問に思うことでも追っていくとなかなか面白いですね。