Bitcoin Standard Transactions（送信）

# Standard Transactions

Bitcoinでは標準的なTransactionというものがあります。
[Standard Transactions](https://bitcoin.org/en/developer-guide#standard-transactions)
これは、`tx_out`の`pk_script`に設定する`script`の形式の事といっても過言ではないと思います。
SegwitがActiveになる前は、5つの`Standard Transactions`が定められていました。
ここでは`bitcoin-cli`を使って、5つの`Standard Transactions`に送信し、送信されたものを、さらに送信してみます。

### Pay To Public Key Hash (P2PKH)

現在のBitcoinで最も使われている形式です。（今後はSegwitへ移行していくと思いますが・・・）
`Transaction`の`output`に設定する、`Pubkey script`（`pk_script`や`locking script`など呼び方は様々）
は、下記の上段にある形式となります。
また、使うときに`input`に設定する、`Signature script`（`scriptSig`や`unlocking script`など呼び方は様々）
は、下記の下段になる形となります。

```text
Pubkey script   : OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Signature script: <sig> <pubkey>
```
ここでは、以下の`<pubkey>`（公開鍵）を利用します。
これから`HASH160`を計算して、`<PubKeyHash>`を求め、`Pubkey script`にします。

<!-- 0x1111 -->

```text
<pubkey>     : 027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70af
<PubKeyHash> : 925d4028880bd0c9d68fbc7fc7dfee976698629c
Pubkey script: 76a914925d4028880bd0c9d68fbc7fc7dfee976698629c88ac
```
### Pay To Script Hash (P2SH)

`Transaction`の`output`が受け取り、`input`が支払いになります。
支払いには、どの`Transaction`（`txid`）のどの`output`（`vout`）が自分が所有している事を証明する必要があります。
P2PKH、Multisig、Public、では決まったScript形式によって、これらを実現する事ができます。
それ以外のScriptを組みたい場合に使うのが、このP2SHとなります。（これもSegwitへ移行していくと思います。）

下記の上段が`output`に設定するScript、下段が`input`に設定するScriptとなります。
独自のScriptを`redeemScript`と言います。

```text
Pubkey script   : OP_HASH160 <Hash160(redeemScript)> OP_EQUAL
Signature script: <sig> [sig] [sig...] <redeemScript>
```

ここでは、`Redeem script`をマルチサインとします。
3つの`pubkey`（公開鍵）から、2つの署名があれば良いScriptとします。
この場合、`Signature script`は下記の一番下となります。
先頭に`OP_0`がありますが、これは`OP_CHECKMULTISIG`のバグで必要となっています。

```text
Redeem script   : OP_2 <A pubkey> <B pubkey> <C pubkey> OP_3 OP_CHECKMULTISIG
Pubkey script   : OP_HASH160 <Hash160(redeemScript)> OP_EQUAL
Signature script: OP_0 <A sig> <C sig> <redeemScript>
```
実際に以下の3つの`pubkey`を利用して、`<redeemScript>`をつくります。
それを`HASH160`をしたものが`<Hash160(redeemScript)>`となります。
これを、`Pubkey script`にします。

<!-- A 0x2222 -->
<!-- B 0x3333 -->
<!-- C 0x4444 -->

```text
<A pubkey>    : 02e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b
<B pubkey>    : 02ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6
<C pubkey>    : 0271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a9
<redeemScript>: 522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae
<Hash160(redeemScript)>: f58d75163cbaa805d2c63f8bdf11b59f19062ce4
Pubkey script: a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487
```

### Multisig

これはマルチサインの形となります。
`n`個の公開鍵から`m`個の署名で良いという形式です。`n`と`m`は1から15まで(`n<=m`）可能です。

```text
Pubkey script   : <m> <A pubkey> [B pubkey] [C pubkey...] <n> OP_CHECKMULTISIG
Signature script: OP_0 <A sig> [B sig] [C sig...]
```
P2SHと同じように、以下の3つの`pubkey`を利用して、`Pubkey script`を作成します。
3つの`pubkey`（公開鍵）から、2つの署名があれば良いというマルチサインです。

```text
<A pubkey>   : 02e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b
<B pubkey>   : 02ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6
<C pubkey>   : 0271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a9
Pubkey script: OP_2 <A pubkey> <B pubkey> <C pubkey> OP_3 OP_CHECKMULTISIG
Pubkey script: 522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae
```

### Pubkey

初期の形式となります、`bitcoind`でマイニングするとこの形式が使われているようです。
下記の上段が`output`に設定するScript、下段が`input`に設定するScriptとなります。

```text
Pubkey script   : <pubkey> OP_CHECKSIG
Signature script: <sig>
```

P2PKHと同じように、以下の`<pubkey>`（公開鍵）を利用すると、`Pubkey script`は以下のようになります。

<!-- 0x1111 -->

```text
<pubkey>     : 027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70af
Pubkey script: 21027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70afac
```

### Null Data

これは特殊な`output`で、`input`には使う事が出来ません。したがって、`outpot`の`value`が`0`でも許されます。
コメントなどの用途で、実際には日時を入れる事が多いようです。
ただし、これを入れると`Transaction`のデータ量が増える為、手数料（`fee`）が高くなります。

`Pubkey Script`の先頭に`OP_RETURN`を入れるだけで良いです。

```text
Pubkey Script: OP_RETURN <0 to 40 bytes of data>
(Null data scripts cannot be spent, so there's no signature script.)
```
今回は、データを以下の上段にします。
その場合、`Pubkey Script`は以下の下段にのようになります。

```text
<0 to 40 bytes of data>: 00112233445566778899aabbccddeeff
Pubkey Script          : 6a1000112233445566778899aabbccddeeff
```

## Transactionの送信

５つの`Standard Transactions`に送信してみましょう。
`regtest`でBitcoinを起動します。（[Bitcoindの起動と停止](https://qiita.com/tnakagawa/items/a8aefab40a97aa1159f7)）
Bitcoinを所持しているか確認します。

```bash
./bitcoin-cli -regtest getbalance
```
無い場合は、`generate`を行います。

```bash
./bitcoin-cli -regtest generate 101
```

`createrawtransaction`で`Transaction`を作成したいのですが、P2PKHとP2SHにしか対応していないようなので、
以下の`Transaction`を作成しました。

```bash
010000000005509e9800000000001976a914925d4028880bd0c9d68fbc7fc7dfee976698629c88ac509e98000000000017a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487509e98000000000069522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae509e9800000000002321027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70afac0000000000000000126a1000112233445566778899aabbccddeeff00000000
```

まずは、`Transaction`の内容を`decoderawtransaction`で見てみます。
`input`（`vin`）が0個、`output`（`vout`）が5個、「`Null Data`」以外、それぞれ`0.10002000 BTC`づつ入れます。

```bash
./bitcoin-cli -regtest decoderawtransaction 010000000005509e9800000000001976a914925d4028880bd0c9d68fbc7fc7dfee976698629c88ac509e98000000000017a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487509e98000000000069522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae509e9800000000002321027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70afac0000000000000000126a1000112233445566778899aabbccddeeff00000000
```

この`Transaction`を送信する為に、`fundrawtransaction`を使って、必要な`input`を追加します。
「`"{\"changePosition\":5}"`」オプションは、お釣りの`output`を一番最後にする為のものです。

```bash
./bitcoin-cli -regtest fundrawtransaction 010000000005509e9800000000001976a914925d4028880bd0c9d68fbc7fc7dfee976698629c88ac509e98000000000017a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487509e98000000000069522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae509e9800000000002321027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70afac0000000000000000126a1000112233445566778899aabbccddeeff00000000 "{\"changePosition\":5}"
```

※：ここからは、`input`がそれぞれの環境で違うので、結果が異なります。自身の環境での結果を利用してください。
結果が以下のように表示されます。

```json
{
  "hex": "<transaction hex>",
  "changepos": 5,
  "fee": 0.00008180
}
```

一旦、この`<transaction hex>`を`decoderawtransaction`を使って見てみます。
`input`（`vin`）が１個以上設定されている事がわかります。
また、`output`(`vout`）の最後にお釣り用の`output`が追加されている事がわかります。

```bash
./bitcoin-cli -regtest decoderawtransaction <transaction hex>
```
この`Transaction`には、`input`（`vin`）の`scriptSig`に何も入っていない為、署名する必要がありあます。
`<transaction hex>`を`signrawtransaction`を用いて、署名します。

```bash
./bitcoin-cli -regtest signrawtransaction <transaction hex>
```

結果が以下のように出ます。

```json
{
  "hex": "<signed transaction hex>",
  "complete": true
}
```

この`<signed transaction hex>`を`decoderawtransaction`を使って見てみます。

```bash
./bitcoin-cli -regtest decoderawtransaction <signed transaction hex>
```

`Transaction`の`input`（`vin`）に`scriptSig`が設定されている事がわかります。

この`<signed transaction hex>`を`sendrawtransaction`を使って送信します。

```bash
./bitcoin-cli -regtest sendrawtransaction <signed transaction hex>
```
結果は、`<txid>`が出ます。（32byte、hexで64文字の値が出ます。）
この`<txid>`をコピーしておいてください。この後で使います。

このままでは、ブロックに入らないので、`generate`してブロックに入れます。
`<txid>`を`getrawtransaction`で見てみます。

```bash
./bitcoin-cli -regtest generate 1
./bitcoin-cli -regtest getrawtransaction <txid> 1
```
５つの`Standard Transactions`への送信は完了となります。

## Transactionの利用

５つの`Standard Transactions`への送信が出来たと思います。
４つの、`output`(`vout`）を利用していきたいと思います。
（１つは、「`Null Data`」なので利用できません。）

送信先は、全て以下とします。

<!-- 0x5555 -->

```text
address : mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh
```

### Pay To Public Key Hash (P2PKH)

先ほど送信した、`<txid>`の`0`番目がP2PKHなので、`createrawtransaction`で`Transaction`を作成します。
（`value`は、手数料（`fee`）`2,000 satoshi`を引いた、`0.1 BTC`としています。）

```bash
./bitcoin-cli -regtest createrawtransaction "[{\"txid\":\"<txid>\",\"vout\":0}]" "{\"mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh\":0.1}"
```

結果は`Transaction`の`hex`（`<p2pkh transaction hex>`）が出ます、これをコピーしてください。
この`<p2pkh transaction hex>`を`decoderawtransaction`を使って見てみます。


```bash
./bitcoin-cli -regtest decoderawtransaction <p2pkh transaction hex>
```

この、`Transaction`は`scriptSig`に何も入っていない為、署名が必要となります。
`private key`は以下のとおりです。

```text
<p2phk prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN8kokULeTxo
```

`<p2pkh transaction hex>`から、`signrawtransaction`を使って署名します。

```bash
./bitcoin-cli -regtest signrawtransaction <p2pkh transaction hex> "[]" "[\"cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN8kokULeTxo\"]"
```

結果が以下のように出ます。

```json
{
  "hex": "<signed p2pkh transaction hex>",
  "complete": true
}
```

この`<signed p2pkh transaction hex>`を`sendrawtransaction`を使って送信します。

```bash
./bitcoin-cli -regtest sendrawtransaction <signed p2pkh transaction hex>
```
結果は、`<p2pkh txid>`が出ます。（32byte、hexで64文字の値が出ます。）

このままでは、ブロックに入らないので、`generate`してブロックに入れます。
`<p2pkh txid>`を`getrawtransaction`で見てみます。

```bash
./bitcoin-cli -regtest generate 1
./bitcoin-cli -regtest getrawtransaction <p2pkh txid> 1
```

### Pay To Script Hash (P2SH)

送信した、`<txid>`の`1`番目がP2SHなので、`createrawtransaction`で`Transaction`を作成します。
（`value`は、手数料（`fee`）`2,000 satoshi`を引いた、`0.1 BTC`としています。）

```bash
./bitcoin-cli -regtest createrawtransaction "[{\"txid\":\"<txid>\",\"vout\":1}]" "{\"mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh\":0.1}"
```

結果は`Transaction`の`hex`（`<p2sh transaction hex>`）が出ます、これをコピーしてください。
この`<p2sh transaction hex>`を`decoderawtransaction`を使って見てみます。


```bash
./bitcoin-cli -regtest decoderawtransaction <p2sh transaction hex>
```

この、`Transaction`は`scriptSig`に何も入っていない為、署名が必要となります。
このP2SHは、３つの`pubkey`（公開鍵）から、２つの署名が必要です。
２つの`private key`は以下のとおりです。

```text
<p2sh A prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN9QKPG3J8w2
<p2sh C prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMNAhLetXSy6B
```

`<p2sh transaction hex>`と`<txid>`から、`signrawtransaction`を使って署名します。
P2SHの場合、`redeemScript`が必要となる為、`signrawtransaction`の第２パラメータが必要となります。

```bash
./bitcoin-cli -regtest signrawtransaction <p2sh transaction hex> "[{\"txid\":\"<txid>\",\"vout\":1,\"scriptPubKey\":\"a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487\",\"redeemScript\":\"522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae\"}]" "[\"cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN9QKPG3J8w2\",\"cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMNAhLetXSy6B\"]"
```

結果が以下のように出ます。

```json
{
  "hex": "<signed p2sh transaction hex>",
  "complete": true
}
```

この`<signed p2sh transaction hex>`を`sendrawtransaction`を使って送信します。

```bash
./bitcoin-cli -regtest sendrawtransaction <signed p2sh transaction hex>
```
結果は、`<p2sh txid>`が出ます。（32byte、hexで64文字の値が出ます。）

このままでは、ブロックに入らないので、`generate`してブロックに入れます。
`<p2sh txid>`を`getrawtransaction`で見てみます。

```bash
./bitcoin-cli -regtest generate 1
./bitcoin-cli -regtest getrawtransaction <p2sh txid> 1
```

### Multisig

送信した、`<txid>`の`2`番目がMultisigなので、`createrawtransaction`で`Transaction`を作成します。
（`value`は、手数料（`fee`）`2,000 satoshi`を引いた、`0.1 BTC`としています。）

```bash
./bitcoin-cli -regtest createrawtransaction "[{\"txid\":\"<txid>\",\"vout\":2}]" "{\"mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh\":0.1}"
```

結果は`Transaction`の`hex`（`<multisig transaction hex>`）が出ます、これをコピーしてください。
この`<multisig transaction hex>`を`decoderawtransaction`を使って見てみます。

```bash
./bitcoin-cli -regtest decoderawtransaction <multisig transaction hex>
```

この、`Transaction`は`scriptSig`に何も入っていない為、署名が必要となります。
このMultisigは、３つの`pubkey`（公開鍵）から、２つの署名が必要です。
２つの`private key`は以下のとおりです。

```text
<p2sh A prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN9QKPG3J8w2
<p2sh C prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMNAhLetXSy6B
```

`<multisig transaction hex>`と`<txid>`から、`signrawtransaction`を使って署名します。
P2SHの場合、`redeemScript`が必要となる為、`signrawtransaction`の第２パラメータが必要となります。

```bash
./bitcoin-cli -regtest signrawtransaction <multisig transaction hex> "[]" "[\"cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN9QKPG3J8w2\",\"cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMNAhLetXSy6B\"]"
```

結果が以下のように出ます。

```json
{
  "hex": "<signed multisig transaction hex>",
  "complete": true
}
```

この`<signed multisig transaction hex>`を`sendrawtransaction`を使って送信します。

```bash
./bitcoin-cli -regtest sendrawtransaction <signed multisig transaction hex>
```
結果は、`<multisig txid>`が出ます。（32byte、hexで64文字の値が出ます。）

このままでは、ブロックに入らないので、`generate`してブロックに入れます。
`<multisig txid>`を`getrawtransaction`で見てみます。

```bash
./bitcoin-cli -regtest generate 1
./bitcoin-cli -regtest getrawtransaction <multisig txid> 1
```

### Pubkey

送信した、`<txid>`の`3`番目がPubkeyなので、`createrawtransaction`で`Transaction`を作成します。
（`value`は、手数料（`fee`）`2,000 satoshi`を引いた、`0.1 BTC`としています。）

```bash
./bitcoin-cli -regtest createrawtransaction "[{\"txid\":\"<txid>\",\"vout\":3}]" "{\"mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh\":0.1}"
```

結果は`Transaction`の`hex`（`<p2pk transaction hex>`）が出ます、これをコピーしてください。
この`<p2pk transaction hex>`を`decoderawtransaction`を使って見てみます。

```bash
./bitcoin-cli -regtest decoderawtransaction <p2pk transaction hex>
```

この、`Transaction`は`scriptSig`に何も入っていない為、署名が必要となります。
`private key`は以下のとおりです。

```text
<p2pk prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN8kokULeTxo
```

`<p2pk transaction hex>`から、`signrawtransaction`を使って署名します。

```bash
./bitcoin-cli -regtest signrawtransaction <p2pk transaction hex> "[]" "[\"cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN8kokULeTxo\"]"
```

結果が以下のように出ます。

```json
{
  "hex": "<signed p2pk transaction hex>",
  "complete": true
}
```

この`<signed p2pk transaction hex>`を`sendrawtransaction`を使って送信します。

```bash
./bitcoin-cli -regtest sendrawtransaction <signed p2pk transaction hex>
```
結果は、`<p2pk txid>`が出ます。（32byte、hexで64文字の値が出ます。）

このままでは、ブロックに入らないので、`generate`してブロックに入れます。
`<p2pk txid>`を`getrawtransaction`で見てみます。

```bash
./bitcoin-cli -regtest generate 1
./bitcoin-cli -regtest getrawtransaction <p2pk txid> 1
```

## 確認

以下を実行して、アドレスに送信された事を確認してみましょう。

```bash
./bitcoin-cli -regtest importaddress mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh
./bitcoin-cli -regtest getreceivedbyaddress mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh
./bitcoin-cli -regtest listunspent 1 9999999 "[\"mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh\"]"
```

`0.4 BTC`入っている事が確認できます。