blockchain-lite 0.1.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +8 -1
- data/README.md +123 -7
- data/lib/blockchain-lite.rb +7 -1
- data/lib/blockchain-lite/basic/block.rb +44 -0
- data/lib/blockchain-lite/bitcoin/block.rb +57 -0
- data/lib/blockchain-lite/block.rb +2 -34
- data/lib/blockchain-lite/blockchain.rb +96 -0
- data/lib/blockchain-lite/proof_of_work/block.rb +64 -0
- data/lib/blockchain-lite/version.rb +1 -1
- data/test/test_block.rb +35 -0
- data/test/test_block_basic.rb +29 -0
- data/test/test_block_proof_of_work.rb +29 -0
- data/test/test_blockchain.rb +70 -0
- metadata +9 -2
- data/test/test_version.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7543889414d4d92f12f6f5bfe9d708ba12c0093
|
4
|
+
data.tar.gz: 96017ba92283640a77ed3be91d52721f1e245791
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9648bcb18e39173799709aef395c346f63ff4fe6fdff824199cc0934b3b2ade710e5ef6e11e1a802d7d435cdb2ee3d905bc4bf28efbcafe64e94c3b154198d10
|
7
|
+
data.tar.gz: 9b0ca66ac0656b65bc3179387ba7b9818313f94ec7e6d7f25b6ac2cb54ed57a492be7a2a37a13a813a7c6ca9550b7e50c22e3bb0268d8a4c2284d62847079b0d
|
data/Manifest.txt
CHANGED
@@ -4,7 +4,14 @@ Manifest.txt
|
|
4
4
|
README.md
|
5
5
|
Rakefile
|
6
6
|
lib/blockchain-lite.rb
|
7
|
+
lib/blockchain-lite/basic/block.rb
|
8
|
+
lib/blockchain-lite/bitcoin/block.rb
|
7
9
|
lib/blockchain-lite/block.rb
|
10
|
+
lib/blockchain-lite/blockchain.rb
|
11
|
+
lib/blockchain-lite/proof_of_work/block.rb
|
8
12
|
lib/blockchain-lite/version.rb
|
9
13
|
test/helper.rb
|
10
|
-
test/
|
14
|
+
test/test_block.rb
|
15
|
+
test/test_block_basic.rb
|
16
|
+
test/test_block_proof_of_work.rb
|
17
|
+
test/test_blockchain.rb
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Blockchain Lite (Ruby Edition)
|
2
2
|
|
3
|
-
|
3
|
+
blockchain-lite library / gem - build your own blockchain with crypto hashes - revolutionize the world with blockchains, blockchains, blockchains one block at a time
|
4
4
|
|
5
5
|
* home :: [github.com/openblockchains/blockchain.lite.rb](https://github.com/openblockchains/blockchain.lite.rb)
|
6
6
|
* bugs :: [github.com/openblockchains/blockchain.lite.rb/issues](https://github.com/openblockchains/blockchain.lite.rb/issues)
|
@@ -23,14 +23,13 @@ See the [Awesome Blockchains](https://github.com/openblockchains/awesome-blockch
|
|
23
23
|
Let's get started. Build your own blockchain one block at a time.
|
24
24
|
Example:
|
25
25
|
|
26
|
-
|
27
26
|
``` ruby
|
28
27
|
require 'blockchain-lite'
|
29
28
|
|
30
|
-
b0 = Block.first(
|
31
|
-
b1 = Block.next( b0,
|
32
|
-
b2 = Block.next( b1,
|
33
|
-
b3 = Block.next( b2,
|
29
|
+
b0 = Block.first( 'Genesis' )
|
30
|
+
b1 = Block.next( b0, 'Transaction Data...' )
|
31
|
+
b2 = Block.next( b1, 'Transaction Data......' )
|
32
|
+
b3 = Block.next( b2, 'More Transaction Data...' )
|
34
33
|
|
35
34
|
blockchain = [b0, b1, b2, b3]
|
36
35
|
|
@@ -65,12 +64,129 @@ pp blockchain
|
|
65
64
|
# @previous_hash = "be50017ee4bbcb33844b3dc2b7c4e476d46569b5df5762d14ceba9355f0a85f4">]
|
66
65
|
```
|
67
66
|
|
67
|
+
### Blocks
|
68
|
+
|
69
|
+
[Basic](#basic)
|
70
|
+
[Proof-of-Work](#proof-of-work)
|
71
|
+
|
72
|
+
Supported block types / classes for now include:
|
73
|
+
|
74
|
+
#### Basic
|
75
|
+
|
76
|
+
``` ruby
|
77
|
+
class Block
|
78
|
+
|
79
|
+
attr_reader :index
|
80
|
+
attr_reader :timestamp
|
81
|
+
attr_reader :data
|
82
|
+
attr_reader :previous_hash
|
83
|
+
attr_reader :hash
|
84
|
+
|
85
|
+
def initialize(index, data, previous_hash)
|
86
|
+
@index = index
|
87
|
+
@timestamp = Time.now.utc ## note: use coordinated universal time (utc)
|
88
|
+
@data = data
|
89
|
+
@previous_hash = previous_hash
|
90
|
+
@hash = calc_hash
|
91
|
+
end
|
92
|
+
|
93
|
+
def calc_hash
|
94
|
+
sha = Digest::SHA256.new
|
95
|
+
sha.update( @index.to_s + @timestamp.to_s + @data + @previous_hash )
|
96
|
+
sha.hexdigest
|
97
|
+
end
|
98
|
+
...
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
(Source: [basic/block.rb](lib/blockchain-lite/basic/block.rb))
|
103
|
+
|
104
|
+
|
105
|
+
#### Proof-of-Work
|
106
|
+
|
107
|
+
``` ruby
|
108
|
+
class Block
|
109
|
+
|
110
|
+
attr_reader :index
|
111
|
+
attr_reader :timestamp
|
112
|
+
attr_reader :data
|
113
|
+
attr_reader :previous_hash
|
114
|
+
attr_reader :nonce ## proof of work if hash starts with leading zeros (00)
|
115
|
+
attr_reader :hash
|
116
|
+
|
117
|
+
def initialize(index, data, previous_hash)
|
118
|
+
@index = index
|
119
|
+
@timestamp = Time.now.utc ## note: use coordinated universal time (utc)
|
120
|
+
@data = data
|
121
|
+
@previous_hash = previous_hash
|
122
|
+
@nonce, @hash = compute_hash_with_proof_of_work
|
123
|
+
end
|
124
|
+
|
125
|
+
def calc_hash
|
126
|
+
sha = Digest::SHA256.new
|
127
|
+
sha.update( @nonce.to_s + @index.to_s + @timestamp.to_s + @data + @previous_hash )
|
128
|
+
sha.hexdigest
|
129
|
+
end
|
130
|
+
...
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
(Source: [proof_of_work/block.rb](lib/blockchain-lite/proof_of_work/block.rb))
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
### Blockchain Helper / Convenience Wrapper
|
139
|
+
|
140
|
+
The `Blockchain` class offers some convenience helpers
|
141
|
+
for building and checking blockchains. Example:
|
142
|
+
|
143
|
+
``` ruby
|
144
|
+
b = Blockchain.new # note: will (auto-) add the first (genesis) block
|
145
|
+
|
146
|
+
b << 'Transaction Data...'
|
147
|
+
b << 'Transaction Data......'
|
148
|
+
b << 'More Transaction Data...'
|
149
|
+
|
150
|
+
pp b
|
151
|
+
```
|
152
|
+
|
153
|
+
Check for broken chain links. Example:
|
154
|
+
|
155
|
+
``` ruby
|
156
|
+
|
157
|
+
b.broken?
|
158
|
+
# => false ## blockchain OK
|
159
|
+
```
|
160
|
+
|
161
|
+
or use the `Blockchain` class as a wrapper (pass in the blockchain array):
|
162
|
+
|
163
|
+
``` ruby
|
164
|
+
b0 = Block.first( 'Genesis' )
|
165
|
+
b1 = Block.next( b0, 'Transaction Data...' )
|
166
|
+
b2 = Block.next( b1, 'Transaction Data......' )
|
167
|
+
b3 = Block.next( b2, 'More Transaction Data...' )
|
168
|
+
|
169
|
+
blockchain = [b0, b1, b2, b3]
|
170
|
+
|
171
|
+
|
172
|
+
b = Blockchain.new( blockchain )
|
173
|
+
|
174
|
+
b.broken?
|
175
|
+
# => false ## blockchain OK
|
176
|
+
```
|
177
|
+
|
178
|
+
and so on.
|
179
|
+
|
180
|
+
|
181
|
+
|
68
182
|
|
69
183
|
## Install
|
70
184
|
|
71
185
|
Just install the gem:
|
72
186
|
|
73
|
-
|
187
|
+
```
|
188
|
+
$ gem install blockchain-lite
|
189
|
+
```
|
74
190
|
|
75
191
|
|
76
192
|
## License
|
data/lib/blockchain-lite.rb
CHANGED
@@ -12,7 +12,13 @@ require 'uri'
|
|
12
12
|
|
13
13
|
## our own code
|
14
14
|
require 'blockchain-lite/version' # note: let version always go first
|
15
|
-
|
15
|
+
|
16
|
+
require 'blockchain-lite/basic/block'
|
17
|
+
require 'blockchain-lite/proof_of_work/block'
|
18
|
+
|
19
|
+
require 'blockchain-lite/blockchain'
|
20
|
+
|
21
|
+
require 'blockchain-lite/block' ## configure "standard" default block (e.g. basic, proof-of-work, etc.)
|
16
22
|
|
17
23
|
|
18
24
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module BlockchainLite
|
4
|
+
module Basic
|
5
|
+
|
6
|
+
|
7
|
+
class Block
|
8
|
+
|
9
|
+
attr_reader :index
|
10
|
+
attr_reader :timestamp
|
11
|
+
attr_reader :data
|
12
|
+
attr_reader :previous_hash
|
13
|
+
attr_reader :hash
|
14
|
+
|
15
|
+
def initialize(index, data, previous_hash)
|
16
|
+
@index = index
|
17
|
+
@timestamp = Time.now.utc ## note: use coordinated universal time (utc)
|
18
|
+
@data = data
|
19
|
+
@previous_hash = previous_hash
|
20
|
+
@hash = calc_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def calc_hash
|
24
|
+
sha = Digest::SHA256.new
|
25
|
+
sha.update( @index.to_s + @timestamp.to_s + @data + @previous_hash )
|
26
|
+
sha.hexdigest
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
def self.first( data='Genesis' ) # create genesis (big bang! first) block
|
32
|
+
## uses index zero (0) and arbitrary previous_hash ('0')
|
33
|
+
Block.new( 0, data, '0' )
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.next( previous, data='Transaction Data...' )
|
37
|
+
Block.new( previous.index+1, data, previous.hash )
|
38
|
+
end
|
39
|
+
|
40
|
+
end # class Block
|
41
|
+
|
42
|
+
|
43
|
+
end ## module Basic
|
44
|
+
end ## module BlockchainLite
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
##
|
4
|
+
## Note: Work in Progress
|
5
|
+
## -- under construction!!!!!!
|
6
|
+
## do NOT yet use this class
|
7
|
+
|
8
|
+
module BlockchainLite
|
9
|
+
module Bitcoin
|
10
|
+
|
11
|
+
|
12
|
+
## bitcoin-compatible block
|
13
|
+
## note: work-in-progress
|
14
|
+
|
15
|
+
class Block
|
16
|
+
|
17
|
+
|
18
|
+
class Header
|
19
|
+
|
20
|
+
attr_reader :index
|
21
|
+
attr_reader :timestamp
|
22
|
+
attr_reader :data
|
23
|
+
attr_reader :previous_hash
|
24
|
+
attr_reader :hash
|
25
|
+
|
26
|
+
def initialize(index, data, previous_hash)
|
27
|
+
@index = index
|
28
|
+
@timestamp = Time.now.utc ## note: use coordinated universal time (utc)
|
29
|
+
@data = data
|
30
|
+
@previous_hash = previous_hash
|
31
|
+
@hash = calc_hash
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def calc_hash
|
37
|
+
sha = Digest::SHA256.new
|
38
|
+
sha.update( @index.to_s + @timestamp.to_s + @data + @previous_hash )
|
39
|
+
sha.hexdigest
|
40
|
+
end
|
41
|
+
end # class Header
|
42
|
+
|
43
|
+
|
44
|
+
def self.first( data='Genesis' ) # create genesis (big bang! first) block
|
45
|
+
## uses index zero (0) and arbitrary previous_hash ('0')
|
46
|
+
Block.new( 0, data, '0' )
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.next( previous, data='Transaction Data...' )
|
50
|
+
Block.new( previous.index+1, data, previous.hash )
|
51
|
+
end
|
52
|
+
|
53
|
+
end # class Block
|
54
|
+
|
55
|
+
|
56
|
+
end ## module Bitcoin
|
57
|
+
end ## module BlockchainLite
|
@@ -1,37 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
attr_reader :index
|
7
|
-
attr_reader :timestamp
|
8
|
-
attr_reader :data
|
9
|
-
attr_reader :previous_hash
|
10
|
-
attr_reader :hash
|
11
|
-
|
12
|
-
def initialize(index, timestamp, data, previous_hash)
|
13
|
-
@index = index
|
14
|
-
@timestamp = timestamp
|
15
|
-
@data = data
|
16
|
-
@previous_hash = previous_hash
|
17
|
-
@hash = calc_hash
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.first( data="Genesis" ) # create genesis (big bang! first) block
|
21
|
-
## uses index zero and arbitrary previous_hash
|
22
|
-
Block.new( 0, Time.now, data, "0" )
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.next( previous, data="Transaction Data..." )
|
26
|
-
Block.new( previous.index+1, Time.now, data, previous.hash )
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def calc_hash
|
32
|
-
sha = Digest::SHA256.new
|
33
|
-
sha.update @index.to_s + @timestamp.to_s + @data.to_s + @previous_hash.to_s
|
34
|
-
sha.hexdigest
|
35
|
-
end
|
36
|
-
|
37
|
-
end # class Block
|
4
|
+
## "standard" default block for now block with proof of work
|
5
|
+
Block = BlockchainLite::ProofOfWork::Block
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
##
|
5
|
+
# convenience wrapper for array holding blocks (that is, a blockchain)
|
6
|
+
|
7
|
+
|
8
|
+
class Blockchain
|
9
|
+
|
10
|
+
def initialize( chain=nil, block_class: nil )
|
11
|
+
if chain.nil?
|
12
|
+
@block_class = block_class || BlockchainLite::ProofOfWork::Block
|
13
|
+
b0 = @block_class.first( 'Genesis' )
|
14
|
+
@chain = [b0]
|
15
|
+
else
|
16
|
+
@chain = chain # "wrap" passed in blockchain (in array)
|
17
|
+
if block_class # configure block class ("factory")
|
18
|
+
@block_class = block_class
|
19
|
+
else
|
20
|
+
### no block class configured; use class of first block
|
21
|
+
## todo/fix: throw except if chain is empty (no class configured) - why? why not??
|
22
|
+
@block_class = @chain.first.class if @chain.first
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def last() @chain.last; end ## return last block in chain
|
29
|
+
|
30
|
+
|
31
|
+
def <<( arg )
|
32
|
+
if arg.is_a? String ## assume its (just) data
|
33
|
+
data = arg
|
34
|
+
bl = @chain.last
|
35
|
+
b = @block_class.next( bl, data )
|
36
|
+
elsif arg.class.respond_to?( :first ) && ## check if respond_to? Block.first? and Block.next? - assume it's a block
|
37
|
+
arg.class.respond_to?( :next ) ## check/todo: use is_a? @block_class why? why not?
|
38
|
+
b = arg
|
39
|
+
else ## fallback; assume its (just) data (not a block)
|
40
|
+
data = arg.to_s ## note: always convert arg to string!! - why? why not??
|
41
|
+
bl = @chain.last
|
42
|
+
b = @block_class.next( bl, data )
|
43
|
+
end
|
44
|
+
@chain << b ## add/append (new) block to chain
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
def broken?
|
50
|
+
## check for validation conventions
|
51
|
+
## - start with first block?
|
52
|
+
## - or start with last block (reversve)? -why? why not??
|
53
|
+
|
54
|
+
@chain.size.times do |i|
|
55
|
+
###puts "checking block #{i+1}/#{@chain.size}..."
|
56
|
+
|
57
|
+
current = @chain[i]
|
58
|
+
|
59
|
+
if i==0 ### special case for first (genesis) block; has no previous/parent block
|
60
|
+
if current.index != 0
|
61
|
+
## raise error -- invalid index!!!
|
62
|
+
return true
|
63
|
+
end
|
64
|
+
if current.previous_hash != '0'
|
65
|
+
## raise error -- invalid previous hash (hash checksums MUST match)
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
else
|
69
|
+
previous = @chain[i-1]
|
70
|
+
|
71
|
+
if current.index != previous.index+1
|
72
|
+
## raise error -- invalid index!!!
|
73
|
+
puts "!!! blockchain corrupt - block ##{current.index}: index must be a sequence (with +1 steps)"
|
74
|
+
return true
|
75
|
+
end
|
76
|
+
|
77
|
+
if current.previous_hash != previous.hash
|
78
|
+
## raise error -- invalid previous hash (hash checksums MUST match)
|
79
|
+
puts "!!! blockchain corrupt - block ##{current.index}: previous_hash and hash in previous block must match"
|
80
|
+
return true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if current.hash != current.calc_hash ## (re)calc / double-check hash
|
85
|
+
## raise error -- invalid hash (hash checksums MUST match)
|
86
|
+
puts "!!! blockchain corrupt - block ##{current.index}: calc_hash and hash must match; block corrupt - cannot recalculate hash"
|
87
|
+
return true
|
88
|
+
end
|
89
|
+
end # loop times
|
90
|
+
|
91
|
+
false ## chain OK -- chain is NOT broken if we get here
|
92
|
+
end # method broken?
|
93
|
+
|
94
|
+
def valid?() !broken?; end
|
95
|
+
|
96
|
+
end ## class Blockchain
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module BlockchainLite
|
4
|
+
module ProofOfWork
|
5
|
+
|
6
|
+
|
7
|
+
class Block
|
8
|
+
|
9
|
+
attr_reader :index
|
10
|
+
attr_reader :timestamp
|
11
|
+
attr_reader :data
|
12
|
+
attr_reader :previous_hash
|
13
|
+
attr_reader :nonce ## proof of work if hash starts with leading zeros (00)
|
14
|
+
attr_reader :hash
|
15
|
+
|
16
|
+
def initialize(index, data, previous_hash)
|
17
|
+
@index = index
|
18
|
+
@timestamp = Time.now.utc ## note: use coordinated universal time (utc)
|
19
|
+
@data = data
|
20
|
+
@previous_hash = previous_hash
|
21
|
+
@nonce, @hash = compute_hash_with_proof_of_work
|
22
|
+
end
|
23
|
+
|
24
|
+
def calc_hash
|
25
|
+
sha = Digest::SHA256.new
|
26
|
+
sha.update( @nonce.to_s + @index.to_s + @timestamp.to_s + @data + @previous_hash )
|
27
|
+
sha.hexdigest
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def self.first( data='Genesis' ) # create genesis (big bang! first) block
|
32
|
+
## uses index zero (0) and arbitrary previous_hash ('0')
|
33
|
+
Block.new( 0, data, '0' )
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.next( previous, data='Transaction Data...' )
|
37
|
+
Block.new( previous.index+1, data, previous.hash )
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def compute_hash_with_proof_of_work( difficulty='00' )
|
43
|
+
nonce = 0
|
44
|
+
loop do
|
45
|
+
hash = calc_hash_with_nonce( nonce )
|
46
|
+
if hash.start_with?( difficulty )
|
47
|
+
return [nonce,hash] ## bingo! proof of work if hash starts with leading zeros (00)
|
48
|
+
else
|
49
|
+
nonce += 1 ## keep trying (and trying and trying)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def calc_hash_with_nonce( nonce=0 )
|
55
|
+
sha = Digest::SHA256.new
|
56
|
+
sha.update( nonce.to_s + @index.to_s + @timestamp.to_s + @data + @previous_hash )
|
57
|
+
sha.hexdigest
|
58
|
+
end
|
59
|
+
|
60
|
+
end # class Block
|
61
|
+
|
62
|
+
|
63
|
+
end ## module ProofOfWork
|
64
|
+
end ## module BlockchainLite
|
data/test/test_block.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_block.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestBlock < MiniTest::Test
|
12
|
+
|
13
|
+
def test_version
|
14
|
+
pp BlockchainLite.version
|
15
|
+
pp BlockchainLite.banner
|
16
|
+
pp BlockchainLite.root
|
17
|
+
|
18
|
+
assert true ## (for now) everything ok if we get here
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_example
|
22
|
+
|
23
|
+
b0 = Block.first( 'Genesis' )
|
24
|
+
b1 = Block.next( b0, 'Transaction Data...' )
|
25
|
+
b2 = Block.next( b1, 'Transaction Data......' )
|
26
|
+
b3 = Block.next( b2, 'More Transaction Data...' )
|
27
|
+
|
28
|
+
blockchain = [b0, b1, b2, b3]
|
29
|
+
|
30
|
+
pp blockchain
|
31
|
+
|
32
|
+
assert true ## (for now) everything ok if we get here
|
33
|
+
end
|
34
|
+
|
35
|
+
end # class TestBlock
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_block_basic.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestBlockBasic < MiniTest::Test
|
12
|
+
|
13
|
+
def test_example
|
14
|
+
|
15
|
+
block_class = BlockchainLite::Basic::Block
|
16
|
+
|
17
|
+
b0 = block_class.first( 'Genesis' )
|
18
|
+
b1 = block_class.next( b0, 'Transaction Data...' )
|
19
|
+
b2 = block_class.next( b1, 'Transaction Data......' )
|
20
|
+
b3 = block_class.next( b2, 'More Transaction Data...' )
|
21
|
+
|
22
|
+
blockchain = [b0, b1, b2, b3]
|
23
|
+
|
24
|
+
pp blockchain
|
25
|
+
|
26
|
+
assert true ## (for now) everything ok if we get here
|
27
|
+
end
|
28
|
+
|
29
|
+
end # class TestBlockBasic
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_block_proof_of_work.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestBlockProofOfWork < MiniTest::Test
|
12
|
+
|
13
|
+
def test_example
|
14
|
+
|
15
|
+
block_class = BlockchainLite::ProofOfWork::Block
|
16
|
+
|
17
|
+
b0 = block_class.first( 'Genesis' )
|
18
|
+
b1 = block_class.next( b0, 'Transaction Data...' )
|
19
|
+
b2 = block_class.next( b1, 'Transaction Data......' )
|
20
|
+
b3 = block_class.next( b2, 'More Transaction Data...' )
|
21
|
+
|
22
|
+
blockchain = [b0, b1, b2, b3]
|
23
|
+
|
24
|
+
pp blockchain
|
25
|
+
|
26
|
+
assert true ## (for now) everything ok if we get here
|
27
|
+
end
|
28
|
+
|
29
|
+
end # class TestBlockProofOfWork
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_blockchain.rb
|
6
|
+
|
7
|
+
require 'helper'
|
8
|
+
|
9
|
+
|
10
|
+
class TestBlockchain < MiniTest::Test
|
11
|
+
|
12
|
+
def test_new
|
13
|
+
|
14
|
+
b = Blockchain.new
|
15
|
+
|
16
|
+
b << 'Transaction Data...'
|
17
|
+
|
18
|
+
## add do-it-yourself built block
|
19
|
+
b << Block.next( b.last, 'Transaction Data......' )
|
20
|
+
|
21
|
+
b << 'More Transaction Data...'
|
22
|
+
|
23
|
+
pp b
|
24
|
+
|
25
|
+
assert true ## (for now) everything ok if we get here
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def test_with_block_class
|
30
|
+
|
31
|
+
b = Blockchain.new( block_class: BlockchainLite::Basic::Block )
|
32
|
+
|
33
|
+
b << 'Transaction Data...'
|
34
|
+
b << 'Transaction Data......'
|
35
|
+
b << 'More Transaction Data...'
|
36
|
+
|
37
|
+
pp b
|
38
|
+
|
39
|
+
assert true ## (for now) everything ok if we get here
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def test_wrap
|
44
|
+
|
45
|
+
b0 = Block.first( 'Genesis' )
|
46
|
+
b1 = Block.next( b0, 'Transaction Data...' )
|
47
|
+
b2 = Block.next( b1, 'Transaction Data......' )
|
48
|
+
b3 = Block.next( b2, 'More Transaction Data...' )
|
49
|
+
blockchain = [b0, b1, b2, b3]
|
50
|
+
|
51
|
+
b = Blockchain.new( blockchain )
|
52
|
+
puts "broken? #{b.broken?}"
|
53
|
+
puts "valid? #{b.valid?}"
|
54
|
+
|
55
|
+
pp b
|
56
|
+
|
57
|
+
assert_equal false, b.broken?
|
58
|
+
assert_equal true, b.valid?
|
59
|
+
|
60
|
+
## corrupt data in block in chain
|
61
|
+
b2.instance_eval %{ @data='XXXXXXX' }
|
62
|
+
|
63
|
+
assert_equal true, b.broken?
|
64
|
+
assert_equal false, b.valid?
|
65
|
+
|
66
|
+
pp b
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end # class TestBlockchain
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blockchain-lite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
@@ -55,10 +55,17 @@ files:
|
|
55
55
|
- README.md
|
56
56
|
- Rakefile
|
57
57
|
- lib/blockchain-lite.rb
|
58
|
+
- lib/blockchain-lite/basic/block.rb
|
59
|
+
- lib/blockchain-lite/bitcoin/block.rb
|
58
60
|
- lib/blockchain-lite/block.rb
|
61
|
+
- lib/blockchain-lite/blockchain.rb
|
62
|
+
- lib/blockchain-lite/proof_of_work/block.rb
|
59
63
|
- lib/blockchain-lite/version.rb
|
60
64
|
- test/helper.rb
|
61
|
-
- test/
|
65
|
+
- test/test_block.rb
|
66
|
+
- test/test_block_basic.rb
|
67
|
+
- test/test_block_proof_of_work.rb
|
68
|
+
- test/test_blockchain.rb
|
62
69
|
homepage: https://github.com/openblockchains/blockchain.lite.rb
|
63
70
|
licenses:
|
64
71
|
- Public Domain
|
data/test/test_version.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
|
5
|
-
class TestVersion < MiniTest::Test
|
6
|
-
|
7
|
-
def test_version
|
8
|
-
pp BlockchainLite.version
|
9
|
-
pp BlockchainLite.banner
|
10
|
-
pp BlockchainLite.root
|
11
|
-
|
12
|
-
assert true ## (for now) everything ok if we get here
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_example
|
16
|
-
|
17
|
-
b0 = Block.first( "Genesis" )
|
18
|
-
b1 = Block.next( b0, "Transaction Data..." )
|
19
|
-
b2 = Block.next( b1, "Transaction Data......" )
|
20
|
-
b3 = Block.next( b2, "More Transaction Data..." )
|
21
|
-
|
22
|
-
blockchain = [b0, b1, b2, b3]
|
23
|
-
|
24
|
-
pp blockchain
|
25
|
-
|
26
|
-
assert true ## (for now) everything ok if we get here
|
27
|
-
end
|
28
|
-
|
29
|
-
end # class TestVersion
|