Class: Bitcoin::Block
- Inherits:
-
Object
- Object
- Bitcoin::Block
- Defined in:
- lib/bitcoin/block.rb
Instance Attribute Summary collapse
-
#header ⇒ Object
Returns the value of attribute header.
-
#transactions ⇒ Object
Returns the value of attribute transactions.
Class Method Summary collapse
-
.create_genesis(msg, script, time, nonce, bits, version, rewards = 50 * 100000000) ⇒ Object
Create genesis block.
- .parse_from_payload(payload) ⇒ Object
Instance Method Summary collapse
- #block_hash ⇒ Object
-
#calculate_merkle_root ⇒ Object
calculate merkle root from tx list.
-
#calculate_witness_commitment ⇒ Object
calculate witness commitment from tx list.
- #hash ⇒ Object
-
#height ⇒ Object
return this block height.
-
#initialize(header, transactions = []) ⇒ Block
constructor
Constructor.
-
#size ⇒ Object
calculate total size (include witness data.).
-
#stripped_size ⇒ Object
calculate base size (not include witness data.).
-
#valid_merkle_root? ⇒ Boolean
check the merkle root in the block header matches merkle root calculated from tx list.
-
#valid_witness_commitment? ⇒ Boolean
check the witness commitment in coinbase tx matches witness commitment calculated from tx list.
-
#weight ⇒ Object
calculate block weight.
Constructor Details
#initialize(header, transactions = []) ⇒ Block
Constructor
11 12 13 14 15 16 |
# File 'lib/bitcoin/block.rb', line 11 def initialize(header, transactions = []) raise ArgumentError, "header must be Bitcoin::BlockHeader." unless header.is_a?(Bitcoin::BlockHeader) raise ArgumentError, "transactions must be an Array." unless transactions.is_a?(Array) @header = header @transactions = transactions end |
Instance Attribute Details
#header ⇒ Object
Returns the value of attribute header.
4 5 6 |
# File 'lib/bitcoin/block.rb', line 4 def header @header end |
#transactions ⇒ Object
Returns the value of attribute transactions.
5 6 7 |
# File 'lib/bitcoin/block.rb', line 5 def transactions @transactions end |
Class Method Details
.create_genesis(msg, script, time, nonce, bits, version, rewards = 50 * 100000000) ⇒ Object
Create genesis block.
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/bitcoin/block.rb', line 26 def self.create_genesis(msg, script, time, nonce, bits, version, rewards = 50 * 100000000) coinbase = Bitcoin::Tx.create_coinbase(msg, script, rewards) header = BlockHeader.new( version, '00' * 32, MerkleTree.build_from_leaf([coinbase.txid]).merkle_root.rhex, time, bits, nonce ) Block.new(header, [coinbase]) end |
.parse_from_payload(payload) ⇒ Object
39 40 41 |
# File 'lib/bitcoin/block.rb', line 39 def self.parse_from_payload(payload) Bitcoin::Message::Block.parse_from_payload(payload).to_block end |
Instance Method Details
#block_hash ⇒ Object
47 48 49 |
# File 'lib/bitcoin/block.rb', line 47 def block_hash header.block_hash end |
#calculate_merkle_root ⇒ Object
calculate merkle root from tx list.
74 75 76 |
# File 'lib/bitcoin/block.rb', line 74 def calculate_merkle_root Bitcoin::MerkleTree.build_from_leaf(transactions.map(&:tx_hash)).merkle_root end |
#calculate_witness_commitment ⇒ Object
calculate witness commitment from tx list.
84 85 86 87 88 89 90 |
# File 'lib/bitcoin/block.rb', line 84 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 ⇒ Object
43 44 45 |
# File 'lib/bitcoin/block.rb', line 43 def hash header.hash end |
#height ⇒ Object
return this block height. block height is included in coinbase. if block version under 1, height does not include in coinbase, so return nil.
94 95 96 97 98 99 100 101 |
# File 'lib/bitcoin/block.rb', line 94 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 ⇒ Object
calculate total size (include witness data.)
57 58 59 60 |
# File 'lib/bitcoin/block.rb', line 57 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 ⇒ Object
calculate base size (not include witness data.)
63 64 65 66 |
# File 'lib/bitcoin/block.rb', line 63 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.
69 70 71 |
# File 'lib/bitcoin/block.rb', line 69 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.
79 80 81 |
# File 'lib/bitcoin/block.rb', line 79 def valid_witness_commitment? transactions[0].witness_commitment == calculate_witness_commitment end |
#weight ⇒ Object
calculate block weight
52 53 54 |
# File 'lib/bitcoin/block.rb', line 52 def weight stripped_size * (WITNESS_SCALE_FACTOR - 1) + size end |