lib/bitcoin/protocol/block.rb in bitcoin-ruby-0.0.7 vs lib/bitcoin/protocol/block.rb in bitcoin-ruby-0.0.8
- old
+ new
@@ -12,11 +12,13 @@
# block hash
attr_accessor :hash
# previous block hash
- attr_accessor :prev_block
+ attr_accessor :prev_block_hash
+ alias :prev_block :prev_block_hash
+ def prev_block=(hash); @prev_block_hash = hash; end
# transactions (Array of Tx)
attr_accessor :tx
# merkle root
@@ -50,11 +52,11 @@
def binary_hash
[@hash].pack("H*")
end
def prev_block_hex
- @prev_block_hex ||= @prev_block.reverse.unpack("H*")[0]
+ @prev_block_hex ||= @prev_block_hash.reverse.unpack("H*")[0]
end
# create block from raw binary +data+
def initialize(data=nil)
@tx = []
@@ -68,11 +70,11 @@
end
# parse raw binary data
def parse_data_from_io(buf, header_only=false)
buf = buf.is_a?(String) ? StringIO.new(buf) : buf
- @ver, @prev_block, @mrkl_root, @time, @bits, @nonce = buf.read(80).unpack("Va32a32VVV")
+ @ver, @prev_block_hash, @mrkl_root, @time, @bits, @nonce = buf.read(80).unpack("Va32a32VVV")
recalc_block_hash
if Bitcoin.network[:auxpow_chain_id] != nil && (@ver & BLOCK_VERSION_AUXPOW) > 0
@aux_pow = AuxPow.new(nil)
@aux_pow.parse_data_from_io(buf)
@@ -82,11 +84,14 @@
tx_size = Protocol.unpack_var_int_from_io(buf)
@tx_count = tx_size
return buf if header_only
- tx_size.times{ break if payload == true
+ tx_size.times{
+ break if payload == true
+ return buf if buf.eof?
+
t = Tx.new(nil)
payload = t.parse_data_from_io(buf)
@tx << t
}
@@ -94,15 +99,15 @@
buf
end
# recalculate the block hash
def recalc_block_hash
- @hash = Bitcoin.block_hash(@prev_block.reverse_hth, @mrkl_root.reverse_hth, @time, @bits, @nonce, @ver)
+ @hash = Bitcoin.block_hash(@prev_block_hash.reverse_hth, @mrkl_root.reverse_hth, @time, @bits, @nonce, @ver)
end
def recalc_block_scrypt_hash
- @scrypt_hash = Bitcoin.block_scrypt_hash(@prev_block.reverse_hth, @mrkl_root.reverse_hth, @time, @bits, @nonce, @ver)
+ @scrypt_hash = Bitcoin.block_scrypt_hash(@prev_block_hash.reverse_hth, @mrkl_root.reverse_hth, @time, @bits, @nonce, @ver)
end
def recalc_mrkl_root
@mrkl_root = Bitcoin.hash_mrkl_tree( @tx.map(&:hash) ).last.htb_reverse
end
@@ -113,31 +118,31 @@
end
# get the block header info
# [<version>, <prev_block>, <merkle_root>, <time>, <bits>, <nonce>, <txcount>, <size>]
def header_info
- [@ver, @prev_block.reverse_hth, @mrkl_root.reverse_hth, Time.at(@time), @bits, @nonce, @tx.size, @payload.size]
+ [@ver, @prev_block_hash.reverse_hth, @mrkl_root.reverse_hth, Time.at(@time), @bits, @nonce, @tx.size, @payload.size]
end
# convert to raw binary format
def to_payload
- head = [@ver, @prev_block, @mrkl_root, @time, @bits, @nonce].pack("Va32a32VVV")
+ head = [@ver, @prev_block_hash, @mrkl_root, @time, @bits, @nonce].pack("Va32a32VVV")
head << @aux_pow.to_payload if @aux_pow
return head if @tx.size == 0
head << Protocol.pack_var_int(@tx.size)
@tx.each{|tx| head << tx.to_payload }
head
end
# convert to ruby hash (see also #from_hash)
- def to_hash
+ def to_hash(options = {})
h = {
'hash' => @hash, 'ver' => @ver,
- 'prev_block' => @prev_block.reverse_hth, 'mrkl_root' => @mrkl_root.reverse_hth,
+ 'prev_block' => @prev_block_hash.reverse_hth, 'mrkl_root' => @mrkl_root.reverse_hth,
'time' => @time, 'bits' => @bits, 'nonce' => @nonce,
'n_tx' => @tx.size, 'size' => (@payload||to_payload).bytesize,
- 'tx' => @tx.map{|i| i.to_hash },
+ 'tx' => @tx.map{|i| i.to_hash(options) },
'mrkl_tree' => Bitcoin.hash_mrkl_tree( @tx.map{|i| i.hash } )
}
h['aux_pow'] = @aux_pow.to_hash if @aux_pow
h
end
@@ -175,11 +180,11 @@
end
# convert to json representation as seen in the block explorer.
# (see also #from_json)
def to_json(options = {:space => ''}, *a)
- JSON.pretty_generate( to_hash, options )
+ JSON.pretty_generate( to_hash(options), options )
end
# write json representation to a file
# (see also #to_json)
def to_json_file(path)
@@ -189,16 +194,16 @@
# parse ruby hash (see also #to_hash)
def self.from_hash(h, do_raise=true)
blk = new(nil)
blk.instance_eval{
@ver, @time, @bits, @nonce = h.values_at('ver', 'time', 'bits', 'nonce')
- @prev_block, @mrkl_root = h.values_at('prev_block', 'mrkl_root').map{|i| i.htb_reverse }
+ @prev_block_hash, @mrkl_root = h.values_at('prev_block', 'mrkl_root').map{|i| i.htb_reverse }
unless h['hash'] == recalc_block_hash
raise "Block hash mismatch! Claimed: #{h['hash']}, Actual: #{@hash}" if do_raise
end
@aux_pow = AuxPow.from_hash(h['aux_pow']) if h['aux_pow']
- h['tx'].each{|tx| @tx << Tx.from_hash(tx) }
+ h['tx'].each{|tx| @tx << Tx.from_hash(tx, do_raise) }
if h['tx'].any?
(raise "Block merkle root mismatch! Block: #{h['hash']}" unless verify_mrkl_root) if do_raise
end
}
blk
@@ -220,10 +225,10 @@
JSON.pretty_generate( h, options )
end
# block header binary output
def block_header
- [@ver, @prev_block, @mrkl_root, @time, @bits, @nonce, Protocol.pack_var_int(0)].pack("Va32a32VVVa*")
+ [@ver, @prev_block_hash, @mrkl_root, @time, @bits, @nonce, Protocol.pack_var_int(0)].pack("Va32a32VVVa*")
end
# read binary block from a file
def self.from_file(path); new( Bitcoin::Protocol.read_binary_file(path) ); end