今回はSymbol from NEM やmijin Catapult で使用するアカウント関連情報のまとめです。
秘密鍵、公開鍵、アドレスなどの生成、QRコード、ニーモニックなどアカウントを管理するための方法について説明します。
事前準備
必要なもの
インターネット接続環境
Google Chromeブラウザ
使用するツール・ライブラリ
symbol-sdk-typescript-javascript
symbol-qr-library
symbol-hd-wallets
nemtechレポジトリが公開している上記ライブラリをbrowserify化した
symbol-sdk-pack-1.0.0.jsを使用します。
開発者コンソール起動とsymbol-sdkの準備
開発者コンソールの起動
Google Chrome ブラウザを起動しノードにアクセスしてF12キーを押して開発者コンソールを開きます。
私の検証用ノードです(メインネット)
設定値の定義とライブラリの埋め込み
コンソールに以下のスクリプトをコピーして貼り付けます。
NODE = window.origin;
(script = document.createElement('script')).src = 'https://xembook.github.io/nem2-browserify/symbol-sdk-pack-1.0.0.js';
document.getElementsByTagName('head')[0].appendChild(script);
- NODE
- 接続するノードのURL
- script
- browserify化したsymbol-sdkを読み込むスクリプトタグを表示中のページに埋め込みます
スクリプトタグが無事に埋め込まれました。
このようにコンソールには最後に実行されたコマンドの結果が出力されるようになっています。
ライブラリのインポート
nem = require("/node_modules/symbol-sdk");
qr = require("/node_modules/symbol-qr-library");
hd = require("/node_modules/symbol-hd-wallets");
repo = new nem.RepositoryFactoryHttp(NODE);
generationHash = await repo.getGenerationHash().toPromise();
networkType = await repo.getNetworkType().toPromise();
Accountクラス
Accountは秘密鍵を知っているユーザだけが生成できる、トランザクション署名などに使用するクラスです。
後述するQRコードにパスフレーズで暗号化して埋め込んだり、さらに上位に位置するニーモニックで復元されるHDウォレットなどから導出したりすることが可能です。
新規作成
alice = nem.Account.generateNewAccount(networkType);
秘密鍵から復元
alice = nem.Account.createFromPrivateKey(
"01E2597D5B3A11502B121AD994F67D27A1662C4FAF9D1DA1A4E57600BD65853C",
networkType
)
秘密鍵の導出
alice.privateKey
01E2597D5B3A11502B121AD994F67D27A1662C4FAF9D1DA1A4E57600BD65853C
公開鍵の導出
alice.publicKey
749D1BD458E055F3A76D34FB33DA9CBD5E55AFAC4902A0BBE45620F48C48BDA0
PublicAccountクラス
PublicAccountクラスは署名検証に利用する重要なクラスです。
検証のほかにもアグリゲートトランザクションにて他者の署名を要求したい用途にも使用します。
Accountクラスから導出
alice.publicAccount
PublicAccountから公開鍵の導出
publicAlice = alice.PublicAccount;
publicAlice.publicKey
749D1BD458E055F3A76D34FB33DA9CBD5E55AFAC4902A0BBE45620F48C48BDA0
公開鍵から生成
nem.PublicAccount.createFromPublicKey(
"749D1BD458E055F3A76D34FB33DA9CBD5E55AFAC4902A0BBE45620F48C48BDA0",
networkType
)
Addressクラス
Addressクラスは送信先の指定に使用するクラスです。
様々な表現方法があり、用途に応じて変換をかける必要があります。
Addressクラスからテキストへの変換
plain address
alice.address.plain()
TD6EVQBWBBS3ELM5RVPRSIFQXW7IN57LHKTJM2Y
pretty format address
alice.address.pretty()
TD6EVQ-BWBBS3-ELM5RV-PRSIFQ-XW7IN5-7LHKTJ-M2Y
encoded address
alice.address.encoded()
98FC4AC0360865B22D9D8D5F1920B0BDBE86F7EB3AA6966B
encoded addressは普段見かけることはありませんが、ノードのエンドポイントから直接APIでアドレス情報を取得した場合はこのフォーマットで出力されています。
Addressクラスへの変換
encoded addressから
nem.Address.createFromEncoded("98FC4AC0360865B22D9D8D5F1920B0BDBE86F7EB3AA6966B")
plain addressから
nem.Address.createFromRawAddress("TD6EVQBWBBS3ELM5RVPRSIFQXW7IN57LHKTJM2Y")
PublicAccountクラスから
publicAlice.address
RawAddress変換
RawAddressはトランザクションをノードにアナウンスする際のアドレス情報をシリアライズする時に使用されます。普段使用することはありませんが、トランザクションのPayloadを読み解く必要が出てきた場合は知っておく必要があります。
plain address から Uint8Arrayへの変換
uint8Address = nem.RawAddress.stringToAddress(alice.address.plain())
Uint8Array(24) [152, 252, 74, 192, 54, 8, 101, 178, 45, 157, 141, 95, 25, 32, 176, 189, 190, 134, 247, 235, 58, 166, 150, 107]
Uint8Array から plain address への変換
nem.RawAddress.addressToString(uint8Address)
TD6EVQBWBBS3ELM5RVPRSIFQXW7IN57LHKTJM2Y
AccountQR生成
symbol-qr-libraryを使用してQRコードの生成、そこからアカウントクラスを復元します。
QRコード生成
aliceQR = new qr.AccountQR(alice,"パスフレーズ",networkType);
aliceQR.toBase64().subscribe(x => {
(tag= document.createElement('img')).src = x;
document.getElementsByTagName('body')[0].appendChild(tag);
});
QRコードからAccountクラスを復元する
jsonQR = aliceQR.toJSON()
aliceQR = qr.AccountQR.fromJSON(jsonQR ,"パスフレーズ");
alice= aliceQR.account;
ニーモニック
symbol-hd-walletsを利用してニーモニックを生成、アカウントを導出します。
ニーモニック生成
mnemonic = hd.MnemonicPassPhrase.createRandom();
MnemonicPassPhrase {plain: "stick panel thought level stamp city dynamic nasty… evoke govern shoot spy family when master oppose"}
エントロピーを利用したニーモニック生成
(script = document.createElement('script')).src = 'https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js';
document.getElementsByTagName('head')[0].appendChild(script);
//一度ここで改行
entropy = CryptoJS.SHA256("エントロピー" + nem.Crypto.randomBytes(8)).toString();
mnemonic = hd.MnemonicPassPhrase.createFromEntropy(entropy)
アカウント生成
aliceSeedHex = mnemonic.toSeed('パスフレーズ');
aliceKey = hd.ExtendedKey.createFromSeed(aliceSeedHex , hd.Network.SYMBOL);
aliceWallet = new hd.Wallet(aliceKey.derivePath("m/44'/4343'/0'/0'/0'"));
alice = nem.Account.createFromPrivateKey(wallet.getAccountPrivateKey(), networkType);
ニーモニックからアカウントを導出します。パスフレーズは省略可能です。
アカウント復元
mnemonic = new hd.MnemonicPassPhrase(
"stick panel thought level stamp city dynamic nasty want suggest goose actress sugar clap small clinic evoke govern shoot spy family when master oppose"
);
aliceSeedHex = mnemonic.toSeed('パスフレーズ');
aliceKey = hd.ExtendedKey.createFromSeed(aliceSeedHex , hd.Network.SYMBOL);
aliceWallet = new hd.Wallet(aliceKey.derivePath("m/44'/4343'/0'/0'/0'"));
alice = nem.Account.createFromPrivateKey(wallet.getAccountPrivateKey(), networkType);
//オプトインアカウントを復元する場合はhd.Network.BITCOINに変更
子アカウント生成
wallet = new hd.Wallet(xkey.derivePath("m/44'/4343'/1'/0'/0'"));
account = nem.Account.createFromPrivateKey(aliceWallet.getAccountPrivateKey(), networkType);
44はSLIP44(SatoshiLabs improvement proposals)を意味しています。
4343はSymbolのcoin typeを意味しています。
ニーモニックをQRコードで出力する
mnemonicQR = new qr.MnemonicQR(mnemonic, 'パスフレーズ', networkType,generationHash);
base64 = mnemonicQR.toBase64().subscribe(x => {
(tag= document.createElement('img')).src = x;
document.getElementsByTagName('body')[0].appendChild(tag);
});
QRコードからニーモニックを復元する
jsonQR = mnemonicQR.toJSON();
qr.MnemonicQR.fromJSON(jsonQR,'パスフレーズ');
