keoken 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +2 -0
- data/Gemfile.lock +1 -1
- data/lib/keoken/backend/base.rb +38 -21
- data/lib/keoken/backend/bitcoin_ruby/transaction.rb +1 -1
- data/lib/keoken/backend/trezor/transaction.rb +79 -29
- data/lib/keoken/errors/no_token.rb +9 -0
- data/lib/keoken/errors/output_not_found.rb +0 -1
- data/lib/keoken/token.rb +1 -2
- data/lib/keoken/version.rb +1 -1
- data/spec/keoken_spec.rb +101 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 36a966435a46a152f5aee0c5c00a304c64031c140e1b2ff5b507a6744eb3d3f6
|
4
|
+
data.tar.gz: 735d9de726b7242405f69810b4c90b0b21778e7748eb32cbcc2da37cbfd1f921
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbae48063498f66dd47fb7c2cc65a8fdb107450d1dd6895610eb60db50e86f96b10327f2b9ea8f0db05dbb0a5f34144138b14d89e7148af392a51f6489ed60a7
|
7
|
+
data.tar.gz: b74a780b42b28c763a17f68d210d8c3db8aefb2a54fc3d8959d6b6348d0c159e6351ca8d2c6eb227567db6dcd3b2d979c4ff35bd455b5db41b1de621e8f65b7c
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
data/lib/keoken/backend/base.rb
CHANGED
@@ -1,35 +1,28 @@
|
|
1
1
|
module Keoken
|
2
2
|
module Backend
|
3
3
|
class Base
|
4
|
-
attr_accessor :inputs, :bitprim_transaction, :total_inputs_amount
|
4
|
+
attr_accessor :inputs, :bitprim_transaction, :total_inputs_amount, :tokens
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@inputs = []
|
8
|
+
@tokens = []
|
9
|
+
@total_inputs_amount = 0
|
8
10
|
@bitprim_transaction = Keoken::Bitprim::Transaction.new
|
9
11
|
end
|
10
12
|
|
11
13
|
protected
|
12
14
|
|
13
|
-
def build_inputs(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
output = outputs.first
|
25
|
-
amount = output['value'].sub!(/\./, '').sub!(/^0+/, '').to_i
|
26
|
-
@inputs.push(
|
27
|
-
tx_id: txid,
|
28
|
-
position: output['n'],
|
29
|
-
input_script: output['scriptPubKey']['hex'],
|
30
|
-
input_amount: amount
|
31
|
-
)
|
32
|
-
@total_inputs_amount += amount
|
15
|
+
def build_inputs(addresses)
|
16
|
+
addresses.each do |address|
|
17
|
+
@total_inputs_amount =
|
18
|
+
bitprim_transaction.utxos(address).inject(0) do |previous_amount, utxo|
|
19
|
+
txid = utxo['txid']
|
20
|
+
transaction = bitprim_transaction.tx(txid)
|
21
|
+
add_script_token(transaction['vout'])
|
22
|
+
output = output_for_input(txid, transaction['vout'], addresses)
|
23
|
+
@inputs.push(output)
|
24
|
+
previous_amount + output[:input_amount]
|
25
|
+
end
|
33
26
|
end
|
34
27
|
end
|
35
28
|
|
@@ -49,6 +42,30 @@ module Keoken
|
|
49
42
|
3
|
50
43
|
end
|
51
44
|
end
|
45
|
+
|
46
|
+
def add_script_token(outputs)
|
47
|
+
outputs.each do |vout|
|
48
|
+
if vout['scriptPubKey']['asm'].split.first == 'OP_RETURN'
|
49
|
+
@tokens.push(Token.new(script: vout['scriptPubKey']['hex']))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def output_for_input(txid, outputs, addresses)
|
55
|
+
output = nil
|
56
|
+
outputs.each do |vout|
|
57
|
+
next if (vout['scriptPubKey']['addresses'].to_a & addresses).empty?
|
58
|
+
output =
|
59
|
+
{
|
60
|
+
tx_id: txid,
|
61
|
+
position: vout['n'],
|
62
|
+
input_script: vout['scriptPubKey']['hex'],
|
63
|
+
input_amount: vout['value'].sub!(/\./, '').sub!(/^0+/, '').to_i
|
64
|
+
}
|
65
|
+
end
|
66
|
+
raise Keoken::Error::OutputNotFound unless output
|
67
|
+
output
|
68
|
+
end
|
52
69
|
end
|
53
70
|
end
|
54
71
|
end
|
@@ -41,7 +41,7 @@ module Keoken
|
|
41
41
|
# @return [Keoken::Backend::BitcoinRuby::Transaction] An object instanciated with the transaction to broadcast.
|
42
42
|
#
|
43
43
|
def build(address, addr2, key, script, type)
|
44
|
-
build_inputs(address)
|
44
|
+
build_inputs([address])
|
45
45
|
total, fee = build_fee(type)
|
46
46
|
case type
|
47
47
|
when :create
|
@@ -16,10 +16,15 @@ module Keoken
|
|
16
16
|
# @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
|
17
17
|
#
|
18
18
|
def build_for_creation(address, path, script, xpubs = [])
|
19
|
-
build_inputs(address)
|
19
|
+
build_inputs([address])
|
20
20
|
total, fee = build_fee(:create)
|
21
21
|
output_amount = total - fee.to_i
|
22
|
-
create(@inputs,
|
22
|
+
create(inputs: @inputs,
|
23
|
+
path: path,
|
24
|
+
address: address,
|
25
|
+
output_amount: output_amount,
|
26
|
+
script: script,
|
27
|
+
xpubs: xpubs)
|
23
28
|
end
|
24
29
|
|
25
30
|
# Create the transaction to broadcast in order to send amount between tokens.
|
@@ -33,26 +38,57 @@ module Keoken
|
|
33
38
|
# @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
|
34
39
|
#
|
35
40
|
def build_for_send_amount(address, address_dest, path, script, xpubs = [])
|
36
|
-
build_inputs(address)
|
41
|
+
build_inputs([address])
|
37
42
|
total, fee = build_fee(:send)
|
38
43
|
output_amount = total - (fee.to_i * 2)
|
39
44
|
output_amount_to_addr2 = fee.to_i
|
40
|
-
send(@inputs,
|
45
|
+
send(inputs: @inputs,
|
46
|
+
path: path,
|
47
|
+
output_amount: output_amount,
|
48
|
+
address: address,
|
49
|
+
output_amount_to_addr2: output_amount_to_addr2,
|
50
|
+
addr2: address_dest,
|
51
|
+
script: script,
|
52
|
+
xpubs: xpubs)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Create the transaction to broadcast in order to empty the wallet.
|
56
|
+
#
|
57
|
+
# @param addresses [Array] Addresses that will contain the token and will be emptied.
|
58
|
+
# @param address_dest [String] Address to receive the tokens.
|
59
|
+
# @param path [Array] Address derivation path.
|
60
|
+
# @param xpubs [Array] The xpubs corresponding to the multisig address.
|
61
|
+
#
|
62
|
+
# @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
|
63
|
+
#
|
64
|
+
def build_for_empty_wallet(addresses, address_dest, path, xpubs = [])
|
65
|
+
build_inputs(addresses)
|
66
|
+
total, fee = build_fee(:send)
|
67
|
+
raise Keoken::Error::NoToken if @tokens.empty?
|
68
|
+
|
69
|
+
send(inputs: @inputs,
|
70
|
+
path: path,
|
71
|
+
output_amount: total - (fee.to_i * 2),
|
72
|
+
address: nil,
|
73
|
+
output_amount_to_addr2: fee.to_i,
|
74
|
+
addr2: address_dest,
|
75
|
+
script: token_script_for_inputs,
|
76
|
+
xpubs: xpubs)
|
41
77
|
end
|
42
78
|
|
43
79
|
private
|
44
80
|
|
45
|
-
def create(
|
81
|
+
def create(options = {})
|
46
82
|
{
|
47
|
-
inputs: build_trezor_inputs(inputs, path, address, xpubs),
|
83
|
+
inputs: build_trezor_inputs(options[:inputs], options[:path], options[:address], options[:xpubs]),
|
48
84
|
outputs: [
|
49
85
|
{
|
50
|
-
address: Cashaddress.from_legacy(address),
|
51
|
-
amount: output_amount.to_s,
|
86
|
+
address: Cashaddress.from_legacy(options[:address]),
|
87
|
+
amount: options[:output_amount].to_s,
|
52
88
|
script_type: 'PAYTOADDRESS'
|
53
89
|
},
|
54
90
|
{
|
55
|
-
op_return_data: script,
|
91
|
+
op_return_data: options[:script],
|
56
92
|
amount: '0',
|
57
93
|
script_type: 'PAYTOOPRETURN'
|
58
94
|
}
|
@@ -60,26 +96,34 @@ module Keoken
|
|
60
96
|
}
|
61
97
|
end
|
62
98
|
|
63
|
-
def send(
|
99
|
+
def send(options = {})
|
100
|
+
first_output = if options[:address]
|
101
|
+
[
|
102
|
+
{
|
103
|
+
address: Cashaddress.from_legacy(options[:address]),
|
104
|
+
amount: options[:output_amount].to_s,
|
105
|
+
script_type: 'PAYTOADDRESS'
|
106
|
+
}
|
107
|
+
]
|
108
|
+
else
|
109
|
+
[]
|
110
|
+
end
|
64
111
|
{
|
65
|
-
inputs: build_trezor_inputs(inputs, path, address, xpubs),
|
66
|
-
outputs:
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
script_type: 'PAYTOOPRETURN'
|
81
|
-
}
|
82
|
-
]
|
112
|
+
inputs: build_trezor_inputs(options[:inputs], options[:path], options[:address], options[:xpubs]),
|
113
|
+
outputs: first_output.concat(
|
114
|
+
[
|
115
|
+
{
|
116
|
+
address: Cashaddress.from_legacy(options[:addr2]),
|
117
|
+
amount: options[:output_amount_to_addr2].to_s,
|
118
|
+
script_type: 'PAYTOADDRESS'
|
119
|
+
},
|
120
|
+
{
|
121
|
+
op_return_data: options[:script],
|
122
|
+
amount: '0',
|
123
|
+
script_type: 'PAYTOOPRETURN'
|
124
|
+
}
|
125
|
+
]
|
126
|
+
)
|
83
127
|
}
|
84
128
|
end
|
85
129
|
|
@@ -124,7 +168,13 @@ module Keoken
|
|
124
168
|
}
|
125
169
|
end
|
126
170
|
end
|
171
|
+
|
172
|
+
def token_script_for_inputs
|
173
|
+
token = Token.new(id: @tokens.first.id)
|
174
|
+
token.send_amount(@tokens.map(&:amount).inject(:+))
|
175
|
+
token.hex
|
176
|
+
end
|
127
177
|
end
|
128
178
|
end
|
129
179
|
end
|
130
|
-
end
|
180
|
+
end
|
data/lib/keoken/token.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Keoken
|
2
2
|
class Token < Parser
|
3
|
-
attr_accessor :data_script, :id
|
3
|
+
attr_accessor :data_script, :id, :amount
|
4
4
|
|
5
5
|
# Creates a new token object.
|
6
6
|
#
|
@@ -43,7 +43,6 @@ module Keoken
|
|
43
43
|
#
|
44
44
|
def send_amount(amount)
|
45
45
|
raise Keoken::Error::IdNotFound unless @id
|
46
|
-
asset_length = Keoken::ASSET_ID_SIZE - @id.to_s.length
|
47
46
|
@data_script =
|
48
47
|
[
|
49
48
|
Keoken::VERSION_NODE,
|
data/lib/keoken/version.rb
CHANGED
data/spec/keoken_spec.rb
CHANGED
@@ -323,6 +323,92 @@ describe Keoken do
|
|
323
323
|
)
|
324
324
|
)
|
325
325
|
end
|
326
|
+
|
327
|
+
it 'empty the wallet' do
|
328
|
+
mock_requests
|
329
|
+
allow(ENV).to receive(:[]).with('KEOKEN_NODE').and_return('PRODUCTION')
|
330
|
+
@transaction_token = Keoken::Backend::Trezor::Transaction.new
|
331
|
+
|
332
|
+
expect(
|
333
|
+
@transaction_token.build_for_empty_wallet(
|
334
|
+
['17wrMVCa9EJUVVEC3c5CZZanjT1NtWU2mX',
|
335
|
+
'32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ'],
|
336
|
+
'32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ',
|
337
|
+
[44, 145, 0, 0, 0],
|
338
|
+
['ypub6WrVGzkKFeNTTppAVe2KkY3yiohKNvFDZm7qAFKBAu8ozm2DYRmwoXwpQUAaEbLkCJmdGaYBLxBUbJcfeLZcwXEtF9neUCDXuWtVyFDApi6',
|
339
|
+
'ypub6WtFU3UPzgvu1AJzw9Quw6TgNp7FM5ro2AZwcwmkgP4HvdurTiGRSDYKV4YaofGny96xFykeNxJGgt8SiNwhFnBbdmwyiiLVRxoKWTeQnuB']
|
340
|
+
)
|
341
|
+
).to(
|
342
|
+
eq(
|
343
|
+
{:inputs=>
|
344
|
+
[{:address_n=>[44, 145, 0, 0, 0],
|
345
|
+
:prev_index=>1,
|
346
|
+
:prev_hash=>
|
347
|
+
"448a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da",
|
348
|
+
:amount=>"8985999",
|
349
|
+
:script_type=>"SPENDMULTISIG",
|
350
|
+
:multisig=>
|
351
|
+
{:signatures=>["", "", ""],
|
352
|
+
:m=>2,
|
353
|
+
:pubkeys=>
|
354
|
+
[{:address_n=>[44, 145, 0, 0, 0],
|
355
|
+
:node=>
|
356
|
+
{:chain_code=>
|
357
|
+
"7bd6545bf255444ba4cf93b893e56deacf59e0b8e065d44673e9afff4e3655c6",
|
358
|
+
:depth=>0,
|
359
|
+
:child_num=>0,
|
360
|
+
:fingerprint=>0,
|
361
|
+
:public_key=>
|
362
|
+
"03db551b0f0962d4cbbf15b6d81dd7dc0e82868867182ec15b1e5e28b90fac97c4"}},
|
363
|
+
{:address_n=>[44, 145, 0, 0, 0],
|
364
|
+
:node=>
|
365
|
+
{:chain_code=>
|
366
|
+
"4199329ed001a33fb58fd75bac23c80c0d38cedc009bac8f89c89df91c35bc8e",
|
367
|
+
:depth=>0,
|
368
|
+
:child_num=>0,
|
369
|
+
:fingerprint=>0,
|
370
|
+
:public_key=>
|
371
|
+
"02408f31733a184b6d0dd52a0800bf1a6b02102b9bfcc9c158b508365869c8c73d"}}]}},
|
372
|
+
{:address_n=>[44, 145, 0, 0, 0],
|
373
|
+
:prev_index=>1,
|
374
|
+
:prev_hash=>
|
375
|
+
"348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da",
|
376
|
+
:amount=>"8985999",
|
377
|
+
:script_type=>"SPENDMULTISIG",
|
378
|
+
:multisig=>
|
379
|
+
{:signatures=>["", "", ""],
|
380
|
+
:m=>2,
|
381
|
+
:pubkeys=>
|
382
|
+
[{:address_n=>[44, 145, 0, 0, 0],
|
383
|
+
:node=>
|
384
|
+
{:chain_code=>
|
385
|
+
"7bd6545bf255444ba4cf93b893e56deacf59e0b8e065d44673e9afff4e3655c6",
|
386
|
+
:depth=>0,
|
387
|
+
:child_num=>0,
|
388
|
+
:fingerprint=>0,
|
389
|
+
:public_key=>
|
390
|
+
"03db551b0f0962d4cbbf15b6d81dd7dc0e82868867182ec15b1e5e28b90fac97c4"}},
|
391
|
+
{:address_n=>[44, 145, 0, 0, 0],
|
392
|
+
:node=>
|
393
|
+
{:chain_code=>
|
394
|
+
"4199329ed001a33fb58fd75bac23c80c0d38cedc009bac8f89c89df91c35bc8e",
|
395
|
+
:depth=>0,
|
396
|
+
:child_num=>0,
|
397
|
+
:fingerprint=>0,
|
398
|
+
:public_key=>
|
399
|
+
"02408f31733a184b6d0dd52a0800bf1a6b02102b9bfcc9c158b508365869c8c73d"}}]}}],
|
400
|
+
:outputs=>
|
401
|
+
[{:address=>"bitcoincash:pqx3eghuvc7kmc4qkwg0qwfjqyedh3wg8qkwanr9pd",
|
402
|
+
:amount=>"124874",
|
403
|
+
:script_type=>"PAYTOADDRESS"},
|
404
|
+
{:op_return_data=>"6a0400004b5010000000010000001100000000000000c8",
|
405
|
+
:amount=>"0",
|
406
|
+
:script_type=>"PAYTOOPRETURN"}
|
407
|
+
]
|
408
|
+
}
|
409
|
+
)
|
410
|
+
)
|
411
|
+
end
|
326
412
|
end
|
327
413
|
end
|
328
414
|
|
@@ -347,6 +433,16 @@ def mock_requests
|
|
347
433
|
}).
|
348
434
|
to_return(:status => 200, :body => body_request, :headers => {})
|
349
435
|
|
436
|
+
body_request = "[{\"address\":\"32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ\",\"txid\":\"348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da\",\"vout\":1,\"scriptPubKey\":\"56a9147bb97684cc43e2f8ea0ed1d50dddce3ebf80063888ac\",\"amount\":0.07985999,\"satoshis\":8985999,\"height\":1282589,\"confirmations\":1356}]"
|
437
|
+
stub_request(:get, "https://bch.blockdozer.com/insight-api/addr/32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ/utxo").
|
438
|
+
with(:headers => {
|
439
|
+
"Accept" => "*/*",
|
440
|
+
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
|
441
|
+
"Host" => "bch.blockdozer.com",
|
442
|
+
"User-Agent" => "Ruby",
|
443
|
+
}).
|
444
|
+
to_return(:status => 200, :body => body_request, :headers => {})
|
445
|
+
|
350
446
|
body_request = "{\"txid\":\"448a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"48c158109ca432e109971ca61e4bccbdc2b51053c02f8183f5ca7f60a55df4d0\",\"vout\":0,\"sequence\":4294967295,\"n\":0,\"scriptSig\":{\"hex\":\"483045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480412102bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\",\"asm\":\"3045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480[ALL|FORKID] 02bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\"},\"addr\":\"mro9aqn4xCzXVS7jRFFuzT2ERKonvPdSDA\",\"valueSat\":9991999,\"value\":0.09991999,\"doubleSpentTxID\":null}],\"vout\":[{\"value\":\"0.01000000\",\"n\":0,\"scriptPubKey\":{\"hex\":\"76a9141a53f3efae04708754ca1c5382085249c0ff597d88ac\",\"asm\":\"OP_DUP OP_HASH160 1a53f3efae04708754ca1c5382085249c0ff597d OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"mhvASBxPioT6eLPtSA5u1SNoT49RsME3BJ\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.08985999\",\"n\":1,\"scriptPubKey\":{\"hex\":\"76a9147bb97684cc43e2f8ea0ed1d50dddce3ebf80063888ac\",\"asm\":\"OP_DUP OP_HASH160 7bb97684cc43e2f8ea0ed1d50dddce3ebf800638 OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"mro9aqn4xCzXVS7jRFFuzT2ERKonvPdSDA\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.00000000\",\"n\":2,\"scriptPubKey\":{\"hex\":\"6a0400004b501000000001000000170000000000000064\",\"asm\":\"OP_RETURN 1347092480 00000001000000170000000000000064\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null}],\"blockhash\":\"0000000000009505e41c238f88f5c9b5591e92f7eb68545962a5dd71cd075525\",\"blockheight\":1282589,\"confirmations\":1356,\"time\":1548360176,\"blocktime\":1548360176,\"valueOut\":0.09985999,\"size\":258,\"valueIn\":0.09991999,\"fees\":0.00006}"
|
351
447
|
stub_request(:get, "https://tbch.blockdozer.com/insight-api/tx/448a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da").
|
352
448
|
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'tbch.blockdozer.com', 'User-Agent'=>'Ruby'}).
|
@@ -357,6 +453,11 @@ def mock_requests
|
|
357
453
|
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'bch.blockdozer.com', 'User-Agent'=>'Ruby'}).
|
358
454
|
to_return(:status => 200, :body => body_request, :headers => {})
|
359
455
|
|
456
|
+
body_request = "{\"txid\":\"348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"58c158109ca432e109971ca61e4bccbdc2b51053c02f8183f5ca7f60a55df4d0\",\"vout\":0,\"sequence\":12345678,\"n\":0,\"scriptSig\":{\"hex\":\"483045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480412102bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\",\"asm\":\"3045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480[ALL|FORKID] 02bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\"},\"addr\":\"17wrMVCa9EJUVVEC3c5CZZanjT1NtWU2mX\",\"valueSat\":9991999,\"value\":0.09991999,\"doubleSpentTxID\":null}],\"vout\":[{\"value\":\"0.01000000\",\"n\":0,\"scriptPubKey\":{\"hex\":\"76a9141a53f3efae04708754ca1c5382085249c0ff597d88ac\",\"asm\":\"OP_DUP OP_HASH160 1a53f3efae04708754ca1c5382085249c0ff597d OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"mhvASBxPioT6eLPtSA5u1SNoT49RsME3BJ\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.08985999\",\"n\":1,\"scriptPubKey\":{\"hex\":\"76a9147bb97684cc43e2f8ea0ed1d50dddce3ebf80063888ac\",\"asm\":\"OP_DUP OP_HASH160 7bb97684cc43e2f8ea0ed1d50dddce3ebf800638 OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"17wrMVCa9EJUVVEC3c5CZZanjT1NtWU2mX\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.00000000\",\"n\":2,\"scriptPubKey\":{\"hex\":\"6a0400004b501000000001000000170000000000000064\",\"asm\":\"OP_RETURN 1347092480 00000001000000170000000000000064\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null}],\"blockhash\":\"0000000000009505e41c238f88f5c9b5591e92f7eb68545962a5dd71cd075525\",\"blockheight\":1282589,\"confirmations\":1356,\"time\":1548360176,\"blocktime\":1548360176,\"valueOut\":0.09985999,\"size\":258,\"valueIn\":0.09991999,\"fees\":0.00006}"
|
457
|
+
stub_request(:get, "https://bch.blockdozer.com/insight-api/tx/348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da").
|
458
|
+
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'bch.blockdozer.com', 'User-Agent'=>'Ruby'}).
|
459
|
+
to_return(:status => 200, :body => body_request, :headers => {})
|
460
|
+
|
360
461
|
stub_request(:get, "https://tbch.blockdozer.com/insight-api/utils/estimatefee").
|
361
462
|
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'tbch.blockdozer.com', 'User-Agent'=>'Ruby'}).
|
362
463
|
to_return(:status => 200, :body => "{\"2\":0.0001021}", :headers => {})
|
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.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bitex
|
@@ -186,6 +186,7 @@ files:
|
|
186
186
|
- lib/keoken/errors/data_not_parsed.rb
|
187
187
|
- lib/keoken/errors/id_not_found.rb
|
188
188
|
- lib/keoken/errors/name_not_found.rb
|
189
|
+
- lib/keoken/errors/no_token.rb
|
189
190
|
- lib/keoken/errors/output_not_found.rb
|
190
191
|
- lib/keoken/extensions/bitcoin/script.rb
|
191
192
|
- lib/keoken/parser.rb
|
@@ -213,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
213
214
|
version: '0'
|
214
215
|
requirements: []
|
215
216
|
rubyforge_project:
|
216
|
-
rubygems_version: 2.
|
217
|
+
rubygems_version: 2.7.7
|
217
218
|
signing_key:
|
218
219
|
specification_version: 4
|
219
220
|
summary: Keoken protocol implemented in Ruby
|