diff --git a/attic/bitshilling/.gitignore b/attic/bitshilling/.gitignore
new file mode 100644
index 0000000..91ce1dc
--- /dev/null
+++ b/attic/bitshilling/.gitignore
@@ -0,0 +1,70 @@
+###########
+# cached / saved state / data
+
+data.json
+data.*.json
+
+
+
+##########
+# ignore Gemfile.lock for now
+
+Gemfile.lock
+
+
+####
+# ignore sass cache
+.sass-cache
+
+
+
+*.gem
+*.rbc
+/.config
+/coverage/
+/InstalledFiles
+/pkg/
+/spec/reports/
+/spec/examples.txt
+/test/tmp/
+/test/version_tmp/
+/tmp/
+
+# Used by dotenv library to load environment variables.
+# .env
+
+## Specific to RubyMotion:
+.dat*
+.repl_history
+build/
+*.bridgesupport
+build-iPhoneOS/
+build-iPhoneSimulator/
+
+## Specific to RubyMotion (use of CocoaPods):
+#
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
+#
+# vendor/Pods/
+
+## Documentation cache and generated files:
+/.yardoc/
+/_yardoc/
+/doc/
+/rdoc/
+
+## Environment normalization:
+/.bundle/
+/vendor/bundle
+/lib/bundler/man/
+
+# for a library or gem, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# Gemfile.lock
+# .ruby-version
+# .ruby-gemset
+
+# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
+.rvmrc
diff --git a/attic/bitshilling/HISTORY.md b/attic/bitshilling/HISTORY.md
new file mode 100644
index 0000000..bf34691
--- /dev/null
+++ b/attic/bitshilling/HISTORY.md
@@ -0,0 +1,3 @@
+### 0.1.0 / 2017-12-26
+
+* Everything is new. First release.
diff --git a/attic/bitshilling/LICENSE.md b/attic/bitshilling/LICENSE.md
new file mode 100644
index 0000000..670154e
--- /dev/null
+++ b/attic/bitshilling/LICENSE.md
@@ -0,0 +1,116 @@
+CC0 1.0 Universal
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator and
+subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for the
+purpose of contributing to a commons of creative, cultural and scientific
+works ("Commons") that the public can reliably and without fear of later
+claims of infringement build upon, modify, incorporate in other works, reuse
+and redistribute as freely as possible in any form whatsoever and for any
+purposes, including without limitation commercial purposes. These owners may
+contribute to the Commons to promote the ideal of a free culture and the
+further production of creative, cultural and scientific works, or to gain
+reputation or greater distribution for their Work in part through the use and
+efforts of others.
+
+For these and/or other purposes and motivations, and without any expectation
+of additional consideration or compensation, the person associating CC0 with a
+Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
+and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
+and publicly distribute the Work under its terms, with knowledge of his or her
+Copyright and Related Rights in the Work and the meaning and intended legal
+effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not limited
+to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
+ and translate a Work;
+
+ ii. moral rights retained by the original author(s) and/or performer(s);
+
+ iii. publicity and privacy rights pertaining to a person's image or likeness
+ depicted in a Work;
+
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+
+ v. rights protecting the extraction, dissemination, use and reuse of data in
+ a Work;
+
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation thereof,
+ including any amended or successor version of such directive); and
+
+ vii. other similar, equivalent or corresponding rights throughout the world
+ based on applicable law or treaty, and any national implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention of,
+applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
+unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
+and Related Rights and associated claims and causes of action, whether now
+known or unknown (including existing as well as future claims and causes of
+action), in the Work (i) in all territories worldwide, (ii) for the maximum
+duration provided by applicable law or treaty (including future time
+extensions), (iii) in any current or future medium and for any number of
+copies, and (iv) for any purpose whatsoever, including without limitation
+commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
+the Waiver for the benefit of each member of the public at large and to the
+detriment of Affirmer's heirs and successors, fully intending that such Waiver
+shall not be subject to revocation, rescission, cancellation, termination, or
+any other legal or equitable action to disrupt the quiet enjoyment of the Work
+by the public as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason be
+judged legally invalid or ineffective under applicable law, then the Waiver
+shall be preserved to the maximum extent permitted taking into account
+Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
+is so judged Affirmer hereby grants to each affected person a royalty-free,
+non transferable, non sublicensable, non exclusive, irrevocable and
+unconditional license to exercise Affirmer's Copyright and Related Rights in
+the Work (i) in all territories worldwide, (ii) for the maximum duration
+provided by applicable law or treaty (including future time extensions), (iii)
+in any current or future medium and for any number of copies, and (iv) for any
+purpose whatsoever, including without limitation commercial, advertising or
+promotional purposes (the "License"). The License shall be deemed effective as
+of the date CC0 was applied by Affirmer to the Work. Should any part of the
+License for any reason be judged legally invalid or ineffective under
+applicable law, such partial invalidity or ineffectiveness shall not
+invalidate the remainder of the License, and in such case Affirmer hereby
+affirms that he or she will not (i) exercise any of his or her remaining
+Copyright and Related Rights in the Work or (ii) assert any associated claims
+and causes of action with respect to the Work, in either case contrary to
+Affirmer's express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+
+ b. Affirmer offers the Work as-is and makes no representations or warranties
+ of any kind concerning the Work, express, implied, statutory or otherwise,
+ including without limitation warranties of title, merchantability, fitness
+ for a particular purpose, non infringement, or the absence of latent or
+ other defects, accuracy, or the present or absence of errors, whether or not
+ discoverable, all to the greatest extent permissible under applicable law.
+
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without limitation
+ any person's Copyright and Related Rights in the Work. Further, Affirmer
+ disclaims responsibility for obtaining any necessary consents, permissions
+ or other rights required for any use of the Work.
+
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to this
+ CC0 or use of the Work.
+
+For more information, please see
+
diff --git a/attic/bitshilling/Manifest.txt b/attic/bitshilling/Manifest.txt
new file mode 100644
index 0000000..9d6a446
--- /dev/null
+++ b/attic/bitshilling/Manifest.txt
@@ -0,0 +1,25 @@
+HISTORY.md
+LICENSE.md
+Manifest.txt
+README.md
+Rakefile
+bin/shilling
+lib/shilling.rb
+lib/shilling/bank.rb
+lib/shilling/block.rb
+lib/shilling/blockchain.rb
+lib/shilling/cache.rb
+lib/shilling/node.rb
+lib/shilling/pool.rb
+lib/shilling/service.rb
+lib/shilling/tool.rb
+lib/shilling/transaction.rb
+lib/shilling/version.rb
+lib/shilling/views/_blockchain.erb
+lib/shilling/views/_ledger.erb
+lib/shilling/views/_peers.erb
+lib/shilling/views/_pending_transactions.erb
+lib/shilling/views/_wallet.erb
+lib/shilling/views/index.erb
+lib/shilling/views/style.scss
+lib/shilling/wallet.rb
diff --git a/attic/bitshilling/README.md b/attic/bitshilling/README.md
new file mode 100644
index 0000000..aae2de7
--- /dev/null
+++ b/attic/bitshilling/README.md
@@ -0,0 +1,117 @@
+# shilling (or schilling) command line tool (and core library)
+
+shilling (or schilling) on the blockchain! rock-solid alpine dollar from austria;
+print (mine) your own shillings; run your own federated shilling central bank nodes
+w/ public distributed (hyper) ledger book on the blockchain peer-to-peer over HTTP; revolutionize the world one block at a time with cryptos
+
+
+
+* home :: [github.com/bitshilling/bitshilling.tools](https://github.com/bitshilling/bitshilling.tools)
+* bugs :: [github.com/bitshilling/bitshilling.tools/issues](https://github.com/bitshilling/bitshilling.tools/issues)
+* gem :: [rubygems.org/gems/shilling](https://rubygems.org/gems/shilling)
+* rdoc :: [rubydoc.info/gems/shilling](http://rubydoc.info/gems/shilling)
+
+
+
+## Command Line
+
+Use the `shilling` command line tool. Try:
+
+```
+$ shilling -h
+```
+
+resulting in:
+
+```
+Usage: shilling [options]
+
+ Wallet options:
+ -n, --name=NAME Address name (default: Theresa)
+
+ Server (node) options:
+ -o, --host HOST listen on HOST (default: 0.0.0.0)
+ -p, --port PORT use PORT (default: 4567)
+ -h, --help Prints this help
+```
+
+To start a new (network) node using the default wallet
+address (that is, Theresa) and the default server host and port settings
+use:
+
+```
+$ shilling
+```
+
+Stand back ten feets :-) while starting up the machinery.
+Ready to print (mine) shillings on the blockchain?
+In your browser open up the page e.g. `http://localhost:4567`. Voila!
+
+
+
+
+
+Note: You can start a second node on your computer -
+make sure to use a different port (use the `-p/--port` option)
+and (recommended)
+a different wallet address (use the `-n/--name` option).
+Example:
+
+```
+$ shilling -p 5678 -n Franz
+```
+
+Happy mining!
+
+
+
+## Local Development Setup
+
+For local development - clone or download (and unzip) the shilling.tools code repo.
+Next install all dependencies using bundler with a Gemfile e.g.:
+
+``` ruby
+# Gemfile
+
+source "https://rubygems.org"
+
+gem 'sinatra'
+gem 'sass'
+gem 'blockchain-lite'
+gem 'ledger-lite'
+```
+
+run
+
+```
+$ bundle ## will use the Gemfile (see above)
+```
+
+and now you're ready to run your own shilling server node. Use the [`config.ru`](config.ru) script for rack:
+
+``` ruby
+# config.ru
+
+$LOAD_PATH << './lib'
+
+require 'shilling'
+
+run Shilling::Service
+```
+
+and startup the money printing machine using rackup - the rack command line tool:
+
+```
+$ rackup ## will use the config.ru - rackup configuration script (see above).
+```
+
+In your browser open up the page e.g. `http://localhost:9292`. Voila! Happy mining!
+
+
+
+## License
+
+
+
+The `shilling` scripts are dedicated to the public domain.
+Use it as you please with no restrictions whatsoever.
diff --git a/attic/bitshilling/Rakefile b/attic/bitshilling/Rakefile
new file mode 100644
index 0000000..5136dc7
--- /dev/null
+++ b/attic/bitshilling/Rakefile
@@ -0,0 +1,34 @@
+require 'hoe'
+require './lib/shilling/version.rb'
+
+Hoe.spec 'shilling' do
+
+ self.version = Shilling::VERSION
+
+ self.summary = 'shilling (or schilling) on the blockchain! rock-solid alpine dollar from austria; print (mine) your own shillings; run your own federated shilling central bank nodes w/ public distributed (hyper) ledger book on the blockchain peer-to-peer over HTTP; revolutionize the world one block at a time with cryptos'
+ self.description = summary
+
+ self.urls = ['https://github.com/bitshilling/bitshilling.tools']
+
+ self.author = 'Gerald Bauer'
+ self.email = 'ruby-talk@ruby-lang.org'
+
+ # switch extension to .markdown for gihub formatting
+ self.readme_file = 'README.md'
+ self.history_file = 'History.md'
+
+ self.extra_deps = [
+ ['sinatra', '>=2.0'],
+ ['sass'], ## used for css style preprocessing (scss)
+ ['blockchain-lite', '>=1.4.0'],
+ ['ledger-lite', '>=1.1.1' ]
+ ]
+
+
+ self.licenses = ['Public Domain']
+
+ self.spec_extras = {
+ required_ruby_version: '>= 2.3'
+ }
+
+end
diff --git a/attic/bitshilling/attic/ledger.rb b/attic/bitshilling/attic/ledger.rb
new file mode 100644
index 0000000..1975e3a
--- /dev/null
+++ b/attic/bitshilling/attic/ledger.rb
@@ -0,0 +1,34 @@
+###
+## old "custom" ledger
+## delete - use ledger-lite library
+
+
+class Ledger
+ attr_reader :wallets ## use addresses - why? why not? for now single address wallet (wallet==address)
+
+ def initialize( chain=[] )
+ @wallets = {}
+ chain.each do |block|
+ apply_transactions( block.transactions )
+ end
+ end
+
+ def sufficient_funds?( wallet, amount )
+ return true if Shilling.config.coinbase?( wallet )
+ @wallets.has_key?( wallet ) && @wallets[wallet] - amount >= 0
+ end
+
+
+private
+
+ def apply_transactions( transactions )
+ transactions.each do |tx|
+ if sufficient_funds?(tx.from, tx.amount)
+ @wallets[tx.from] -= tx.amount unless Shilling.config.coinbase?( tx.from )
+ @wallets[tx.to] ||= 0
+ @wallets[tx.to] += tx.amount
+ end
+ end
+ end
+
+end ## class Ledger
diff --git a/attic/bitshilling/bin/shilling b/attic/bitshilling/bin/shilling
new file mode 100644
index 0000000..064793d
--- /dev/null
+++ b/attic/bitshilling/bin/shilling
@@ -0,0 +1,17 @@
+#!/usr/bin/env ruby
+
+###################
+# == DEV TIPS:
+#
+# For local testing run like:
+#
+# ruby -Ilib bin/shilling
+#
+# Set the executable bit in Linux. Example:
+#
+# % chmod a+x bin/shilling
+#
+
+require 'shilling'
+
+Shilling.main
diff --git a/attic/bitshilling/config.ru b/attic/bitshilling/config.ru
new file mode 100644
index 0000000..c34d57b
--- /dev/null
+++ b/attic/bitshilling/config.ru
@@ -0,0 +1,11 @@
+### note: for local testing - add to load path ./lib
+## to test / run use:
+## $ rackup
+
+
+$LOAD_PATH << './lib'
+
+require 'shilling'
+
+
+run Shilling::Service
diff --git a/attic/bitshilling/lib/shilling.rb b/attic/bitshilling/lib/shilling.rb
new file mode 100644
index 0000000..bf7bdf5
--- /dev/null
+++ b/attic/bitshilling/lib/shilling.rb
@@ -0,0 +1,119 @@
+# encoding: utf-8
+
+# stdlibs
+require 'json'
+require 'digest'
+require 'net/http'
+require 'set'
+require 'pp'
+require 'optparse' ## note: used for command line tool (see Tool in tool.rb)
+
+
+### 3rd party gems
+require 'sinatra/base' # note: use "modular" sinatra app / service
+
+
+require 'blockchain-lite/base'
+
+###
+# add convenience top-level shortcut / alias
+# "standard" default block for now block with proof of work
+Block = BlockchainLite::ProofOfWork::Block
+
+
+require 'ledger-lite/base'
+
+###
+# add convenience top-level shortcut / alias
+Ledger = LedgerLite::Ledger
+
+
+
+### our own code
+require 'shilling/version' ## let version always go first
+require 'shilling/block'
+require 'shilling/cache'
+require 'shilling/transaction'
+require 'shilling/blockchain'
+require 'shilling/pool'
+require 'shilling/bank'
+require 'shilling/wallet'
+
+require 'shilling/node'
+require 'shilling/service'
+
+require 'shilling/tool' ## add (optional) command line tool
+
+
+
+
+
+module Shilling
+
+
+ class Configuration
+ ## user/node settings
+ attr_accessor :address ## single wallet address (for now "clear" name e.g.Sepp, Franz, etc.)
+
+ WALLET_ADDRESSES = %w[Theresa Franz Antonia Maximilan Maria Ferdinand Elisabeth Adam Eva]
+
+ ## system/blockchain settings
+ attr_accessor :coinbase
+ attr_accessor :mining_reward
+
+ ## note: add a (†) coinbase marker
+ ## fix: "sync" with ledger-lite config!!!!
+ COINBASE = ['Coinbase†']
+=begin
+ COINBASE = ['Großglockner†', 'Wildspitze†', 'Großvenediger†',
+ 'Hochfeiler†', 'Zuckerhütl†', 'Hochalmspitze†',
+ 'Gr. Muntanitz†', 'Hoher Riffler†',
+ 'Parseierspitze†', 'Hoher Dachstein†'
+ ]
+=end
+
+
+ def initialize
+ ## try default setup via ENV variables
+ ## pick "random" address if nil (none passed in)
+ @address = ENV[ 'SHILLING_NAME'] || rand_address()
+
+ @coinbase = COINBASE ## use a different name - why? why not?
+ ## note: for now is an array (multiple coinbases)
+ @mining_reward = 43 ## use country code for austria (43)
+ end
+
+ def rand_address() WALLET_ADDRESSES[rand( WALLET_ADDRESSES.size )]; end
+ def rand_coinbase() @coinbase[rand( @coinbase.size )]; end
+
+ def coinbase?( address ) ## check/todo: use wallet - why? why not? (for now wallet==address)
+ @coinbase.include?( address )
+ end
+
+ end # class Configuration
+
+
+ ## lets you use
+ ## Shilling.configure do |config|
+ ## config.address = 'Sepp'
+ ## end
+
+ def self.configure
+ yield( config )
+ end
+
+ def self.config
+ @config ||= Configuration.new
+ end
+
+
+ ## add command line binary (tool) e.g. $ try shilling -h
+ def self.main
+ Tool.new.run(ARGV)
+ end
+
+end # module Shilling
+
+
+# say hello
+puts Shilling::Service.banner
diff --git a/attic/bitshilling/lib/shilling/bank.rb b/attic/bitshilling/lib/shilling/bank.rb
new file mode 100644
index 0000000..4207ba8
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/bank.rb
@@ -0,0 +1,109 @@
+
+
+class Bank
+ attr_reader :pending, :chain, :ledger
+
+
+ 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( Shilling.config.rand_coinbase,
+ @address,
+ Shilling.config.mining_reward )] # genesis (big bang!) starter block
+ @pending = Pool.new
+ end
+
+ ## update ledger (balances) with confirmed transactions
+ @ledger = Ledger.new( @chain )
+ end
+
+
+
+ def mine_block!
+ add_transaction( Tx.new( Shilling.config.rand_coinbase,
+ @address,
+ Shilling.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
+
+
+ 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?( wallet, amount )
+ end
+
+
+ def add_transaction( tx )
+ if tx.valid? && transaction_is_new?( tx )
+ @pending << tx
+ @cache.write as_json
+ return true
+ else
+ return false
+ end
+ end
+
+
+ ##
+ # check - how to name incoming chain - chain_new, chain_candidate - why? why not?
+ # what's an intuitive name - what's gets used most often???
+
+ 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
+
+
+
+ def as_json
+ { chain: @chain.as_json,
+ transactions: @pending.as_json
+ }
+ end
+
+
+
+private
+
+ 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
+
+end ## class Bank
diff --git a/attic/bitshilling/lib/shilling/block.rb b/attic/bitshilling/lib/shilling/block.rb
new file mode 100644
index 0000000..46ab0e9
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/block.rb
@@ -0,0 +1,39 @@
+
+######
+## add more methods
+
+
+class Block
+
+def to_h
+ { index: @index,
+ timestamp: @timestamp,
+ nonce: @nonce,
+ transactions: @transactions.map { |tx| tx.to_h },
+ transactions_hash: @transactions_hash,
+ previous_hash: @previous_hash,
+ hash: @hash }
+end
+
+def self.from_h( h )
+ transactions = h['transactions'].map { |h_tx| Tx.from_h( h_tx ) }
+
+ ## todo: use hash and transactions_hash to check integrity of block - why? why not?
+
+ ## parse iso8601 format e.g 2017-10-05T22:26:12-04:00
+ timestamp = Time.parse( h['timestamp'] )
+
+ self.new( h['index'],
+ transactions,
+ h['previous_hash'],
+ timestamp: timestamp,
+ nonce: h['nonce'].to_i )
+end
+
+
+def valid?
+ true ## for now always valid
+end
+
+
+end # class Block
diff --git a/attic/bitshilling/lib/shilling/blockchain.rb b/attic/bitshilling/lib/shilling/blockchain.rb
new file mode 100644
index 0000000..a040e64
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/blockchain.rb
@@ -0,0 +1,47 @@
+
+
+
+class Blockchain
+ extend Forwardable
+ def_delegators :@chain, :[], :size, :each, :empty?, :any?, :last
+
+
+ def initialize( chain=[] )
+ @chain = chain
+ end
+
+ def <<( txs )
+ ## todo: check if is block or array
+ ## if array (of transactions) - auto-add (build) block
+ ## allow block - why? why not?
+ ## for now just use transactions (keep it simple :-)
+
+ if @chain.size == 0
+ block = Block.first( txs )
+ else
+ block = Block.next( @chain.last, txs )
+ end
+ @chain << block
+ end
+
+
+
+ def as_json
+ @chain.map { |block| block.to_h }
+ end
+
+ def transactions
+ ## "accumulate" get all transactions from all blocks "reduced" into a single array
+ @chain.reduce( [] ) { |acc, block| acc + block.transactions }
+ end
+
+
+
+ def self.from_json( data )
+ ## note: assumes data is an array of block records/objects in json
+ chain = data.map { |h| Block.from_h( h ) }
+ self.new( chain )
+ end
+
+
+end # class Blockchain
diff --git a/attic/bitshilling/lib/shilling/cache.rb b/attic/bitshilling/lib/shilling/cache.rb
new file mode 100644
index 0000000..b7f520f
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/cache.rb
@@ -0,0 +1,22 @@
+
+
+class Cache
+ def initialize( name )
+ @name = name
+ end
+
+ def write( data )
+ File.open( @name, 'w:utf-8' ) do |f|
+ f.write JSON.pretty_generate( data )
+ end
+ end
+
+ def read
+ if File.exists?( @name )
+ data = File.open( @name, 'r:bom|utf-8' ).read
+ JSON.parse( data )
+ else
+ nil
+ end
+ end
+end ## class Cache
diff --git a/attic/bitshilling/lib/shilling/node.rb b/attic/bitshilling/lib/shilling/node.rb
new file mode 100644
index 0000000..cec219d
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/node.rb
@@ -0,0 +1,82 @@
+
+
+class Node
+ attr_reader :id, :peers, :wallet, :bank
+
+ def initialize( address: )
+ @id = SecureRandom.uuid
+ @peers = []
+ @wallet = Wallet.new( address )
+ @bank = Bank.new @wallet.address
+ end
+
+
+
+ def on_add_peer( host, port )
+ @peers << [host, port]
+ @peers.uniq!
+ # TODO/FIX: no need to send to every peer, just the new one
+ send_chain_to_peers
+ @bank.pending.each { |tx| send_transaction_to_peers( tx ) }
+ end
+
+ def on_delete_peer( index )
+ @peers.delete_at( index )
+ end
+
+
+ def on_add_transaction( from, to, amount, id )
+ ## note: for now must always pass in id - why? why not? possible tx without id???
+ tx = Tx.new( from, to, amount, id )
+ if @bank.sufficient_funds?( tx.from, tx.amount ) && @bank.add_transaction( tx )
+ send_transaction_to_peers( tx )
+ return true
+ else
+ return false
+ end
+ end
+
+ def on_send( to, amount )
+ tx = @wallet.generate_transaction( to, amount )
+ if @bank.sufficient_funds?( tx.from, tx.amount ) && @bank.add_transaction( tx )
+ send_transaction_to_peers( tx )
+ return true
+ else
+ return false
+ end
+ end
+
+
+ def on_mine!
+ @bank.mine_block!
+ send_chain_to_peers
+ end
+
+ def on_resolve( data )
+ chain_new = Blockchain.from_json( data )
+ if @bank.resolve!( chain_new )
+ send_chain_to_peers
+ return true
+ else
+ return false
+ end
+ end
+
+
+
+private
+
+ def send_chain_to_peers
+ data = JSON.pretty_generate( @bank.as_json ) ## payload in json
+ @peers.each do |(host, port)|
+ Net::HTTP.post(URI::HTTP.build(host: host, port: port, path: '/resolve'), data )
+ end
+ end
+
+ def send_transaction_to_peers( tx )
+ @peers.each do |(host, port)|
+ Net::HTTP.post_form(URI::HTTP.build(host: host, port: port, path: '/transactions'), tx.to_h )
+ end
+ end
+
+end ## class Node
diff --git a/attic/bitshilling/lib/shilling/pool.rb b/attic/bitshilling/lib/shilling/pool.rb
new file mode 100644
index 0000000..d9002b1
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/pool.rb
@@ -0,0 +1,42 @@
+####################################
+# pending (unconfirmed) transactions (mem) pool
+
+class Pool
+ extend Forwardable
+ def_delegators :@transactions, :[], :size, :each, :empty?, :any?
+
+
+ def initialize( transactions=[] )
+ @transactions = transactions
+ end
+
+ def transactions() @transactions; end
+
+ def <<( tx )
+ @transactions << tx
+ end
+
+
+ def update!( txns_confirmed )
+ ## find a better name?
+ ## remove confirmed transactions from pool
+
+ ## document - keep only pending transaction not yet (confirmed) in blockchain ????
+ @transactions = @transactions.select do |tx_unconfirmed|
+ txns_confirmed.none? { |tx_confirmed| tx_confirmed.id == tx_unconfirmed.id }
+ end
+ end
+
+
+
+ def as_json
+ @transactions.map { |tx| tx.to_h }
+ end
+
+ def self.from_json( data )
+ ## note: assumes data is an array of block records/objects in json
+ transactions = data.map { |h| Tx.from_h( h ) }
+ self.new( transactions )
+ end
+
+end # class Pool
diff --git a/attic/bitshilling/lib/shilling/service.rb b/attic/bitshilling/lib/shilling/service.rb
new file mode 100644
index 0000000..fc74db1
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/service.rb
@@ -0,0 +1,113 @@
+# encoding: utf-8
+
+module Shilling
+
+ class Service < Sinatra::Base
+
+ def self.banner
+ "shilling/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] on Sinatra/#{Sinatra::VERSION} (#{ENV['RACK_ENV']})"
+ end
+
+
+ PUBLIC_FOLDER = "#{Shilling.root}/lib/shilling/public"
+ VIEWS_FOLDER = "#{Shilling.root}/lib/shilling/views"
+
+ set :public_folder, PUBLIC_FOLDER # set up the static dir (with images/js/css inside)
+ set :views, VIEWS_FOLDER # set up the views dir
+
+ set :static, true # set up static file routing -- check - still needed?
+
+
+ set connections: []
+
+
+
+ get '/style.css' do
+ scss :style ## note: converts (pre-processes) style.scss to style.css
+ end
+
+
+ get '/' do
+ @node = node ## todo: pass along node as hash varialbe / assigns to erb
+ erb :index
+ end
+
+
+ post '/send' do
+ node.on_send( params[:to], params[:amount].to_i )
+ settings.connections.each { |out| out << "data: added transaction\n\n" }
+ redirect '/'
+ end
+
+
+ post '/transactions' do
+ if node.on_add_transaction(
+ params[:from],
+ params[:to],
+ params[:amount].to_i,
+ params[:id]
+ )
+ settings.connections.each { |out| out << "data: added transaction\n\n" }
+ end
+ redirect '/'
+ end
+
+ post '/mine' do
+ node.on_mine!
+ redirect '/'
+ end
+
+ post '/peers' do
+ node.on_add_peer( params[:host], params[:port].to_i )
+ redirect '/'
+ end
+
+ post '/peers/:index/delete' do
+ node.on_delete_peer( params[:index].to_i )
+ redirect '/'
+ end
+
+
+
+ post '/resolve' do
+ data = JSON.parse(request.body.read)
+ if data['chain'] && node.on_resolve( data['chain'] )
+ status 202 ### 202 Accepted; see httpstatuses.com/202
+ settings.connections.each { |out| out << "data: resolved\n\n" }
+ else
+ status 200 ### 200 OK
+ end
+ end
+
+
+ get '/events', provides: 'text/event-stream' do
+ stream :keep_open do |out|
+ settings.connections << out
+ out.callback { settings.connections.delete(out) }
+ end
+ end
+
+private
+
+#########
+## return network node (built and configured on first use)
+## fix: do NOT use @@ - use a class level method or something
+def node
+ if defined?( @@node )
+ @@node
+ else
+ puts "[debug] shilling - build (network) node (address: #{Shilling.config.address})"
+ @@node = Node.new( address: Shilling.config.address )
+ @@node
+ end
+ ####
+ ## check why this is a syntax error:
+ ## @node ||= do
+ ## puts "[debug] shilling - build (network) node (address: #{Shilling.config.address})"
+ ## @node = Node.new( address: Shilling.config.address )
+ ## end
+end
+
+ end # class Service
+
+end # module Shilling
diff --git a/attic/bitshilling/lib/shilling/tool.rb b/attic/bitshilling/lib/shilling/tool.rb
new file mode 100644
index 0000000..6896304
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/tool.rb
@@ -0,0 +1,66 @@
+# encoding: utf-8
+
+
+module Shilling
+
+class Tool
+
+def run( args )
+ opts = {}
+
+ parser = OptionParser.new do |cmd|
+ cmd.banner = "Usage: shilling [options]"
+
+ cmd.separator ""
+ cmd.separator " Wallet options:"
+
+ cmd.on("-n", "--name=NAME", "Address name (default: Theresa)") do |name|
+ ## use -a or --adr or --address as option flag - why? why not?
+ ## note: default now picks a random address from WALLET_ADDRESSES
+ opts[:address] = name
+ end
+
+
+ cmd.separator ""
+ cmd.separator " Server (node) options:"
+
+ cmd.on("-o", "--host HOST", "listen on HOST (default: 0.0.0.0)") do |host|
+ opts[:Host] = host ## note: rack server handler expects :Host
+ end
+
+ cmd.on("-p", "--port PORT", "use PORT (default: 4567)") do |port|
+ opts[:Port] = port ## note: rack server handler expects :Post
+ end
+
+ cmd.on("-h", "--help", "Prints this help") do
+ puts cmd
+ exit
+ end
+ end
+
+ parser.parse!( args )
+ pp opts
+
+
+ ###################
+ ## startup server (via rack interface/handler)
+
+ app_class = Service ## use app = Service.new -- why? why not?
+ host = opts[:Host] || '0.0.0.0'
+ port = opts[:Port] || '4567'
+
+ Shilling.configure do |config|
+ config.address = opts[:address] || 'Theresa'
+ end
+
+ Rack::Handler::WEBrick.run( app_class, Host: host, Port: port ) do |server|
+ ## todo: add traps here - why, why not??
+ end
+
+
+end ## method run
+
+
+end ## class Tool
+
+end ## module Shilling
diff --git a/attic/bitshilling/lib/shilling/transaction.rb b/attic/bitshilling/lib/shilling/transaction.rb
new file mode 100644
index 0000000..77ab849
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/transaction.rb
@@ -0,0 +1,30 @@
+
+
+class Transaction
+
+ attr_reader :from, :to, :amount, :id
+
+ def initialize( from, to, amount, id=SecureRandom.uuid )
+ @from = from
+ @to = to
+ @amount = amount
+ @id = id
+ end
+
+ def self.from_h( hash )
+ self.new *hash.values_at( 'from', 'to', 'amount', 'id' )
+ end
+
+ def to_h
+ { from: @from, to: @to, amount: @amount, id: @id }
+ end
+
+
+ def valid?
+ ## check signature in the future; for now always true
+ true
+ end
+
+end # class Transaction
+
+Tx = Transaction ## add Tx shortcut / alias
diff --git a/attic/bitshilling/lib/shilling/version.rb b/attic/bitshilling/lib/shilling/version.rb
new file mode 100644
index 0000000..60369bf
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/version.rb
@@ -0,0 +1,11 @@
+# encoding: utf-8
+
+module Shilling
+
+ VERSION = '0.2.0'
+
+ def self.root
+ "#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
+ end
+
+end # module Shilling
diff --git a/attic/bitshilling/lib/shilling/views/_blockchain.erb b/attic/bitshilling/lib/shilling/views/_blockchain.erb
new file mode 100644
index 0000000..ba39805
--- /dev/null
+++ b/attic/bitshilling/lib/shilling/views/_blockchain.erb
@@ -0,0 +1,37 @@
+