2017年10月12日木曜日

[Bitcoin]マークルルートを調べてみる

ブロックにはマークルルートというものがあります。

私は疑り深いので、あるブロックのマークルルートが本当に正しいのかをRuby標準添付ライブラリだけを使うというしばりで確認してみたいとおもいます。
(P2PKHはこのしばりが失敗におわりました。今回はどうでしょうか)

前提

Bitcoin coreインストールしておく必要があります。



require 'digest'
require 'json'
# 参考にした資料
# https://www.slideshare.net/kenjiurushima/20140602-bitcoin1-201406031222
def sha256_double(input)
Digest::SHA256.hexdigest(Digest::SHA256.digest(["#{input}"].pack('H*')))
end
def rev(tx_id)
# https://qiita.com/paty-fakename/items/990fe9d57864054409e1
# 2文字ずつに分割した配列を逆順にして連結
tx_id.each_char.each_slice(2).to_a.reverse.join('')
end
def fm(tx_id_a, tx_id_b)
rev(sha256_double(rev(tx_id_a) + rev(tx_id_b)))
end
def getblock(block_hash_value)
JSON.parse(`bitcoin-cli getblock #{block_hash_value}`)
end
def merkleroot(ary)
loop do
return ary.first if ary.size == 1
unless ary.size % 2 == 0
ary << ary.last
end
ary = ary.each_slice(2).map do |tx_id_a, tx_id_b|
fm(tx_id_a, tx_id_b)
end
end
end
block_hash_value = '000000000000000002c83e28c1f17571fb3a45efd6184ebf4f0bb49c322f3915'
block = getblock(block_hash_value)
transaction_ids = block['tx']
right_merkleroot = block['merkleroot']
my_calc_merkleroot = merkleroot(transaction_ids)
puts "my_calc_merkleroot = #{my_calc_merkleroot}"
puts "right_merkleroot = #{right_merkleroot}"
puts my_calc_merkleroot == right_merkleroot
# => true
view raw merkle_root.rb hosted with ❤ by GitHub



合いましたよ! おっかさん!

あとtxidってtransactionのバイナリデータのハッシュ値だったのね。
txid = '052e38afaa59f3ee8328b76be44233c386e6d77a3a5fc682d1d31d92708b4100'
puts rev(sha256_double(`bitcoin-cli getrawtransaction #{txid}`.strip))
# => 052e38afaa59f3ee8328b76be44233c386e6d77a3a5fc682d1d31d92708b4100
view raw txid.rb hosted with ❤ by GitHub








0 件のコメント:

コメントを投稿