取引ID(transaction id) の hash値を求めてみる 〜 txinsまで

技術メモ

以前pycoinを使い取引IDのhash値を求めてしまったが、今回はより深く理解するためにhashlibでがんばって取引IDのhash値を求めてみる

取引IDの構造

全体の構造を抑えるには以下の図が非常にわかりやすい。
Bitcoinを技術的に理解する 39ページ

ちなみに、bitcoin wikiの記載はこちら

これらを元に以下数値をくっつけてhash化していき「fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4」を求める。

具体的な計算

https://api.blockcypher.com/v1/btc/main/txs/fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4

こちらの取引IDの計算を自分でも実際にやってみる。

https://github.com/richardkiss/pycoin/blob/1105b29dfae217b41944c6bd379c1a6d9eb4fdb7/pycoin/tx/Tx.py#L204
https://github.com/richardkiss/pycoin/blob/master/pycoin/tx/TxIn.py#L56
https://github.com/richardkiss/pycoin/blob/master/pycoin/tx/TxOut.py#L50

この辺りを必死に読みとく。

まずは以下のような値を用意する。

version  = 1
txinsvi = 1
txins = [
    {
         'previous_hash': '87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03'
        ,'previous_index': 0
        ,'script': '493046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748014104f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3'
        ,'sequence': 4294967295
    }
]
txoutsvi = 2
txouts = [
    {
        'coin_value' : 556000000
        ,'script' :  '76a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac'
    }
    ,{
        'coin_value' : 4444000000
        ,'script' :  '76a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac'
    }
]
nlocktime = 0

値の選定の仕方があっているかどうか不安だったため、txins の値を自分でhashしてみて、pycoinの値と合うかまず確認

txinから。
stream_structのコードを確認しておく。

https://github.com/richardkiss/pycoin/blob/6b9fb1c280343164d469d1c50b327a06ea6e89de/pycoin/serialize/streamer.py#L46

    def stream_struct(self, fmt, f, *args):
        for c, v in zip(fmt, args):
            self.stream_lookup(f, v)

で、stream_lookup は

https://github.com/richardkiss/pycoin/blob/6b9fb1c280343164d469d1c50b327a06ea6e89de/pycoin/serialize/streamer.py#L10

    def register_functions(self, lookup):
        for c, v in lookup:
            parse_f, stream_f = v
            self.parse_lookup = parse_f
            self.stream_lookup = stream_f

で入れられていて、

https://github.com/richardkiss/pycoin/blob/d25926a41c67e2ada2c04c5035f705b2476fd868/pycoin/serialize/bitcoin_streamer.py#L54

で定義されている。

txinのstream。

    def stream(self, f, blank_solutions=False):
        script = b'' if blank_solutions else self.script
        stream_struct("#LSL", f, self.previous_hash, self.previous_index, script, self.sequence)

これらを参照に、各変数をバイト列に直すと以下のような式なるはず。

txinは上述の値の順番でいくと

– 前のハッシュ入力
– 前の出力index
– スクリプトバイト長
– 署名スクリプト
– シーケンス終端記号

となる。

b_version = format(version, "08x").decode("hex")[::-1]
b_txinsvi = format(txinsvi, "02x").decode("hex")[::-1]

script = txins[0]['script'].decode("hex")
b_txins = h2b_rev(txins[0]['previous_hash']) + format(txins[0]['previous_index'], "08x").decode("hex")[::-1] + format(len(script), "02x").decode("hex") + script + format(txins[0]['sequence'], "02x").decode("hex")[::-1]

こんな感じだろうか。

pycoinの実装をpdbでデバッグしてtxinの値を検証していったが、上記の実装で計算があった。

from pycoin.tx import Tx
data = Tx.from_hex('0100000001032e38e9c0a84c6046d687d10556dcacc41d275ec55fc00779ac88fdf357a187000000008c493046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748014104f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3ffffffff0200e32321000000001976a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00000000')
import pdb; pdb.set_trace()
b = data.hash()

時間がなく今日はtxinまでだったが、次はtxoutもバイト列に直して実際にhash値を求めてみる。

Sponsored Link

ビットコイン(Bitcoin)、イーサリアム(Ethereum)、リップル(Ripple)、ネム(NEM)などの仮想通貨を買うならZaifがおすすめです。

特に国内でETHを購入するなら、アルトコインでも板取引に対応しているZaif(ザイフ)が割安なのでよいですよ。

コメントはまだありません

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


Ethereum(イーサリアム)
Ethereumの開発用ツールリストが公開されていた!

ALISのCTO石井さんがつぶやいてたんですが とてもありがたい #Ethereum 開発ツールの一 …

技術メモ
Counterpartyの環境構築が大変という話

暗号通貨の独自通貨を作ろうとするとEthereumが有名で簡単ですが、BitcoinでもCounte …

Ethereum(イーサリアム)
Error: The contract code couldn’t be stored, please check your gas amount.

ALISのICOソースのzeppelinバージョンを1.2から1.8にあげようとしたときにはまったエ …