Skip to content

Commit 35fe33b

Browse files
committed
add ledger lite
1 parent bedaa63 commit 35fe33b

16 files changed

+1187
-1
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Gems:
44

55
- [blockchain-lite](blockchain-lite) - build your own blockchain with crypto hashes - revolutionize the world with blockchains, blockchains, blockchains one block at a time
66
- [merkletree](merkletree) - build your own crypto hash trees; named after Ralph Merkle who patented hash trees in 1979 (the patent expired in 2002); grow your own money on trees
7+
- [ledger-lite](ledger-lite) - hyper ledger book for the distributed blockchain internet era; add your transactions one block at a time; transfer crypto(currencie)s and balance the accounts
8+
9+
10+
711

812

913

ledger-lite/.gitignore

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
*.gem
2+
*.rbc
3+
/.config
4+
/coverage/
5+
/InstalledFiles
6+
/pkg/
7+
/spec/reports/
8+
/spec/examples.txt
9+
/test/tmp/
10+
/test/version_tmp/
11+
/tmp/
12+
13+
# Used by dotenv library to load environment variables.
14+
# .env
15+
16+
## Specific to RubyMotion:
17+
.dat*
18+
.repl_history
19+
build/
20+
*.bridgesupport
21+
build-iPhoneOS/
22+
build-iPhoneSimulator/
23+
24+
## Specific to RubyMotion (use of CocoaPods):
25+
#
26+
# We recommend against adding the Pods directory to your .gitignore. However
27+
# you should judge for yourself, the pros and cons are mentioned at:
28+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29+
#
30+
# vendor/Pods/
31+
32+
## Documentation cache and generated files:
33+
/.yardoc/
34+
/_yardoc/
35+
/doc/
36+
/rdoc/
37+
38+
## Environment normalization:
39+
/.bundle/
40+
/vendor/bundle
41+
/lib/bundler/man/
42+
43+
# for a library or gem, you might want to ignore these files since the code is
44+
# intended to run in multiple environments; otherwise, check them in:
45+
# Gemfile.lock
46+
# .ruby-version
47+
# .ruby-gemset
48+
49+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50+
.rvmrc

ledger-lite/HISTORY.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### 0.0.1 / 2018-01-02
2+
3+
* Everything is new. First release

ledger-lite/Manifest.txt

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
HISTORY.md
2+
LICENSE.md
3+
Manifest.txt
4+
README.md
5+
Rakefile
6+
lib/ledger-lite.rb
7+
lib/ledger-lite/base.rb
8+
lib/ledger-lite/version.rb
9+
test/helper.rb
10+
test/test_blocks.rb
11+
test/test_transactions.rb
12+
test/test_transactions_v2.rb
13+
test/test_version.rb

ledger-lite/NOTES.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Notes
2+
3+
4+
## Todos

ledger-lite/README.md

+310
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
# Ledger Lite
2+
3+
ledger-lite library / gem - hyper ledger book for the distributed blockchain internet era; add your transactions one block at a time; transfer crypto(currencie)s and balance the accounts
4+
5+
6+
* home :: [github.com/openblockchains/ledger.lite.rb](https://github.com/openblockchains/ledger.lite.rb)
7+
* bugs :: [github.com/openblockchains/ledger.lite.rb/issues](https://github.com/openblockchains/ledger.lite.rb/issues)
8+
* gem :: [rubygems.org/gems/ledger-lite](https://rubygems.org/gems/ledger-lite)
9+
* rdoc :: [rubydoc.info/gems/ledger-lite](http://rubydoc.info/gems/ledger-lite)
10+
11+
12+
13+
## Usage
14+
15+
Let's add some transactions to the (hyper) ledger book:
16+
17+
| From | To | $ |
18+
|---------------------------|--------------|----:|
19+
| Central Bank (†) | Vincent | 11 |
20+
| Vincent | Anne | 3 |
21+
| Anne | Julia | 2 |
22+
| Julia | Luuk | 1 |
23+
| | | |
24+
| De Nederlandsche Bank (†) | Ruben | 11 |
25+
| Vincent | Max | 3 |
26+
| Ruben | Julia | 2 |
27+
| Anne | Martijn | 1 |
28+
29+
(†): Mining Transaction - New Dutch Gulden ($) on the Market!
30+
31+
32+
33+
### Use `send` (send payment/transfer money)
34+
35+
```ruby
36+
37+
ledger = Ledger.new
38+
39+
ledger.send( "Central Bank†", "Vincent", 11 )
40+
ledger.send( "Vincent", "Anne", 3 )
41+
ledger.send( "Anne", "Julia", 2 )
42+
ledger.send( "Julia", "Luuk", 1 )
43+
44+
ledger.send( "De Nederlandsche Bank†", "Ruben", 11 )
45+
ledger.send( "Vincent", "Max", 3 )
46+
ledger.send( "Ruben", "Julia", 2 )
47+
ledger.send( "Anne", "Martijn", 1 )
48+
49+
pp ledger ## pp = pretty print
50+
51+
```
52+
53+
resulting in
54+
55+
```
56+
#<LedgerLite::Ledger
57+
@addr={
58+
"Vincent" => 5,
59+
"Anne" => 0,
60+
"Julia" => 3,
61+
"Luuk" => 1,
62+
"Ruben" => 9,
63+
"Max" => 3,
64+
"Martijn" => 1}>
65+
```
66+
67+
that is, the addr hash holds all addresses (addr) with the account balances
68+
telling you who owns how much:
69+
70+
| Addr(ess) | Balance $ |
71+
|---------------------|----------:|
72+
| Vincent | 5 |
73+
| Anne | 0 |
74+
| Julia | 3 |
75+
| Luuk | 1 |
76+
| Ruben | 9 |
77+
| Max | 3 |
78+
| Martijn | 1 |
79+
80+
81+
### Use `write` to write / add transactions
82+
83+
84+
Or use transaction hashes:
85+
86+
``` ruby
87+
ledger = Ledger.new
88+
89+
ledger.write( from: "Central Bank†", to: "Vincent", amount: 11 )
90+
ledger.write( from: "Vincent", to: "Anne", amount: 3 )
91+
ledger.write( from: "Anne", to: "Julia", amount: 2 )
92+
ledger.write( from: "Julia", to: "Luuk", amount: 1 )
93+
94+
ledger.write( { from: "De Nederlandsche Bank†", to: "Ruben", amount: 11 },
95+
{ from: "Vincent", to: "Max", amount: 3 },
96+
{ from: "Ruben", to: "Julia", amount: 2 },
97+
{ from: "Anne", to: "Martijn", amount: 1 } )
98+
99+
pp ledger
100+
```
101+
102+
Or use transaction (tx) classes/structs:
103+
104+
``` ruby
105+
ledger = Ledger.new
106+
107+
ledger.write( Tx.new( "Central Bank†", "Vincent", 11 ))
108+
ledger.write( Tx.new( "Vincent", "Anne", 3 ))
109+
ledger.write( Tx.new( "Anne", "Julia", 2 ))
110+
ledger.write( Tx.new( "Julia", "Luuk", 1 ))
111+
112+
ledger.write( Tx.new( "De Nederlandsche Bank†", "Ruben", 11 ),
113+
Tx.new( "Vincent", "Max", 3 ),
114+
Tx.new( "Ruben", "Julia", 2 ),
115+
Tx.new( "Anne", "Martijn", 1 ))
116+
117+
pp ledger
118+
```
119+
120+
Or use the operator `<<` alias for `write`:
121+
122+
```ruby
123+
ledger = Ledger.new
124+
125+
ledger << Tx.new( "Central Bank†", "Vincent", 11 )
126+
ledger << Tx.new( "Vincent", "Anne", 3 )
127+
ledger << Tx.new( "Anne", "Julia", 2 )
128+
ledger << Tx.new( "Julia", "Luuk", 1 )
129+
130+
ledger << [Tx.new( "De Nederlandsche Bank†", "Ruben", 11 ),
131+
Tx.new( "Vincent", "Max", 3 ),
132+
Tx.new( "Ruben", "Julia", 2 ),
133+
Tx.new( "Anne", "Martijn", 1 )]
134+
135+
pp ledger
136+
```
137+
138+
139+
Or use blocks of transaction hashes:
140+
141+
``` ruby
142+
143+
ledger = Ledger.new
144+
145+
ledger.write( Block.new( { from: "Central Bank†", to: "Vincent", amount: 11 },
146+
{ from: "Vincent", to: "Anne", amount: 3 },
147+
{ from: "Anne", to: "Julia", amount: 2 },
148+
{ from: "Julia", to: "Luuk", amount: 1 } ),
149+
Block.new( { from: "De Nederlandsche Bank†", to: "Ruben", amount: 11 },
150+
{ from: "Vincent", to: "Max", amount: 3 },
151+
{ from: "Ruben", to: "Julia", amount: 2 },
152+
{ from: "Anne", to: "Martijn", amount: 1 } ))
153+
154+
pp ledger
155+
```
156+
157+
158+
Or use blocks of transaction classes/structs:
159+
160+
``` ruby
161+
ledger = Ledger.new
162+
163+
ledger.write( Block.new( Tx.new( "Central Bank†", "Vincent", 11 ),
164+
Tx.new( "Vincent", "Anne", 3 ),
165+
Tx.new( "Anne", "Julia", 2 ),
166+
Tx.new( "Julia", "Luuk", 1 )),
167+
Block.new( Tx.new( "De Nederlandsche Bank†", "Ruben", 11 ),
168+
Tx.new( "Vincent", "Max", 3 ),
169+
Tx.new( "Ruben", "Julia", 2 ),
170+
Tx.new( "Anne", "Martijn", 1 )))
171+
172+
pp ledger
173+
```
174+
175+
Or use blocks of transaction classes/structs (with keyword arguments):
176+
177+
```ruby
178+
ledger = Ledger.new
179+
180+
ledger.write( Block.new( Tx.new( from: "Central Bank†", to: "Vincent", amount: 11 ),
181+
Tx.new( from: "Vincent", to: "Anne", amount: 3 ),
182+
Tx.new( from: "Anne", to: "Julia", amount: 2 ),
183+
Tx.new( from: "Julia", to: "Luuk", amount: 1 )),
184+
Block.new( Tx.new( from: "De Nederlandsche Bank†", to: "Ruben", amount: 11 ),
185+
Tx.new( from: "Vincent", to: "Max", amount: 3 ),
186+
Tx.new( from: "Ruben", to: "Julia", amount: 2 ),
187+
Tx.new( from: "Anne", to: "Martijn", amount: 1 )))
188+
189+
pp ledger
190+
```
191+
192+
# Bonus: Track Commodities, Collectibles or Assets
193+
194+
Ledger Lite lets you design / create your own transactions. For example, let's use
195+
`from`, `to`, `qty` (quantity) and `name` (of commodity, collectible or asset).
196+
Override the `Ledger#unpack` method for "unpacking" arguments from transactions
197+
and the `Ledger#send` method for "committing" transactions:
198+
199+
200+
``` ruby
201+
def unpack( tx )
202+
## "unpack" from, to, qty, name values
203+
if tx.is_a?( Hash ) ## support hashes
204+
from = tx[:from]
205+
to = tx[:to]
206+
qty = tx[:qty]
207+
name = tx[:name]
208+
else ## assume it's a transaction (tx) struct/class
209+
from = tx.from
210+
to = tx.to
211+
qty = tx.qty
212+
name = tx.name
213+
end
214+
[from,to,qty,name]
215+
end
216+
```
217+
218+
and
219+
220+
``` ruby
221+
def send( from, to, qty, name )
222+
if sufficient?( from, qty, name )
223+
if self.class.config.coinbase?( from )
224+
# note: coinbase has unlimited supply!! magic happens here
225+
else
226+
@addr[ from ][ name ] -= qty
227+
end
228+
@addr[ to ] ||= {} ## make sure addr exists (e.g. init with empty hash {})
229+
@addr[ to ][ name ] ||= 0
230+
@addr[ to ][ name ] += qty
231+
end
232+
end
233+
```
234+
235+
Now use the ledger with the new transaction format like:
236+
237+
238+
``` ruby
239+
ledger = Ledger.new
240+
241+
ledger.send( "Keukenhof†", "Vincent", 11, "Tulip Admiral van Eijck" )
242+
ledger.send( "Vincent", "Anne", 3, "Tulip Admiral van Eijck" )
243+
ledger.send( "Anne", "Julia", 2, "Tulip Admiral van Eijck" )
244+
ledger.send( "Julia", "Luuk", 1, "Tulip Admiral van Eijck" )
245+
246+
ledger.send( "Dutchgrown†", "Ruben", 11, "Tulip Semper Augustus" )
247+
ledger.send( "Vincent", "Max", 3, "Tulip Admiral van Eijck" )
248+
ledger.send( "Ruben", "Julia", 2, "Tulip Semper Augustus" )
249+
ledger.send( "Anne", "Martijn", 1, "Tulip Admiral van Eijck" )
250+
251+
pp ledger ## pp == pretty print
252+
```
253+
254+
resulting in:
255+
256+
```
257+
#<LedgerLite::Ledger
258+
@addr={
259+
"Vincent" => {"Tulip Admiral van Eijck" => 5},
260+
"Anne" => {"Tulip Admiral van Eijck" => 0},
261+
"Julia" => {"Tulip Admiral van Eijck" => 1, "Tulip Semper Augustus" => 2},
262+
"Luuk" => {"Tulip Admiral van Eijck" => 1},
263+
"Ruben" => {"Tulip Semper Augustus" => 9},
264+
"Max" => {"Tulip Admiral van Eijck" => 3},
265+
"Martijn" => {"Tulip Admiral van Eijck" => 1}}>
266+
```
267+
268+
Or use blocks of transaction classes/structs (with keyword arguments):
269+
270+
271+
``` ruby
272+
ledger = Ledger.new
273+
274+
ledger.write( Block.new( Tx.new( from: "Keukenhof†", to: "Vincent", qty: 11, name: "Tulip Admiral van Eijck" ),
275+
Tx.new( from: "Vincent", to: "Anne", qty: 3, name: "Tulip Admiral van Eijck" ),
276+
Tx.new( from: "Anne", to: "Julia", qty: 2, name: "Tulip Admiral van Eijck" ),
277+
Tx.new( from: "Julia", to: "Luuk", qty: 1, name: "Tulip Admiral van Eijck" )),
278+
Block.new( Tx.new( from: "Dutchgrown†", to: "Ruben", qty: 11, name: "Tulip Semper Augustus" ),
279+
Tx.new( from: "Vincent", to: "Max", qty: 3, name: "Tulip Admiral van Eijck" ),
280+
Tx.new( from: "Ruben", to: "Julia", qty: 2, name: "Tulip Semper Augustus" ),
281+
Tx.new( from: "Anne", to: "Martijn", qty: 1, name: "Tulip Admiral van Eijck" )))
282+
283+
pp ledger
284+
```
285+
286+
And so on and on.
287+
288+
289+
290+
291+
## Ledger Lite in the Real World
292+
293+
- [**centralbank**](https://github.com/openblockchains/centralbank) - command line tool (and core library) - 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
294+
- [**tulipmania**](https://github.com/openblockchains/tulipmania) - command line tool (and core library) - tulips on the blockchain; learn by example from the real world (anno 1637) - buy! sell! hodl! enjoy the beauty of admiral of admirals, semper augustus, and more; run your own hyper ledger tulip exchange nodes on the blockchain peer-to-peer over HTTP; revolutionize the world one block at a time
295+
- [**shilling**](https://github.com/bitshilling/bitshilling.tools) - 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
296+
- You? Add your tool / service
297+
298+
299+
300+
## References
301+
302+
[**Programming Cryptocurrencies and Blockchains (in Ruby)**](http://yukimotopress.github.io/blockchains) by Gerald Bauer et al, 2018, Yuki & Moto Press
303+
304+
305+
## License
306+
307+
![](https://publicdomainworks.github.io/buttons/zero88x31.png)
308+
309+
The `ledger-lite` scripts are dedicated to the public domain.
310+
Use it as you please with no restrictions whatsoever.

0 commit comments

Comments
 (0)