keoken 0.3.2 → 0.4.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 +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
|