eip55 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 979aa4ae1e5c3bd0d1a494b883473c0af665a12c68422b6059fc1df6ff001616
4
+ data.tar.gz: 49f2f4c70194dd9560edab690b5ff89cea31155b384901012491bc48b33f0d96
5
+ SHA512:
6
+ metadata.gz: c25aad542bd53972fffca1081825d92819ec8d1740270bf5d9ce96125665fa5db59fe7ce0bc1a3d88179866866597669215c1a0ef07654ff29f910026bd87bf7
7
+ data.tar.gz: 552ffb437a30a85ce287b1e97823706a9cc8c8fe67da7a90f25b3188c38ddcfd0da05db14e7bac84fc065e112cd2604a354b5faa6bcb9247b1e7422487fef7cd
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Steve Ellis
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.
@@ -0,0 +1,35 @@
1
+ # EIP55 [![CircleCI](https://circleci.com/gh/FractalBlockchain/ruby-eip55.svg?style=svg)](https://circleci.com/gh/FractalBlockchain/ruby-eip55)
2
+
3
+ A library for [Ethereum mixed-case checksum address encoding](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md). Mostly extracted from [se3000/ruby-eth](https://github.com/se3000/ruby-eth).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'eip55'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself:
18
+
19
+ $ gem install eip55
20
+
21
+ ## Usage
22
+
23
+ See tests for usage examples
24
+
25
+ ## Tests
26
+
27
+ $ rake test
28
+
29
+ ## Code style
30
+
31
+ $ bundle exec rubocop
32
+
33
+ ## License
34
+
35
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,9 @@
1
+ require "rake/testtask"
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << "test"
5
+ t.test_files = FileList["test/**/*_test.rb"]
6
+ t.verbose = true
7
+ end
8
+
9
+ task default: :test
@@ -0,0 +1,5 @@
1
+ require "eip55/util"
2
+ require "eip55/address"
3
+
4
+ module EIP55
5
+ end
@@ -0,0 +1,62 @@
1
+ module EIP55
2
+ class InvalidAddressError < StandardError
3
+ end
4
+
5
+ class Address
6
+ def initialize address
7
+ @address = Util.prefix(address)
8
+ end
9
+
10
+ def valid?
11
+ if !matches_any_format?
12
+ false
13
+ elsif not_checksummed?
14
+ true
15
+ else
16
+ checksum_matches?
17
+ end
18
+ end
19
+
20
+ def checksummed
21
+ raise InvalidAddressError.new("Invalid address: #{address}") unless matches_any_format?
22
+
23
+ cased = unprefixed.chars.zip(checksum.chars).map do |char, check|
24
+ check.match?(/[0-7]/) ? char.downcase : char.upcase
25
+ end
26
+
27
+ Util.prefix(cased.join)
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :address
33
+
34
+ def checksum_matches?
35
+ address == checksummed
36
+ end
37
+
38
+ def matches_any_format?
39
+ address.match(/\A(?:0[xX])[a-fA-F0-9]{40}\z/)
40
+ end
41
+
42
+ def not_checksummed?
43
+ all_uppercase? || all_lowercase?
44
+ end
45
+
46
+ def all_uppercase?
47
+ address.match(/\A(?:0[xX])[A-F0-9]{40}\z/)
48
+ end
49
+
50
+ def all_lowercase?
51
+ address.match(/\A(?:0[xX])[a-f0-9]{40}\z/)
52
+ end
53
+
54
+ def unprefixed
55
+ Util.unprefix(address)
56
+ end
57
+
58
+ def checksum
59
+ Util.encode_hex(Util.keccak256(unprefixed.downcase))
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,23 @@
1
+ require "digest"
2
+
3
+ module EIP55
4
+ class Util
5
+ class << self
6
+ def encode_hex string
7
+ string.unpack1("H*")
8
+ end
9
+
10
+ def keccak256 buffer
11
+ Digest::SHA3.new(256).digest(buffer)
12
+ end
13
+
14
+ def prefix address
15
+ address[0, 2] == "0x" ? address : "0x#{address}"
16
+ end
17
+
18
+ def unprefix address
19
+ address[0, 2] == "0x" ? address[2..-1] : address
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module EIP55
2
+ VERSION = "1.0.0".freeze
3
+ end
@@ -0,0 +1,125 @@
1
+ require "test_helper"
2
+
3
+ describe EIP55::Address do
4
+ describe "#valid?" do
5
+ describe "given an address with a valid checksum" do
6
+ let(:addresses) do
7
+ %w[
8
+ 0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed
9
+ 0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359
10
+ 0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB
11
+ 0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb
12
+ ]
13
+ end
14
+
15
+ it "returns true" do
16
+ addresses.each do |address|
17
+ assert EIP55::Address.new(address).valid?
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "given an address with an invalid checksum" do
23
+ let(:addresses) do
24
+ %w[
25
+ 0x5AAeb6053F3E94C9b9A09f33669435E7Ef1BeAed
26
+ 0xFB6916095ca1df60bB79Ce92cE3Ea74c37c5d359
27
+ 0xDbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB
28
+ 0xd1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb
29
+ ]
30
+ end
31
+
32
+ it "returns false" do
33
+ addresses.each do |address|
34
+ refute EIP55::Address.new(address).valid?
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "given an address with all uppercase letters" do
40
+ let(:addresses) do
41
+ %w[
42
+ 0x5AAEB6053F3E94C9B9A09F33669435E7EF1BEAED
43
+ 0xFB6916095CA1DF60BB79CE92CE3EA74C37C5D359
44
+ 0xDBF03B407C01E7CD3CBEA99509D93F8DDDC8C6FB
45
+ 0xD1220A0CF47C7B9BE7A2E6BA89F429762E7B9ADB
46
+ 0x52908400098527886E0F7030069857D2E4169EE7
47
+ 0x8617E340B3D01FA5F11F306F4090FD50E238070D
48
+ ]
49
+ end
50
+
51
+ it "returns true" do
52
+ addresses.each do |address|
53
+ assert EIP55::Address.new(address).valid?
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "given an address with all lowercase letters" do
59
+ let(:addresses) do
60
+ %w[
61
+ 0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed
62
+ 0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359
63
+ 0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb
64
+ 0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb
65
+ 0xde709f2102306220921060314715629080e2fb77
66
+ 0x27b1fdb04752bbc536007a920d24acb045561c26
67
+ ]
68
+ end
69
+
70
+ it "returns true" do
71
+ addresses.each do |address|
72
+ assert EIP55::Address.new(address).valid?
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "given an invalid address" do
78
+ let(:addresses) do
79
+ %w[
80
+ 0x5aaeb6053f3e94c9b9a09f33669435e7ef1beae
81
+ 0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359d
82
+ 0x5AAEB6053F3E94C9B9A09F33669435E7EF1BEAE
83
+ 0xFB6916095CA1DF60BB79CE92CE3EA74C37C5D359D
84
+ ]
85
+ end
86
+
87
+ it "returns false" do
88
+ addresses.each do |address|
89
+ refute EIP55::Address.new(address).valid?
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "#checksummed" do
96
+ let(:addresses) do
97
+ %w[
98
+ 5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed
99
+ fB6916095ca1df60bB79Ce92cE3Ea74c37c5d359
100
+ dbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB
101
+ D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb
102
+ ]
103
+ end
104
+
105
+ it "follows EIP55 standard" do
106
+ addresses.each do |checksummed|
107
+ assert_equal "0x#{checksummed}", EIP55::Address.new(checksummed.upcase).checksummed
108
+ end
109
+
110
+ addresses.each do |checksummed|
111
+ assert_equal "0x#{checksummed}", EIP55::Address.new(checksummed.downcase).checksummed
112
+ end
113
+ end
114
+
115
+ describe "given an invalid address" do
116
+ let(:bad) { "0x#{SecureRandom.hex(21)}" }
117
+
118
+ it "raises an error" do
119
+ assert_raises EIP55::InvalidAddressError do
120
+ EIP55::Address.new(bad).checksummed
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,7 @@
1
+ require "minitest/autorun"
2
+ require "minitest/spec"
3
+ require "minitest/reporters"
4
+ require "securerandom"
5
+ require "eip55"
6
+
7
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eip55
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Steve Ellis
8
+ - Mário Carneiro
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2018-07-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: digest-sha3
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: minitest
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '5.11'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '5.11'
42
+ - !ruby/object:Gem::Dependency
43
+ name: minitest-reporters
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.3'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.3'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rubocop
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0.58'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.58'
70
+ description:
71
+ email:
72
+ - email@steveell.is
73
+ - mario.carneiro@frctls.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/eip55.rb
83
+ - lib/eip55/address.rb
84
+ - lib/eip55/util.rb
85
+ - lib/eip55/version.rb
86
+ - test/address_test.rb
87
+ - test/test_helper.rb
88
+ homepage: https://github.com/FractalBlockchain/ruby-eip55
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 2.5.0
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.7.3
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Implementation of the EIP55 checksum address encoding
112
+ test_files:
113
+ - test/address_test.rb
114
+ - test/test_helper.rb