class Bank
Attributes
chain[R]
ledger[R]
pending[R]
Public Class Methods
new( address )
click to toggle source
# File lib/centralbank/bank.rb, line 7 def initialize( address ) @address = address ## note: add address name for now to cache ## allows to start more nodes in same folder / directory @cache = Cache.new( "data.#{address.downcase}.json" ) h = @cache.read if h ## restore blockchain @chain = Blockchain.from_json( h['chain'] ) ## restore pending (unconfirmed) transactions pool too @pending = Pool.from_json( h['transactions'] ) else @chain = Blockchain.new @chain << [Tx.new( Centralbank.config.rand_coinbase, @address, Centralbank.config.mining_reward )] # genesis (big bang!) starter block @pending = Pool.new end ## update ledger (balances) with confirmed transactions @ledger = Ledger.new( @chain ) end
Public Instance Methods
add_transaction( tx )
click to toggle source
# File lib/centralbank/bank.rb, line 57 def add_transaction( tx ) if tx.valid? && transaction_is_new?( tx ) @pending << tx @cache.write as_json return true else return false end end
as_json()
click to toggle source
# File lib/centralbank/bank.rb, line 91 def as_json { chain: @chain.as_json, transactions: @pending.as_json } end
mine_block!()
click to toggle source
# File lib/centralbank/bank.rb, line 33 def mine_block! add_transaction( Tx.new( Centralbank.config.rand_coinbase, @address, Centralbank.config.mining_reward )) ## add mined (w/ computed/calculated hash) block @chain << @pending.transactions @pending = Pool.new ## clear out/ empty pool (just create a new one for now) ## update ledger (balances) with new confirmed transactions @ledger = Ledger.new( @chain ) @cache.write as_json end
resolve!( chain_new )
click to toggle source
check - how to name incoming chain - chain_new, chain_candidate - why? why not?
what's an intuitive name - what's gets used most often???
# File lib/centralbank/bank.rb, line 72 def resolve!( chain_new ) # TODO this does not protect against invalid block shapes (bogus COINBASE transactions for example) if !chain_new.empty? && chain_new.last.valid? && chain_new.size > @chain.size @chain = chain_new ## update ledger (balances) with new confirmed transactions @ledger = Ledger.new( @chain ) ## document - keep only pending transaction not yet (confirmed) in (new) blockchain ???? @pending.update!( @chain.transactions ) @cache.write as_json return true else return false end end
sufficient_funds?( wallet, amount )
click to toggle source
# File lib/centralbank/bank.rb, line 49 def sufficient_funds?( wallet, amount ) ## (convenience) delegate for ledger ## todo/check: use address instead of wallet - why? why not? ## for now single address wallet (that is, wallet==address) @ledger.sufficient_funds?( wallet, amount ) end
Private Instance Methods
transaction_is_new?( tx_new )
click to toggle source
# File lib/centralbank/bank.rb, line 101 def transaction_is_new?( tx_new ) ## check if tx exists already in blockchain or pending tx pool ## todo: use chain.include? to check for include ## avoid loop and create new array for check!!! (@chain.transactions + @pending.transactions).none? { |tx| tx_new.id == tx.id } end