資料の最新化
【追記】
こちらの資料で最新化してしています。
はじめに
本記事は、9/29(水)ビットコインとか勉強会ハンズオンの資料になります。
↓アーカイブ動画も公開していますので、併せてご覧ください。
ハンズオンの準備
nodejs
nodejsをインストールしておきます。
ソースコードの準備
git clone https://github.com/shu-kob/walllet-dev-study
cd walllet-dev-study
npm install
鍵・アドレスの生成
ニーモニックの生成
node getMnemonic.js
mnemonic:
inject chuckle author whale diary hero link cinnamon dutch flip exchange indicate demand tenant minimum illness mistake emotion assault arena pilot rally belt special
walllet-dev-studyディレクトリにmnemonic.jsonが生成されますが、本番利用では暗号化していないニーモニックを置かないでください。
拡張鍵の生成
ニーモニックから拡張秘密鍵と拡張公開鍵を生成します。
node getKeys.js
path:
m/44'/1'/0'
xpriv:
tprv8goYRjMj2PEAjVQhL9ysuTYFRGCHNVGfgJXc119tWJ2hQ9RccUMiSe9xxrMQtY2f9iWvpWc6Tpv2nTDr4CfzzpgeLo4y7vy5BGffc5LV1HF
xpub:
tpubDDVaa9PyAkuqcxSVDoeUJsCMzHiDXpTaFc8PHXCBvZq6EdgPEsBJd8mq8yxofjXPA7XK2xFqbYHyYTfQXZjHafkgcoZrokaPumcYGpRbqPS
walllet-dev-studyディレクトリにxpriv.jsonとxpub.jsonが生成されますが、本番利用では暗号化していない拡張秘密鍵を置かないでください。
シングルシグアドレスの生成
拡張公開鍵からアドレスを生成します。P2PKH、P2SH-P2WPKH(Nested Segwit)、P2WPKH(Native Segwit)の3種をアドレスパスごとに出します。
これらの形式は互換性はなく、変換して使用することはできません。P2PKHで受け取ったコインをP2WPKHで使うことはできないということです。
node getSingleSigAddresses.js
Non Change Addresses
addressPath: m/44'/1'/0'/0/0
P2PKH:
mt8xMnq8MGPSHC42hfFc8xuTxJ3uqoJTA9
P2SH-P2WPKH:
2N55dKSbYKmt75dvbr4pYjBu1JLfeSy3rz9
P2WPKH:
tb1q3fcgnt3xp4k46wfz6epw5pd4w7hqh796jggprq
addressPath: m/44'/1'/0'/0/1
〜略〜
Change Addresses
addressPath: m/44'/1'/0'/1/0
P2PKH:
n1kUSYA5CNJrLMCfLLAmKyCkDLuCZCRqoH
P2SH-P2WPKH:
2N1YL3hm9fKcTP84cT761eTjc8er9tQieXv
P2WPKH:
tb1qmhc3dz9qtmdfk98r3653jdahgu4tdqy7ne6qkx
addressPath: m/44'/1'/0'/1/1
〜略〜
Non Change Addressesは受取り用に使用し、外部に公開するアドレス、Change Addressesはお釣りアドレスです。
# 生成したアドレスに送金
Signet Faucetのアドレス入力欄にaddressPath:m/44'/1'/0'/0/0のP2WPKHアドレスを入れます。
送金できらたら、Explorerで確認しましょう。入金されてからExplorerに表示されるまで数十秒かかります。
マルチシグアドレスを作成
受け取りアドレスとなる2-of-3のマルチシグアドレスを作成します。
node getMultiSigMnemonics.js
mnemonic1:
elder abandon erupt during mixed world merge flat flat good gain solution wild idea very frequent artefact awake scene chaos adjust drop kind okay
mnemonic3:
fault copy era apology fancy truth pond brush token wrist rate unknown disorder real differ exhaust enlist ostrich only annual remind cabin capable width
mnemonic2:
live seminar wool job devote celery owner endorse across recycle era bounce session disorder upper trouble poet tag region popular country monitor slogan bulk
それぞれjsonファイルが生成されますが、本番利用では暗号化していないニーモニックを置かないでください。
node getMultiSigKeys.js
path:
m/44'/1'/0'
mnemonic: elder abandon erupt during mixed world merge flat flat good gain solution wild idea very frequent artefact awake scene chaos adjust drop kind okay
mnemonic: live seminar wool job devote celery owner endorse across recycle era bounce session disorder upper trouble poet tag region popular country monitor slogan bulk
mnemonic: fault copy era apology fancy truth pond brush token wrist rate unknown disorder real differ exhaust enlist ostrich only annual remind cabin capable width
xpriv3:
tprv8fTKpNffqYGBG4n7XoYxkHy8C5GXTgu2knGY7FfD44AjL2F3J4Sxm4sLUpVceT2GLYoaLVfFH6t16BPHU4pCvXtE4uLFvfDEhbmFgNe3p9H
xpriv1:
tprv8gNQoNNSq2W9fuG7zS4FL4vMYABfVA2p5TE1ct6yG5ENLi8WB2N4xZBXzRn9E4HZabqeeqNiFgntFVRNgPxXH8gmU6wNZwymQCuYAmK6eog
xpub1:
tpubDD4SwnQgyQBpZNHut5iqjUaU7BhbeVDiekpnuQ9GgM2mBCPGoRBf93oQAZbhYaZSfcd1nTfE5Kya1qpdDjsiHwvNGh19QSu1WNNYZdtnHMq
xpub2:
tpubDDJAmBRNAknqYDTXh1aUGkU9i4fFcSTo5cPoWYceUeQXu21WyHDtCnsjFALTRx4aWhpYTEwsNdfvc2w9pCEoWg2ZBfNctXq5bewU4v8DGeG
xpub3:
tpubDC9Mxnhuyuwr9XouRTDZ9hdEm6nTd25wL5sKPmhWUKy8AWVovTGYwZVCez26fYqjNTN9GnKeJZkYEo6TCWRk84Q1uhrtjEPHRDYd2DinZbE
xpriv2:
tprv8gc8cmP82P7AekRjoMussLp3939KT7GtWJo2E2aM4Nc94XkkLtQJ2JFs51DhMymuxHHiuBTm3oRhjB37yfaBzeDFKmqR5tunVsrpr7qT6FF
xprivはそれぞれjsonファイルが生成されますが、本番利用では暗号化していない拡張秘密鍵を置かないでください。
xpubは3つまとめて生成されます。
node getMultiSigAddresses.js
Non Change Addresses
addressPath: m/44'/1'/0'/0/0
P2SH:
2MzX5zHJkZX3GyrD92ijvT7FyEXiTajud1d
P2SH-P2WSH:
2MwZhrfcLDFJX1PG2LhuUJPzDiqMFxzSQ4G
P2WSH:
tb1qh9yf6tvdj9qq5rlxvmpj7l67lcm3xd9ws5uzavnl8l8z42n0py6slg6xta
addressPath: m/44'/1'/0'/0/1
〜略〜
Change Addresses
addressPath: m/44'/1'/0'/1/0
P2SH:
2MydWLqQAAy992WxBgkgBWvwTjANpGTJCDS
P2SH-P2WSH:
2Myv2XaqYXiM5ttNiG4jvtALrCmE6qJRCtZ
P2WSH:
tb1qgxxkdf0undcc9l4eyz5grxxaw4dateuf0etze5d688prd2g6r07qgq9jdr
addressPath: m/44'/1'/0'/1/1
〜略〜
P2WPKHトランザクションを作成
こちらのコードを流用します。
↑こちらの行のTxHashを入金Txで置き換えます。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wpkhTx.js#L43
↑Indexを編集します。(0, 1, 2という順番で数えます)
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wpkhTx.js#L47
↑受け取った金額を編集します。(単位はSatoshiです。1億分の1BTC=1satoshi)
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wpkhTx.js#L51
↑宛先はマルチシグアドレスのaddressPath:m/44'/1'/0'/0/0のP2WSHを指定しましょう。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wpkhTx.js#L52
↑送金額を編集します。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wpkhTx.js#L55
↑お釣りアドレスを編集します。addressPath:m/44'/1'/0'/1/0のP2WPKHアドレスを指定しましょう。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wpkhTx.js#L56
↑お釣り金額を編集します。
トランザクションの作成にはbitcoinjs-libでPSBTを使っていますが、PSBTについては下記ブログ記事をご覧ください。
psbt.addInput({
hash: 'a0b29aefdaebc24452e9aa89ecca6efc487f1e8cc3aafea2bf98ed5090cc5629',
index: 0,
sequence: 0xffffffff,
witnessUtxo: {
script: Buffer.from(p2wpkh.output.toString('hex'),'hex',),
value: 10000000,
},
});
psbt.addOutput({
address: "tb1qh9yf6tvdj9qq5rlxvmpj7l67lcm3xd9ws5uzavnl8l8z42n0py6slg6xta",
value: 8000000,
});
psbt.addOutput({
address: "tb1qmhc3dz9qtmdfk98r3653jdahgu4tdqy7ne6qkx",
value: 1999999,
});
編集したら、トランザクション生成スクリプトを動かします。
node p2wpkhTx.js
privateKey_wif:
cPQ1kuReB8wWmLG6cK9LSBZCrxxBZDGFU19ngsfiMZT629MnphDJ
privateKey_wif:
cPQ1kuReB8wWmLG6cK9LSBZCrxxBZDGFU19ngsfiMZT629MnphDJ
Witness script:
00148a7089ae260d6d5d3922d642ea05b577ae0bf8ba
P2WPKH address:
tb1q3fcgnt3xp4k46wfz6epw5pd4w7hqh796jggprq
RawTx:
020000000001012956cc9050ed98bfa2feaac38c1e7f48fc6ecaec89aae95244c2ebdaef9ab2a00000000000ffffffff0200127a0000000000220020b9489d2d8d91400a0fe666c32f7f5efe371334ae85382eb27f3fce2aaa6f09357f841e0000000000160014ddf11688a05eda9b14e38ea91937b7472ab6809e024730440220763cc98c90693912e8e992b71bfe045cde1ad0bf2ad9594ad0c1561d2d414db202204e893980c7ec12779962de62cbb6c9ba434e280ba117491bed6f636631fb5f43012102fc637ace8e2141d73bbb4bf68a8963ac60521d11a7b35fdaf1cf8d292f84ae9400000000
RawTxをブロードキャストします。
sendrawtransaction RPC error: {"code":-26,"message":"min relay fee not met, 1 < 153"}
となりました。このエラーは手数料が足りないためです。153以上の手数料を設定しましょう。
手数料を書く場所はなく、(Inputの合計-Outputの合計)がマイナーに支払う手数料となります。
psbt.addOutput({
address: "tb1qmhc3dz9qtmdfk98r3653jdahgu4tdqy7ne6qkx",
value: 1999847,
});
お釣りの金額を調整しました。
再度、トランザクションを生成してブロードキャストします。
node p2wpkhTx.js
privateKey_wif:
cPQ1kuReB8wWmLG6cK9LSBZCrxxBZDGFU19ngsfiMZT629MnphDJ
privateKey_wif:
cPQ1kuReB8wWmLG6cK9LSBZCrxxBZDGFU19ngsfiMZT629MnphDJ
Witness script:
00148a7089ae260d6d5d3922d642ea05b577ae0bf8ba
P2WPKH address:
tb1q3fcgnt3xp4k46wfz6epw5pd4w7hqh796jggprq
RawTx:
020000000001012956cc9050ed98bfa2feaac38c1e7f48fc6ecaec89aae95244c2ebdaef9ab2a00000000000ffffffff0200127a0000000000220020b9489d2d8d91400a0fe666c32f7f5efe371334ae85382eb27f3fce2aaa6f0935e7831e0000000000160014ddf11688a05eda9b14e38ea91937b7472ab6809e0248304502210090ee3d3dd8cc5c76983ce5bf1285a34794f5d080b15bfef179aff7c53f94e08e02207867121ead642f2f0b1de785e8d0dcb4ba04e9f557e959311055c9d873926b7d012102fc637ace8e2141d73bbb4bf68a8963ac60521d11a7b35fdaf1cf8d292f84ae9400000000
ブロードキャストできました。
P2WSHマルチシグアドレスからの送金
先ほどの送金ではマルチシグアドレス宛に送金したので、それを原資にマルチシグアドレスからの送金を行います。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js
↑こちらのコードを編集していきます。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js#L52
↑こちらの行のTxHashを入金Txで置き換えます。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js#L53
↑Indexを編集します。(0, 1, 2という順番で数えます)
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js#L57
↑受け取った金額を編集します。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js#L60
↑宛先はマルチシグアドレスのaddressPath:m/44'/1'/0'/0/0のP2SH-P2WSHを指定しましょう。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js#L62
↑送金額を編集します。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js#L64
↑お釣りアドレスを編集します。addressPath:m/44'/1'/0'/1/0のP2WSHアドレスを指定しましょう。
https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wshTx.js#L66
↑お釣り金額を編集します。
psbt.addInput({
hash: '5ff70114e63214da1d1385935118cfb8791c17efffbdef88b3babd0ebc167839',
index: 0,
witnessScript: p2wsh.redeem.output,
witnessUtxo: {
script: Buffer.from('0020' + bitcoin.crypto.sha256(p2ms.output).toString('hex'), 'hex'),
value: 8000000,
},
});
psbt.addOutput({
address: "2MwZhrfcLDFJX1PG2LhuUJPzDiqMFxzSQ4G",
value: 6000000,
});
psbt.addOutput({
address: "tb1qgxxkdf0undcc9l4eyz5grxxaw4dateuf0etze5d688prd2g6r07qgq9jdr",
value: 1999810,
});
トランザクションスクリプトを動かして、、RawTxを得ます。
node p2wshTx.js
privateKey_wif:
cNCZNNyMvB7qrZQixiSdAc4YRUVyBqmEmZq7kHC7YBZza7u2TpWw
privateKey_wif:
cRrsUh3MsDdQjDbGodpTbp358rYt4CbLuN1zqgd5Mrk9Tv94kJmq
privateKey_wif:
cTH57qRVtUS9yHcCjmA3xpVjyMY6QKdBkG47w5Yx4bKE3fMWvAXh
P2WSH address:
tb1qh9yf6tvdj9qq5rlxvmpj7l67lcm3xd9ws5uzavnl8l8z42n0py6slg6xta
RawTx:
02000000000101397816bc0ebdbab388efbdffef171c79b8cf18519385131dda1432e61401f75f0000000000ffffffff02808d5b000000000017a9142f5f41088f837f36925b277cf4f97e5b77d58e7d87c2831e0000000000220020418d66a5fc9b7182feb920a88198dd755bd5e7897e562cd1ba39c236a91a1bfc040047304402202549b3e56ceb5562bac9691abf19d4c8c2a453580e732f788a755ce33d477ae602205306aaa5dc9bfc185ef6fc350f2c18c60c3d199f1c2620426f8955baa57176a801483045022100d8e8367c02269c9da9dfa03774a33456aa529f7e5008cb566c00998096dec43602202b163e10a7523a4701326322f59bcd13bca807a8454efdb0864a566433291a9801695221021d0abb918de315b7714b97d37a8105a271ad2d291e2c4eb5042ab50ab545494f2102bc527ea1d670def3afc5f60b36b7f194510c8d54568468845f061f77e4bf2a032102d0a09bd913cb01f44a7c656bab9a8b80b648c24139d039af8d01aed5679f8e6153ae00000000
先ほどと同じようにブロードキャストします。
ブロードキャストできました。
https://explorer.bc-2.jp/tx/f131cfd38f5020aa589bb9190e295ffb24cc569133b9b8d5826ef85a0a644a9a
Signetフルノードセットアップ
ここからは、Signetのフルノードを使います。Dockerを使えるようにしておいてください。
↑上記記事にまとめていますが、↓下記の方法でも実行できます(オススメは上記)
git clone https://github.com/kallewoof/signet-platform
signet-platform/fullnode/docker-entrypoint.sh
echo -e "signet=1\n[signet]\n$BITCOIN_EXTRA_ARGS" > $BITCOIN_DATA/bitcoin.conf
↓txindex=1\nを追加して以下の通りに書き換えてください。
echo -e "signet=1\n[signet]\ntxindex=1\n$BITCOIN_EXTRA_ARGS" > $BITCOIN_DATA/bitcoin.conf
cd fullnode
./build.sh
./run.sh
Docker操作
別ターミナルを開き、Dockerの中を操作するためコンテナのIDを取得
docker ps
ID=XXX
起動中のコンテナが一つだけの場合は以下で取得
ID=$(docker ps -q)
Dockerコンテナ内でコマンドを打ちやすくするためにエイリアスを設定
alias bcli="docker exec $ID bitcoin-cli"
bitcoindの状態を確認
bcli getblockchaininfo
同期できたら準備完了です。
P2SH-P2WSHアドレスから出金
P2SH-P2WSHアドレスへ入金したTXIDからRawTXを得ます。
bcli getrawtransaction f131cfd38f5020aa589bb9190e295ffb24cc569133b9b8d5826ef85a0a644a9a
02000000000101397816bc0ebdbab388efbdffef171c79b8cf18519385131dda1432e61401f75f0000000000ffffffff02808d5b000000000017a9142f5f41088f837f36925b277cf4f97e5b77d58e7d87c2831e0000000000220020418d66a5fc9b7182feb920a88198dd755bd5e7897e562cd1ba39c236a91a1bfc040047304402202549b3e56ceb5562bac9691abf19d4c8c2a453580e732f788a755ce33d477ae602205306aaa5dc9bfc185ef6fc350f2c18c60c3d199f1c2620426f8955baa57176a801483045022100d8e8367c02269c9da9dfa03774a33456aa529f7e5008cb566c00998096dec43602202b163e10a7523a4701326322f59bcd13bca807a8454efdb0864a566433291a9801695221021d0abb918de315b7714b97d37a8105a271ad2d291e2c4eb5042ab50ab545494f2102bc527ea1d670def3afc5f60b36b7f194510c8d54568468845f061f77e4bf2a032102d0a09bd913cb01f44a7c656bab9a8b80b648c24139d039af8d01aed5679f8e6153ae00000000
walllet-dev-study/p2shP2wshTx.jsを編集していきます。
https://github.com/shu-kob/walllet-dev-study/blob/6cf14dcad4ccd9869df0d6b7433a852388cf53b4/p2shP2wshTx.js#L58
↑得たRawTxで置き換えます。
https://github.com/shu-kob/walllet-dev-study/blob/6cf14dcad4ccd9869df0d6b7433a852388cf53b4/p2shP2wshTx.js#L61
↑こちらの行のTxHashを入金Txで置き換えます。
https://github.com/shu-kob/walllet-dev-study/blob/6cf14dcad4ccd9869df0d6b7433a852388cf53b4/p2shP2wshTx.js#L62
↑Indexを編集します。(0, 1, 2という順番で数えます)
https://github.com/shu-kob/walllet-dev-study/blob/6cf14dcad4ccd9869df0d6b7433a852388cf53b4/p2shP2wshTx.js#L68
↑宛先はシングルシグアドレスのaddressPath:m/44'/1'/0'/0/0のP2PKHを指定しましょう。
https://github.com/shu-kob/walllet-dev-study/blob/6cf14dcad4ccd9869df0d6b7433a852388cf53b4/p2shP2wpkhTx.js#L55
↑お釣りアドレスを編集します。addressPath:m/44'/1'/0'/1/0のP2SH-P2WSHアドレスを指定しましょう。
https://github.com/shu-kob/walllet-dev-study/blob/6cf14dcad4ccd9869df0d6b7433a852388cf53b4/p2shP2wpkhTx.js#L56
↑お釣り金額を編集します。
addressPath:m/44'/1'/0'/0/1のP2SH-P2WSHへのOutputを二つ増やして以下のように組み立てました。
増やすのに使ったアドレスは以下です。
addressPath:m/44'/1'/0'/0/1のP2PKH
addressPath:m/44'/1'/0'/0/2のP2PKH
psbt.addInput({
hash: 'f131cfd38f5020aa589bb9190e295ffb24cc569133b9b8d5826ef85a0a644a9a',
index: 0,
redeemScript: p2wsh.output,
witnessScript: p2wsh.redeem.output,
nonWitnessUtxo: Buffer.from(previousRawTx, 'hex'),
});
psbt.addOutput({
address: "mt8xMnq8MGPSHC42hfFc8xuTxJ3uqoJTA9",
value: 4000000,
});
psbt.addOutput({
address: "mj12LAXrTjvyQQBBJQg1MqhN2JHHWxc8QZ",
value: 1700000,
});
psbt.addOutput({
address: "mqhpyiCtz9xL9YZMc4QrBEbKZDUBnAQiU8",
value: 200000,
});
psbt.addOutput({
address: "2Myv2XaqYXiM5ttNiG4jvtALrCmE6qJRCtZ",
value: 99716,
});
node p2shP2wshTx.js
privateKey_wif:
cNCZNNyMvB7qrZQixiSdAc4YRUVyBqmEmZq7kHC7YBZza7u2TpWw
privateKey_wif:
cRrsUh3MsDdQjDbGodpTbp358rYt4CbLuN1zqgd5Mrk9Tv94kJmq
privateKey_wif:
cTH57qRVtUS9yHcCjmA3xpVjyMY6QKdBkG47w5Yx4bKE3fMWvAXh
P2SH-P2WSH address:
2MwZhrfcLDFJX1PG2LhuUJPzDiqMFxzSQ4G
RawTx:
020000000001019a4a640a5af86e82d5b8b9339156cc24fb5f290e19b99b58aa20508fd3cf31f10000000023220020b9489d2d8d91400a0fe666c32f7f5efe371334ae85382eb27f3fce2aaa6f0935ffffffff0400093d00000000001976a9148a7089ae260d6d5d3922d642ea05b577ae0bf8ba88aca0f01900000000001976a914263764c95da84aa2324ff65ec092f1d4d1af60d888ac400d0300000000001976a9146fbfb9e2b678fea2b9300ae8285ec6e01855ee9088ac848501000000000017a9144927691d3824f9906de54aaded6d08c7d44421008704004830450221008c8454354cbdcb426acdc5934c224704916c45d10ea6eeb2b74b13e71385ad8502204fd58d62fc2a8de9ab39245479a5217f6a7558a137c8a47f1226ac35b127b8fa01483045022100c1615d91a2dbacff54d346079aae66fdac265ef37bbe815b7fe1310a34548ad202207abf2facf05dd3da880b0e06c8bb7e20e605365725d694a76a9d9a9d1411626f01695221021d0abb918de315b7714b97d37a8105a271ad2d291e2c4eb5042ab50ab545494f2102bc527ea1d670def3afc5f60b36b7f194510c8d54568468845f061f77e4bf2a032102d0a09bd913cb01f44a7c656bab9a8b80b648c24139d039af8d01aed5679f8e6153ae00000000
今はフルノードを起動させているので、フルノードからブロードキャストしてみましょう。
bcli sendrawtransaction 020000000001019a4a640a5af86e82d5b8b9339156cc24fb5f290e19b99b58aa20508fd3cf31f10000000023220020b9489d2d8d91400a0fe666c32f7f5efe371334ae85382eb27f3fce2aaa6f0935ffffffff0400093d00000000001976a9148a7089ae260d6d5d3922d642ea05b577ae0bf8ba88aca0f01900000000001976a914263764c95da84aa2324ff65ec092f1d4d1af60d888ac400d0300000000001976a9146fbfb9e2b678fea2b9300ae8285ec6e01855ee9088ac848501000000000017a9144927691d3824f9906de54aaded6d08c7d44421008704004830450221008c8454354cbdcb426acdc5934c224704916c45d10ea6eeb2b74b13e71385ad8502204fd58d62fc2a8de9ab39245479a5217f6a7558a137c8a47f1226ac35b127b8fa01483045022100c1615d91a2dbacff54d346079aae66fdac265ef37bbe815b7fe1310a34548ad202207abf2facf05dd3da880b0e06c8bb7e20e605365725d694a76a9d9a9d1411626f01695221021d0abb918de315b7714b97d37a8105a271ad2d291e2c4eb5042ab50ab545494f2102bc527ea1d670def3afc5f60b36b7f194510c8d54568468845f061f77e4bf2a032102d0a09bd913cb01f44a7c656bab9a8b80b648c24139d039af8d01aed5679f8e6153ae00000000
900b72ca70b8fea9cea4dd8fa0cbb3650da0a4a5ac04f18f1c5048d2c853cd8d
3つ以上OutputのあるTXをブロードキャストできました。
https://explorer.bc-2.jp/tx/900b72ca70b8fea9cea4dd8fa0cbb3650da0a4a5ac04f18f1c5048d2c853cd8d
複数のInputを持つトランザクション
例1
https://github.com/shu-kob/walllet-dev-study/blob/master/p2pkhTx.js
こちらを編集してにP2PKHの3アドレス宛Output3つをInputに持つTXを作ってみましょう。
↓例では、手数料を積みすぎているので、うまいこと調整してください。
https://explorer.bc-2.jp/tx/15552e62bb92a84a7209cf16f51c2ac65fe5a4e2cfe1acbe2fb067326acf4619
例2
例1ではInputのpreviousTxが全て同一でした。このようなケースは稀で、previousTxが異なるケースを作ってみましょう。