はじめに
こちらと同じように、P2SH-P2WSHのトランザクションを作成します。
Signetフルノードの動かし方などは上記記事を参考にしてください。
準備
鍵
鍵はこちらと同じjsonファイルを使います。
BTCをアドレスに入れておく
こちらで作成したアドレスにsBTCを送っておきます。
P2SH-P2WSH:
2N9mgCypNXq8qkx1SHqBkDW4u92rXKsdJjH
TXは
f77f76cbc68444716894f5884f99e281c943e7f1832886bc8030cda5d05e803d
Indexは1です。
RawTxを取得
資金源のTxのRawTxを取得します。
bcli getrawtransaction f77f76cbc68444716894f5884f99e281c943e7f1832886bc8030cda5d05e803d
02000000000101de2a2fc215b03e798e4b25b313c595a207621798991c1bc3526b688b78d852bb0000000000feffffff0285f29000000000001600146f5fcbf72dd6bce849eb78dc5b984f5cdc69ec0ca08601000000000017a914b54460b9b1339d23d349cdd216ab44314cbeca2a870247304402206a7c7ae6b7135b8091467d72869ef6ee01b5d53ebf24c75e79b0d339c672d5af02206ed9c92a56e91c3ac8afc8abae493e84f59b6a76edbe32360091470bb00b39440121034e87fe334e75b2a1ccb6ef9a6b2beac216d7763f321eeb75c1191889ce191a498ece0000
トランザクション作成
previousRawTxに前節で得たRawTxを入れます。
const previousRawTx = '02000000000101de2a2fc215b03e798e4b25b313c595a207621798991c1bc3526b688b78d852bb0000000000feffffff0285f29000000000001600146f5fcbf72dd6bce849eb78dc5b984f5cdc69ec0ca08601000000000017a914b54460b9b1339d23d349cdd216ab44314cbeca2a870247304402206a7c7ae6b7135b8091467d72869ef6ee01b5d53ebf24c75e79b0d339c672d5af02206ed9c92a56e91c3ac8afc8abae493e84f59b6a76edbe32360091470bb00b39440121034e87fe334e75b2a1ccb6ef9a6b2beac216d7763f321eeb75c1191889ce191a498ece0000';
TX
f77f76cbc68444716894f5884f99e281c943e7f1832886bc8030cda5d05e803d
Index:1をpsbt.addInputに入れます。
psbt.addInput({
hash: 'f77f76cbc68444716894f5884f99e281c943e7f1832886bc8030cda5d05e803d',
index: 1,
宛先、送金額は任意でセットします。ただし、Input - OutputであるFeeが1satoshi/byteでなくてはなりません。
const bitcoin = require('bitcoinjs-lib');
const bip32 = require('bip32');
const bip39 = require('bip39');
const wif = require('wif');
const {xpub1, xpub2, xpub3} = require('./xpubs.json');
const MAINNET = bitcoin.networks.bitcoin;
const TESTNET = bitcoin.networks.testnet;
// let bitcoinNetwork = MAINNET;
let bitcoinNetwork = TESTNET;
const xpriv1 = require('./xpriv1.json').xpriv;
const xpriv2 = require('./xpriv2.json').xpriv;
const xpriv3 = require('./xpriv3.json').xpriv;
function getPrivkeyFromXpriv(xpriv) {
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);
const obj = wif.decode(privateKey_wif);
const privkey = bitcoin.ECPair.fromPrivateKey(obj.privateKey);
return privkey;
}
const privkey1 = getPrivkeyFromXpriv(xpriv1);
const privkey2 = getPrivkeyFromXpriv(xpriv2);
const privkey3 = getPrivkeyFromXpriv(xpriv3);
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 pubkey1 = getPubkeyFromXpub(xpub1);
const pubkey2 = getPubkeyFromXpub(xpub2);
const pubkey3 = getPubkeyFromXpub(xpub3);
const pubkeys = [
pubkey1,
pubkey2,
pubkey3,
].map(Buffer => Buffer);
const p2wsh = bitcoin.payments.p2wsh({
redeem: bitcoin.payments.p2ms({ m: 2, pubkeys, network: bitcoinNetwork, })
})
const p2sh = bitcoin.payments.p2sh({
redeem: p2wsh
});
console.log('P2SH-P2WSH address')
console.log(p2sh.address)
const psbt = new bitcoin.Psbt({ network: bitcoinNetwork });
const previousRawTx = '02000000000101de2a2fc215b03e798e4b25b313c595a207621798991c1bc3526b688b78d852bb0000000000feffffff0285f29000000000001600146f5fcbf72dd6bce849eb78dc5b984f5cdc69ec0ca08601000000000017a914b54460b9b1339d23d349cdd216ab44314cbeca2a870247304402206a7c7ae6b7135b8091467d72869ef6ee01b5d53ebf24c75e79b0d339c672d5af02206ed9c92a56e91c3ac8afc8abae493e84f59b6a76edbe32360091470bb00b39440121034e87fe334e75b2a1ccb6ef9a6b2beac216d7763f321eeb75c1191889ce191a498ece0000';
psbt.addInput({
hash: 'f77f76cbc68444716894f5884f99e281c943e7f1832886bc8030cda5d05e803d',
index: 1,
redeemScript: p2wsh.output,
witnessScript: p2wsh.redeem.output,
nonWitnessUtxo: Buffer.from(previousRawTx, 'hex'),
});
psbt.addOutput({
address: "tb1q2adzgyzuy3msvjjfn3pkghf5fnwtwmxcglw3cuk5gvvv3ahmt63qqqa3n6",
value: 30000,
});
psbt.addOutput({
address: "tb1qzwwvqxr2m8l0kt8trnnhaa48awtq45zauflz5y",
value: 69776,
});
psbt.signInput(0, privkey2)
psbt.signInput(0, privkey3);
psbt.validateSignaturesOfInput(0, Buffer.from(pubkey2, 'hex'))
psbt.validateSignaturesOfInput(0, Buffer.from(pubkey3, 'hex'))
psbt.validateSignaturesOfInput(0);
psbt.finalizeAllInputs();
const txHex = psbt.extractTransaction().toHex();
console.log(txHex);
コードを実行します。
$ node p2shP2wshTx.js
privateKey_wif:
cVqL1ToSfwLw2xt6AB6bXoN51MrpTKj4RawFN682mD3zockVgqXD
privateKey_wif:
cRbPqcaZ9L9hvGkFkjyALCmb5hvwfkW8j4GhVpFqN1vvmNDGJZ61
privateKey_wif:
cStFWwyLBG6SGtNsqZ5MjnaLdYpsyzu5hp5U11WrL3ZBMPAWshdc
P2SH-P2WSH address
2N9mgCypNXq8qkx1SHqBkDW4u92rXKsdJjH
020000000001013d805ed0a5cd3080bc862883f1e743c981e2994f88f59468714484c6cb767ff70100000023220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea2ffffffff023075000000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea29010010000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d040047304402206def24babcd21f73271892e5e20a37cf24f32c7f548405a880d50f2b4ba0490302207d6f935be1dedb3b4dd0b09231126082be75873ef07f861a51f229789d75a05d01473044022026dfcc2f82eda5cfba13745573fe4521bcc3ee50539cc5b8c605ec4749234c0e022014d665a81548dcef10643a3060239cfc4a0dce13ac292d39543db4890f443eaa01695221036791fd096f2a83f355826012c9a29bc07ea4460cdbc424f57d7b181a502121092102f94b3a35c8464d8fe3a121e685b4f56adff15f5976f57f7b3e176b3b4707ba6121039ff1a14f03925083945d1158bcd7167979f8fb73dc8af80818a178aaaf64fa7553ae00000000
得られたRawTxをブロードキャストします。
$ bcli sendrawtransaction 020000000001013d805ed0a5cd3080bc862883f1e743c981e2994f88f59468714484c6cb767ff70100000023220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea2ffffffff023075000000000000220020575a24105c2477064a499c43645d344cdcb76cd847dd1c72d44318c8f6fb5ea29010010000000000160014139cc0186ad9fefb2ceb1ce77ef6a7eb960ad05d040047304402206def24babcd21f73271892e5e20a37cf24f32c7f548405a880d50f2b4ba0490302207d6f935be1dedb3b4dd0b09231126082be75873ef07f861a51f229789d75a05d01473044022026dfcc2f82eda5cfba13745573fe4521bcc3ee50539cc5b8c605ec4749234c0e022014d665a81548dcef10643a3060239cfc4a0dce13ac292d39543db4890f443eaa01695221036791fd096f2a83f355826012c9a29bc07ea4460cdbc424f57d7b181a502121092102f94b3a35c8464d8fe3a121e685b4f56adff15f5976f57f7b3e176b3b4707ba6121039ff1a14f03925083945d1158bcd7167979f8fb73dc8af80818a178aaaf64fa7553ae00000000
475c9caf689b136a3d9ad03a90d66959257812cc9df7f51865bc1df636ad8901
送金できました。