merkletree 0.0.1 → 0.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 +4 -0
- data/README.md +143 -0
- data/Rakefile +2 -2
- data/lib/merkletree.rb +138 -4
- data/lib/merkletree/version.rb +4 -3
- data/test/helper.rb +10 -0
- data/test/test_build.rb +158 -0
- data/test/test_readme.rb +74 -0
- data/test/test_version.rb +21 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bdd4412b5bb49cfa7d3f5d5d93d5f0254248952
|
4
|
+
data.tar.gz: 3759dac07a1eb87444a7264089a83a113ec62a18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a99eb56b3472efcca00ea11d2b9a7dedc69903dc43d33cd5d9677dd737b32288a216fd6d5f1be9bf4b6b893c311034c9c30cc7ffd0f890e65827dd730f36881f
|
7
|
+
data.tar.gz: a0c2465fcb59581478779ef74bd05bf74642fb5b818072d53847fa949cdb66e8f127852edc5d99ef4ab4652d3a454ab850fbcc640a75bf6e73a91b5fc3f23594
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -9,6 +9,149 @@ merkletree library / gem - build your own crypto hash trees; named after Ralph M
|
|
9
9
|
* rdoc :: [rubydoc.info/gems/merkletree](http://rubydoc.info/gems/merkletree)
|
10
10
|
|
11
11
|
|
12
|
+
## What's a Merkle Tree?
|
13
|
+
|
14
|
+
> A Merkle tree or hash tree is a tree in which every leaf node is labelled with
|
15
|
+
> the hash of a data block and every non-leaf node is labelled with the
|
16
|
+
> cryptographic hash of the labels of its child nodes.
|
17
|
+
> Hash trees allow efficient and secure verification of the
|
18
|
+
> contents of large data structures. [...]
|
19
|
+
>
|
20
|
+
> The concept of hash trees is named after Ralph Merkle
|
21
|
+
> who patented it in 1979.
|
22
|
+
>
|
23
|
+
> -- [Wikipedia](https://en.wikipedia.org/wiki/Merkle_tree)
|
24
|
+
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
|
29
|
+
Pass along all (leaf / data block) hashes as strings or packaged in an array.
|
30
|
+
Example:
|
31
|
+
|
32
|
+
``` ruby
|
33
|
+
merkle = MerkleTree.new(
|
34
|
+
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
|
35
|
+
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
|
36
|
+
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' )
|
37
|
+
|
38
|
+
# -or-
|
39
|
+
|
40
|
+
merkle = MerkleTree.new( [
|
41
|
+
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
|
42
|
+
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
|
43
|
+
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' ])
|
44
|
+
|
45
|
+
|
46
|
+
puts 'merkle tree root hash:'
|
47
|
+
puts merkle.root.value
|
48
|
+
# => '25fd59b79d70bbdf043d66a7b0fc01409d11b990e943bb46b840fbbddd5ab895'
|
49
|
+
|
50
|
+
pp merkle ## pp (pretty print)
|
51
|
+
```
|
52
|
+
|
53
|
+
resulting in:
|
54
|
+
|
55
|
+
```
|
56
|
+
@root = #<MerkleTree::Node:0x46b55e0
|
57
|
+
@left = #<MerkleTree::Node:0x46b6060
|
58
|
+
@left = #<MerkleTree::Node:0x46b6870
|
59
|
+
@left = nil,
|
60
|
+
@right = nil,
|
61
|
+
@value = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743">,
|
62
|
+
@right = #<MerkleTree::Node:0x46b6810
|
63
|
+
@left = nil,
|
64
|
+
@right = nil,
|
65
|
+
@value = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
|
66
|
+
@value = "c9de03ced4db3c63835807016b1efedb647c694d2db8b9a8579cbf0c5dcb5ab0">,
|
67
|
+
@right= #<MerkleTree::Node:0x46b5ca0
|
68
|
+
@left= #<MerkleTree::Node:0x46b6798
|
69
|
+
@left = nil,
|
70
|
+
@right = nil,
|
71
|
+
@value = "5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d">,
|
72
|
+
@right = #<MerkleTree::Node:0x46b6798
|
73
|
+
@left = nil,
|
74
|
+
@right = nil,
|
75
|
+
@value = "5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d">,
|
76
|
+
@value = "50963aa3b2047e0d58bb850fc12e5a324cf01061af55889389be72d3849e1d03">,
|
77
|
+
@value="25fd59b79d70bbdf043d66a7b0fc01409d11b990e943bb46b840fbbddd5ab895">>
|
78
|
+
```
|
79
|
+
|
80
|
+
|
81
|
+
Use `MerkleTree.compute_root` for computing the root (crypto) hash without building a
|
82
|
+
tree. Example:
|
83
|
+
|
84
|
+
``` ruby
|
85
|
+
merkle_root_value = MerkleTree.compute_root(
|
86
|
+
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
|
87
|
+
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
|
88
|
+
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' )
|
89
|
+
|
90
|
+
# -or-
|
91
|
+
|
92
|
+
merkle_root_value = MerkleTree.compute_root( [
|
93
|
+
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
|
94
|
+
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
|
95
|
+
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' ])
|
96
|
+
|
97
|
+
|
98
|
+
puts 'merkle tree root hash:'
|
99
|
+
puts merkle_root_value
|
100
|
+
# => '25fd59b79d70bbdf043d66a7b0fc01409d11b990e943bb46b840fbbddd5ab895'
|
101
|
+
```
|
102
|
+
|
103
|
+
|
104
|
+
### Transactions
|
105
|
+
|
106
|
+
Use `MerkleTree.for` or `MerkleTree.compute_root_for` for passing along transactions.
|
107
|
+
Will use `to_s` on every transaction and use the resulting "serialized" string
|
108
|
+
to (auto-) calculate the (crypto) hash.
|
109
|
+
|
110
|
+
Let's put the transactions from the (hyper) ledger book from [Tulips on the Blockchain!](https://github.com/openblockchains/tulips)
|
111
|
+
on the ~~blockchain~~ merkle tree:
|
112
|
+
|
113
|
+
|
114
|
+
| From | To | What | Qty |
|
115
|
+
|---------------------|--------------|---------------------------|----:|
|
116
|
+
| Bloom & Blossom (†) | Daisy | Tulip Admiral of Admirals | 8 |
|
117
|
+
| Vincent | Max | Tulip Bloemendaal Sunset | 2 |
|
118
|
+
| Anne | Martijn | Tulip Semper Augustus | 2 |
|
119
|
+
| Ruben | Julia | Tulip Admiral van Eijck | 2 |
|
120
|
+
|
121
|
+
(†): Grower Transaction - New Tulips on the Market!
|
122
|
+
|
123
|
+
``` ruby
|
124
|
+
merkle = MerkleTree.for(
|
125
|
+
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
|
126
|
+
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
|
127
|
+
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
|
128
|
+
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
|
129
|
+
|
130
|
+
puts 'merkle tree root hash:'
|
131
|
+
puts merkle.root.value
|
132
|
+
# => '703f44630117ef9b4ac20cb149ed8a0f06e4c3ed2a791e11e16a2fe7a7d0de3d'
|
133
|
+
|
134
|
+
# -or-
|
135
|
+
|
136
|
+
merkle_root_value = MerkleTree.compute_root_for(
|
137
|
+
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
|
138
|
+
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
|
139
|
+
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
|
140
|
+
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
|
141
|
+
|
142
|
+
puts 'merkle tree root hash:'
|
143
|
+
puts merkle_root_value
|
144
|
+
# => '703f44630117ef9b4ac20cb149ed8a0f06e4c3ed2a791e11e16a2fe7a7d0de3d'
|
145
|
+
```
|
146
|
+
|
147
|
+
|
148
|
+
## Install
|
149
|
+
|
150
|
+
Just install the gem:
|
151
|
+
|
152
|
+
```
|
153
|
+
$ gem install merkletree
|
154
|
+
```
|
12
155
|
|
13
156
|
|
14
157
|
## License
|
data/Rakefile
CHANGED
data/lib/merkletree.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
require 'digest' # for hash checksum digest function SHA256
|
4
4
|
require 'pp' # for pp => pretty printer
|
5
5
|
|
6
|
-
require 'date'
|
7
|
-
require 'time'
|
8
|
-
require 'json'
|
9
|
-
require 'uri'
|
6
|
+
## require 'date'
|
7
|
+
## require 'time'
|
8
|
+
## require 'json'
|
9
|
+
## require 'uri'
|
10
10
|
|
11
11
|
|
12
12
|
|
@@ -14,6 +14,140 @@ require 'uri'
|
|
14
14
|
require 'merkletree/version' # note: let version always go first
|
15
15
|
|
16
16
|
|
17
|
+
class MerkleTree
|
18
|
+
|
19
|
+
class Node
|
20
|
+
attr_reader :value
|
21
|
+
attr_reader :left
|
22
|
+
attr_reader :right
|
23
|
+
|
24
|
+
def initialize( value, left, right )
|
25
|
+
@value = value
|
26
|
+
@left = left
|
27
|
+
@right = right
|
28
|
+
end
|
29
|
+
end # class Node
|
30
|
+
|
31
|
+
|
32
|
+
## convenience helpers
|
33
|
+
def self.for( *args )
|
34
|
+
if args.size == 1 && args[0].is_a?( Array )
|
35
|
+
transactions = args[0] ## "unwrap" array in array
|
36
|
+
else
|
37
|
+
transactions = args ## use "auto-wrapped" splat array
|
38
|
+
end
|
39
|
+
## for now use to_s for calculation hash
|
40
|
+
hashes = transactions.map { |tx| calc_hash( tx.to_s ) }
|
41
|
+
self.new( hashes )
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.compute_root_for( *args )
|
45
|
+
if args.size == 1 && args[0].is_a?( Array )
|
46
|
+
transactions = args[0] ## "unwrap" array in array
|
47
|
+
else
|
48
|
+
transactions = args ## use "auto-wrapped" splat array
|
49
|
+
end
|
50
|
+
|
51
|
+
## for now use to_s for calculation hash
|
52
|
+
hashes = transactions.map { |tx| calc_hash( tx.to_s ) }
|
53
|
+
self.compute_root( hashes )
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
attr_reader :root
|
59
|
+
attr_reader :leaves
|
60
|
+
|
61
|
+
def initialize( *args )
|
62
|
+
if args.size == 1 && args[0].is_a?( Array )
|
63
|
+
hashes = args[0] ## "unwrap" array in array
|
64
|
+
else
|
65
|
+
hashes = args ## use "auto-wrapped" splat array
|
66
|
+
end
|
67
|
+
|
68
|
+
@hashes = hashes
|
69
|
+
@root = build_tree
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def build_tree
|
74
|
+
level = @leaves = @hashes.map { |hash| Node.new( hash, nil, nil ) }
|
75
|
+
|
76
|
+
## todo/fix: handle hashes.size == 0 case
|
77
|
+
## - throw exception - why? why not?
|
78
|
+
## - return empty node with hash '0' - why? why not?
|
79
|
+
|
80
|
+
if @hashes.size == 1
|
81
|
+
level[0]
|
82
|
+
else
|
83
|
+
## while there's more than one hash in the layer, keep looping...
|
84
|
+
while level.size > 1
|
85
|
+
## loop through hashes two at a time
|
86
|
+
level = level.each_slice(2).map do |left, right|
|
87
|
+
## note: handle special case
|
88
|
+
# if number of nodes is odd e.g. 3,5,7,etc.
|
89
|
+
# last right node is nil -- duplicate node value for hash
|
90
|
+
## todo/check - duplicate just hash? or add right node ref too - why? why not?
|
91
|
+
right = left if right.nil?
|
92
|
+
|
93
|
+
Node.new( MerkleTree.calc_hash( left.value + right.value ), left, right)
|
94
|
+
end
|
95
|
+
## debug output
|
96
|
+
## puts "current merkle hash level (#{level.size} nodes):"
|
97
|
+
## pp level
|
98
|
+
end
|
99
|
+
### finally we end up with a single hash
|
100
|
+
level[0]
|
101
|
+
end
|
102
|
+
end # method build tree
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
### shortcut/convenience - compute root hash w/o building tree nodes
|
107
|
+
def self.compute_root( *args )
|
108
|
+
if args.size == 1 && args[0].is_a?( Array )
|
109
|
+
hashes = args[0] ## "unwrap" array in array
|
110
|
+
else
|
111
|
+
hashes = args ## use "auto-wrapped" splat array
|
112
|
+
end
|
113
|
+
|
114
|
+
## todo/fix: handle hashes.size == 0 case
|
115
|
+
## - throw exception - why? why not?
|
116
|
+
## - return empty node with hash '0' - why? why not?
|
117
|
+
|
118
|
+
if hashes.size == 1
|
119
|
+
hashes[0]
|
120
|
+
else
|
121
|
+
## while there's more than one hash in the list, keep looping...
|
122
|
+
while hashes.size > 1
|
123
|
+
# if number of hashes is odd e.g. 3,5,7,etc., duplicate last hash in list
|
124
|
+
hashes << hashes[-1] if hashes.size % 2 != 0
|
125
|
+
|
126
|
+
## loop through hashes two at a time
|
127
|
+
hashes = hashes.each_slice(2).map do |left,right|
|
128
|
+
## join both hashes slice[0]+slice[1] together
|
129
|
+
hash = calc_hash( left + right )
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
## debug output
|
134
|
+
## puts "current merkle hashes (#{hashes.size}):"
|
135
|
+
## pp hashes
|
136
|
+
### finally we end up with a single hash
|
137
|
+
hashes[0]
|
138
|
+
end
|
139
|
+
end # method compute_root
|
140
|
+
|
141
|
+
|
142
|
+
def self.calc_hash( data )
|
143
|
+
sha = Digest::SHA256.new
|
144
|
+
sha.update( data )
|
145
|
+
sha.hexdigest
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
end # class MerkleTree
|
150
|
+
|
17
151
|
|
18
152
|
# say hello
|
19
153
|
puts MerkleTree.banner if defined?($RUBYLIBS_DEBUG) && $RUBYLIBS_DEBUG
|
data/lib/merkletree/version.rb
CHANGED
data/test/helper.rb
ADDED
data/test/test_build.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_build.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestBuild < MiniTest::Test
|
12
|
+
|
13
|
+
|
14
|
+
def test_example_4
|
15
|
+
|
16
|
+
hashes = [
|
17
|
+
'00',
|
18
|
+
'11',
|
19
|
+
'22',
|
20
|
+
'33',
|
21
|
+
]
|
22
|
+
|
23
|
+
hash00 = '00'
|
24
|
+
hash11 = '11'
|
25
|
+
hash0011 = MerkleTree.calc_hash( hash00 + hash11 )
|
26
|
+
|
27
|
+
hash22 = '22'
|
28
|
+
hash33 = '33'
|
29
|
+
hash2233 = MerkleTree.calc_hash( hash22 + hash33 )
|
30
|
+
|
31
|
+
hash00112233 = MerkleTree.calc_hash( hash0011 + hash2233 )
|
32
|
+
|
33
|
+
|
34
|
+
merkle = MerkleTree.new( hashes )
|
35
|
+
|
36
|
+
puts "merkletree root hash:"
|
37
|
+
puts merkle.root.value
|
38
|
+
|
39
|
+
puts "merkletree:"
|
40
|
+
pp merkle.root
|
41
|
+
|
42
|
+
assert_equal hash00, merkle.root.left.left.value
|
43
|
+
assert_equal hash11, merkle.root.left.right.value
|
44
|
+
assert_equal hash22, merkle.root.right.left.value
|
45
|
+
assert_equal hash33, merkle.root.right.right.value
|
46
|
+
|
47
|
+
assert_equal hash0011, merkle.root.left.value
|
48
|
+
assert_equal hash2233, merkle.root.right.value
|
49
|
+
|
50
|
+
assert_equal hash00112233, merkle.root.value
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
merkle_root_value = MerkleTree.compute_root( hashes )
|
55
|
+
puts "merkletree root hash:"
|
56
|
+
puts merkle_root_value
|
57
|
+
|
58
|
+
assert_equal merkle.root.value, merkle_root_value
|
59
|
+
end # method test_example_4
|
60
|
+
|
61
|
+
|
62
|
+
def test_example_3 ## test odd (not even hashes)
|
63
|
+
|
64
|
+
hashes = [
|
65
|
+
'00',
|
66
|
+
'11',
|
67
|
+
'22',
|
68
|
+
]
|
69
|
+
|
70
|
+
hash00 = '00'
|
71
|
+
hash11 = '11'
|
72
|
+
hash0011 = MerkleTree.calc_hash( hash00 + hash11 )
|
73
|
+
|
74
|
+
hash22 = '22'
|
75
|
+
hash2222 = MerkleTree.calc_hash( hash22 + hash22 )
|
76
|
+
|
77
|
+
hash00112222 = MerkleTree.calc_hash( hash0011 + hash2222 )
|
78
|
+
|
79
|
+
|
80
|
+
merkle = MerkleTree.new( hashes )
|
81
|
+
|
82
|
+
puts "merkletree root hash:"
|
83
|
+
puts merkle.root.value
|
84
|
+
|
85
|
+
puts "merkletree:"
|
86
|
+
pp merkle.root
|
87
|
+
|
88
|
+
assert_equal hash00, merkle.root.left.left.value
|
89
|
+
assert_equal hash11, merkle.root.left.right.value
|
90
|
+
assert_equal hash22, merkle.root.right.left.value
|
91
|
+
assert_equal hash22, merkle.root.right.right.value
|
92
|
+
|
93
|
+
assert_equal hash0011, merkle.root.left.value
|
94
|
+
assert_equal hash2222, merkle.root.right.value
|
95
|
+
|
96
|
+
assert_equal hash00112222, merkle.root.value
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
merkle_root_value = MerkleTree.compute_root( hashes )
|
101
|
+
puts "merkletree root hash:"
|
102
|
+
puts merkle_root_value
|
103
|
+
|
104
|
+
assert_equal merkle.root.value, merkle_root_value
|
105
|
+
end # method test_example_3
|
106
|
+
|
107
|
+
|
108
|
+
def test_example_5 ## test odd (not even hashes)
|
109
|
+
|
110
|
+
hashes = [
|
111
|
+
'0000',
|
112
|
+
'0011',
|
113
|
+
'0022',
|
114
|
+
'0033',
|
115
|
+
'0044',
|
116
|
+
]
|
117
|
+
|
118
|
+
merkle = MerkleTree.new( hashes )
|
119
|
+
|
120
|
+
puts "merkletree root hash:"
|
121
|
+
puts merkle.root.value
|
122
|
+
|
123
|
+
puts "merkletree:"
|
124
|
+
pp merkle.root
|
125
|
+
|
126
|
+
|
127
|
+
merkle_root_value = MerkleTree.compute_root( hashes )
|
128
|
+
puts "merkletree root hash:"
|
129
|
+
puts merkle_root_value
|
130
|
+
|
131
|
+
assert_equal merkle.root.value, merkle_root_value
|
132
|
+
end # method test_example_5
|
133
|
+
|
134
|
+
|
135
|
+
def test_tulips
|
136
|
+
|
137
|
+
merkle = MerkleTree.for(
|
138
|
+
{ from: "Dutchgrown", to: "Vincent", what: "Tulip Bloemendaal Sunset", qty: 10 },
|
139
|
+
{ from: "Keukenhof", to: "Anne", what: "Tulip Semper Augustus", qty: 7 } )
|
140
|
+
|
141
|
+
puts "merkletree root hash:"
|
142
|
+
puts merkle.root.value
|
143
|
+
|
144
|
+
puts "merkletree:"
|
145
|
+
pp merkle.root
|
146
|
+
|
147
|
+
merkle_root_value = MerkleTree.compute_root_for(
|
148
|
+
{ from: "Dutchgrown", to: "Vincent", what: "Tulip Bloemendaal Sunset", qty: 10 },
|
149
|
+
{ from: "Keukenhof", to: "Anne", what: "Tulip Semper Augustus", qty: 7 } )
|
150
|
+
|
151
|
+
puts "merkletree root hash:"
|
152
|
+
puts merkle_root_value
|
153
|
+
|
154
|
+
assert_equal merkle.root.value, merkle_root_value
|
155
|
+
end # method test_tulips
|
156
|
+
|
157
|
+
|
158
|
+
end # class TestBuild
|
data/test/test_readme.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_readme.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestReadme < MiniTest::Test
|
12
|
+
|
13
|
+
|
14
|
+
def xxx_test_hashes
|
15
|
+
|
16
|
+
merkle1 = MerkleTree.new(
|
17
|
+
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
|
18
|
+
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
|
19
|
+
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' )
|
20
|
+
|
21
|
+
# -or-
|
22
|
+
|
23
|
+
puts merkle1.root.value
|
24
|
+
pp merkle1
|
25
|
+
|
26
|
+
merkle2 = MerkleTree.new( [
|
27
|
+
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
|
28
|
+
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
|
29
|
+
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' ])
|
30
|
+
|
31
|
+
pp merkle2
|
32
|
+
puts merkle2.root.value
|
33
|
+
|
34
|
+
assert_equal merkle1.root.value, merkle2.root.value
|
35
|
+
|
36
|
+
|
37
|
+
merkle_root_value = MerkleTree.compute_root(
|
38
|
+
'eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743',
|
39
|
+
'edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b',
|
40
|
+
'5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d' )
|
41
|
+
|
42
|
+
puts merkle_root_value
|
43
|
+
|
44
|
+
assert_equal merkle1.root.value, merkle_root_value
|
45
|
+
end # method test_hashes
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
def test_transactions
|
50
|
+
|
51
|
+
merkle = MerkleTree.for(
|
52
|
+
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
|
53
|
+
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
|
54
|
+
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
|
55
|
+
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
|
56
|
+
|
57
|
+
puts 'merkle tree root hash:'
|
58
|
+
puts merkle.root.value
|
59
|
+
pp merkle
|
60
|
+
|
61
|
+
merkle_root_value = MerkleTree.compute_root_for(
|
62
|
+
{ from: "Bloom & Blossom", to: "Daisy", what: "Tulip Admiral of Admirals", qty: 8 },
|
63
|
+
{ from: "Vincent", to: "Max", what: "Tulip Bloemendaal Sunset", qty: 2 },
|
64
|
+
{ from: "Anne", to: "Martijn", what: "Tulip Semper Augustus", qty: 2 },
|
65
|
+
{ from: "Ruben", to: "Julia", what: "Tulip Admiral van Eijck", qty: 2 } )
|
66
|
+
|
67
|
+
puts 'merkle tree root hash:'
|
68
|
+
puts merkle_root_value
|
69
|
+
|
70
|
+
assert_equal merkle.root.value, merkle_root_value
|
71
|
+
end # method test_transactions
|
72
|
+
|
73
|
+
|
74
|
+
end # class TestReadme
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_version.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestVersion < MiniTest::Test
|
12
|
+
|
13
|
+
def test_version
|
14
|
+
puts MerkleTree.version
|
15
|
+
puts MerkleTree.banner
|
16
|
+
puts MerkleTree.root
|
17
|
+
|
18
|
+
assert true ## (for now) everything ok if we get here
|
19
|
+
end
|
20
|
+
|
21
|
+
end # class TestVersion
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: merkletree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -56,6 +56,10 @@ files:
|
|
56
56
|
- Rakefile
|
57
57
|
- lib/merkletree.rb
|
58
58
|
- lib/merkletree/version.rb
|
59
|
+
- test/helper.rb
|
60
|
+
- test/test_build.rb
|
61
|
+
- test/test_readme.rb
|
62
|
+
- test/test_version.rb
|
59
63
|
homepage: https://github.com/openblockchains/merkletree.rb
|
60
64
|
licenses:
|
61
65
|
- Public Domain
|