cryptos 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 821b977f9586beced716c6274e4c4de1b2bd59eacb2ca2d1f00ba7555cda7a46
4
- data.tar.gz: aef2d8dcd9b5ef0155925df43d89fb8738fe09cfa1e99d9d78065a82ee3bcf6c
3
+ metadata.gz: 4443865be6e4d80fd14379b9a069cc5c2de35c1d9ef805bfdc63fc1c8f58dab3
4
+ data.tar.gz: 2f7af68e8ecd589d0239f7d998d491017950a7b24b7e50e64e5909a35c2832b7
5
5
  SHA512:
6
- metadata.gz: cc3b5bc76776036438e1bb65efa1988f7fd0c8c12adcd57feab46bf94103086a024b5e92b7774891e27eaa9ed330b48ea7e841ddd87bbe5e816d2762f2cee353
7
- data.tar.gz: 51fb82e5739d2a160f7968dcc8fa37f72b805614e85407051789b3b060c08a49a8153e9cba83f212a8aa236c5325f3a2f7ff05ca91cc2b42c650924a2e8c22f6
6
+ metadata.gz: 8e68269fc968d716d372284dc3685d69155dcdb0fe31f22e5a8f5af7156a4950a87019f8ab667136da914b379d36498e69d6696e43b3b4f3d6a05c5fe955db6d
7
+ data.tar.gz: 4d7014a5f7b23eef84a2aa6b61d3804878a29d26316c95ce1a8be8016f02119685494c196e9114af7b78a2848af4a365cee0d2bc6d3dea66ae52b87a85c81fe5
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Browser [e.g. chrome, safari]
29
+ - Version [e.g. 22]
30
+
31
+ **Smartphone (please complete the following information):**
32
+ - Device: [e.g. iPhone6]
33
+ - OS: [e.g. iOS8.1]
34
+ - Browser [e.g. stock browser, safari]
35
+ - Version [e.g. 22]
36
+
37
+ **Additional context**
38
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -7,7 +7,7 @@ rvm:
7
7
 
8
8
  env:
9
9
  global:
10
- - CC_TEST_REPORTER_ID=38c8686e073a8123e72d8f7c580edbfae244922662e6202e9a964152b6b234a0
10
+ - CC_TEST_REPORTER_ID=0574ba014fdce356c974c3b8e6e74ea6b07079b9355c35b391b8e17e72aec5c1
11
11
 
12
12
  apt_packages:
13
13
  - bitcoind
@@ -1 +1,33 @@
1
- # CryptoCrafts changelog
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+ ### Added
10
+ - Atomic swap between Bitcoin and Litecoin
11
+ ### Changed
12
+ ### Removed
13
+
14
+ ## [0.0.3] - 2018-12-11
15
+ ### Added
16
+ - LICENSE, changelog, Github template files
17
+ ### Changed
18
+ - Rename project to Cryptos-ruby
19
+ - Fixes in README, gemspec files
20
+
21
+ ## [0.0.2] - 2018-12-01
22
+ ### Added
23
+ - Bitcoin/Litecoin transactions
24
+ - Automated tests with regtest mode
25
+ - Travis, CodeClimate integration
26
+ ### Changed
27
+ - Refactoring big old base files
28
+
29
+ ## [0.0.1] - 2018-11-26
30
+ ### Added
31
+ - Elliptic curves math, digital signature algorithm
32
+ - Generate private / public keys
33
+ - Generate Bitcoin/Litecoin addresses
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cryptos (0.0.2)
4
+ cryptos (0.0.3)
5
5
  hashie
6
6
  httparty
7
7
 
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Iulian Costan
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,11 +1,29 @@
1
- # Cryptos
2
- [![Build Status](https://travis-ci.org/icostan/cryptos.svg?branch=master)](https://travis-ci.org/icostan/cryptos)
3
- [![Maintainability](https://api.codeclimate.com/v1/badges/d929c152bff4fe5be78f/maintainability)](https://codeclimate.com/github/icostan/cryptos/maintainability)
4
- [![Test Coverage](https://api.codeclimate.com/v1/badges/d929c152bff4fe5be78f/test_coverage)](https://codeclimate.com/github/icostan/cryptos/test_coverage)
1
+ # Cryptos-ruby
2
+
3
+ [![Build Status](https://travis-ci.org/icostan/cryptos-ruby.svg?branch=master)](https://travis-ci.org/icostan/cryptos-ruby)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/3e4566b45ebc3f887cef/maintainability)](https://codeclimate.com/github/icostan/cryptos-ruby/maintainability)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/3e4566b45ebc3f887cef/test_coverage)](https://codeclimate.com/github/icostan/cryptos-ruby/test_coverage)
5
6
  [![Gem Version](https://badge.fury.io/rb/cryptos.svg)](https://badge.fury.io/rb/cryptos)
6
7
 
7
- Cryptos project is meant to provide an unified Ruby API to work with different crypto-currencies but the ultimate goal is to support atomic-swaps between any two coins.
8
+ ### The Why - the vision and goals
9
+
10
+ * I believe there are none of very few Ruby implementations and support for different crypto technologies
11
+ * I like to craft my own wallets, transactions, block explorers in all shapes and forms
12
+ * I dream to execute atomic swaps between any crypto coins out there
13
+
14
+ ### The How - the actions
15
+
16
+ * Implementing basic cryptography from scratch - elliptic curves math, digital signature schemes, etc
17
+ * Building a simple and easy to use Ruby API
18
+ * Lean and continuous improvment along the way (aka adding more coins) while I understand more advanced concepts: pairing cryptography
19
+
20
+ ### The What - the features
8
21
 
22
+ * Generate private and public keys
23
+ * Generate addresses for Bitcoin, Litecoin, Ethereum and much more
24
+ * Create transaction to spend standard inputs or more complex multisig, hashed timelock contracts
25
+ * Execute atomic swaps between Bitcoin and Litecoin, more to come
26
+ * TODO: Create, import, export wallets
9
27
 
10
28
  ## Installation
11
29
 
@@ -36,7 +54,7 @@ Alright, let's begin, first thing first, lets generate private and public keys:
36
54
  => #<Cryptos::PublicKey:0x00007f8cc105ed58 @private_key=#<Cryptos::PrivateKey:0x00007f8cc10c0ad0 @value=1991485315816438798044329630916774278846523543844864946402119577704095054145, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=107779388491921327681974754398507503201871466663959093103394577491037829153768, @y=78060352001932916201234328232450653863791592111885208305671830584742527863131>
37
55
  ```
38
56
 
39
- Based in publik key above lets create a Bitcoin address:
57
+ Based on public key above lets create a Bitcoin address:
40
58
 
41
59
  ```ruby
42
60
  2.5.3 :003 > from_address = Cryptos::Bitcoin::Address.new public_key
@@ -53,7 +71,7 @@ brew install bitcoin
53
71
  apt-get install bitcoin
54
72
 
55
73
  # start Bitcoin daemon in regtest mode
56
- bitcoin-cli -regtest -printtoconsole
74
+ bitcoind -regtest -printtoconsole
57
75
  ```
58
76
 
59
77
  Now we create a simple Cli connector that will communicate to underlying bitcoin daemon.
@@ -79,7 +97,7 @@ Generate and import destination address to send BTC to then check that it has no
79
97
  => #<Cryptos::Bitcoin::Address:0x00007f8cc134f2b0 @public_key=#<Cryptos::PublicKey:0x00007f8cc128fa78 @private_key=#<Cryptos::PrivateKey:0x00007f8cc128faa0 @value=104555233989943463494354097619221894829574308702717051161491781222000198727347, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=1402024405898287938501468401055931693243587868828983898835308320263377717122, @y=89146164815925753866667564550747587615674131412309491381641677989226156891240>, @testnet=true>
80
98
  2.5.3 :008 > to_address.import cli
81
99
  => true
82
- 2.5.3 :009 > cli.get_received_by_address to_address
100
+ 2.5.3 :009 > to_address.get_balance cli
83
101
  => "0.00000000"
84
102
  ```
85
103
 
data/TODOs.org CHANGED
@@ -8,3 +8,13 @@
8
8
  * deterministic signature (https://tools.ietf.org/html/rfc6979)
9
9
  * refactor elliptic curve module, extract to classes
10
10
  * implement #to_s method for all classes, right now they are too verbose
11
+ * refactor: add input#sign and mark input as signed
12
+ * atomic swaps:
13
+ * happy path - successful redeem both coins
14
+ * sad path - no redeem, broadcast refund transactions
15
+ * error paths - redeem with invalid secret, refund before locktime
16
+ * refactor: simplify swap interfaces
17
+ * bitcoin:
18
+ * add address type to constructor
19
+ * support segwit address
20
+ * add ZCash support
data/bin/run CHANGED
@@ -1,19 +1,40 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'bundler/setup'
4
+ require 'cryptos'
5
+
6
+ cli = Cryptos::Connectors::Cli.new
7
+
8
+ puts 'Generating private key...'
3
9
  private_key = Cryptos::PrivateKey.generate
10
+
11
+ puts 'Generating public key...'
4
12
  public_key = Cryptos::PublicKey.new private_key
13
+
14
+ puts 'Generating source address...'
5
15
  from_address = Cryptos::Bitcoin::Address.new public_key
6
- cli = Cryptos::Connectors::Cli.new
7
16
  from_address.import cli
17
+
18
+ puts 'Mine 101 blocks...'
8
19
  cli.generate_to_address from_address, blocks: 101
20
+
21
+ puts 'Generating destination address...'
9
22
  to_address = Cryptos::Bitcoin::Address.new Cryptos::PublicKey.new Cryptos::PrivateKey.generate
10
23
  to_address.import cli
11
- cli.get_received_by_address to_address
24
+ to_address.get_balance cli
25
+
26
+ puts 'Create transaction...'
12
27
  input = Cryptos::Input.from_utxo cli, from_address
13
28
  output = Cryptos::Output.p2pkh to_address, 123_456_789
14
29
  change = Cryptos::Output.p2pkh_change from_address, input, output
15
30
  transaction = Cryptos::Transaction.from_ioc input, output, change
31
+
32
+ puts 'Sign and broadcast transaction...'
16
33
  transaction.sign_single_input from_address
17
34
  transaction.broadcast cli
35
+
36
+ puts 'Mine next block...'
18
37
  cli.generate blocks: 1
19
- cli.get_received_by_address to_address
38
+
39
+ puts 'Check destination balance...'
40
+ puts to_address.get_balance cli
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = %q{Crypto craft your own transactions}
12
12
  spec.description = %q{The easiest way to craft your own transactions for multiple crypto currencies}
13
- spec.homepage = 'https://github.com/icostan/cryptos'
13
+ spec.homepage = 'https://github.com/icostan/cryptos-ruby'
14
14
 
15
15
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
16
16
  # to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
19
19
 
20
20
  spec.metadata['homepage_uri'] = spec.homepage
21
- spec.metadata['source_code_uri'] = 'https://github.com/icostan/cryptos.git'
22
- spec.metadata['changelog_uri'] = 'https://github.com/icostan/cryptos/blob/master/CHANGELOG'
21
+ spec.metadata['source_code_uri'] = 'https://github.com/icostan/cryptos-ruby.git'
22
+ spec.metadata['changelog_uri'] = 'https://github.com/icostan/cryptos-ruby/blob/master/CHANGELOG'
23
23
  else
24
24
  raise 'RubyGems 2.0 or newer is required to protect against ' \
25
25
  'public gem pushes.'
@@ -43,6 +43,10 @@ module Cryptos
43
43
  cli.import_address self
44
44
  end
45
45
 
46
+ def get_balance(cli)
47
+ cli.get_received_by_address self
48
+ end
49
+
46
50
  def to_s
47
51
  p2pkh
48
52
  end
@@ -17,6 +17,11 @@ module Cryptos
17
17
  Output.p2pkh address, change_value
18
18
  end
19
19
 
20
+ def self.atomic_swap(secret_hash, to_address, locktime, from_address, amount)
21
+ swap_script = Cryptos::Script.swap secret_hash, to_address, locktime, from_address
22
+ Output.new amount, Cryptos::Script.p2sh(swap_script)
23
+ end
24
+
20
25
  def serialize
21
26
  script_hex = script_pubkey.to_hex
22
27
  long_to_hex(value) + byte_to_hex(hex_size(script_hex)) + script_hex
@@ -3,20 +3,29 @@ module Cryptos
3
3
  include Utils::Hexas, Utils::Hashes
4
4
 
5
5
  OPCODES = {
6
- 'OP_0' => 0x00,
7
- 'OP_1' => 0x51,
8
- 'OP_2' => 0x52,
9
- 'OP_DUP' => 0x76,
10
- 'OP_HASH160' => 0xA9,
6
+ 'OP_0' => 0x00,
7
+ 'OP_PUSHDATA1' => 0x4c,
8
+ 'OP_1' => 0x51,
9
+ 'OP_2' => 0x52,
10
+ 'OP_IF' => 0x63,
11
+ 'OP_ELSE' => 0x67,
12
+ 'OP_ENDIF' => 0x68,
13
+ 'OP_DROP' => 0x75,
14
+ 'OP_DUP' => 0x76,
11
15
  'OP_EQUAL' => 0x87,
12
- 'OP_EQUALVERIFY' => 0x88,
13
- 'OP_CHECKSIG' => 0xAC,
14
- 'OP_CHECKMULTISIG' => 0xAE
16
+ 'OP_EQUALVERIFY' => 0x88,
17
+ 'OP_RIPEMD160' => 0xA6,
18
+ 'OP_HASH160' => 0xA9,
19
+ 'OP_CHECKSIG' => 0xAC,
20
+ 'OP_CHECKMULTISIG' => 0xAE,
21
+ 'OP_CHECKLOCKTIMEVERIFY' => 0xB1,
22
+ 'OP_CHECKSEQUENCEVERIFY' => 0xB2,
15
23
  }.freeze
16
24
 
17
25
  attr_reader :script
18
26
 
19
- # scriptSig for pay-to-pubkey-hash outputs
27
+ # ScriptSig for pay-to-pubkey-hash outputs
28
+ #
20
29
  # @param der - signature in der format
21
30
  # @param public_key - the public key
22
31
  # @return script - a Script object holding scriptSig
@@ -26,7 +35,12 @@ module Cryptos
26
35
 
27
36
  # scriptSig for pay-to-multisig-hash outputs
28
37
  def self.sig_multisig(der1, der2, redeem_script)
29
- new "OP_0 #{der1.serialize} #{der2.serialize} #{redeem_script.serialize}"
38
+ new "OP_0 #{der1.serialize} #{der2.serialize} #{redeem_script.to_hex}"
39
+ end
40
+
41
+ # scriptSig for atomic swaps
42
+ def self.sig_swap(der, public_key, secret, redeem_script)
43
+ new "#{der.serialize} #{public_key.to_sec} #{secret} OP_1 #{redeem_script.to_hex}"
30
44
  end
31
45
 
32
46
  def self.p2pkh(address_or_hex)
@@ -47,12 +61,25 @@ module Cryptos
47
61
  new "OP_2 #{address1.public_key.to_sec} #{address2.public_key.to_sec} OP_2 OP_CHECKMULTISIG"
48
62
  end
49
63
 
64
+ def self.swap(secret_hash, to_address, locktime, from_address)
65
+ new %{
66
+ OP_IF
67
+ OP_RIPEMD160 #{secret_hash} OP_EQUALVERIFY
68
+ OP_DUP OP_HASH160 #{to_address.to_hash160}
69
+ OP_ELSE
70
+ #{locktime} OP_CHECKLOCKTIMEVERIFY OP_DROP
71
+ OP_DUP OP_HASH160 #{from_address.to_hash160}
72
+ OP_ENDIF
73
+ OP_EQUALVERIFY OP_CHECKSIG
74
+ }.delete("\n").squeeze ' '
75
+ end
76
+
50
77
  def self.bare(script)
51
78
  new script
52
79
  end
53
80
 
54
81
  def initialize(script)
55
- @script = script
82
+ @script = script.strip
56
83
  end
57
84
 
58
85
  def to_hash160
@@ -86,7 +113,11 @@ module Cryptos
86
113
  def data(token)
87
114
  bin_size = data_size token
88
115
  # TODO: data size is defined as 1-9 bytes
89
- byte_to_hex(bin_size) + token
116
+ if bin_size > 0x4b
117
+ opcode('OP_PUSHDATA1') + byte_to_hex(bin_size) + token
118
+ else
119
+ byte_to_hex(bin_size) + token
120
+ end
90
121
  end
91
122
 
92
123
  def data_size(token)
@@ -60,6 +60,18 @@ module Cryptos
60
60
  serialize
61
61
  end
62
62
 
63
+ def sign_atomic_swap(secret, secret_hash, to_address, locktime, from_address, sighash_type = 0x01)
64
+ redeem_script = Cryptos::Script.swap secret_hash, to_address, locktime, from_address
65
+ bytes_string = signature_hash redeem_script, sighash_type
66
+
67
+ r, s = ecdsa_sign to_address.public_key.private_key.value, bytes_string
68
+ der = Cryptos::Der.new r: r, s: s
69
+ sig_swap = Script.sig_swap der, to_address.public_key, secret, redeem_script
70
+ inputs[0].script_sig = sig_swap
71
+
72
+ serialize
73
+ end
74
+
63
75
  def broadcast(cli)
64
76
  cli.send_raw_transaction serialize
65
77
  end
@@ -7,6 +7,10 @@ module Cryptos
7
7
  Digest::SHA256.hexdigest([data].pack('H*'))
8
8
  end
9
9
 
10
+ def ripemd160(data)
11
+ Digest::RMD160.hexdigest([data].pack('H*'))
12
+ end
13
+
10
14
  def hash160(data)
11
15
  sha256 = Digest::SHA256.digest([data].pack('H*'))
12
16
  Digest::RMD160.hexdigest sha256
@@ -1,3 +1,3 @@
1
1
  module Cryptos
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cryptos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iulian Costan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-01 00:00:00.000000000 Z
11
+ date: 2018-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -143,6 +143,8 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
147
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
146
148
  - ".gitignore"
147
149
  - ".rspec"
148
150
  - ".ruby-version"
@@ -151,6 +153,7 @@ files:
151
153
  - CODE_OF_CONDUCT.md
152
154
  - Gemfile
153
155
  - Gemfile.lock
156
+ - LICENSE
154
157
  - README.md
155
158
  - Rakefile
156
159
  - TODOs.org
@@ -181,13 +184,13 @@ files:
181
184
  - lib/cryptos/utils/hashes.rb
182
185
  - lib/cryptos/utils/hexas.rb
183
186
  - lib/cryptos/version.rb
184
- homepage: https://github.com/icostan/cryptos
187
+ homepage: https://github.com/icostan/cryptos-ruby
185
188
  licenses: []
186
189
  metadata:
187
190
  allowed_push_host: https://rubygems.org
188
- homepage_uri: https://github.com/icostan/cryptos
189
- source_code_uri: https://github.com/icostan/cryptos.git
190
- changelog_uri: https://github.com/icostan/cryptos/blob/master/CHANGELOG
191
+ homepage_uri: https://github.com/icostan/cryptos-ruby
192
+ source_code_uri: https://github.com/icostan/cryptos-ruby.git
193
+ changelog_uri: https://github.com/icostan/cryptos-ruby/blob/master/CHANGELOG
191
194
  post_install_message:
192
195
  rdoc_options: []
193
196
  require_paths: