0
Help us understand the problem. What are the problem?

posted at

updated at

bitcoinjs-libでP2SH-P2WPKHのトランザクションを作る

はじめに

上記の記事では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

送金できました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?