Transactions (Hyper) Ledger Book
From | To | Amount |
---|---|---|
Grossklockner (†) | Sepp | 3798 |
Grossvenediger (†) | Franz | 3666 |
Dachstein (†) | Sissi | 2995 |
Wildspitze (†) | Maria | 3768 |
Sissi | Eva | 20 |
Sepp | Maria | 17 |
Franz | Sissi | 3 |
Sepp | Ferdl | 100 |
Franz | Max | 17 |
Maria | Adam | 4 |
(†): Miner Transaction - New Shilling on the Market!
(Source: bitshilling/bitshilling)
What’s Blockchain?
Yes. Yes. Yes. Blockchain! Blockchain! Blockchain!
(Source: openblockchains/whatsblockchain)
A Success Story on the Blockchain.
May 22, 2010 - World’s 1st Bitcoin Payment
A developer bought two pizzas using 10 000 Bitcoin (BTC) - a then-little-known digital (crypto)currency. Estimated worth about $40.
Triva Q: How much is one Bitcoin worth today? Q: How much are 10 000 Bitcoin worth today?
(Source: coinmarketcap.com/currencies/bitcoin)
Crypto God? Ruby Ninja / Rockstar?
Yes, you can.
What’s Blockchain?
It’s a list (chain) of blocks linked and secured by digital fingerprints (also known as crypto hashes).
require "digest" # for hash checksum digest function SHA256
class Block
attr_reader :index
attr_reader :timestamp
attr_reader :data
attr_reader :previous_hash
attr_reader :hash
def initialize(index, data, previous_hash)
@index = index
@timestamp = Time.now
@data = data
@previous_hash = previous_hash
@hash = calc_hash
end
def calc_hash
sha = Digest::SHA256.new
sha.update( @index.to_s + @timestamp.to_s + @data + @previous_hash )
sha.hexdigest
end
(Source: openblockchains/awesome-blockchains/blockchain.rb)
Yes, that’s it.
Let’s add two helpers (first
, next
) for building (“mining”) blocks.
class Block
def self.first( data="Genesis" ) # create genesis (big bang! first) block
## uses index zero (0) and arbitrary previous_hash ("0")
Block.new( 0, data, "0" )
end
def self.next( previous, data="Transaction Data..." )
Block.new( previous.index+1, data, previous.hash )
end
end # class Block
(Source: openblockchains/awesome-blockchains/blockchain.rb)
Let’s get started - build a blockchain a block at a time!
b0 = Block.first( "Genesis" )
b1 = Block.next( b0, "Transaction Data..." )
b2 = Block.next( b1, "Transaction Data......" )
b3 = Block.next( b2, "More Transaction Data..." )
blockchain = [b0, b1, b2, b3]
pp blockchain ## pp (pretty print to console)
Wait, so a blockchain is just a linked list?
No. A linked list is only required to have a reference to the previous element, a block must have an identifier depending on the previous block’s identifier, meaning that you cannot replace a block without recomputing every single block that comes after. In this implementation that happens as the previous digest is input in the calc_hash method.
will log something like:
[#<Block:0x1eed2a0
@index = 0,
@timestamp = 1637-09-15 20:52:38,
@data = "Genesis",
@previous_hash = "0",
@hash = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
#<Block:0x1eec9a0
@index = 1,
@timestamp = 1637-09-15 21:02:38,
@data = "Transaction Data...",
@previous_hash = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b",
@hash = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743">,
#<Block:0x1eec838
@index = 2,
@timestamp = 1637-09-15 21:12:38,
@data = "Transaction Data......",
@previous_hash = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743",
@hash = "be50017ee4bbcb33844b3dc2b7c4e476d46569b5df5762d14ceba9355f0a85f4">,
...
Making (Hash) Mining a Lottery - Find the Lucky Number
def calc_hash
sha = Digest::SHA256.new
sha.update( @index.to_s + @timestamp.to_s + @data + @previous_hash )
sha.hexdigest
end
The computer (node) in the blockchain network that computes the next block with a valid hash wins the lottery.
For adding a block to the chain you get a reward! You get ~25~ 12.5 Bitcoin! (†)
Bitcoin adds a block every ten minutes.
(†) The reward gets halfed about every two years. In Sep’17 you’ll get 12.5 Bitcoin.
Random SHA256 hash #1: c396de4c03ddb5275661982adc75ce5fc5905d2a2457d1266c74436c1f3c50f1
Random SHA256 hash #2: 493131e09c069645c82795c96e4715cea0f5558be514b5096d853a5b9899154a
Triva Q: What’s SHA256?
A: SHA256 == Secure Hash Algorithms 256 Bits
Trivia: Designed by the National Security Agency (NSA) of the United States of America (USA).
Secure == Random e.g. Change one Letter and the Hash will Change Completely
Making (Hash) Mining a Lottery - Find the Lucky Number
Find a hash that starts with ten leading zeros e.g.
0000000000069645c82795c96e4715cea0f5558be514b5096d853a5b9899154a
Hard to compute! Easy to check / validate.
Making (Hash) Mining a Lottery
def compute_hash_with_proof_of_work( difficulty="00" )
nonce = 0
loop do
hash = calc_hash_with_nonce( nonce )
if hash.start_with?( difficulty )
return [nonce,hash] ## bingo! proof of work if hash starts with leading zeros (00)
else
nonce += 1 ## keep trying (and trying and trying)
end
end
end
def calc_hash_with_nonce( nonce=0 )
sha = Digest::SHA256.new
sha.update( nonce.to_s + @index.to_s + @timestamp.to_s + @data + @previous_hash )
sha.hexdigest
end
(Source: awesome-blockchains/blockchain_with_proof_of_work.rb)
Let’s rerun the sample with the proof of work machinery added. Now the sample will pretty print (pp) something like:
[#<Block:0x1e204f0
@index = 0,
@timestamp = 1637-09-20 20:13:38,
@data = "Genesis",
@previous_hash = "0",
@nonce = 242,
@hash = "00b8e77e27378f9aa0afbcea3a2882bb62f6663771dee053364beb1887e18bcf">,
#<Block:0x1e56e20
@index = 1,
@timestamp = 1637-09-20 20:23:38,
@data = "Transaction Data...",
@previous_hash = "00b8e77e27378f9aa0afbcea3a2882bb62f6663771dee053364beb1887e18bcf",
@nonce = 46,
@hash = "00aae8d2e9387e13c71b33f8cd205d336ac250d2828011f5970062912985a9af">,
#<Block:0x1e2bd58
@index = 2,
@timestamp = 1637-09-20 20:33:38,
@data = "Transaction Data......",
@previous_hash = "00aae8d2e9387e13c71b33f8cd205d336ac250d2828011f5970062912985a9af",
@nonce = 350,
@hash = "00ea45e0f4683c3bec4364f349ee2b6816be0c9fd95cfd5ffcc6ed572c62f190">,
...
See the difference?
All hashes now start with leading zeros (00
)
and the nonce is the random “lucky number” that makes it happen.
That’s the magic behind the proof of work.
(Source: Tony Arcieri - On the dangers of a blockchain monoculture)
Tulip Mania Quiz - Win 100 Shilling on the Blockchain!
Q: Tulip Mania Bubble in Holland - What Year?
Q: What’s the Name of the Most Expensive Tulip?
Learn by Example from the Real World (Anno 1637) - Buy! Sell! Hold! Enjoy the Beauty of Admiral of Admirals, Semper Augustus and More.
Transactions (Hyper) Ledger Book
From | To | What | Qty |
---|---|---|---|
Dutchgrown (†) | Vincent | Tulip Bloemendaal Sunset | 10 |
Keukenhof (†) | Anne | Tulip Semper Augustus | 7 |
Flowers (†) | Ruben | Tulip Admiral van Eijck | 5 |
Vicent | Anne | Tulip Bloemendaal Sunset | 3 |
Anne | Julia | Tulip Semper Augustus | 1 |
Julia | Luuk | Tulip Semper Augustus | 1 |
Bloom & Blossom (†) | Daisy | Tulip Admiral of Admirals | 8 |
Vincent | Max | Tulip Bloemendaal Sunset | 2 |
Anne | Martijn | Tulip Semper Augustus | 2 |
Ruben | Julia | Tulip Admiral van Eijck | 2 |
Teleflora (†) | Max | Tulip Red Impression | 11 |
Anne | Naomi | Tulip Bloemendaal Sunset | 1 |
Daisy | Vincent | Tulip Admiral of Admirals | 3 |
Julia | Mina | Tulip Admiral van Eijck | 1 |
Max | Isabel | Tulip Red Impression | 2 |
(†): Grower Transaction - New Tulips on the Market!
(Source: openblockchains/tulips)
Quotes - Blockchains are the next Internets / Tulips
People who compare digital tokens to tulips are essentially saying digital tokens are a bubble backed by nothing but pure hype and speculation.
What they fail to understand is that tulips come from dirt, not a blockchain.
And as we all know, blockchain is possibly the best technological innovation since the internet. It will have a tremendous impact on global business and society in general. – TulipToken
Adding Transactions:
b0 = Block.first(
{ from: "Dutchgrown", to: "Vincent", what: "Tulip Bloemendaal Sunset", qty: 10 },
{ from: "Keukenhof", to: "Anne", what: "Tulip Semper Augustus", qty: 7 } )
b1 = Block.next( b0,
{ from: "Flowers", to: "Ruben", what: "Tulip Admiral van Eijck", qty: 5 },
{ from: "Vicent", to: "Anne", what: "Tulip Bloemendaal Sunset", qty: 3 },
{ from: "Anne", to: "Julia", what: "Tulip Semper Augustus", qty: 1 },
{ from: "Julia", to: "Luuk", what: "Tulip Semper Augustus", qty: 1 } )
b2 = Block.next( b1,
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
...
resulting in:
[#<Block:0x2da3da0
@hash="32bd169baebba0b70491b748329ab631c85175be15e1672f924ca174f628cb66",
@index=0,
@previous_hash="0",
@timestamp=1637-09-25 17:39:21,
@transactions=
[{:from=>"Dutchgrown", :to=>"Vincent", :what=>"Tulip Bloemendaal Sunset", :qty=>10},
{:from=>"Keukenhof", :to=>"Anne", :what=>"Tulip Semper Augustus", :qty=>7}],
@transactions_count=2>,
#<Block:0x2da2ff0
@hash="57b519a8903e45348ac8a739c788815e2bd90423663957f87e276307f77f1028",
@index=1,
@previous_hash=
"32bd169baebba0b70491b748329ab631c85175be15e1672f924ca174f628cb66",
@timestamp=1637-09-25 17:49:21,
@transactions=
[{:from=>"Flowers", :to=>"Ruben", :what=>"Tulip Admiral van Eijck", :qty=>5},
{:from=>"Vicent", :to=>"Anne", :what=>"Tulip Bloemendaal Sunset", :qty=>3},
{:from=>"Anne", :to=>"Julia", :what=>"Tulip Semper Augustus", :qty=>1},
{:from=>"Julia", :to=>"Luuk", :what=>"Tulip Semper Augustus", :qty=>1}],
@transactions_count=4>,
...
Revolutionize the world with blockchains, blockchains, blockchains one block at a time!
github: openblockchains/blockchain.lite.rb, rubygems: blockchain-lite, rdoc: blockchain-lite ++ more: comments on reddit, please!
A blockchain is a distributed database with a list (that is, chain) of records (that is, blocks) linked and secured by digital fingerprints (that is, crypto hashes).
See the Awesome Blockchains page for more.
Build your own blockchain one block at a time. Example:
require 'blockchain-lite'
b0 = Block.first( 'Genesis' )
b1 = Block.next( b0, 'Transaction Data...' )
b2 = Block.next( b1, 'Transaction Data......' )
b3 = Block.next( b2, 'More Transaction Data...' )
blockchain = [b0, b1, b2, b3]
pp blockchain
will pretty print (pp) something like:
[#<Block:0x1eed2a0
@index = 0,
@timestamp = 2017-09-15 20:52:38,
@data = "Genesis",
@previous_hash = "0",
@hash ="edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
#<Block:0x1eec9a0
@index = 1,
@timestamp = 2017-09-15 20:52:38,
@data = "Transaction Data...",
@hash = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743",
@previous_hash = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
#<Block:0x1eec838
@index = 2,
@timestamp = 2017-09-15 20:52:38,
@data = "Transaction Data......",
@hash = "be50017ee4bbcb33844b3dc2b7c4e476d46569b5df5762d14ceba9355f0a85f4",
@previous_hash = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743">,
#<Block:0x1eec6d0
@index = 3,
@timestamp = 2017-09-15 20:52:38
@data = "More Transaction Data...",
@hash = "5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d",
@previous_hash = "be50017ee4bbcb33844b3dc2b7c4e476d46569b5df5762d14ceba9355f0a85f4">]
Supported block types / classes for now include basic and proof-of-work.
class Block
attr_reader :index
attr_reader :timestamp
attr_reader :data
attr_reader :previous_hash
attr_reader :hash
def initialize(index, data, previous_hash)
@index = index
@timestamp = Time.now.utc ## note: use coordinated universal time (utc)
@data = data
@previous_hash = previous_hash
@hash = calc_hash
end
def calc_hash
sha = Digest::SHA256.new
sha.update( @index.to_s + @timestamp.to_s + @data + @previous_hash )
sha.hexdigest
end
...
end
Comments from the reddit ruby posting:
Wait, so a blockchain is just a linked list?
No. A linked list is only required to have a reference to the previous element, a block must have an identifier depending on the previous block’s identifier, meaning that you cannot replace a block without recomputing every single block that comes after. In this implementation that happens as the previous digest is input in the calc_hash method.
class Block
attr_reader :index
attr_reader :timestamp
attr_reader :data
attr_reader :previous_hash
attr_reader :nonce ## proof of work if hash starts with leading zeros (00)
attr_reader :hash
def initialize(index, data, previous_hash)
@index = index
@timestamp = Time.now.utc ## note: use coordinated universal time (utc)
@data = data
@previous_hash = previous_hash
@nonce, @hash = compute_hash_with_proof_of_work
end
...
end
Let’s add a proof of work to the blockchain.
In the classic blockchain you have to compute a block hash that starts with leading zeros (00
). The more leading zeros the harder (more difficult) to compute. Let’s keep it easy to compute with two leading zeros (00
), that is, 16^2 = 256 possibilites (^1,2). Three leading zeros (000
) would be 16^3 = 4_096 possibilites and four zeros (0000
) would be 16^4 = 65_536 and so on.
(^1): 16 possibilties because it’s a hex or hexadecimal or base 16 number, that is, 0
1
2
3
4
6
7
8
9
a
(10) b
(11) c
(12) d
(13) e
(14) f
(15).
(^2): A random secure hash algorithm needs on average 256 tries (might be lets say 305 tries, for example, because it’s NOT a perfect statistic distribution of possibilities).
Example:
def compute_hash_with_proof_of_work( difficulty="00" )
nonce = 0
loop do
hash = calc_hash_with_nonce( nonce )
if hash.start_with?( difficulty )
return [nonce,hash] ## bingo! proof of work if hash starts with leading zeros (00)
else
nonce += 1 ## keep trying (and trying and trying)
end
end
end
def calc_hash_with_nonce( nonce=0 )
sha = Digest::SHA256.new
sha.update( nonce.to_s + @index.to_s + @timestamp.to_s + @data + @previous_hash )
sha.hexdigest
end
Let’s rerun the sample with the proof of work machinery added. Now the sample will pretty print (pp) something like:
[#<Block:0x1e204f0
@index = 0,
@timestamp = 1637-09-20 20:13:38,
@data = "Genesis",
@previous_hash = "0",
@nonce = 242,
@hash = "00b8e77e27378f9aa0afbcea3a2882bb62f6663771dee053364beb1887e18bcf">,
#<Block:0x1e56e20
@index = 1,
@timestamp = 1637-09-20 20:23:38,
@data = "Transaction Data...",
@previous_hash = "00b8e77e27378f9aa0afbcea3a2882bb62f6663771dee053364beb1887e18bcf",
@nonce = 46,
@hash = "00aae8d2e9387e13c71b33f8cd205d336ac250d2828011f5970062912985a9af">,
#<Block:0x1e2bd58
@index = 2,
@timestamp = 1637-09-20 20:33:38,
@data = "Transaction Data......",
@previous_hash = "00aae8d2e9387e13c71b33f8cd205d336ac250d2828011f5970062912985a9af",
@nonce = 350,
@hash = "00ea45e0f4683c3bec4364f349ee2b6816be0c9fd95cfd5ffcc6ed572c62f190">,
#<Block:0x1fa8338
@index = 3,
@timestamp = 1637-09-20 20:43:38,
@data = "More Transaction Data...",
@previous_hash = "00ea45e0f4683c3bec4364f349ee2b6816be0c9fd95cfd5ffcc6ed572c62f190",
@nonce = 59,
@hash = "00436f0fca677652963e904ce4c624606a255946b921132d5b1f70f7d86c4ab8">]
See the difference? All hashes now start with leading zeros (00
) and the nonce is the random “lucky number”
that makes it happen. That’s the magic behind the proof of work.
Let’s put the transactions from the (hyper) ledger book from Tulips on the Blockchain! on the blockchain:
From | To | What | Qty |
---|---|---|---|
Dutchgrown (†) | Vincent | Tulip Bloemendaal Sunset | 10 |
Keukenhof (†) | Anne | Tulip Semper Augustus | 7 |
Flowers (†) | Ruben | Tulip Admiral van Eijck | 5 |
Vicent | Anne | Tulip Bloemendaal Sunset | 3 |
Anne | Julia | Tulip Semper Augustus | 1 |
Julia | Luuk | Tulip Semper Augustus | 1 |
Bloom & Blossom (†) | Daisy | Tulip Admiral of Admirals | 8 |
Vincent | Max | Tulip Bloemendaal Sunset | 2 |
Anne | Martijn | Tulip Semper Augustus | 2 |
Ruben | Julia | Tulip Admiral van Eijck | 2 |
Teleflora (†) | Max | Tulip Red Impression | 11 |
Anne | Naomi | Tulip Bloemendaal Sunset | 1 |
Daisy | Vincent | Tulip Admiral of Admirals | 3 |
Julia | Mina | Tulip Admiral van Eijck | 1 |
(†): Grower Transaction - New Tulips on the Market!
b0 = Block.first(
{ from: "Dutchgrown", to: "Vincent", what: "Tulip Bloemendaal Sunset", qty: 10 },
{ from: "Keukenhof", to: "Anne", what: "Tulip Semper Augustus", qty: 7 } )
b1 = Block.next( b0,
{ from: "Flowers", to: "Ruben", what: "Tulip Admiral van Eijck", qty: 5 },
{ from: "Vicent", to: "Anne", what: "Tulip Bloemendaal Sunset", qty: 3 },
{ from: "Anne", to: "Julia", what: "Tulip Semper Augustus", qty: 1 },
{ from: "Julia", to: "Luuk", what: "Tulip Semper Augustus", qty: 1 } )
b2 = Block.next( b1,
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
...
resulting in:
[#<Block:0x2da3da0
@index = 0,
@timestamp = 1637-09-24 11:40:15,
@previous_hash = "0",
@hash = "32bd169baebba0b70491b748329ab631c85175be15e1672f924ca174f628cb66",
@transactions_count = 2,
@transactions =
[{:from=>"Dutchgrown", :to=>"Vincent", :what=>"Tulip Bloemendaal Sunset", :qty=>10},
{:from=>"Keukenhof", :to=>"Anne", :what=>"Tulip Semper Augustus", :qty=>7}]>,
#<Block:0x2da2ff0
@index = 1,
@timestamp = 1637-09-24 11:50:15,
@previous_hash = "32bd169baebba0b70491b748329ab631c85175be15e1672f924ca174f628cb66",
@hash = "57b519a8903e45348ac8a739c788815e2bd90423663957f87e276307f77f1028",
@transactions_count = 4,
@transactions =
[{:from=>"Flowers", :to=>"Ruben", :what=>"Tulip Admiral van Eijck", :qty=>5},
{:from=>"Vicent", :to=>"Anne", :what=>"Tulip Bloemendaal Sunset", :qty=>3},
{:from=>"Anne", :to=>"Julia", :what=>"Tulip Semper Augustus", :qty=>1},
{:from=>"Julia", :to=>"Luuk", :what=>"Tulip Semper Augustus", :qty=>1}]>,
#<Block:0x2da2720
@index = 2,
@timestamp = 1637-09-24 12:00:15,
@previous_hash = "57b519a8903e45348ac8a739c788815e2bd90423663957f87e276307f77f1028",
@hash = "ec7dd5ea86ab966d4d4db182abb7aa93c7e5f63857476e6301e7e38cebf36568",
@transactions_count = 4,
@transactions =
[{:from=>"Bloom & Blossom", :to=>"Daisy", :what=>"Tulip Admiral of Admirals", :qty=>8},
{:from=>"Vincent", :to=>"Max", :what=>"Tulip Bloemendaal Sunset", :qty=>2},
{:from=>"Anne", :to=>"Martijn", :what=>"Tulip Semper Augustus", :qty=>2},
{:from=>"Ruben", :to=>"Julia", :what=>"Tulip Admiral van Eijck", :qty=>2}]>,
...
That’s it. Now revolutionize the world with blockchains one block at a time.
github: openblockchains/merkletree.rb, rubygems: merkletree, rdoc: merkletree ++ more: comments on reddit, please!
A Merkle tree or hash tree is a tree in which every leaf node is labelled with the hash of a data block and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes. Hash trees allow efficient and secure verification of the contents of large data structures. […]
The concept of hash trees is named after Ralph Merkle who patented it in 1979.
Pass along all (leaf / data block) hashes as strings or packaged in an array. Example:
merkle = MerkleTree.new(
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' )
# -or-
merkle = MerkleTree.new( [
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' ])
puts merkle.root.value
# => '25fd59b79d70bbdf043d66a7b0fc01409d11b990e943bb46b840fbbddd5ab895'
pp merkle ## pp (pretty print)
resulting in:
@root = #<MerkleTree::Node:0x46b55e0
@left = #<MerkleTree::Node:0x46b6060
@left = #<MerkleTree::Node:0x46b6870
@left = nil,
@right = nil,
@value = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743">,
@right = #<MerkleTree::Node:0x46b6810
@left = nil,
@right = nil,
@value = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
@value = "c9de03ced4db3c63835807016b1efedb647c694d2db8b9a8579cbf0c5dcb5ab0">,
@right= #<MerkleTree::Node:0x46b5ca0
@left= #<MerkleTree::Node:0x46b6798
@left = nil,
@right = nil,
@value = "5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d">,
@right = #<MerkleTree::Node:0x46b6798
@left = nil,
@right = nil,
@value = "5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d">,
@value = "50963aa3b2047e0d58bb850fc12e5a324cf01061af55889389be72d3849e1d03">,
@value="25fd59b79d70bbdf043d66a7b0fc01409d11b990e943bb46b840fbbddd5ab895">>
Use MerkleTree.compute_root
for computing the root (crypto) hash without building a
tree. Example:
merkle_root_value = MerkleTree.compute_root(
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' )
# -or-
merkle_root_value = MerkleTree.compute_root( [
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' ])
puts merkle_root_value
# => '25fd59b79d70bbdf043d66a7b0fc01409d11b990e943bb46b840fbbddd5ab895'
Use MerkleTree.for
or MerkleTree.compute_root_for
for passing along transactions.
Will use to_s
on every transaction and use the resulting “serialized” string
to (auto-) calculate the (crypto) hash.
Let’s put the transactions from the (hyper) ledger book from Tulips on the Blockchain!
on the blockchain merkle tree:
From | To | What | Qty |
---|---|---|---|
Bloom & Blossom (†) | Daisy | Tulip Admiral of Admirals | 8 |
Vincent | Max | Tulip Bloemendaal Sunset | 2 |
Anne | Martijn | Tulip Semper Augustus | 2 |
Ruben | Julia | Tulip Admiral van Eijck | 2 |
(†): Grower Transaction - New Tulips on the Market!
merkle = MerkleTree.for(
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
puts merkle.root.value
# => '703f44630117ef9b4ac20cb149ed8a0f06e4c3ed2a791e11e16a2fe7a7d0de3d'
# -or-
merkle_root_value = MerkleTree.compute_root_for(
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
puts merkle_root_value
# => '703f44630117ef9b4ac20cb149ed8a0f06e4c3ed2a791e11e16a2fe7a7d0de3d'
Cryptos, Cryptos, Cryptos - Revolutionize the world with blockchains, blockchains, blockchains one block at a time!
github: openblockchains/centralbank, rubygems: centralbank, rdoc: centralbank ++ more: comments on reddit, please!
Use the centralbank
command line tool. Try:
$ centralbank -h
resulting in:
Usage: centralbank [options]
Wallet options:
-n, --name=NAME Address name (default: Alice)
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, Alice) and the default server host and port settings use:
$ centralbank
Stand back ten feets :-) while starting up the machinery.
Ready to print (mine) money 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:
$ centralbank -p 5678 -n Bob
Happy mining!
What happens when you hit the “Mine a block” button? Let follow the code.
The form gets posted by the browser and hits the /mine route in centralbank network service
class Service < Sinatra::Base
# ...
post '/mine' do
node.on_mine!
redirect '/'
end
# ...
end
(Source: lib/centralbank/service.rb)
So the code mines a block and refreshes the page. That’s it!
Let’s dive into the on_mine!
method in the network node:
class Node
# ...
def on_mine!
@bank.mine_block!
send_chain_to_peers
end
# ...
end
(Source: lib/centralbank/node.rb)
So the code mines a block and sends the new blockchain (chain) to
all peers (nodes). That’s it!
Let’s dive into the mine_block!
method for the centralbank machinery:
class Bank
# ...
def mine_block!
@pending << Tx.new( Centralbank.config.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 )
end
# ...
end
(Source: lib/centralbank/bank.rb)
So the code adds a “COINBASE” transaction (tx) to the pending pool
(of unconfirmed transactions).
For mining a new block you will get a
mining reward (e.g. $5). That’s the magic moment of printing new money
on the blockchain.
Next all pending (unconfirmed but validated) transactions
get added to the blockchain (chain) as a new block.
Done! Block mined! Let’s clear out the pending pool
and update all wallet balances, that is, update the ledger book.
Let’s dive into the <<
method for the blockchain (chain) machinery:
class Blockchain
# ...
def <<( txs )
if @chain.size == 0
block = Block.first( txs )
else
block = Block.next( @chain.last, txs )
end
@chain << block
end
# ...
end
(Source: lib/centralbank/blockchain.rb)
So the code adds a block to the chain at the end and passes along the hash of the last block on the blockchain to the new block. That’s all the magic of printing money.
What about proof-of-work and the hashing power/rate? See the blockchain-lite library - Build Your Own Blockchains with Crypto Hashes article in the series.
Happy mining!
For local development - clone or download (and unzip) the centralbank code repo. Next install all dependencies using bundler with a Gemfile e.g.:
# Gemfile
source "https://rubygems.org"
gem 'sinatra'
gem 'sass'
gem 'blockchain-lite'
run
$ bundle ## will use the Gemfile (see above)
and now you’re ready to run your own centralbank server node. Use the config.ru
script for rack:
# config.ru
$LOAD_PATH << './lib'
require 'centralbank'
run Centralbank::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!
Cryptos, Cryptos, Cryptos • Do-It-Yourself (D-I-Y) - Build Your Own Cryptos • Bitcoin (Classic, Cash, Gold, Unlimited), Monero & Futures
Digest::SHA256.hexdigest( 'Hello, Cryptos!' )
#=> "dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f"
Digest::SHA256.hexdigest( 'Hello, Cryptos! - Hello, Cryptos! - Hello, Cryptos!' )
#=> "9e513dbdfe60a14f0cac37aeacbe24fa961b428e8ddeb4d6a66006b29425bbd2"
A collection of awesome crypto goodies about cryptocurrencies and blockchains, public key infrastructure (pki), and more
Do-It-Yourself (D-I-Y) - Build Your Own Cryptos
Blockchain Lite (gem: blockchain-lite, github: openblockchains/blockchain.lite.rb) - build your own blockchain with crypto hashes - revolutionize the world with blockchains, blockchains, blockchains one block at a time
Merkle Tree (gem: merkletree, github: openblockchains/merkletree.rb) - build your own crypto hash trees; named after Ralph Merkle who patented hash trees in 1979; grow your own money on trees
Central Bank (gem: centralbank, github: openblockchains/centralbank) - command line tool to print your own money / cryptocurrency; run your own federated central bank nodes on the blockchain peer-to-peer over HTTP; revolutionize the world one block at a time
Classic, Cash, Cash Plus, Gold, Silver, Diamond, Platinum, Unlimited
Bitcoin (gem: bitcoin-ruby, github: lian/bitcoin-ruby) - bitcoin utils and protocol
Bitcoin Questions & Answers @ Stackexchange - popular tags: transactions × blockchain × bitcoin-core × wallet × bitcoind × address × mining-pools × blockchain.info × transaction-fees × unconfirmed-transactions × security × exchanges × client × api × json-rpc × litecoin × private-key × block × mining-theory × mining-hardware × altcoin …
Monero (gem: monero, github: krtschmr/monero) - client for monero-wallet-rpc
Monero Questions & Answers @ Stackexchange - popular tags: monero-wallet-cli × monerod × monero-wallet-gui × blockchain × security × mining-pools × mining × ringct × cpu-mining × synchronization × privacy × full-node × gpu-mining × mnemonic-seed × cryptonote × cold-storage × transaction-data × cryptography × mymonero × daemon × viewkey × transaction-fees × kovri × payment-id × ring-signatures × hard-fork × ringsize × transaction-confirmation × mining-theory × aeon × wallet-recovery × cryptocurrency-comparison × hashrate …
How Does Bitcoin Force Consensus Among Byzantine Generals? by Fabio Akita, November 2017
Let’s build a blockchain (github: Haseeb-Qureshi/lets-build-a-blockchain) by Haseeb Qureshi - a mini cryptocurrency built from scratch in six stages
Crypthography @ Stackexchange - popular tags: encryption × hash × rsa × aes × public-key × cryptanalysis × elliptic-curves × signature × block-cipher × algorithm-design × random-number-generator × diffie-hellman × protocol-design × keys × authentication × symmetric × homomorphic-encryption × hmac × collision-resistance …
Ethereum @ Stackexchange - popular tags: solidity × go-ethereum × contract-development × web3js × transactions × blockchain × ether × contract-design × mining × truffle × wallets × mist × tokens × private-blockchain × parity × contract-deployment × contract-invocation × gas × synchronization × remix × 368 dapp-development × ethereum-wallet-dapp × testrpc × testnets × accounts × json-rpc × security × dapps × myetherwallet × erc-20 × contract-debugging × addresses × metamask × evm …
A curated list of awesome lists.
(Source: coinmarketcap.com/currencies/gulden)
Who’s in? Invest now!
Crypto #Shilling on the #Blockchain in 324 Days 7 Hours 30 Minutes!
Join the Rock-Solid Alpine Dollar Movement!
Learn more @ bitshilling
Collectible. Breedable. Adorable.
Collect and breed digital cats. Start meow. Buy! Sell! Hold!
Learn more @ cryptokitties.co
Latest (and Greatest) Investment Opportunity!
Blockchain has unlocked the magic of digital scarcity, and combining that with the power of making the digital goods persistent gives them a potential value that is only limited by how much prestige a wealthy person might place on ownership of the item.
All I want for Christmas is a CryptoKitty.
I got a fever. And the only prescription is more CryptoKitties.
My Gen 7 CryptoKitty #104375. The Future is Meow.
A collection about Awesome CryptoKitties (Yes, Cute Little Cartoon Cats) on the Blockchain! and CryptoCopycats - digital collectibles secured on a distributed public databases w/ crypto hashes. Are CryptoPuppies the new CryptoKitties? Learn by Example from the Real World (Anno 2017) - Buy! Sell! Hodl!
Reflections on the Blockchain by Rufus Pollock (Open Knowledge Foundation), July 2016 – The DAO: Code is not Law – and It’s Dangerous to Think So ++ The Internet changed the world - surely the Blockchain will too? ++ Gold-rush or Internet-rush? ++ Governance Matters in Bitcoin ++ The Myth of a Costless, Ownerless Network ++ Lessons from History
On the Dangers of a Blockchain Monoculture by Tony Arcieri, January 2016 – The Bitcoin blockchain: the world’s worst database ++ Next-generation protocols ++ Decentralized ledger protocols ++ Bitcoin-NG ++ Blockchain! Blockchain! Blockchain! ++ The great decentralized database in the sky
I Don’t Believe in Blockchain by Tim Bray, May 2017
Minimum Viable Blockchain by Ilya Grigorik, May 2014 – Securing transactions with triple-entry bookkeeping ++ Securing transactions with PKI ++ Balance = Σ(receipts) ++ Multi-party transfers & verification ++ Double-spending and distributed consensus - Requirements for a distributed consensus network; Protecting the network from Sybil attacks; Proof-of-work as a participation requirement ++ Building the minimum viable blockchain - Adding “blocks” & transaction fee incentives; Racing to claim the transaction fees; Resolving chain conflicts; Blocks are never final ++ Properties of the (minimum viable) blockchain
Blockchains by analogies and applications: How blockchain compares to Git, Raft, and other technologies. by Kieren James-Lubin, January 2016 – Blockchains are databases ++ Understanding transactions ++ Persistent, replicated databases (related technology: Git) ++ Peer-to-peer networks (related technology: BitTorrent) ++ Distributed consensus (related technology: distributed databases, Raft) ++ Minting new coins (mining) ++ Embedded identities (related technology: TLS) ++ Smart contracts: Like SQL expressions & triggers ++ What can we really do with blockchains?
Attack of the 50 Foot Blockchain: Bitcoin, Blockchain, Ethereum & Smart Contracts by David Gerard, London, 2017 – What is a bitcoin? ++ The Bitcoin ideology ++ The incredible promises of Bitcoin! ++ Early Bitcoin: the rise to the first bubble ++ How Bitcoin mining centralised ++ Who is Satoshi Nakamoto? ++ Spending bitcoins in 2017 ++ Trading bitcoins in 2017: the second crypto bubble ++ Altcoins ++ Smart contracts, stupid humans ++ Business bafflegab, but on the Blockchain ++ Case study: Why you can’t put the music industry on a blockchain
Mastering Bitcoin - Programming the Open Blockchain 2nd Edition, by Andreas M. Antonopoulos, 2017 - FREE (Online Source Version) – What Is Bitcoin? ++ How Bitcoin Works ++ Bitcoin Core: The Reference Implementation ++ Keys, Addresses ++ Wallets ++ Transactions ++ Advanced Transactions and Scripting ++ The Bitcoin Network ++ The Blockchain ++ Mining and Consensus ++ Bitcoin Security ++ Blockchain Applications
Blockchain for Dummies, IBM Limited Edition by Manav Gupta, 2017 - FREE (Digital Download w/ Email) – Grasping Blockchain Fundamentals ++ Taking a Look at How Blockchain Works ++ Propelling Business with Blockchains ++ Blockchain in Action: Use Cases ++ Hyperledger, a Linux Foundation Project ++ Ten Steps to Your First Blockchain application
A collection about awesome blockchains - open distributed public databases w/ crypto hashes incl. git ;-). Blockchains are the new tulips. Distributed is the new centralized.
Everything is local. Distributed is the new centralized.
Yep, that’s the joke. Nobody has been able to explain to me how the “blockchain” buzzword is significantly different to “git repo”. – Yaakov
But if you said “let’s build a currency where all transactions are stored in a git repo” you wouldn’t be taken seriously for even 24 hrs. – Yaakov
Soon explaining git like “a git repo is like a blockchain with commits instead of blocks”. – Nicolás Berger
“A local branch is like a state channel. It can be pushed and merged into the master blockchain at any moment.” – Nicolás Berger
The #Blockchain has changed the world. Here I make the argument that the #Blockchain is just like #git. – Jackson Kelley
git merge [-m REF] [-g BLOB] --push
Merge and push all signed commits to the blockchain. – Git Commands