はじめに
上記の記事ではNatice SegwitのP2WPKHのUTXOをInputに持つトランザクションを作成する手順を書きましたが、
今回は、P2SH-P2WPKHのUTXOをInputに持つトランザクションを作成していきます。
準備
フルノード
上記記事と同様、DockerでSignetノードを立ち上げますが、
vi ~/docker-signet/bitcoin.conf
txindex=1
を[signet]の下に追記して起動します。
txindexなしで起動したことがあるなら、reindexするかブロックチェーンデータを消すなりしてください。
鍵
鍵はこちらと同じjsonファイルを使います。
BTCをアドレスに入れておく
こちらで作成したアドレスにsBTCを送っておきます。
P2SH-P2WPKH:
2N7XBZfKVZ3h9ysFyZLroQpQ5cwxzY25tWE
TXは
bb52d8788b686b52c31b1c9998176207a295c513b3254b8e793eb015c22f2ade
Indexは1です。
RawTxを取得
資金源のTxのRawTxを取得します。
$ bcli getrawtransaction bb52d8788b686b52c31b1c9998176207a295c513b3254b8e793eb015c22f2ade
02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360100000000feffffff02b379920000000000160014a13008ccc2f7b83463984b5b4afa65fbbdf87851a08601000000000017a9149c966478e58697e07ba4aec10fa6f3508f4325fa870247304402205dd9a3c774fc720dd7855c79baa19a28b025ff9596959b05dd2767fa22bbe24602201969d84c378222af595bf2addeb929a2dd74e906dc806b2418e47622b18ca8e0012102a37d8b815cea0042b01ce49c9f83ab942c8e4b8a85b3c7aca5b641120d654ea179ce0000
トランザクション作成
previousRawTxに前節で得たRawTxを入れます。
const previousRawTx = '02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360100000000feffffff02b379920000000000160014a13008ccc2f7b83463984b5b4afa65fbbdf87851a08601000000000017a9149c966478e58697e07ba4aec10fa6f3508f4325fa870247304402205dd9a3c774fc720dd7855c79baa19a28b025ff9596959b05dd2767fa22bbe24602201969d84c378222af595bf2addeb929a2dd74e906dc806b2418e47622b18ca8e0012102a37d8b815cea0042b01ce49c9f83ab942c8e4b8a85b3c7aca5b641120d654ea179ce0000';
TXが
bb52d8788b686b52c31b1c9998176207a295c513b3254b8e793eb015c22f2ade
Index:1を入れます。
psbt.addInput({
hash: 'bb52d8788b686b52c31b1c9998176207a295c513b3254b8e793eb015c22f2ade',
index: 1,
p2shP2wpkhTx.js
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, });
const p2sh = bitcoin.payments.p2sh({
redeem: p2wpkh
});
console.log('P2SH-P2WPKH address')
console.log(p2sh.address)
const psbt = new bitcoin.Psbt({ network: bitcoinNetwork });
const previousRawTx = '02000000000101387eee5dd96c6349fb16ceef466c0b9265e029cd71abe47d7ee0a08621424c360100000000feffffff02b379920000000000160014a13008ccc2f7b83463984b5b4afa65fbbdf87851a08601000000000017a9149c966478e58697e07ba4aec10fa6f3508f4325fa870247304402205dd9a3c774fc720dd7855c79baa19a28b025ff9596959b05dd2767fa22bbe24602201969d84c378222af595bf2addeb929a2dd74e906dc806b2418e47622b18ca8e0012102a37d8b815cea0042b01ce49c9f83ab942c8e4b8a85b3c7aca5b641120d654ea179ce0000';
psbt.addInput({
hash: 'bb52d8788b686b52c31b1c9998176207a295c513b3254b8e793eb015c22f2ade',
index: 1,
redeemScript: p2wpkh.output,
nonWitnessUtxo: Buffer.from(previousRawTx, 'hex'),
});
psbt.addOutput({
address: "tb1q2adzgyzuy3msvjjfn3pkghf5fnwtwmxcglw3cuk5gvvv3ahmt63qqqa3n6",
value: 30000,
});
psbt.addOutput({
address: "tb1qzwwvqxr2m8l0kt8trnnhaa48awtq45zauflz5y",
value: 69824,
});
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 p2shP2wpkhTx.js
privateKey_wif:
cVa9bD3JAoc6hJHfU68PkLWrYmn6AN81PJs7kG6BHR1TeA4nKJtF
P2SH-P2WPKH address
2N7XBZfKVZ3h9ysFyZLroQpQ5cwxzY25tWE
02000000000101de2a2fc215b03e798e4b25b313c595a207621798991c1bc3526b688b78d852bb0100000017160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05dffffffff023075000000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea2c010010000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d02483045022100eaab6fc6e9f30c0010ebfc2c4aa87a0ab3a0d638916a5eba60ed8d09b2dcd16302204389db680cb65affb50f811a7786a0ef3bfc282e8e19b4ae2beee1119fcd77280121034c30836747cd7d7a50db1de9ceb1c953a4c308bbf2669c620d62a4370f63b47200000000
得られたRawTxをブロードキャストします。
$ bcli sendrawtransaction 02000000000101de2a2fc215b03e798e4b25b313c595a207621798991c1bc3526b688b78d852bb0100000017160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05dffffffff023075000000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea2c010010000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d02483045022100eaab6fc6e9f30c0010ebfc2c4aa87a0ab3a0d638916a5eba60ed8d09b2dcd16302204389db680cb65affb50f811a7786a0ef3bfc282e8e19b4ae2beee1119fcd77280121034c30836747cd7d7a50db1de9ceb1c953a4c308bbf2669c620d62a4370f63b47200000000
46fbfca1236acf4cfcdc8eb97856370cc4294eb1578f9fd00ed2a6be5536b50b
送金できました。