この記事は最終更新日から1年以上が経過しています。
@programming
投稿日 2021/9/16
更新日 2021/9/16 ✏
BTC: Node.jsでsegwit対応アカウント生成
bitcoinjs-libを使って segwit に対応したBTCアカウント(アドレス、秘密鍵他)を生成するサンプルコードです。
目次:
前提
- node v12.16.1
- bitcoinjs-libv5.2.0
ランダムなニーモニックを生成
getMnemonic.js
/*
ランダムなニーモニックを生成
Usage:
$ node getMnemonic.js
*/
const bip39 = require('bip39');
const mnemonic = bip39.generateMnemonic(256);
console.log("mnemonic:");
console.log(mnemonic);
実行
## npmモジュールをインストール:
$ npm install --save bip39
## ニーモニックを生成:
$ node getMnemonic.js
mnemonic:
abandon genuine poet car gorilla try need plug arrest orient very salad ramp ...
ニーモニックからBTCアカウントを生成
getAccountsFromMnemonic.js
/*
ニーモニックからキーペアを派生
Usage:
## メインネット用アカウントを3つ生成:
$ node getAccountsFromMnemonic.js \
--mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
## テストネット用アカウントを5つ生成:
$ node getAccountsFromMnemonic.js \
--mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
--count=5 \
--testnet
*/
const bitcoin = require('bitcoinjs-lib');
const bip39 = require('bip39');
const bip32 = require('bip32');
let {
testnet,
mnemonic,
count,
} = require('minimist')(process.argv.slice(2));
const network = (testnet) ? bitcoin.networks.testnet : bitcoin.networks.bitcoin; // bitcoin or testnet
if (!mnemonic) {
console.log("ERROR: --mnemonic オプションでニーモニックを指定して下さい。");
process.exit(0);
return;
}
if (!count) count = 3; // デフォルトは3個生成
const seed = bip39.mnemonicToSeedSync(mnemonic);
const root = bip32.fromSeed(seed, network);
for (let len = count, i = 0; i < len; i++) {
// IMPORTANT: BIP84対応のderivation path。
// derivation path は将来的に変わる可能性あり:
const derivePath = `m/84'/${testnet ? "1'" : "0'"}/0'/0/${i}`; // , "m/44'/0'/0'/0/0", "m/84'/0'/0'/0/0" (segwit)
console.log("Generating account by derivation path:", derivePath);
const child = root.derivePath(derivePath);
// or:
// const child = root.deriveHardened(84).deriveHardened(testnet ? 1 : 0).deriveHardened(0).derive(0).derive(i);
console.log("Account #" + i);
const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: child.publicKey, network });
const account = {
address: p2wpkh.address,
witness: p2wpkh.output.toString("hex"),
privateKey_wif: child.toWIF(),
publicKey: child.publicKey.toString("hex"),
privateKey: child.privateKey.toString("hex"),
xpub: child.neutered().toBase58(),
xpriv: child.toBase58(),
};
console.log(account);
console.log("");
}
実行
## npmモジュールをインストール:
$ npm install --save bitcoinjs-lib bip39 bip32 minimist
## 指定したニーモニックでtestnet用のBTCアカウントを3つ生成:
$ node getAccountsFromMnemonic.js --mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" --testnet --count=3
Generating account by derivation path: m/84'/1'/0'/0/0
Account #0
{
address: 'tb1q6rz28mcfaxtmd6v789l9rrlrusdprr9pqcpvkl',
witness: '0014d0c4a3ef09e997b6e99e397e518fe3e41a118ca1',
privateKey_wif: 'cTGhosGriPpuGA586jemcuH9pE9spwUmneMBmYYzrQEbY92DJrbo',
publicKey: '02e7ab2537b5d49e970309aae06e9e49f36ce1c9febbd44ec8e0d1cca0b4f9c319',
privateKey: 'a9c4134b73560f43fc5c081e5c1daa7ce068adc806d80e1f37cb658e0fea4c8d',
xpub: 'tpubDHPpQL4fzb9hrQZuxDoybkLzpFFCFf65rSGQ3Q73Wc2bfxH6PT5MKK5oHgU68iaRoikGrJiPag1nJx7J7R7uzGBRcVhphzVCZgzyexMLJVJ',
xpriv: 'tprv8khnFv2RrDU2xwY84a9PCLgtFDjG6KuBH8fckt4k6LECqU2Km4Fm8pTw7Z3vxEKegpWMaR4rPydEzLhnvKt5WFDhFu9b6BbCPJA6ucBMtU2'
}
Generating account by derivation path: m/84'/1'/0'/0/1
Account #1
{
address: 'tb1qd7spv5q28348xl4myc8zmh983w5jx32cjhkn97',
witness: '00146fa016500a3c6a737ebb260e2ddca78ba9234558',
privateKey_wif: 'cQFUndrpAyMaE3HAsjMCXiT94MzfsABCREat1x7Qe3Mtq9KihD4V',
publicKey: '03eeed205a69022fed4a62a02457f3699b19c06bf74bf801acc6d9ae84bc16a9e1',
privateKey: '4f9fb140e0586691de963613549631e2048ab4030d74f4d98405686dd30a9d75',
xpub: 'tpubDHPpQL4fzb9htigiZ3BZFSRUQVVZM8bT9G7N2swUHCQULJRbA1Z7hxEqJJr9g5VhDLDHGrVWrrpGmuZcdHLuMqo7ET2zBzrT6mXBfE4jNZo',
xpriv: 'tprv8khnFv2RrDU31FevfPWxr2mMqTydBoQYZxWakMuArvc5VpApXcjXXTcy88kMNLRw2u86g9CnLB9tieDDeqrAHH3P5jjb7dHocnkaRqiPMUS'
}
Generating account by derivation path: m/84'/1'/0'/0/2
Account #2
{
address: 'tb1qxdyjf6h5d6qxap4n2dap97q4j5ps6ua8sll0ct',
witness: '0014334924eaf46e806e86b3537a12f81595030d73a7',
privateKey_wif: 'cRe5KDj3rcZJAtZVmWe3G2rdGdXyKCjVbWBVDXqSg2WHq1qq6MNe',
publicKey: '02339193c34cd8ecb21ebd48af64ead71d78213470d61d7274f932489d6ba21bd3',
privateKey: '7915c74bbe3a2f3e3e9ef6ba62dd01590102a2e36ad1d0fd4b0329f9f76fa986',
xpub: 'tpubDHPpQL4fzb9hvejcBLQzx2TqtXmN9ayfRaxgNViP9gdE5oB6jfByQNukWs3MVeHehVhZVd9AKUrBVzJLgkmyMJiioTEKLMPD9gtVLixBthB',
xpriv: 'tprv8khnFv2RrDU33BhpHgkQYcojKWFRzFnkrHMu5yg5jQpqFJvL7GNPDtHtLkd5Eg12xmFUFnsSkUxF9TrSKd5qi1JYZ2oVopdaKZaFiqX4s1V'
}
PrivateKey(WIF)からBTCアカウントを生成
getAccountFromWif.js
/*
PrivateKey WIFからアドレスを生成
Usage:
メインネット用:
$ node getAccountFromWif.js --wif=<privateKey_wif>
テストネット用:
$ node getAccountFromWif.js --wif=<privateKey_wif> --testnet
*/
const bitcoin = require('bitcoinjs-lib');
let {
testnet,
wif,
} = require('minimist')(process.argv.slice(2));
const network = (testnet) ? bitcoin.networks.testnet : bitcoin.networks.bitcoin; // bitcoin or testnet
if (!wif) {
console.log("ERROR: --wif オプションで PrivateKey(WIF) を指定して下さい。");
process.exit(0);
return;
}
console.log("P2WPKH Account:\n", getAccountFromWif(wif, network));
function getAccountFromWif(wif, network) {
const keyPair = bitcoin.ECPair.fromWIF(wif, network);
const publicKey = keyPair.publicKey;
const privateKey = keyPair.privateKey;
const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: publicKey, network });
const address = p2wpkh.address;
const witness = p2wpkh.output;
return {
address,
witness: witness.toString("hex"),
privateKey_wif: wif,
publicKey: publicKey.toString("hex"),
privateKey: privateKey.toString("hex"),
};
}
実行
## npmモジュールをインストール:
$ npm install --save bitcoinjs-lib bip39 bip32 minimist
## 指定したPrivateKey(WIF)でtestnet用BTCアカウントを取得:
$ node getAccountFromWif.js --wif="cTGhosGriPpuGA586jemcuH9pE9spwUmneMBmYYzrQEbY92DJrbo" --testnet
P2WPKH Account:
{
address: 'tb1q6rz28mcfaxtmd6v789l9rrlrusdprr9pqcpvkl',
witness: '0014d0c4a3ef09e997b6e99e397e518fe3e41a118ca1',
privateKey_wif: 'cTGhosGriPpuGA586jemcuH9pE9spwUmneMBmYYzrQEbY92DJrbo',
publicKey: '02e7ab2537b5d49e970309aae06e9e49f36ce1c9febbd44ec8e0d1cca0b4f9c319',
privateKey: 'a9c4134b73560f43fc5c081e5c1daa7ce068adc806d80e1f37cb658e0fea4c8d'
}
以上です。