はじめに
上記記事で作成したP2WPKHアドレスにSignetで入金し、トランザクションを作成してブロードキャストするところまでをやってみます。
準備
フルノード
Dockerのある環境で、Signetフルノードを立ち上げます。
$ ID=$(docker ps -q)
$ alias bcli="docker exec $ID bitcoin-cli"
$ bcli getblockchaininfo
{
"chain": "signet",
"blocks": 52781,
"headers": 52781,
"bestblockhash": "0000011901fe5f02923fd64aa9d1ae97d4defa9e0ee130cd360986f7e896cd57",
"difficulty": 0.002919030932507782,
"mediantime": 1629981736,
"verificationprogress": 0.9999984371265536,
"initialblockdownload": false,
"chainwork": "00000000000000000000000000000000000000000000000000000094db3d1966",
"size_on_disk": 154655081,
"pruned": false,
"softforks": {
"bip34": {
"type": "buried",
"active": true,
"height": 1
},
"bip66": {
"type": "buried",
"active": true,
"height": 1
},
"bip65": {
"type": "buried",
"active": true,
"height": 1
},
"csv": {
"type": "buried",
"active": true,
"height": 1
},
"segwit": {
"type": "buried",
"active": true,
"height": 1
},
"taproot": {
"type": "bip9",
"bip9": {
"status": "active",
"start_time": -1,
"timeout": 9223372036854775807,
"since": 0,
"min_activation_height": 0
},
"height": 0,
"active": true
}
},
"warnings": ""
}
"blocks"と"headers"が同じブロック高になれば同期OKです。
同期している間に先に進みます。
アドレス準備
アドレス作成編で作成したP2WPKHを使います。
P2WPKH:
tb1qzwwvqxr2m8l0kt8trnnhaa48awtq45zauflz5y
Signet BTC調達
Signet Faucetを使ってP2WPKHに入金します。
ときどき、不調な時がありますので、そういう場合は時間をおいてお試しください。
Exploreで確認します。
鍵の準備
ここで、シングルシグのアドレスを作成しましたが、そのときの拡張秘密鍵、拡張公開鍵を使用します。
$ node getKeys.js
mnemonic:
task foster wet panther noble tissue hockey ancient faint mandate suit thank mad wrist where category lecture margin wrap evoke desert topic empty include
xpriv:
tprv8gPHaXkdRLgnE1NgPqZPkH1ffYBiQkuAVowFDi5rGDuxj19vuBsD53cmXHxq8u4gmDv9t8a2YaY56roA8KNZRNTNSe6Yv6jVdDhUvxYbcRj
xpub:
tpubDD5KiwnsZiNT7UQUHVDz9gfnEZhea66557Y2WE89gViMZVQhXagoFYEdhSnsRKtJJrv9yAmEkdCUA68GPmPk9W8tdfq5iWU7JpcXpEUfhyL
拡張秘密鍵と拡張公開鍵は別々のファイルで作成します。
ディレクトリはこれから作成するプログラムと同じです。
{
"xpriv": "tprv8gPHaXkdRLgnE1NgPqZPkH1ffYBiQkuAVowFDi5rGDuxj19vuBsD53cmXHxq8u4gmDv9t8a2YaY56roA8KNZRNTNSe6Yv6jVdDhUvxYbcRj"
}
{
"xpub": "tpubDD5KiwnsZiNT7UQUHVDz9gfnEZhea66557Y2WE89gViMZVQhXagoFYEdhSnsRKtJJrv9yAmEkdCUA68GPmPk9W8tdfq5iWU7JpcXpEUfhyL"
}
トランザクション作成
前回のアドレス作成で得たxprivとxprivをセット、
入金時のTXIDとIndexをセットします。
psbt.addOutputの宛先、送金額を適当にセットします。
const bitcoin = require('bitcoinjs-lib');
const bip32 = require('bip32');
const bip39 = require('bip39');
const wif = require('wif');
const { xpub } = require('./xpub.json');
const MAINNET = bitcoin.networks.bitcoin;
const TESTNET = bitcoin.networks.testnet;
// let bitcoinNetwork = MAINNET;
let bitcoinNetwork = TESTNET;
const { xpriv } = require('./xpriv.json');
const privkeyNode = bitcoin.bip32.fromBase58(xpriv, bitcoinNetwork);
const privateKey_wif = privkeyNode.derive(1).derive(0).derive(0).derive(0).toWIF();
console.log("privateKey_wif:");
console.log(privateKey_wif);
function getPubkeyFromXpub(xpub) {
const pubkeyNode = bitcoin.bip32.fromBase58(xpub, bitcoinNetwork);
const pubkey = pubkeyNode.derive(1).derive(0).derive(0).derive(0).publicKey;
return pubkey;
}
const pubkey = getPubkeyFromXpub(xpub);
const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: pubkey, network: bitcoinNetwork, });
console.log('Witness script:')
console.log(p2wpkh.output.toString('hex'))
console.log('P2WPKH address')
console.log(p2wpkh.address)
const psbt = new bitcoin.Psbt({ network: bitcoinNetwork });
psbt.addInput({
hash: '364c422186a0e07e7de4ab71cd29e065920b6c46efce16fb49636cd95dee7e38',
index: 0,
sequence: 0xffffffff,
witnessUtxo: {
script: Buffer.from(p2wpkh.output.toString('hex'),'hex',),
value: 100000,
},
});
psbt.addOutput({
address: "tb1q2adzgyzuy3msvjjfn3pkghf5fnwtwmxcglw3cuk5gvvv3ahmt63qqqa3n6",
value: 70000,
});
psbt.addOutput({
address: "tb1qzwwvqxr2m8l0kt8trnnhaa48awtq45zauflz5y",
value: 29890,
});
const obj = wif.decode(privateKey_wif);
const privKey = bitcoin.ECPair.fromPrivateKey(obj.privateKey);
psbt.signInput(0, privKey);
psbt.validateSignaturesOfInput(0);
psbt.finalizeAllInputs();
const txHex = psbt.extractTransaction().toHex();
console.log(txHex);
$ node singleSigTx.js
privateKey_wif:
cVa9bD3JAoc6hJHfU68PkLWrYmn6AN81PJs7kG6BHR1TeA4nKJtF
02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360000000000ffffffff027011010000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea2c274000000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d024830450221008b022898583d8dd4eb8136982b3ed7bdd0f632a6613def653d171c1536ef954702206e7d958b881a6e66c42d9ba8c3fd88a9724fc10d9c12a5e15340c564e8a0d3ae0121034c30836747cd7d7a50db1de9ceb1c953a4c308bbf2669c620d62a4370f63b47200000000
なお、WIF形式の秘密鍵(privateKey_wif)はBitcoin Coreのウォレットに取り込めます。
$ bcli importprivkey cVa9bD3JAoc6hJHfU68PkLWrYmn6AN81PJs7kG6BHR1TeA4nKJtF
得られた生トランザクションをデコードして確認します。
$ bcli decoderawtransaction 02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360000000000ffffffff027011010000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea2c274000000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d024830450221008b022898583d8dd4eb8136982b3ed7bdd0f632a6613def653d171c1536ef954702206e7d958b881a6e66c42d9ba8c3fd88a9724fc10d9c12a5e15340c564e8a0d3ae0121034c30836747cd7d7a50db1de9ceb1c953a4c308bbf2669c620d62a4370f63b47200000000
フルノードが同期完了した後、ブロードキャストします。
$ bcli sendrawtransaction 02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360000000000ffffffff027011010000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea2c274000000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d024830450221008b022898583d8dd4eb8136982b3ed7bdd0f632a6613def653d171c1536ef954702206e7d958b881a6e66c42d9ba8c3fd88a9724fc10d9c12a5e15340c564e8a0d3ae0121034c30836747cd7d7a50db1de9ceb1c953a4c308bbf2669c620d62a4370f63b47200000000
error code: -26
error message:
min relay fee not met, 110 < 153
このエラーは手数料不足で送金できませんでした。
Input - OutPut >= 153 になるように調整します。
psbt.addOutput({
address: "tb1qzwwvqxr2m8l0kt8trnnhaa48awtq45zauflz5y",
value: 29847,
});
$ node singleSigTx.js
privateKey_wif:
cVa9bD3JAoc6hJHfU68PkLWrYmn6AN81PJs7kG6BHR1TeA4nKJtF
02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360000000000ffffffff027011010000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea29774000000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d0248304502210090508855aaca0dc1a5387d136ca4373791855792c3467a39991aca10d4814639022057312bedf9d922999ccba8dab4b8f3d5a32548c4c380e9f316a93e347e36e88d0121034c30836747cd7d7a50db1de9ceb1c953a4c308bbf2669c620d62a4370f63b47200000000
再度送金
$ bcli sendrawtransaction 02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360000000000ffffffff027011010000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea29774000000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d0248304502210090508855aaca0dc1a5387d136ca4373791855792c3467a39991aca10d4814639022057312bedf9d922999ccba8dab4b8f3d5a32548c4c380e9f316a93e347e36e88d0121034c30836747cd7d7a50db1de9ceb1c953a4c308bbf2669c620d62a4370f63b47200000000
19fdd3ba91d7b7e2a05a49cdf20998334d5e5a774025e8cb51bfc2c4d06c364b
得られたトランザクションをExplorerで確認してみましょう。