bitcoinjs-libを使ったウォレット開発入門

# 資料の最新化

【追記】
こちらの資料で最新化してしています。
 - https://github.com/shu-kob/study-dev-wallet

# はじめに

https://cryptocurrency.connpass.com/event/224832/

本記事は、9/29(水)ビットコインとか勉強会ハンズオンの資料になります。

↓アーカイブ動画も公開していますので、併せてご覧ください。

https://youtu.be/QLWieBgTAto

# ハンズオンの準備

## nodejs

nodejsをインストールしておきます。

## ソースコードの準備

https://github.com/shu-kob/walllet-dev-study

```
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はお釣りアドレスです。

#　生成したアドレスに送金

https://signet.bc-2.jp/

Signet Faucetのアドレス入力欄にaddressPath:m/44'/1'/0'/0/0のP2WPKHアドレスを入れます。

送金できらたら、Explorerで確認しましょう。入金されてからExplorerに表示されるまで数十秒かかります。

https://explorer.bc-2.jp/tx/a0b29aefdaebc24452e9aa89ecca6efc487f1e8cc3aafea2bf98ed5090cc5629

# マルチシグアドレスを作成

受け取りアドレスとなる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トランザクションを作成

https://github.com/shu-kob/walllet-dev-study/blob/master/getSingleSigAddresses.js

こちらのコードを流用します。

https://github.com/shu-kob/walllet-dev-study/blob/3478d2fd792c5112a25711b7b25b136969cbd003/p2wpkhTx.js#L42

↑こちらの行の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については下記ブログ記事をご覧ください。


https://techmedia-think.hatenablog.com/entry/2017/09/19/193313


https://tech.bitbank.cc/20201213/

```
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をブロードキャストします。

https://explorer.bc-2.jp/tx/push

```
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
```

https://explorer.bc-2.jp/tx/5ff70114e63214da1d1385935118cfb8791c17efffbdef88b3babd0ebc167839

ブロードキャストできました。

# 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/push

ブロードキャストできました。
https://explorer.bc-2.jp/tx/f131cfd38f5020aa589bb9190e295ffb24cc569133b9b8d5826ef85a0a644a9a

# Signetフルノードセットアップ

ここからは、Signetのフルノードを使います。Dockerを使えるようにしておいてください。

https://qiita.com/shu-kob/items/488b291ce40fbc398c3c

↑上記記事にまとめていますが、↓下記の方法でも実行できます（オススメは上記）

```
git clone https://github.com/kallewoof/signet-platform
```

signet-platform/fullnode/docker-entrypoint.sh

https://github.com/kallewoof/signet-platform/blob/d171663c219e93bba05e150a7e5cc555c402d7cd/fullnode/docker-entrypoint.sh#L8

```
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#L52
↑送金額を編集します。

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が異なるケースを作ってみましょう。

https://github.com/shu-kob/walllet-dev-study/blob/master/p2shP2wpkhTx.js

https://explorer.bc-2.jp/tx/f0d6fb180b6506701248575701ca004fd903c766d4d27e114124f4edb19b1f2a