LoginSignup
14

More than 5 years have passed since last update.

Bitcoin Standard Transactions(送信)

Last updated at Posted at 2017-11-20

Standard Transactions

Bitcoinでは標準的なTransactionというものがあります。
Standard Transactions
これは、tx_outpk_scriptに設定するscriptの形式の事といっても過言ではないと思います。
SegwitがActiveになる前は、5つのStandard Transactionsが定められていました。
ここではbitcoin-cliを使って、5つのStandard Transactionsに送信し、送信されたものを、さらに送信してみます。

Pay To Public Key Hash (P2PKH)

現在のBitcoinで最も使われている形式です。(今後はSegwitへ移行していくと思いますが・・・)
Transactionoutputに設定する、Pubkey scriptpk_scriptlocking scriptなど呼び方は様々)
は、下記の上段にある形式となります。
また、使うときにinputに設定する、Signature scriptscriptSigunlocking scriptなど呼び方は様々)
は、下記の下段になる形となります。

Pubkey script   : OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Signature script: <sig> <pubkey>

ここでは、以下の<pubkey>(公開鍵)を利用します。
これからHASH160を計算して、<PubKeyHash>を求め、Pubkey scriptにします。

<pubkey>     : 027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70af
<PubKeyHash> : 925d4028880bd0c9d68fbc7fc7dfee976698629c
Pubkey script: 76a914925d4028880bd0c9d68fbc7fc7dfee976698629c88ac

Pay To Script Hash (P2SH)

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

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

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のバグで必要となっています。

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 pubkey>    : 02e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b
<B pubkey>    : 02ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6
<C pubkey>    : 0271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a9
<redeemScript>: 522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae
<Hash160(redeemScript)>: f58d75163cbaa805d2c63f8bdf11b59f19062ce4
Pubkey script: a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487

Multisig

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

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つの署名があれば良いというマルチサインです。

<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となります。

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

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

<pubkey>     : 027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70af
Pubkey script: 21027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70afac

Null Data

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

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

Pubkey Script: OP_RETURN <0 to 40 bytes of data>
(Null data scripts cannot be spent, so there's no signature script.)

今回は、データを以下の上段にします。
その場合、Pubkey Scriptは以下の下段にのようになります。

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

Transactionの送信

5つのStandard Transactionsに送信してみましょう。
regtestでBitcoinを起動します。(Bitcoindの起動と停止
Bitcoinを所持しているか確認します。

./bitcoin-cli -regtest getbalance

無い場合は、generateを行います。

./bitcoin-cli -regtest generate 101

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

010000000005509e9800000000001976a914925d4028880bd0c9d68fbc7fc7dfee976698629c88ac509e98000000000017a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487509e98000000000069522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae509e9800000000002321027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70afac0000000000000000126a1000112233445566778899aabbccddeeff00000000

まずは、Transactionの内容をdecoderawtransactionで見てみます。
inputvin)が0個、outputvout)が5個、「Null Data」以外、それぞれ0.10002000 BTCづつ入れます。

./bitcoin-cli -regtest decoderawtransaction 010000000005509e9800000000001976a914925d4028880bd0c9d68fbc7fc7dfee976698629c88ac509e98000000000017a914f58d75163cbaa805d2c63f8bdf11b59f19062ce487509e98000000000069522102e5740e63bad28081ed7cf654dd6c19029ca03382fc05ab5f5dda81f2c55b845b2102ec6d499aefd540e90357f1004a136049d1f7df5ad99c44c46e3ed4169e40acb6210271550e6c83a9381f35c568d1a80e11fa3e0efc97dfd0e0f17492a2edb64c37a953ae509e9800000000002321027592aab5d43618dda13fba71e3993cd7517a712d3da49664c06ee1bd3d1f70afac0000000000000000126a1000112233445566778899aabbccddeeff00000000

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

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

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

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

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

./bitcoin-cli -regtest decoderawtransaction <transaction hex>

このTransactionには、inputvin)のscriptSigに何も入っていない為、署名する必要がありあます。
<transaction hex>signrawtransactionを用いて、署名します。

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

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

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

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

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

Transactioninputvin)にscriptSigが設定されている事がわかります。

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

./bitcoin-cli -regtest sendrawtransaction <signed transaction hex>

結果は、<txid>が出ます。(32byte、hexで64文字の値が出ます。)
この<txid>をコピーしておいてください。この後で使います。

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

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

5つのStandard Transactionsへの送信は完了となります。

Transactionの利用

5つのStandard Transactionsへの送信が出来たと思います。
4つの、output(vout)を利用していきたいと思います。
(1つは、「Null Data」なので利用できません。)

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

address : mrkcWXtBEiTsgrjFDppGNZZU1Zgr7bnseh

Pay To Public Key Hash (P2PKH)

先ほど送信した、<txid>0番目がP2PKHなので、createrawtransactionTransactionを作成します。
valueは、手数料(fee2,000 satoshiを引いた、0.1 BTCとしています。)

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

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

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

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

<p2phk prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN8kokULeTxo

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

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

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

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

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

./bitcoin-cli -regtest sendrawtransaction <signed p2pkh transaction hex>

結果は、<p2pkh txid>が出ます。(32byte、hexで64文字の値が出ます。)

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

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

Pay To Script Hash (P2SH)

送信した、<txid>1番目がP2SHなので、createrawtransactionTransactionを作成します。
valueは、手数料(fee2,000 satoshiを引いた、0.1 BTCとしています。)

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

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

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

この、TransactionscriptSigに何も入っていない為、署名が必要となります。
このP2SHは、3つのpubkey(公開鍵)から、2つの署名が必要です。
2つのprivate keyは以下のとおりです。

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

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

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

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

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

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

./bitcoin-cli -regtest sendrawtransaction <signed p2sh transaction hex>

結果は、<p2sh txid>が出ます。(32byte、hexで64文字の値が出ます。)

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

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

Multisig

送信した、<txid>2番目がMultisigなので、createrawtransactionTransactionを作成します。
valueは、手数料(fee2,000 satoshiを引いた、0.1 BTCとしています。)

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

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

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

この、TransactionscriptSigに何も入っていない為、署名が必要となります。
このMultisigは、3つのpubkey(公開鍵)から、2つの署名が必要です。
2つのprivate keyは以下のとおりです。

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

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

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

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

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

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

./bitcoin-cli -regtest sendrawtransaction <signed multisig transaction hex>

結果は、<multisig txid>が出ます。(32byte、hexで64文字の値が出ます。)

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

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

Pubkey

送信した、<txid>3番目がPubkeyなので、createrawtransactionTransactionを作成します。
valueは、手数料(fee2,000 satoshiを引いた、0.1 BTCとしています。)

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

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

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

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

<p2pk prvkey> : cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN8kokULeTxo

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

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

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

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

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

./bitcoin-cli -regtest sendrawtransaction <signed p2pk transaction hex>

結果は、<p2pk txid>が出ます。(32byte、hexで64文字の値が出ます。)

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

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

確認

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

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

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14