keoken 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23b1ae2d3240583fad89b5acaad6923edd0daedc1b24a99c906ebed1d7c8fb4b
4
- data.tar.gz: a39bfbafdad72692b19424b536d3818bae2847b905e344b2ba37a3f9d514573e
3
+ metadata.gz: 910f95d9e5c38b7bd38a3931b31172285811a45d0dcfdbd280d0c9f86c177a8c
4
+ data.tar.gz: f6d5dbc887a6bb374da47157dcede765a4f236f2d241058b9e9bd3e08b60e196
5
5
  SHA512:
6
- metadata.gz: 509d886950b38bea4f0ebd1a5522354b634f46824caee6df85f2a89e9f95445d17f651c91141944332fd1eeb529828386cc300fbc32853258c1ec0face1a8ba9
7
- data.tar.gz: 4bc290015e815d72b52a6e952e3df2a6fc86f0d7345a568844dca6bedb5a032c6e5e5fb131be22aab64fc46ca19413d2feca51fd6b058525061475a32ec631ed
6
+ metadata.gz: a3b15901f51755d600d766fab2c96c4a0e42b2722368d763d27a4930761882060f5ab2d7f9f053e1639c3cc841bf862b6556c9cb0fd8214c0a0211a13bb8667c
7
+ data.tar.gz: a0c828852eb3b6929c39b78e9454add080bb142b708bff5c60488eec17b5ffeb6f015f74a994e8aaf0e5ab2ae046bb43571e2343a2ea9fe31b5d75c4ed32c5b8
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ Metrics/LineLength:
2
+ Max: 120
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keoken (0.1.0)
4
+ keoken (0.1.1)
5
5
  bitcoin-ruby (~> 0.0.18)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -22,17 +22,17 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
+ It uses bitcoin-ruby, but you can use Trezor or Electrum, the most important command is the script,
26
+ which you can obtain with token.hex,
27
+ then you can send it as an output with a scriptPubKey and a value of 0.
28
+ In order to crate a token you need two outputs,
29
+ the change address with an amount less than original (for fees)
30
+ and the other one for the script. To send money you need three outputs,
31
+ the change address, the address who owns the recipient token and the script.
32
+
25
33
  ### Create token and send it to the blockchain
26
34
 
27
35
  ```ruby
28
- # It uses bitcoin-ruby, but you can use Trezor or Electrum, the most important command is the script,
29
- # which you can obtain with token.hex,
30
- # then you can send it as an output with a scriptPubKey and a value of 0.
31
- # In order to crate a token you need two outputs,
32
- # the change address with an amount less than original (for fees)
33
- # and the other one for the script. To send money you need three outputs,
34
- # the change address, the address who owns the recipient token and the script.
35
-
36
36
  Bitcoin.network = :testnet3
37
37
  token = Keoken::Token.new(name: "test-keoken-bitex")
38
38
  token.create(1_000_000)
@@ -0,0 +1,55 @@
1
+ module Keoken
2
+ module Backend
3
+ class Base
4
+ attr_accessor :inputs, :bitprim_transaction
5
+
6
+ def initialize
7
+ @inputs = []
8
+ @bitprim_transaction = Keoken::Bitprim::Transaction.new
9
+ end
10
+
11
+ protected
12
+
13
+ def build_inputs(address)
14
+ utxos = bitprim_transaction.utxos(address)
15
+ utxos.each do |utxo|
16
+ txid = utxo['txid']
17
+ transaction = bitprim_transaction.tx(txid)
18
+ outputs = transaction['vout'].select do |vout|
19
+ addresses = vout['scriptPubKey']['addresses']
20
+ if addresses
21
+ addresses.any? { |vout_address| vout_address == address }
22
+ end
23
+ end
24
+ raise Keoken::OutputNotFound if outputs.empty?
25
+ output = outputs.first
26
+ @inputs.push(
27
+ tx_id: txid,
28
+ position: output['n'],
29
+ input_script: output['scriptPubKey']['hex'],
30
+ input_amount: output['value'].sub!(/\./, '').sub!(/^0+/, '').to_i
31
+ )
32
+ end
33
+ end
34
+
35
+ def build_fee(type)
36
+ total = @inputs.map { |input| input[:input_amount].to_i }.inject(:+)
37
+ estimate_fee = @bitprim_transaction.estimate_fee.to_f
38
+ [total,
39
+ ((10 + 149 * @inputs.length + 35 * output_length(type)) * estimate_fee)
40
+ .to_s[0..9].sub!(/\./, '').sub!(/0+/, '')]
41
+ end
42
+
43
+ private
44
+
45
+ def output_length(type)
46
+ case type
47
+ when :create
48
+ 2
49
+ when :send
50
+ 3
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,9 +1,9 @@
1
1
  module Keoken
2
2
  module Backend
3
3
  module BitcoinRuby
4
- class Transaction
4
+ class Transaction < Keoken::Backend::Base
5
5
  attr_accessor :to_json, :raw
6
- extend Bitcoin::Builder
6
+ include Bitcoin::Builder
7
7
 
8
8
  # Create the transaction to broadcast in order to create tokens.
9
9
  #
@@ -13,7 +13,7 @@ module Keoken
13
13
  #
14
14
  # @return [Keoken::Backend::BitcoinRuby::Transaction] An object instanciated with the transaction to broadcast.
15
15
  #
16
- def self.build_for_creation(address, key, script)
16
+ def build_for_creation(address, key, script)
17
17
  build(address, nil, key, script, :create)
18
18
  end
19
19
 
@@ -26,7 +26,7 @@ module Keoken
26
26
  #
27
27
  # @return [Keoken::Backend::BitcoinRuby::Transaction] An object instanciated with the transaction to broadcast.
28
28
  #
29
- def self.build_for_send_amount(address, address_dest, key, script)
29
+ def build_for_send_amount(address, address_dest, key, script)
30
30
  build(address, address_dest, key, script, :send)
31
31
  end
32
32
 
@@ -40,39 +40,17 @@ module Keoken
40
40
  #
41
41
  # @return [Keoken::Backend::BitcoinRuby::Transaction] An object instanciated with the transaction to broadcast.
42
42
  #
43
- def self.build(address, addr2, key, script, type)
44
- bitprim_transaction = Keoken::Bitprim::Transaction.new
45
- utxos = bitprim_transaction.utxos(address)
46
- inputs = []
47
- utxos.each do |utxo|
48
- txid = utxo['txid']
49
- transaction = bitprim_transaction.tx(txid)
50
- outputs = transaction['vout'].select do |vout|
51
- addresses = vout['scriptPubKey']['addresses']
52
- if addresses
53
- addresses.any? { |vout_address| vout_address == address }
54
- end
55
- end
56
- raise Keoken::OutputNotFound if outputs.empty?
57
- output = outputs.first
58
- inputs.push(
59
- tx_id: txid,
60
- position: output['n'],
61
- input_script: output['scriptPubKey']['hex'],
62
- input_amount: output['value'].sub!(/\./, '').sub!(/^0+/, '').to_i
63
- )
64
- end
65
- total = inputs.map { |input| input[:input_amount].to_i }.inject(:+)
66
- estimate_fee = bitprim_transaction.estimate_fee.to_f
67
- fee = ((10 + 149 * inputs.length + 35 * output_length(type)) * estimate_fee).to_s[0..9].sub!(/\./, '').sub!(/0+/, '')
43
+ def build(address, addr2, key, script, type)
44
+ build_inputs(address)
45
+ total, fee = build_fee(type)
68
46
  case type
69
47
  when :create
70
48
  output_amount = total - fee.to_i
71
- create(inputs, output_amount, key.addr, key, script)
49
+ create(@inputs, output_amount, key.addr, key, script)
72
50
  when :send
73
51
  output_amount = total - (fee.to_i * 2)
74
52
  output_amount_to_addr2 = fee.to_i
75
- send_amount(inputs, output_amount, key.addr, output_amount_to_addr2, addr2, key, script)
53
+ send_amount(@inputs, output_amount, key.addr, output_amount_to_addr2, addr2, key, script)
76
54
  end
77
55
  end
78
56
 
@@ -86,8 +64,7 @@ module Keoken
86
64
  #
87
65
  # @return [Keoken::Backend::BitcoinRuby::Transaction] An object instanciated with the transaction to broadcast.
88
66
  #
89
- def self.create(inputs, output_amount, output_address, key, script)
90
- token = new
67
+ def create(inputs, output_amount, output_address, key, script)
91
68
  tx = build_tx do |t|
92
69
  inputs.each do |input|
93
70
  t.input do |i|
@@ -106,9 +83,9 @@ module Keoken
106
83
  o.to(script, :custom)
107
84
  end
108
85
  end
109
- token.to_json = tx.to_json
110
- token.raw = tx.to_payload.bth
111
- token
86
+ @to_json = tx.to_json
87
+ @raw = tx.to_payload.bth
88
+ self
112
89
  end
113
90
 
114
91
  # Create the transaction to broadcast in order to send amount between tokens.
@@ -123,8 +100,7 @@ module Keoken
123
100
  #
124
101
  # @return [Keoken::Backend::BitcoinRuby::Transaction] An object instanciated with the transaction to broadcast.
125
102
  #
126
- def self.send_amount(inputs, output_amount, output_address, output_amount_to_addr2, addr2, key, script)
127
- token = self.new
103
+ def send_amount(inputs, output_amount, output_address, output_amount_to_addr2, addr2, key, script)
128
104
  tx = build_tx do |t|
129
105
  inputs.each do |input|
130
106
  t.input do |i|
@@ -149,18 +125,9 @@ module Keoken
149
125
  o.to(script, :custom)
150
126
  end
151
127
  end
152
- token.to_json = tx.to_json
153
- token.raw = tx.to_payload.bth
154
- token
155
- end
156
-
157
- def self.output_length(type)
158
- case type
159
- when :create
160
- 2
161
- when :send
162
- 3
163
- end
128
+ @to_json = tx.to_json
129
+ @raw = tx.to_payload.bth
130
+ self
164
131
  end
165
132
  end
166
133
  end
@@ -0,0 +1,100 @@
1
+ module Keoken
2
+ module Backend
3
+ module Trezor
4
+ class Transaction < Keoken::Backend::Base
5
+ attr_accessor :to_json
6
+
7
+ # Create the transaction to broadcast in order to create tokens.
8
+ #
9
+ # @param address [String] Address that will contain the token.
10
+ # @param path [Array] Address derivation path.
11
+ # @param script [String] The token script.
12
+ #
13
+ # @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
14
+ #
15
+ def build_for_creation(address, path, script)
16
+ build_inputs(address)
17
+ total, fee = build_fee(type)
18
+ output_amount = total - fee.to_i
19
+ create(@inputs, path, address, output_amount, script)
20
+ end
21
+
22
+ # Create the transaction to broadcast in order to send amount between tokens.
23
+ #
24
+ # @param address [String] Address that will contain the token.
25
+ # @param address_dest [String] Address to receive the tokens.
26
+ # @param path [Array] Address derivation path.
27
+ # @param script [String] The token script.
28
+ #
29
+ # @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
30
+ #
31
+ def build_for_send_amount(address, address_dest, path, script)
32
+ build_inputs(address)
33
+ total, fee = build_fee(type)
34
+ output_amount = total - (fee.to_i * 2)
35
+ output_amount_to_addr2 = fee.to_i
36
+ send(@inputs, path, output_amount, address, output_amount_to_addr2, address_dest, script)
37
+ end
38
+
39
+ private
40
+
41
+ def create(inputs, path, address, output_amount, script)
42
+ {
43
+ inputs:
44
+ inputs.map do |input|
45
+ {
46
+ address_n: path,
47
+ prev_index: input[:position],
48
+ prev_hash: input[:tx_id],
49
+ amount: input[:input_amount]
50
+ }
51
+ end,
52
+ outputs: [
53
+ {
54
+ address: address,
55
+ amount: output_amount,
56
+ script_type: 'PAYTOADDRESS'
57
+ },
58
+ {
59
+ op_return_data: script,
60
+ amount: '0',
61
+ script_type: 'PAYTOOPRETURN'
62
+ }
63
+ ]
64
+ }
65
+ end
66
+
67
+ def send(inputs, path, output_amount, address, output_amount_to_addr2, addr2, script)
68
+ {
69
+ inputs:
70
+ inputs.map do |input|
71
+ {
72
+ address_n: path,
73
+ prev_index: input[:position],
74
+ prev_hash: input[:tx_id],
75
+ amount: input[:input_amount]
76
+ }
77
+ end,
78
+ outputs: [
79
+ {
80
+ address: address,
81
+ amount: output_amount,
82
+ script_type: 'PAYTOADDRESS'
83
+ },
84
+ {
85
+ address: addr2,
86
+ amount: output_amount_to_addr2,
87
+ script_type: 'PAYTOADDRESS'
88
+ },
89
+ {
90
+ op_return_data: script,
91
+ amount: '0',
92
+ script_type: 'PAYTOOPRETURN'
93
+ }
94
+ ]
95
+ }
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,7 @@
1
+ module Keoken
2
+ class DataNotParsed < StandardError
3
+ def initialize(msg = 'Data can not be parsed')
4
+ super
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,53 @@
1
+ module Keoken
2
+ class Parser
3
+ attr_accessor :data, :transaction_type, :name, :amount
4
+ def initialize(script)
5
+ binary = script.htb
6
+ @data = binary.bytes
7
+ end
8
+
9
+ def prefix
10
+ result = @data.slice!(0)
11
+ raise Keoken::DataNotParsed, 'OP_RETURN missing' unless result == Bitcoin::Script::OP_RETURN.to_i
12
+ result = @data.slice!(0)
13
+ raise Keoken::DataNotParsed, 'Prefix size missing' unless result == Keoken::PREFIX_SIZE.to_i
14
+ result = @data.slice!(0..Keoken::PREFIX.htb.bytes.length - 1)
15
+ raise Keoken::DataNotParsed, 'Prefix not provided' unless result == Keoken::PREFIX.htb.bytes
16
+ bytesize = @data.slice!(0)
17
+ raise Keoken::DataNotParsed, 'Bytesize not provided' unless bytesize == @data.length
18
+ end
19
+
20
+ def set_transaction_type
21
+ result = @data.slice!(0..3).join
22
+ @transaction_type = if result == Keoken::TYPE_CREATE_ASSET
23
+ :create
24
+ elsif result == Keoken::TYPE_SEND_TOKEN
25
+ :send
26
+ else
27
+ raise Keoken::DataNotParsed, 'Transaction type not valid'
28
+ end
29
+ @transaction_type
30
+ end
31
+
32
+ def name_or_id
33
+ name = []
34
+ end_of_name = false
35
+ loop do
36
+ tmp = @data.slice!(0)
37
+ end_of_name ||= tmp > 0
38
+ next if tmp.zero? && !end_of_name
39
+ break if tmp.zero? && end_of_name
40
+ name.push tmp
41
+ end
42
+ if @transaction_type == :create
43
+ name.map { |n| n.to_s(16).htb }.join
44
+ elsif @transaction_type == :send
45
+ name.map { |n| n.to_s(16) }.join
46
+ end
47
+ end
48
+
49
+ def amount
50
+ @data.map { |byte| byte.zero? ? "#{byte}0" : byte.to_s }.join.to_i
51
+ end
52
+ end
53
+ end
data/lib/keoken/token.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Keoken
2
2
  class Token
3
- attr_accessor :hex, :name, :id
3
+ attr_accessor :data_script, :name, :id, :amount, :transaction_type
4
4
 
5
5
  # Creates a new token object.
6
6
  #
@@ -9,8 +9,8 @@ module Keoken
9
9
  # @option options [Number] :id The id of token to obtain an amount to send to another address.
10
10
  #
11
11
  def initialize(options = {})
12
- @name = options[:name]
13
- @id = options[:id]
12
+ @name = options[:name]
13
+ @id = options[:id]
14
14
  end
15
15
 
16
16
  # Generate the script to create a token.
@@ -21,17 +21,13 @@ module Keoken
21
21
  #
22
22
  def create(amount)
23
23
  raise Keoken::NameNotFound unless @name
24
- data_script =
25
- [Keoken::VERSION_NODE,
26
- Keoken::TYPE_CREATE_ASSET,
27
- name_to_hex(@name),
28
- Keoken::PREFIX_BYTE_AMOUNT[0..(Keoken::AMOUNT_SIZE - amount.to_s.length - 1)] + amount.to_s].flatten.join
29
- data_length = data_script.htb.bytesize.to_s(16)
30
-
31
- @hex = [Bitcoin::Script::OP_RETURN.to_s(16),
32
- Keoken::PREFIX_SIZE,
33
- Keoken::PREFIX,
34
- data_length].join + data_script
24
+ @data_script =
25
+ [
26
+ Keoken::VERSION_NODE,
27
+ Keoken::TYPE_CREATE_ASSET,
28
+ name_to_hex(@name),
29
+ Keoken::PREFIX_BYTE_AMOUNT[0..prefix_length(amount)] + amount.to_s
30
+ ].flatten.join
35
31
  self
36
32
  end
37
33
 
@@ -43,25 +39,77 @@ module Keoken
43
39
  #
44
40
  def send_amount(amount)
45
41
  raise Keoken::IdNotFound unless @id
46
- data_script =
47
- [Keoken::VERSION_NODE,
48
- Keoken::TYPE_SEND_TOKEN,
49
- Keoken::PREFIX_BYTE_ASSET_ID[0..(Keoken::ASSET_ID_SIZE - @id.to_s.length - 1)] + @id.to_s,
50
- Keoken::PREFIX_BYTE_AMOUNT[0..(Keoken::AMOUNT_SIZE - amount.to_s.length - 1)] + amount.to_s].flatten.join
42
+ asset_length = Keoken::ASSET_ID_SIZE - @id.to_s.length - 1
43
+ @data_script =
44
+ [
45
+ Keoken::VERSION_NODE,
46
+ Keoken::TYPE_SEND_TOKEN,
47
+ Keoken::PREFIX_BYTE_ASSET_ID[0..asset_length] + @id.to_s,
48
+ Keoken::PREFIX_BYTE_AMOUNT[0..prefix_length(amount)] + amount.to_s
49
+ ].flatten.join
50
+ self
51
+ end
51
52
 
52
- data_length = data_script.htb.bytesize.to_s(16)
53
+ # Hexadecimal value of script.
54
+ #
55
+ # @return [String] Hexadecimal value of script token.
56
+ def hex
57
+ [
58
+ Bitcoin::Script::OP_RETURN.to_s(16),
59
+ Keoken::PREFIX_SIZE,
60
+ Keoken::PREFIX,
61
+ data_length
62
+ ].join + @data_script
63
+ end
53
64
 
54
- @hex = [Bitcoin::Script::OP_RETURN.to_s(16),
55
- Keoken::PREFIX_SIZE,
56
- Keoken::PREFIX,
57
- data_length].join + data_script
58
- self
65
+ # JSON serialization of object
66
+ #
67
+ # return [String] JSON serialization of token object.
68
+ def to_json
69
+ {
70
+ id: @id,
71
+ name: @name,
72
+ amount: @amount,
73
+ transaction_type: @transaction_type
74
+ }.to_json
75
+ end
76
+
77
+ # Deserialization of object
78
+ #
79
+ # return [Hash] Deserialization of token object.
80
+ def to_hash
81
+ {
82
+ id: @id,
83
+ name: @name,
84
+ amount: @amount,
85
+ transaction_type: @transaction_type
86
+ }
87
+ end
88
+
89
+ def parse_script(script)
90
+ parser = Keoken::Parser.new(script)
91
+ parser.prefix
92
+ @transaction_type = parser.set_transaction_type
93
+ if @transaction_type == :create
94
+ @name = parser.name_or_id
95
+ else
96
+ @id = parser.name_or_id
97
+ end
98
+ @amount = parser.amount
59
99
  end
60
100
 
61
101
  private
62
102
 
103
+ def data_length
104
+ @data_script.htb.bytesize.to_s(16)
105
+ end
106
+
107
+ def prefix_length(amount)
108
+ Keoken::AMOUNT_SIZE - amount.to_s.length - 1
109
+ end
110
+
63
111
  def name_to_hex(name)
64
- asset_bytes = name.bytes.map{|n| n.to_s(16)}
112
+ asset_bytes = name.bytes.map { |n| n.to_s(16) }
65
113
  asset_bytes + ['00']
66
114
  end
67
115
  end
@@ -1,3 +1,3 @@
1
1
  module Keoken
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'.freeze
3
3
  end
data/lib/keoken.rb CHANGED
@@ -2,19 +2,22 @@ require 'bitcoin'
2
2
 
3
3
  require 'keoken/extensions/bitcoin/script'
4
4
  require 'keoken/token'
5
+ require 'keoken/parser'
6
+ require 'keoken/backend/base'
5
7
  require 'keoken/backend/bitcoin_ruby/transaction'
6
8
  require 'keoken/bitprim/transaction'
7
9
  require 'keoken/errors/id_not_found'
8
10
  require 'keoken/errors/name_not_found'
11
+ require 'keoken/errors/data_not_parsed'
9
12
 
10
13
  module Keoken
11
- PREFIX_SIZE = '04'
12
- PREFIX = '00004b50'
13
- VERSION_NODE = '0000'
14
- TYPE_CREATE_ASSET = '0000'
15
- TYPE_SEND_TOKEN = '0001'
16
- PREFIX_BYTE_AMOUNT = '0000000000000000'
14
+ PREFIX_SIZE = '04'.freeze
15
+ PREFIX = '00004b50'.freeze
16
+ VERSION_NODE = '0000'.freeze
17
+ TYPE_CREATE_ASSET = '0000'.freeze
18
+ TYPE_SEND_TOKEN = '0001'.freeze
19
+ PREFIX_BYTE_AMOUNT = '0000000000000000'.freeze
17
20
  AMOUNT_SIZE = 16
18
- PREFIX_BYTE_ASSET_ID = '00000000'
21
+ PREFIX_BYTE_ASSET_ID = '00000000'.freeze
19
22
  ASSET_ID_SIZE = 8
20
23
  end
data/spec/keoken_spec.rb CHANGED
@@ -1,11 +1,11 @@
1
- require "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Keoken do
4
- it "has a version number" do
4
+ it 'has a version number' do
5
5
  expect(Keoken::VERSION).not_to be nil
6
6
  end
7
7
 
8
- it "defines keoken constants" do
8
+ it 'defines keoken constants' do
9
9
  expect(Keoken::PREFIX_SIZE).not_to be nil
10
10
  expect(Keoken::PREFIX).not_to be nil
11
11
  expect(Keoken::VERSION_NODE).not_to be nil
@@ -17,33 +17,67 @@ describe Keoken do
17
17
  expect(Keoken::ASSET_ID_SIZE).not_to be nil
18
18
  end
19
19
 
20
- it "creates the test-keoken token" do
21
- token = Keoken::Token.new(name: "test-keoken")
20
+ it 'creates the test-keoken token' do
21
+ token = Keoken::Token.new(name: 'test-keoken')
22
22
  token.create(1_000_000)
23
23
  expect(token.hex).to(
24
- eq("6a0400004b501800000000746573742d6b656f6b656e000000000001000000")
24
+ eq('6a0400004b501800000000746573742d6b656f6b656e000000000001000000')
25
25
  )
26
26
  end
27
27
 
28
- it "raise an error when name is not provided" do
28
+ it 'serialize the test-keoken token' do
29
+ token = Keoken::Token.new
30
+ token.parse_script('6a0400004b501800000000746573742d6b656f6b656e000000000001000000')
31
+ expect(token.to_json).to(
32
+ eq('{"id":null,"name":"test-keoken","amount":1000000,"transaction_type":"create"}')
33
+ )
34
+ end
35
+
36
+ it 'deserialize the test-keoken token' do
37
+ token = Keoken::Token.new
38
+ token.parse_script('6a0400004b501800000000746573742d6b656f6b656e000000000001000000')
39
+ expect(token.to_hash).to(
40
+ eq(
41
+ amount: 1_000_000,
42
+ name: 'test-keoken',
43
+ id: nil,
44
+ transaction_type: :create
45
+ )
46
+ )
47
+ end
48
+
49
+ it 'deserialize the token with id' do
50
+ token = Keoken::Token.new
51
+ token.parse_script('6a0400004b501000000001000000340000000001000000')
52
+ expect(token.to_hash).to(
53
+ eq(
54
+ amount: 1_000_000,
55
+ name: nil,
56
+ id: '34',
57
+ transaction_type: :send
58
+ )
59
+ )
60
+ end
61
+
62
+ it 'raise an error when name is not provided' do
29
63
  token = Keoken::Token.new
30
64
  expect { token.create(1_000_000) }.to raise_error(Keoken::NameNotFound)
31
65
  end
32
66
 
33
- it "raise an error when id is not provided" do
67
+ it 'raise an error when id is not provided' do
34
68
  token = Keoken::Token.new
35
69
  expect { token.send_amount(1_000_000) }.to raise_error(Keoken::IdNotFound)
36
70
  end
37
71
 
38
- it "send 1_000_000 to token with 34 id" do
72
+ it 'send 1_000_000 to token with 34 id' do
39
73
  token = Keoken::Token.new(id: 34)
40
74
  token.send_amount(1_000_000)
41
75
  expect(token.hex).to(
42
- eq("6a0400004b501000000001000000340000000001000000")
76
+ eq('6a0400004b501000000001000000340000000001000000')
43
77
  )
44
78
  end
45
79
 
46
- describe "creates token" do
80
+ describe 'creates token' do
47
81
  before(:each) do
48
82
  mock_requests
49
83
  Bitcoin.network = :testnet3
@@ -51,7 +85,8 @@ describe Keoken do
51
85
  token.create(1_000_000)
52
86
  key = Bitcoin::Key.from_base58('cShKfHoHVf6iKKZym18ip1MJFQFxJwbcLxW53MQikxdDsGd2oxBU')
53
87
  script = token.hex
54
- @transaction_token = Keoken::Backend::BitcoinRuby::Transaction.build_for_creation(key.addr, key, script)
88
+ @transaction_token = Keoken::Backend::BitcoinRuby::Transaction.new
89
+ @transaction_token.build_for_creation(key.addr, key, script)
55
90
  end
56
91
 
57
92
  it "format to_json" do
@@ -72,22 +107,26 @@ describe Keoken do
72
107
  )
73
108
  end
74
109
 
75
- it "raw transaction" do
110
+ it 'raw transaction' do
76
111
  raw = @transaction_token.raw
77
- expect(raw).to start_with("0100000001dae8143d5422d5e1018c43732baa74ac3114d4399a1f58a9ea7e31f656938a44010000006")
78
- expect(raw).to end_with("6a0400004b501800000000746573742d6b656f6b656e00000000000100000000000000")
112
+ expect(raw).to start_with('0100000001dae8143d5422d5e1018c43732baa74ac3114d4399a1f58a9ea7e31f656938a44010000006')
113
+ expect(raw).to end_with('6a0400004b501800000000746573742d6b656f6b656e00000000000100000000000000')
79
114
  end
80
115
 
81
- it "broadcast transaction" do
82
- stub_request(:post, "https://tbch.blockdozer.com/insight-api/tx/send")
83
- .with(:body => {"rawtx" => /0100000001dae8143d5422d5e1018c43732baa74ac3114d4399a1f58a9ea7e31f656938a44010000006/},
84
- headers: {
85
- "Accept" => "*/*",
86
- "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
87
- "Content-Type" => "application/x-www-form-urlencoded",
88
- "Host" => "tbch.blockdozer.com",
89
- "User-Agent" => "Ruby",
90
- })
116
+ it 'broadcast transaction' do
117
+ stub_request(:post, 'https://tbch.blockdozer.com/insight-api/tx/send')
118
+ .with(
119
+ body:
120
+ {
121
+ 'rawtx' => /0100000001dae8143d5422d5e1018c43732baa74ac3114d4399a1f58a9ea7e31f656938a44010000006/
122
+ },
123
+ headers: {
124
+ "Accept" => "*/*",
125
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
126
+ "Content-Type" => "application/x-www-form-urlencoded",
127
+ "Host" => "tbch.blockdozer.com",
128
+ "User-Agent" => "Ruby",
129
+ })
91
130
  .to_return(status: 200, body: "{\"txid\":\"f410c773d079327b8283c175b08a84faa6ffcfbde40b5939b85f07f0dfde2eb8\"}", headers: {})
92
131
  transaction = Keoken::Bitprim::Transaction.new
93
132
  expect(transaction.send_tx(@transaction_token.raw)).to eq({"txid" => "f410c773d079327b8283c175b08a84faa6ffcfbde40b5939b85f07f0dfde2eb8"})
@@ -104,7 +143,8 @@ describe Keoken do
104
143
  token.send_amount(500_000)
105
144
  key = Bitcoin::Key.from_base58('cShKfHoHVf6iKKZym18ip1MJFQFxJwbcLxW53MQikxdDsGd2oxBU')
106
145
  script = token.hex
107
- @transaction_token = Keoken::Backend::BitcoinRuby::Transaction.build_for_send_amount(key.addr, 'mnTd41YZ1e1YqsaPNJh3wkeSUrFvp1guzi', key, script)
146
+ @transaction_token = Keoken::Backend::BitcoinRuby::Transaction.new
147
+ @transaction_token.build_for_send_amount(key.addr, 'mnTd41YZ1e1YqsaPNJh3wkeSUrFvp1guzi', key, script)
108
148
  end
109
149
 
110
150
  it "format to_json" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keoken
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bitex
@@ -116,6 +116,7 @@ extra_rdoc_files: []
116
116
  files:
117
117
  - ".gitignore"
118
118
  - ".rspec"
119
+ - ".rubocop.yml"
119
120
  - ".travis.yml"
120
121
  - ".yardoc/checksums"
121
122
  - ".yardoc/complete"
@@ -153,13 +154,17 @@ files:
153
154
  - doc/top-level-namespace.html
154
155
  - keoken.gemspec
155
156
  - lib/keoken.rb
157
+ - lib/keoken/backend/base.rb
156
158
  - lib/keoken/backend/bitcoin_ruby/transaction.rb
159
+ - lib/keoken/backend/trezor/transaction.rb
157
160
  - lib/keoken/bitprim/config.yaml
158
161
  - lib/keoken/bitprim/transaction.rb
162
+ - lib/keoken/errors/data_not_parsed.rb
159
163
  - lib/keoken/errors/id_not_found.rb
160
164
  - lib/keoken/errors/name_not_found.rb
161
165
  - lib/keoken/errors/output_not_found.rb
162
166
  - lib/keoken/extensions/bitcoin/script.rb
167
+ - lib/keoken/parser.rb
163
168
  - lib/keoken/token.rb
164
169
  - lib/keoken/version.rb
165
170
  - spec/keoken_spec.rb