Class: Bitcoin::Block

Inherits:
Object
  • Object
show all
Defined in:
lib/bitcoin/block.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(header, transactions = []) ⇒ Block

Returns a new instance of Block.



7
8
9
10
# File 'lib/bitcoin/block.rb', line 7

def initialize(header, transactions = [])
  @header = header
  @transactions = transactions
end

Instance Attribute Details

#headerObject

Returns the value of attribute header.



4
5
6
# File 'lib/bitcoin/block.rb', line 4

def header
  @header
end

#transactionsObject

Returns the value of attribute transactions.



5
6
7
# File 'lib/bitcoin/block.rb', line 5

def transactions
  @transactions
end

Class Method Details

.parse_from_payload(payload) ⇒ Object



12
13
14
# File 'lib/bitcoin/block.rb', line 12

def self.parse_from_payload(payload)
  Bitcoin::Message::Block.parse_from_payload(payload).to_block
end

Instance Method Details

#block_hashObject



20
21
22
# File 'lib/bitcoin/block.rb', line 20

def block_hash
  header.block_hash
end

#calculate_merkle_rootObject

calculate merkle root from tx list.



47
48
49
# 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_commitmentObject

calculate witness commitment from tx list.



57
58
59
60
61
62
63
# 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

#hashObject



16
17
18
# File 'lib/bitcoin/block.rb', line 16

def hash
  header.hash
end

#heightObject

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



67
68
69
70
71
72
73
74
# 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

#sizeObject

calculate total size (include witness data.)



30
31
32
33
# 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_sizeObject

calculate base size (not include witness data.)



36
37
38
39
# 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?Boolean

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

Returns:

  • (Boolean)


42
43
44
# File 'lib/bitcoin/block.rb', line 42

def valid_merkle_root?
  calculate_merkle_root == header.merkle_root
end

#valid_witness_commitment?Boolean

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

Returns:

  • (Boolean)


52
53
54
# File 'lib/bitcoin/block.rb', line 52

def valid_witness_commitment?
  transactions[0].witness_commitment == calculate_witness_commitment
end

#weightObject

calculate block weight



25
26
27
# File 'lib/bitcoin/block.rb', line 25

def weight
  stripped_size * (WITNESS_SCALE_FACTOR - 1) + size
end