class Bitcoin::Block

Attributes

header[RW]
transactions[RW]

Public Class Methods

new(header, transactions = []) click to toggle source
# File lib/bitcoin/block.rb, line 7
def initialize(header, transactions = [])
  @header = header
  @transactions = transactions
end
parse_from_payload(payload) click to toggle source
# File lib/bitcoin/block.rb, line 12
def self.parse_from_payload(payload)
  Bitcoin::Message::Block.parse_from_payload(payload).to_block
end

Public Instance Methods

block_hash() click to toggle source
# File lib/bitcoin/block.rb, line 20
def block_hash
  header.block_hash
end
calculate_merkle_root() click to toggle source

calculate merkle root from tx list.

# File lib/bitcoin/block.rb, line 47
def calculate_merkle_root
  Bitcoin::MerkleTree.build_from_leaf(transactions.map(&:tx_hash)).merkle_root
end
calculate_witness_commitment() click to toggle source

calculate witness commitment from tx list.

# File lib/bitcoin/block.rb, line 57
def calculate_witness_commitment
  witness_hashes = [COINBASE_WTXID]
  witness_hashes += (transactions[1..-1].map(&:witness_hash))
  reserved_value = transactions[0].inputs[0].script_witness.stack.map(&:bth).join
  root_hash = Bitcoin::MerkleTree.build_from_leaf(witness_hashes).merkle_root
  Bitcoin.double_sha256([root_hash + reserved_value].pack('H*')).bth
end
hash() click to toggle source
# File lib/bitcoin/block.rb, line 16
def hash
  header.hash
end
height() click to toggle source

return this block height. block height is included in coinbase. if block version under 1, height does not include in coinbase, so return nil.

# File lib/bitcoin/block.rb, line 67
def height
  return nil if header.version < 2
  coinbase_tx = transactions[0]
  return nil unless coinbase_tx.coinbase_tx?
  buf = StringIO.new(coinbase_tx.inputs[0].script_sig.to_payload)
  len = Bitcoin.unpack_var_int_from_io(buf)
  buf.read(len).reverse.bth.to_i(16)
end
size() click to toggle source

calculate total size (include witness data.)

# File lib/bitcoin/block.rb, line 30
def size
  80 + Bitcoin.pack_var_int(transactions.size).bytesize +
      transactions.inject(0){|sum, tx| sum + (tx.witness? ? tx.serialize_witness_format.bytesize : tx.serialize_old_format.bytesize)}
end
stripped_size() click to toggle source

calculate base size (not include witness data.)

# File lib/bitcoin/block.rb, line 36
def stripped_size
  80 + Bitcoin.pack_var_int(transactions.size).bytesize +
      transactions.inject(0){|sum, tx| sum + tx.serialize_old_format.bytesize}
end
valid_merkle_root?() click to toggle source

check the merkle root in the block header matches merkle root calculated from tx list.

# File lib/bitcoin/block.rb, line 42
def valid_merkle_root?
  calculate_merkle_root == header.merkle_root
end
valid_witness_commitment?() click to toggle source

check the witness commitment in coinbase tx matches witness commitment calculated from tx list.

# File lib/bitcoin/block.rb, line 52
def valid_witness_commitment?
  transactions[0].witness_commitment == calculate_witness_commitment
end
weight() click to toggle source

calculate block weight

# File lib/bitcoin/block.rb, line 25
def weight
  stripped_size * (WITNESS_SCALE_FACTOR - 1) + size
end