Class: Tapyrus::BlockHeader

Inherits:
Object
  • Object
show all
Extended by:
Util
Includes:
HexConverter, Util
Defined in:
lib/tapyrus/block_header.rb

Overview

Block Header

Constant Summary collapse

X_FILED_TYPES =
{ none: 0, aggregate_pubkey: 1 }

Constants included from Util

Util::DIGEST_NAME_SHA256

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

byte_to_bit, calc_checksum, decode_base58_address, double_sha256, encode_base58_address, hash160, hmac_sha256, pack_boolean, pack_var_int, pack_var_string, padding_zero, sha256, unpack_boolean, unpack_var_int, unpack_var_int_from_io, unpack_var_string, valid_address?

Methods included from HexConverter

#to_hex

Constructor Details

#initialize(features, prev_hash, merkle_root, im_merkle_root, time, x_field_type, x_field, proof = nil) ⇒ BlockHeader

Returns a new instance of BlockHeader.



19
20
21
22
23
24
25
26
27
28
# File 'lib/tapyrus/block_header.rb', line 19

def initialize(features, prev_hash, merkle_root, im_merkle_root, time, x_field_type, x_field, proof = nil)
  @features = features
  @prev_hash = prev_hash
  @merkle_root = merkle_root
  @im_merkle_root = im_merkle_root
  @time = time
  @x_field_type = x_field_type
  @x_field = x_field
  @proof = proof
end

Instance Attribute Details

#featuresObject

Returns the value of attribute features.



10
11
12
# File 'lib/tapyrus/block_header.rb', line 10

def features
  @features
end

#im_merkle_rootObject

merkel root of immulable merkle tree which consist of immutable txid.



13
14
15
# File 'lib/tapyrus/block_header.rb', line 13

def im_merkle_root
  @im_merkle_root
end

#merkle_rootObject

Returns the value of attribute merkle_root.



12
13
14
# File 'lib/tapyrus/block_header.rb', line 12

def merkle_root
  @merkle_root
end

#prev_hashObject

Returns the value of attribute prev_hash.



11
12
13
# File 'lib/tapyrus/block_header.rb', line 11

def prev_hash
  @prev_hash
end

#proofObject

Returns the value of attribute proof.



17
18
19
# File 'lib/tapyrus/block_header.rb', line 17

def proof
  @proof
end

#timeObject

unix timestamp



14
15
16
# File 'lib/tapyrus/block_header.rb', line 14

def time
  @time
end

#x_fieldObject

Returns the value of attribute x_field.



16
17
18
# File 'lib/tapyrus/block_header.rb', line 16

def x_field
  @x_field
end

#x_field_typeObject

Returns the value of attribute x_field_type.



15
16
17
# File 'lib/tapyrus/block_header.rb', line 15

def x_field_type
  @x_field_type
end

Class Method Details

.parse_from_payload(payload) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/tapyrus/block_header.rb', line 30

def self.parse_from_payload(payload)
  buf = payload.is_a?(String) ? StringIO.new(payload) : payload
  features, prev_hash, merkle_root, im_merkle_root, time, x_filed_type = buf.read(105).unpack("Va32a32a32Vc")
  x_field = buf.read(unpack_var_int_from_io(buf)) unless x_filed_type == X_FILED_TYPES[:none]
  proof = buf.read(unpack_var_int_from_io(buf))
  new(
    features,
    prev_hash.bth,
    merkle_root.bth,
    im_merkle_root.bth,
    time,
    x_filed_type,
    x_field ? x_field.bth : x_field,
    proof.bth
  )
end

Instance Method Details

#==(other) ⇒ Object



113
114
115
# File 'lib/tapyrus/block_header.rb', line 113

def ==(other)
  other && other.to_payload == to_payload
end

#block_hashString

Calculate block hash

Returns:

  • (String)

    hash of block with hex format.



62
63
64
# File 'lib/tapyrus/block_header.rb', line 62

def block_hash
  Tapyrus.double_sha256(to_payload).bth
end

#block_idString

block hash(big endian)

Returns:

  • (String)

    block id which is reversed version of block hash.



68
69
70
# File 'lib/tapyrus/block_header.rb', line 68

def block_id
  block_hash.rhex
end

#hash_for_signString

Calculate hash using sign which does not contains proof.

Returns:

  • (String)

    hash of block without proof.



56
57
58
# File 'lib/tapyrus/block_header.rb', line 56

def hash_for_sign
  Tapyrus.double_sha256(to_payload(true)).bth
end

#sizeInteger

get bytesize.

Returns:



119
120
121
# File 'lib/tapyrus/block_header.rb', line 119

def size
  to_payload.bytesize
end

#to_payload(skip_proof = false) ⇒ Object



47
48
49
50
51
52
# File 'lib/tapyrus/block_header.rb', line 47

def to_payload(skip_proof = false)
  payload = [features, prev_hash.htb, merkle_root.htb, im_merkle_root.htb, time, x_field_type].pack("Va32a32a32Vc")
  payload << pack_var_string(x_field.htb) unless x_field_type == X_FILED_TYPES[:none]
  payload << pack_var_string(proof.htb) if proof && !skip_proof
  payload
end

#upgrade_agg_pubkey?Boolean

Check this header contains upgrade aggregated public key.

Returns:

  • (Boolean)

    if contains return true, otherwise false.



109
110
111
# File 'lib/tapyrus/block_header.rb', line 109

def upgrade_agg_pubkey?
  x_field_type == X_FILED_TYPES[:aggregate_pubkey]
end

#valid?(agg_pubkey) ⇒ Boolean

evaluate block header

Parameters:

  • agg_pubkey (String)

    aggregated public key for signers with hex format.

Returns:

  • (Boolean)

    result.



75
76
77
# File 'lib/tapyrus/block_header.rb', line 75

def valid?(agg_pubkey)
  valid_timestamp? && valid_proof?(agg_pubkey) && valid_x_field?
end

#valid_proof?(agg_pubkey) ⇒ Boolean

Check whether proof is valid.

Parameters:

  • agg_pubkey (String)

    aggregated public key for signers with hex format.

Returns:

  • (Boolean)

    Return true if proof is valid, otherwise return false.



88
89
90
91
92
# File 'lib/tapyrus/block_header.rb', line 88

def valid_proof?(agg_pubkey)
  pubkey = Tapyrus::Key.new(pubkey: agg_pubkey)
  msg = hash_for_sign.htb
  pubkey.verify(proof.htb, msg, algo: :schnorr)
end

#valid_timestamp?Boolean

evaluate valid timestamp. en.bitcoin.it/wiki/Block_timestamp

Returns:

  • (Boolean)


81
82
83
# File 'lib/tapyrus/block_header.rb', line 81

def valid_timestamp?
  time <= Time.now.to_i + Tapyrus::MAX_FUTURE_BLOCK_TIME
end

#valid_x_field?Boolean

Check whether x_field is valid.

Returns:

  • (Boolean)

    if valid return true, otherwise false



96
97
98
99
100
101
102
103
104
105
# File 'lib/tapyrus/block_header.rb', line 96

def valid_x_field?
  case x_field_type
  when X_FILED_TYPES[:none]
    x_field.nil?
  when X_FILED_TYPES[:aggregate_pubkey]
    Tapyrus::Key.new(pubkey: x_field).fully_valid_pubkey?
  else
    false
  end
end