rubychain 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +35 -0
- data/LICENSE.txt +21 -0
- data/README.md +111 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rubychain.rb +8 -0
- data/lib/rubychain/block.rb +26 -0
- data/lib/rubychain/chain.rb +61 -0
- data/lib/rubychain/version.rb +3 -0
- data/rubychain.gemspec +27 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 66da55fa18e22f2764bcf37fd1d13c9ee06ddd3f
|
4
|
+
data.tar.gz: 5c40b12e0a86a9aebe81470e77e970899fdd93e5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68d24a8d28939700a4872180812b843f17720c9a9e97d8bd5fed59ee790795bc99cb1b9b1c45246138afefc113f64a4cfba9dfadd6c7311830e24619a5d5b7ea
|
7
|
+
data.tar.gz: 806220f881b10756730362fc2d2d59e9c4aeb85ee6042f5ecd2842962093b705f45970b5ac3111c7b2630dc7bf15c48a12c8032de5d0ec87fd4c27da592948be
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rubychain (1.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.3)
|
10
|
+
rake (10.5.0)
|
11
|
+
rspec (3.7.0)
|
12
|
+
rspec-core (~> 3.7.0)
|
13
|
+
rspec-expectations (~> 3.7.0)
|
14
|
+
rspec-mocks (~> 3.7.0)
|
15
|
+
rspec-core (3.7.1)
|
16
|
+
rspec-support (~> 3.7.0)
|
17
|
+
rspec-expectations (3.7.0)
|
18
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
+
rspec-support (~> 3.7.0)
|
20
|
+
rspec-mocks (3.7.0)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.7.0)
|
23
|
+
rspec-support (3.7.1)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
bundler (~> 1.16)
|
30
|
+
rake (~> 10.0)
|
31
|
+
rspec (~> 3.0)
|
32
|
+
rubychain!
|
33
|
+
|
34
|
+
BUNDLED WITH
|
35
|
+
1.16.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Stuart Hanscombe
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# Rubychain
|
2
|
+
|
3
|
+
Rubychain is a very simple implementation of a blockchain for education purposes.
|
4
|
+
It is heavily inspired by the python version
|
5
|
+
which can be found here: https://dev.to/aunyks/lets-build-the-tiniest-blockchain
|
6
|
+
|
7
|
+
There are only 2 classes which are /lib/rubychain/chain and /lib/rubychain/block
|
8
|
+
|
9
|
+
`Rubychain::Chain` for creating, updating and exploring the blockchain
|
10
|
+
|
11
|
+
`Rubychain::Block` for creating each individual block
|
12
|
+
|
13
|
+
Check out the instructions below or the specs to see how it all works
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'rubychain'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
$ gem install rubychain
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
require 'rubychain'
|
34
|
+
|
35
|
+
## Rubychain::Chain
|
36
|
+
### Available methods
|
37
|
+
|
38
|
+
`add_next_block(prev_block, data)` => Adds a new block to the blockchain with the given data and previous block
|
39
|
+
|
40
|
+
`genesis_block` => Returns the Genesis block
|
41
|
+
|
42
|
+
`last_block` => Returns the last block that was added to the blockchain
|
43
|
+
|
44
|
+
`find_block(hash)` => Returns a block from the blockchain with the given hash
|
45
|
+
|
46
|
+
`blockchain` => Returns the whole blockchain as an array
|
47
|
+
|
48
|
+
### Exploring the blockchain
|
49
|
+
|
50
|
+
Initialize a new blockchain with a genesis block:
|
51
|
+
|
52
|
+
`rc = Rubychain::Chain.new`
|
53
|
+
|
54
|
+
`rc.add_next_block(rc.last_block, "some data")` => creates a new block with given data and previous block
|
55
|
+
|
56
|
+
`rc.genesis_block` => returns the genesis block
|
57
|
+
|
58
|
+
`rc.last_block` => returns the last block on the blockchain
|
59
|
+
|
60
|
+
`rc.find_block(hash)` => return the block with the given hash
|
61
|
+
|
62
|
+
`rc.blockchain` => [genesis_block, block2] => Returns the whole blockchain as an array
|
63
|
+
|
64
|
+
## Rubychain::Block
|
65
|
+
### Available methods
|
66
|
+
|
67
|
+
`index` => returns the blocks index
|
68
|
+
|
69
|
+
`timestamp` => returns the blocks timestamp
|
70
|
+
|
71
|
+
`data` => returns the blocks data
|
72
|
+
|
73
|
+
`prev_hash` => returns the previous blocks hash
|
74
|
+
|
75
|
+
`hash` => returns a SHA256 hash representation of all the items in the block
|
76
|
+
|
77
|
+
### Exploring a block
|
78
|
+
|
79
|
+
`myblock = rc.last_block`
|
80
|
+
|
81
|
+
or
|
82
|
+
|
83
|
+
`myblock = rc.find_block(hash)`
|
84
|
+
|
85
|
+
or directly
|
86
|
+
|
87
|
+
`myblock = Rubychain::Block.new(1, Time.now, "Hello World", "abc123")`
|
88
|
+
|
89
|
+
`myblock.index` => 1
|
90
|
+
|
91
|
+
`myblock.timestamp` => Time of creation
|
92
|
+
|
93
|
+
`myblock.data` => "Hello World"
|
94
|
+
|
95
|
+
`myblock.pre_hash` => "abc123"
|
96
|
+
|
97
|
+
`myblock.hash` => sha.hexdigest of index, timestamp, data and previous block hash
|
98
|
+
|
99
|
+
## Development
|
100
|
+
|
101
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
102
|
+
|
103
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
104
|
+
|
105
|
+
## Contributing
|
106
|
+
|
107
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rubychain.
|
108
|
+
|
109
|
+
## License
|
110
|
+
|
111
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rubychain"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/rubychain.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Rubychain
|
4
|
+
class Block
|
5
|
+
|
6
|
+
attr_reader :index, :timestamp, :data, :prev_hash, :hash
|
7
|
+
|
8
|
+
def initialize(index, timestamp, data, prev_hash)
|
9
|
+
@index = index
|
10
|
+
@timestamp = timestamp
|
11
|
+
@data = data
|
12
|
+
@prev_hash = prev_hash
|
13
|
+
@hash = hash_block
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create the blocks hash by encrypting all the blocks data using SHA256
|
17
|
+
|
18
|
+
def hash_block
|
19
|
+
hash_string = [index,timestamp,data,prev_hash].join
|
20
|
+
sha = Digest::SHA256.new
|
21
|
+
sha.update(hash_string)
|
22
|
+
sha.hexdigest
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Rubychain
|
2
|
+
class Chain
|
3
|
+
|
4
|
+
attr_reader :blockchain
|
5
|
+
|
6
|
+
class InvalidBlockError < StandardError; end
|
7
|
+
|
8
|
+
# Initialize a new blockchain by creating a new array with the Genesis block
|
9
|
+
#
|
10
|
+
def initialize
|
11
|
+
@blockchain = [create_genesis_block]
|
12
|
+
end
|
13
|
+
|
14
|
+
# #add_next_block => Adds a new block to the blockchain with the given data
|
15
|
+
# it will raise an error if the previous_block hash does not match the last_block in our blockchain
|
16
|
+
#
|
17
|
+
def add_next_block(prev_block, data)
|
18
|
+
if valid_block?(prev_block)
|
19
|
+
blockchain << next_block(data)
|
20
|
+
else
|
21
|
+
raise InvalidBlockError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# #genesis_block => Returns the Genesis block
|
26
|
+
#
|
27
|
+
def genesis_block
|
28
|
+
blockchain.first
|
29
|
+
end
|
30
|
+
|
31
|
+
# #last_block => Returns the last block that was added to the blockchain
|
32
|
+
#
|
33
|
+
def last_block
|
34
|
+
blockchain.last
|
35
|
+
end
|
36
|
+
|
37
|
+
# #find_block(hash) => Returns a block from the blockchain with the given hash
|
38
|
+
#
|
39
|
+
def find_block(hash)
|
40
|
+
blockchain.select{|block| block if block.hash == hash}.first
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def valid_block?(prev_block)
|
46
|
+
prev_block.hash == last_block.hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def next_block(data)
|
50
|
+
index = last_block.index + 1
|
51
|
+
timestamp = Time.now
|
52
|
+
hash = last_block.hash
|
53
|
+
Block.new(index, timestamp, data, hash)
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_genesis_block()
|
57
|
+
Block.new(0, Time.now, "Genesis Block", 0)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
data/rubychain.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "rubychain/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rubychain"
|
8
|
+
spec.version = Rubychain::VERSION
|
9
|
+
spec.authors = ["Stuart Hanscombe"]
|
10
|
+
spec.email = ["hanscs1969@yahoo.co.uk"]
|
11
|
+
|
12
|
+
spec.summary = "A simple blockchain built on Ruby"
|
13
|
+
spec.description = "A very simple ruby implementation of a blockchain, based on python version: https://dev.to/aunyks/lets-build-the-tiniest-blockchain"
|
14
|
+
spec.homepage = "https://github.com/thelazycamel/rubychain"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubychain
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stuart Hanscombe
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description: 'A very simple ruby implementation of a blockchain, based on python version:
|
56
|
+
https://dev.to/aunyks/lets-build-the-tiniest-blockchain'
|
57
|
+
email:
|
58
|
+
- hanscs1969@yahoo.co.uk
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
66
|
+
- Gemfile
|
67
|
+
- Gemfile.lock
|
68
|
+
- LICENSE.txt
|
69
|
+
- README.md
|
70
|
+
- Rakefile
|
71
|
+
- bin/console
|
72
|
+
- bin/setup
|
73
|
+
- lib/rubychain.rb
|
74
|
+
- lib/rubychain/block.rb
|
75
|
+
- lib/rubychain/chain.rb
|
76
|
+
- lib/rubychain/version.rb
|
77
|
+
- rubychain.gemspec
|
78
|
+
homepage: https://github.com/thelazycamel/rubychain
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.4.5
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: A simple blockchain built on Ruby
|
102
|
+
test_files: []
|