You [Gerald Bauer¹] have been permanently banned [for life] from participating in r/ruby (because of your writing off / outside of r/ruby). I do not see your participation adding anything to this [ruby] community.
-- Richard Schneeman (r/ruby mod and fanatic illiberal ultra leftie on a cancel culture mission)
¹: I know. Who cares? Who is this Gerald Bauer anyway. A random nobody for sure. It just happens that I am the admin among other things of Planet Ruby.
Case Studies of Code of Conduct "Cancel Culture" Out-Of-Control Power Abuse - Ruby - A Call for Tolerance On Ruby-Talk Results In Ban On Reddit RubyUpdate (August, 2022) - A Call for More Tolerance And Call For No-Ban Policy Results In Ban On Ruby-Talk (With No Reason Given)
> I just banned gerald.bauer@gmail.com. > > -- SHIBATA Hiroshi > >> THANK YOU >> >> -- Ryan Davis >> >> >> My full support to moderators. >> >> -- Xavier Noria >> >> My full support to moderators. >> >> -- Carlo E. Prelz >> >> That's fun. >> >> -- Alice
« Ruby Blockchain Week 2021, January 3rd to January 9th - 7 Days of Ruby (Crypto) Gems
Written by Gerald Bauer
A code monkey formerly at Big Korupto. Jobless no coiner having fun staying poor and wrong. Writing the Get Rich Quick “Business Blockchain” Bible - The Secrets of Free Easy Money.
A blockchain is 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 = 2021-01-04 20:52:38,
@data = "Genesis",
@previous_hash = "0",
@hash ="edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
#<Block:0x1eec9a0
@index = 1,
@timestamp = 2021-01-04 20:52:38,
@data = "Transaction Data...",
@hash = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743",
@previous_hash = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
#<Block:0x1eec838
@index = 2,
@timestamp = 2021-01-04 20:52:38,
@data = "Transaction Data......",
@hash = "be50017ee4bbcb33844b3dc2b7c4e476d46569b5df5762d14ceba9355f0a85f4",
@previous_hash = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743">,
#<Block:0x1eec6d0
@index = 3,
@timestamp = 2021-01-04 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.
The bitcoin code is archaic and out-of-date. Burn, baby, burn! Proof-of-waste is a global energy environmental disaster using 300 kWh per bitcoin transaction (!) that’s about 179 kilograms of CO₂ emissions.
To the moon!? The new gold standard!? Programmable money (or the internet of value) for all future generations with (bitcoin) script without loops and jumps (gotos) and all “stateless”!? LOL.
BEWARE: Bitcoin is a gigantic ponzi scheme. Do NOT “invest” trying to get-rich-quick HODLing.
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.
Built with Ruby
(running Jekyll)
on 2023-01-25 18:05:39 +0000 in 0.371 seconds.
Hosted on GitHub Pages.
</> Source on GitHub.
(0) Dedicated to the public domain.