Class: BlockchainLite::Blockchain

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/blockchain-lite/blockchain.rb

Instance Method Summary collapse

Constructor Details

#initialize(chain = []) ⇒ Blockchain

Returns a new instance of Blockchain.



13
14
15
# File 'lib/blockchain-lite/blockchain.rb', line 13

def initialize( chain=[] )
  @chain = chain    # "wrap" passed in blockchain (in array)
end

Instance Method Details

#<<(arg) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/blockchain-lite/blockchain.rb', line 28

def <<( arg )
  if arg.is_a?( block_class )
    b = arg
  else
    if arg.is_a?( Array )   ## assume its (just) data
      data = arg
    else  ## fallback; assume single transaction record; wrap in array - allow fallback - why? why not??
      data = [arg]
    end

    if @chain.empty?
      b = block_class.first( data )
    else
      bl = @chain.last
      b  = block_class.next( bl, data )
    end
  end

  @chain << b   ## add/append (new) block to chain
end

#block_classObject

todo/check: can we make it work without “virtual” block_class method

e.g. use constant lookup with singleton class or something - possible?


20
# File 'lib/blockchain-lite/blockchain.rb', line 20

def block_class() Block; end

#broken?Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/blockchain-lite/blockchain.rb', line 50

def broken?
  ## check for validation conventions
  ##   - start with first block?
  ##   - or start with last block (reversve)? -why? why not??

  @chain.size.times do |i|
    ###puts "checking block #{i+1}/#{@chain.size}..."

    current = @chain[i]

    if i==0   ### special case for first (genesis) block; has no previous/parent block
      if current.index != 0
        ## raise error -- invalid index!!!
        return true
      end
      if current.previous_hash != '0'
        ## raise error -- invalid previous hash (hash checksums MUST match)
        return true
      end
    else
      previous = @chain[i-1]

      if current.index != previous.index+1
        ## raise error -- invalid index!!!
        puts "!!! blockchain corrupt - block ##{current.index}: index must be a sequence (with +1 steps)"
        return true
      end

      if current.previous_hash != previous.hash
        ## raise error -- invalid previous hash (hash checksums MUST match)
        puts "!!! blockchain corrupt - block ##{current.index}: previous_hash and hash in previous block must match"
        return true
      end
    end

    if current.hash != current.calc_hash    ## (re)calc / double-check hash
      ## raise error -- invalid hash (hash checksums MUST match)
      puts "!!! blockchain corrupt - block ##{current.index}: calc_hash and hash must match; block corrupt - cannot recalculate hash"
      return true
    end
  end # loop times

  false   ## chain OK -- chain is NOT broken if we get here
end

#valid?Boolean

method broken?

Returns:

  • (Boolean)


95
# File 'lib/blockchain-lite/blockchain.rb', line 95

def valid?() !broken?; end