Class: BTC::BlockHeader
- Inherits:
-
Object
- Object
- BTC::BlockHeader
- Defined in:
- lib/btcruby/block_header.rb
Overview
Block header is the 80-byte prefix of the block. Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce values to make the block’s hash satisfy proof-of-work requirements. When they solve the proof-of-work, they broadcast the block to everyone and the block is added to the block chain. The first transaction in the block is a special one that creates a new coin owned by the creator of the block.
Direct Known Subclasses
Constant Summary collapse
- CURRENT_VERSION =
2- ZERO_HASH256 =
"\x00".b*32
Instance Attribute Summary collapse
-
#bits ⇒ Object
uint32 proof-of-work in compact format.
-
#block_hash ⇒ Object
readonly
Binary hash of the block.
-
#block_id ⇒ Object
readonly
Hex big-endian hash of the block.
-
#confirmations ⇒ Object
The number of blocks that have been processed since the previous block (including the block itself).
-
#height ⇒ Object
The distance from the first block in the chain (genesis block has height 0).
-
#merkle_root ⇒ Object
Raw binary root hash of the transaction merkle tree.
-
#nonce ⇒ Object
uint32 nonce (used for mining iterations).
-
#previous_block_hash ⇒ Object
Binary hash of the previous block.
-
#previous_block_id ⇒ Object
Hex big-endian hash of the previous block.
-
#time ⇒ Object
Time object derived from timestamp.
-
#timestamp ⇒ Object
uint32 unix timestamp.
-
#version ⇒ Object
Block version.
Class Method Summary collapse
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #data ⇒ Object
- #dup ⇒ Object
-
#header_data ⇒ Object
so that in subclass Block we don’t hash the entire block.
- #init_with_stream(stream) ⇒ Object
-
#initialize(data: nil, stream: nil, version: CURRENT_VERSION, previous_block_hash: nil, previous_block_id: nil, merkle_root: nil, timestamp: 0, time: nil, bits: 0, nonce: 0, height: nil, confirmations: nil) ⇒ BlockHeader
constructor
A new instance of BlockHeader.
- #inspect ⇒ Object
Constructor Details
#initialize(data: nil, stream: nil, version: CURRENT_VERSION, previous_block_hash: nil, previous_block_id: nil, merkle_root: nil, timestamp: 0, time: nil, bits: 0, nonce: 0, height: nil, confirmations: nil) ⇒ BlockHeader
Returns a new instance of BlockHeader.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/btcruby/block_header.rb', line 78 def initialize(data: nil, stream: nil, version: CURRENT_VERSION, previous_block_hash: nil, previous_block_id: nil, merkle_root: nil, timestamp: 0, time: nil, bits: 0, nonce: 0, # optional attributes height: nil, confirmations: nil) if stream || data init_with_stream(stream || StringIO.new(data)) else @version = version || CURRENT_VERSION @previous_block_hash = previous_block_hash || ZERO_HASH256 @previous_block_hash = BTC.hash_from_id(previous_block_id) if previous_block_id @merkle_root = merkle_root || ZERO_HASH256 @timestamp = || 0 @timestamp = time.to_i if time @bits = bits || 0 @nonce = nonce || 0 end @height = height @confirmations = confirmations end |
Instance Attribute Details
#bits ⇒ Object
uint32 proof-of-work in compact format
39 40 41 |
# File 'lib/btcruby/block_header.rb', line 39 def bits @bits end |
#block_hash ⇒ Object (readonly)
Binary hash of the block
15 16 17 |
# File 'lib/btcruby/block_header.rb', line 15 def block_hash @block_hash end |
#block_id ⇒ Object (readonly)
Hex big-endian hash of the block
18 19 20 |
# File 'lib/btcruby/block_header.rb', line 18 def block_id @block_id end |
#confirmations ⇒ Object
The number of blocks that have been processed since the previous block (including the block itself).
52 53 54 |
# File 'lib/btcruby/block_header.rb', line 52 def confirmations @confirmations end |
#height ⇒ Object
The distance from the first block in the chain (genesis block has height 0).
49 50 51 |
# File 'lib/btcruby/block_header.rb', line 49 def height @height end |
#merkle_root ⇒ Object
Raw binary root hash of the transaction merkle tree.
30 31 32 |
# File 'lib/btcruby/block_header.rb', line 30 def merkle_root @merkle_root end |
#nonce ⇒ Object
uint32 nonce (used for mining iterations)
42 43 44 |
# File 'lib/btcruby/block_header.rb', line 42 def nonce @nonce end |
#previous_block_hash ⇒ Object
Binary hash of the previous block
24 25 26 |
# File 'lib/btcruby/block_header.rb', line 24 def previous_block_hash @previous_block_hash end |
#previous_block_id ⇒ Object
Hex big-endian hash of the previous block
27 28 29 |
# File 'lib/btcruby/block_header.rb', line 27 def previous_block_id @previous_block_id end |
#time ⇒ Object
Time object derived from timestamp
36 37 38 |
# File 'lib/btcruby/block_header.rb', line 36 def time @time end |
#timestamp ⇒ Object
uint32 unix timestamp
33 34 35 |
# File 'lib/btcruby/block_header.rb', line 33 def @timestamp end |
#version ⇒ Object
Block version.
21 22 23 |
# File 'lib/btcruby/block_header.rb', line 21 def version @version end |
Class Method Details
.genesis_mainnet ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/btcruby/block_header.rb', line 54 def self.genesis_mainnet self.new( version: 1, previous_block_hash: ZERO_HASH256, merkle_root: BTC.from_hex("3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a"), timestamp: 1231006505, bits: 0x1d00ffff, nonce: 0x7c2bac1d, height: 0 ) end |
.genesis_testnet ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/btcruby/block_header.rb', line 66 def self.genesis_testnet self.new( version: 1, previous_block_hash: ZERO_HASH256, merkle_root: BTC.from_hex("3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a"), timestamp: 1296688602, bits: 0x1d00ffff, nonce: 0x18aea41a, height: 0 ) end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
187 188 189 190 191 192 193 194 |
# File 'lib/btcruby/block_header.rb', line 187 def ==(other) @version == other.version && @previous_block_hash == other.previous_block_hash && @merkle_root == other.merkle_root && @timestamp == other. && @bits == other.bits && @nonce == other.nonce end |
#data ⇒ Object
172 173 174 |
# File 'lib/btcruby/block_header.rb', line 172 def data header_data end |
#dup ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/btcruby/block_header.rb', line 197 def dup self.class.new( version: self.version, previous_block_hash: self.previous_block_hash, merkle_root: self.merkle_root, timestamp: self., bits: self.bits, nonce: self.nonce, height: self.height, confirmations: self.confirmations) end |
#header_data ⇒ Object
so that in subclass Block we don’t hash the entire block
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/btcruby/block_header.rb', line 176 def header_data # so that in subclass Block we don't hash the entire block data = "".b data << BTC::WireFormat.encode_int32le(self.version) data << self.previous_block_hash data << self.merkle_root data << BTC::WireFormat.encode_uint32le(self.) data << BTC::WireFormat.encode_uint32le(self.bits) data << BTC::WireFormat.encode_uint32le(self.nonce) data end |
#init_with_stream(stream) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/btcruby/block_header.rb', line 110 def init_with_stream(stream) raise ArgumentError, "Stream is missing" if !stream if stream.eof? raise ArgumentError, "Can't parse block header from stream because it is already closed." end if !(version = BTC::WireFormat.read_int32le(stream: stream).first) raise ArgumentError, "Failed to read block version prefix from the stream." end if !(prevhash = stream.read(32)) || prevhash.bytesize != 32 raise ArgumentError, "Failed to read 32-byte previous_block_hash from the stream." end if !(mrklroot = stream.read(32)) || mrklroot.bytesize != 32 raise ArgumentError, "Failed to read 32-byte block merkle_root from the stream." end if !( = BTC::WireFormat.read_uint32le(stream: stream).first) raise ArgumentError, "Failed to read 32-byte block timestamp from the stream." end if !(bits = BTC::WireFormat.read_uint32le(stream: stream).first) raise ArgumentError, "Failed to read 32-byte proof-of-work bits from the stream." end if !(nonce = BTC::WireFormat.read_uint32le(stream: stream).first) raise ArgumentError, "Failed to read 32-byte nonce from the stream." end @version = version @previous_block_hash = prevhash @merkle_root = mrklroot @timestamp = @bits = bits @nonce = nonce end |
#inspect ⇒ Object
209 210 211 212 213 214 215 216 217 218 |
# File 'lib/btcruby/block_header.rb', line 209 def inspect %{#<#{self.class.name}:#{self.block_id[0,24]}} + %{ ver:#{self.version}} + %{ prev:#{self.previous_block_id[0,24]}} + %{ merkle_root:#{BTC.id_from_hash(self.merkle_root)[0,16]}} + %{ timestamp:#{self.}} + %{ bits:0x#{self.bits.to_s(16)}} + %{ nonce:0x#{self.nonce.to_s(16)}} + %{>} end |