xgt-ruby 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +56 -0
- data/LICENSE.txt +21 -0
- data/README.md +45 -0
- data/Rakefile +6 -0
- data/bin/.wallet.swp +0 -0
- data/bin/setup +8 -0
- data/bin/wallet +438 -0
- data/examples/api/account_by_key_api/get_key_references.rb +18 -0
- data/examples/api/account_history_api/deprecated/enum_virtual_ops.rb +15 -0
- data/examples/api/account_history_api/deprecated/get_transaction.rb +12 -0
- data/examples/api/account_history_api/get_account_history.rb +16 -0
- data/examples/api/account_history_api/get_ops_in_block.rb +17 -0
- data/examples/api/chain_api/deprecated/dummy_code.rb +65 -0
- data/examples/api/chain_api/deprecated/push_block.rb +20 -0
- data/examples/api/database_api/accounts/find_accounts.rb +16 -0
- data/examples/api/database_api/accounts/list_accounts.rb +18 -0
- data/examples/api/database_api/accounts/not_supported/find_account_recovery_requests.rb +16 -0
- data/examples/api/database_api/accounts/not_supported/find_change_recovery_account_requests.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/find_decline_voting_rights_requests.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/find_escrows.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/find_sbd_conversion_requests.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/find_vesting_delegation_expirations.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/find_vesting_delegations.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/find_withdraw_vesting_routes.rb +18 -0
- data/examples/api/database_api/accounts/not_supported/list_account_recovery_requests.rb +18 -0
- data/examples/api/database_api/accounts/not_supported/list_change_recovery_account_requests.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/list_decline_voting_rights_requests.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/list_escrows.rb +18 -0
- data/examples/api/database_api/accounts/not_supported/list_recovery_histories.rb +17 -0
- data/examples/api/database_api/accounts/not_supported/list_sbd_conversion_requests.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/list_vesting_delegation_expirations.rb +0 -0
- data/examples/api/database_api/accounts/not_supported/list_vesting_delegations.rb +18 -0
- data/examples/api/database_api/accounts/not_supported/list_withdraw_vesting_routes.rb +18 -0
- data/examples/api/database_api/authority/not_supported/find_smt_contributions.rb +0 -0
- data/examples/api/database_api/authority/not_supported/find_smt_token_balances.rb +0 -0
- data/examples/api/database_api/authority/not_supported/find_smt_token_emissions.rb +0 -0
- data/examples/api/database_api/authority/not_supported/find_smt_tokens.rb +0 -0
- data/examples/api/database_api/authority/not_supported/get_nai_pool.rb +0 -0
- data/examples/api/database_api/authority/not_supported/get_potential_signatures.rb +0 -0
- data/examples/api/database_api/authority/not_supported/get_required_signatures.rb +0 -0
- data/examples/api/database_api/authority/not_supported/get_smt_balances.rb +0 -0
- data/examples/api/database_api/authority/not_supported/get_transaction_hex.rb +0 -0
- data/examples/api/database_api/authority/not_supported/list_smt_contributions.rb +0 -0
- data/examples/api/database_api/authority/not_supported/list_smt_token_balances.rb +0 -0
- data/examples/api/database_api/authority/not_supported/list_smt_token_emissions.rb +0 -0
- data/examples/api/database_api/authority/not_supported/list_smt_tokens.rb +0 -0
- data/examples/api/database_api/authority/not_supported/verify_account_authority.rb +0 -0
- data/examples/api/database_api/authority/not_supported/verify_authority.rb +0 -0
- data/examples/api/database_api/authority/not_supported/verify_signatures.rb +0 -0
- data/examples/api/database_api/comments/not_supported/find_comments.rb +0 -0
- data/examples/api/database_api/comments/not_supported/find_votes.rb +0 -0
- data/examples/api/database_api/comments/not_supported/list_comments.rb +0 -0
- data/examples/api/database_api/comments/not_supported/list_votes.rb +0 -0
- data/examples/api/database_api/globals/get_config.rb +14 -0
- data/examples/api/database_api/globals/get_dynamic_global_properties.rb +14 -0
- data/examples/api/database_api/globals/get_hardfork_properties.rb +14 -0
- data/examples/api/database_api/globals/get_reward_funds.rb +14 -0
- data/examples/api/database_api/globals/get_version.rb +15 -0
- data/examples/api/database_api/globals/get_witness_schedule.rb +14 -0
- data/examples/api/database_api/market/not_supported/find_limit_orders.rb +0 -0
- data/examples/api/database_api/market/not_supported/get_order_book.rb +0 -0
- data/examples/api/database_api/market/not_supported/list_limit_orders.rb +0 -0
- data/examples/api/database_api/sps/not_supported/find_proposals.rb +0 -0
- data/examples/api/database_api/sps/not_supported/list_proposal_votes.rb +0 -0
- data/examples/api/database_api/sps/not_supported/list_proposals.rb +0 -0
- data/examples/api/database_api/witnesses/deprecated/get_round.rb +14 -0
- data/examples/api/database_api/witnesses/find_witnesses.rb +16 -0
- data/examples/api/database_api/witnesses/get_active_witnesses.rb +14 -0
- data/examples/api/database_api/witnesses/list_witnesses.rb +17 -0
- data/examples/api/database_api/witnesses/not_supported/list_witness_votes.rb +16 -0
- data/examples/api/extras/get_balance.rb +27 -0
- data/examples/api/network_broadcast_api/broadcast_transaction.rb +16 -0
- data/examples/api/network_broadcast_api/broadcast_transaction_synchronous.rb +15 -0
- data/examples/api/network_broadcast_api/create_wallet.rb +79 -0
- data/examples/api/network_broadcast_api/dummy_code.rb +68 -0
- data/examples/api/network_broadcast_api/get_transaction_hex.rb +17 -0
- data/examples/api/network_broadcast_api/not_supported/broadcast_block.rb +17 -0
- data/examples/api/network_broadcast_api/transfer.rb +45 -0
- data/examples/api/payloads.txt +3580 -0
- data/examples/api/transaction_status_api/find_transaction.rb +16 -0
- data/examples/operations/broadcast_transaction_synchronous.rb +16 -0
- data/examples/operations/completed/account_create.rb +79 -0
- data/examples/operations/completed/account_witness_proxy.rb +29 -0
- data/examples/operations/completed/account_witness_vote.rb +31 -0
- data/examples/operations/completed/claim_account.rb +33 -0
- data/examples/operations/completed/create_claimed_account.rb +62 -0
- data/examples/operations/completed/custom.rb +31 -0
- data/examples/operations/completed/custom_json.rb +32 -0
- data/examples/operations/completed/decline_voting_rights.rb +30 -0
- data/examples/operations/completed/delegate_some_vesting_shares.rb +32 -0
- data/examples/operations/completed/set_withdraw_vesting_route.rb +32 -0
- data/examples/operations/completed/transfer.rb +44 -0
- data/examples/operations/completed/transfer_to_vesting.rb +32 -0
- data/examples/operations/completed/update_proposal_votes.rb +31 -0
- data/examples/operations/completed/withdraw_vesting.rb +30 -0
- data/examples/operations/completed/witness_update.rb +64 -0
- data/examples/operations/deprecated/account_update.rb +44 -0
- data/examples/operations/deprecated/cancel_transfer_from_savings.rb +30 -0
- data/examples/operations/deprecated/challenge_authority.rb +28 -0
- data/examples/operations/deprecated/claim_reward_balance.rb +35 -0
- data/examples/operations/deprecated/convert.rb +38 -0
- data/examples/operations/deprecated/custom_binary.rb +31 -0
- data/examples/operations/deprecated/feed_publish.rb +33 -0
- data/examples/operations/do_later/change_recovery_account.rb +31 -0
- data/examples/operations/do_later/claim_reward_balance2.rb +37 -0
- data/examples/operations/do_later/remove_proposal_votes.rb +0 -0
- data/examples/operations/in_progress/create_proposal.rb +40 -0
- data/examples/operations/in_progress/escrow_approve.rb +36 -0
- data/examples/operations/in_progress/witness_set_properties.rb +62 -0
- data/lib/xgt/.ruby.rb.swp +0 -0
- data/lib/xgt/ruby.rb +200 -0
- data/lib/xgt/ruby/version.rb +5 -0
- data/payloads.txt +461 -0
- data/sample.rb +41 -0
- data/sample2.rb +104 -0
- data/xgt-ruby.gemspec +31 -0
- metadata +262 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'xgt/ruby'
|
|
2
|
+
|
|
3
|
+
def claim_reward_balance2
|
|
4
|
+
rpc = Xgt::Ruby::Rpc.new('http://localhost:8751')
|
|
5
|
+
wif = '5JNHfZYKGaomSFvd4NUdQ9qMcEAC43kujbfjueTHpVapX1Kzq2n'
|
|
6
|
+
config = rpc.call('database_api.get_config', {})
|
|
7
|
+
address_prefix = config['XGT_ADDRESS_PREFIX']
|
|
8
|
+
chain_id = config["XGT_CHAIN_ID"]
|
|
9
|
+
|
|
10
|
+
txn = {
|
|
11
|
+
"extensions": [],
|
|
12
|
+
"operations": [
|
|
13
|
+
[
|
|
14
|
+
"claim_reward_balance2",
|
|
15
|
+
{
|
|
16
|
+
"account": "XGT0000000000000",
|
|
17
|
+
"reward_tokens": [
|
|
18
|
+
{
|
|
19
|
+
"amount": "1",
|
|
20
|
+
"precision": 0,
|
|
21
|
+
"nai": "@@904705667"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"extensions": []
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
signed = Xgt::Ruby::Auth.sign_transaction(rpc, txn, [wif], chain_id)
|
|
31
|
+
puts JSON.pretty_generate(signed)
|
|
32
|
+
puts "\n\n"
|
|
33
|
+
response = rpc.call('network_broadcast_api.broadcast_transaction_synchronous', [signed])
|
|
34
|
+
puts JSON.pretty_generate(response)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
claim_reward_balance2
|
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'xgt/ruby'
|
|
2
|
+
|
|
3
|
+
def create_proposal
|
|
4
|
+
rpc = Xgt::Ruby::Rpc.new('http://localhost:8751')
|
|
5
|
+
wif = ENV["WIF"] || '5JNHfZYKGaomSFvd4NUdQ9qMcEAC43kujbfjueTHpVapX1Kzq2n'
|
|
6
|
+
receiver = ENV["RECEIVER"] || 'XGT0000000000001'
|
|
7
|
+
config = rpc.call('database_api.get_config', {})
|
|
8
|
+
address_prefix = config['XGT_ADDRESS_PREFIX']
|
|
9
|
+
chain_id = config["XGT_CHAIN_ID"]
|
|
10
|
+
current_time = Time.now
|
|
11
|
+
|
|
12
|
+
txn = {
|
|
13
|
+
"extensions": [],
|
|
14
|
+
"operations": [
|
|
15
|
+
[
|
|
16
|
+
"create_proposal",
|
|
17
|
+
{
|
|
18
|
+
"creator": "XGT0000000000000",
|
|
19
|
+
"receiver": receiver,
|
|
20
|
+
"start_date": "2020-05-24T09:00:00",
|
|
21
|
+
"end_date": "2020-05-25T09:00:00",
|
|
22
|
+
"daily_pay": "3000.000 SBD",
|
|
23
|
+
"amount": 8000,
|
|
24
|
+
"precision": 3,
|
|
25
|
+
"nai": "@@000000013",
|
|
26
|
+
"subject": "subject",
|
|
27
|
+
"permlink": "http://test.host"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
signed = Xgt::Ruby::Auth.sign_transaction(rpc, txn, [wif], chain_id)
|
|
34
|
+
puts JSON.pretty_generate(signed)
|
|
35
|
+
puts "\n\n"
|
|
36
|
+
response = rpc.call('network_broadcast_api.broadcast_transaction_synchronous', [signed])
|
|
37
|
+
puts JSON.pretty_generate(response)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
create_proposal
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'xgt/ruby'
|
|
2
|
+
|
|
3
|
+
def escrow_approve
|
|
4
|
+
rpc = Xgt::Ruby::Rpc.new('http://localhost:8751')
|
|
5
|
+
wif = '5JANXuPvF1DuhEpf2AKCDhMgaY7ZhYj6qM6HtKUfvnLkuZ6JwGZ'
|
|
6
|
+
wif2 = '5JdgpjVNcAQQhTjhvZgypEQsZqS7nLfPTyURWUgJXze8k65SKiJ'
|
|
7
|
+
wif3 = '5JWufsfFUfKQKwhsYy26oiVifMpyTy3bCkzuL7bcgYpNrCW731s'
|
|
8
|
+
config = rpc.call('database_api.get_config', {})
|
|
9
|
+
address_prefix = config['XGT_ADDRESS_PREFIX']
|
|
10
|
+
chain_id = config["XGT_CHAIN_ID"]
|
|
11
|
+
|
|
12
|
+
txn = {
|
|
13
|
+
"extensions": [],
|
|
14
|
+
"operations": [
|
|
15
|
+
[
|
|
16
|
+
"escrow_approve",
|
|
17
|
+
{
|
|
18
|
+
"from": "XGT0000000000000",
|
|
19
|
+
"to": "XGT32apWJQf7pVbm",
|
|
20
|
+
"agent": "XGT25svCHdyiRN1C",
|
|
21
|
+
"who": "XGT32apWJQf7pVbm",
|
|
22
|
+
"escrow_id": 59102208,
|
|
23
|
+
"approve": true
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
signed = Xgt::Ruby::Auth.sign_transaction(rpc, txn, [wif3], chain_id)
|
|
30
|
+
puts JSON.pretty_generate(signed)
|
|
31
|
+
puts "\n\n"
|
|
32
|
+
response = rpc.call('network_broadcast_api.broadcast_transaction_synchronous', [signed])
|
|
33
|
+
puts JSON.pretty_generate(response)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
escrow_approve
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'erb'
|
|
3
|
+
require 'pp'
|
|
4
|
+
require 'benchmark'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
require 'bigdecimal'
|
|
7
|
+
require 'uri'
|
|
8
|
+
require 'openssl'
|
|
9
|
+
$LOAD_PATH.unshift(%(#{File.dirname(__FILE__)}/../xgt-ruby/lib))
|
|
10
|
+
require'xgt/ruby'
|
|
11
|
+
|
|
12
|
+
def msg(message)
|
|
13
|
+
puts "\e[36m#{message}\e[0m"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def witness_set_properties
|
|
17
|
+
rpc = Xgt::Ruby::Rpc.new("http://localhost:8751")
|
|
18
|
+
recovery_wif = '5JkEZbn8i8BDRpzTAt38Cj9jhAytkcsPuxbFB6R8kd2L7sGWcbE'
|
|
19
|
+
config = rpc.call('database_api.get_config', {})
|
|
20
|
+
witness_schedule = rpc.call('database_api.get_witness_schedule', {}) || {}
|
|
21
|
+
chain_properties = witness_schedule['median_props']
|
|
22
|
+
address_prefix = config['XGT_ADDRESS_PREFIX']
|
|
23
|
+
chain_id = config['XGT_CHAIN_ID']
|
|
24
|
+
signing_private = Xgt::Ruby::Auth.random_wif
|
|
25
|
+
signing_public = Xgt::Ruby::Auth.wif_to_public_key(signing_private, address_prefix)
|
|
26
|
+
amount = (chain_properties['account_creation_fee'] || {})['amount'].to_f * 0.001
|
|
27
|
+
currency_symbol = config['XGT_SYMBOL_STR']
|
|
28
|
+
fee = "#{'%0.3f' % amount} #{currency_symbol}"
|
|
29
|
+
components = fee.split(' ')
|
|
30
|
+
decimal = BigDecimal(components.first) * 1
|
|
31
|
+
final_fee = decimal.truncate.to_s + '.' + sprintf('%03d', (decimal.frac * 1000).truncate) + ' ' + components.last
|
|
32
|
+
|
|
33
|
+
txn = {
|
|
34
|
+
"operations": [[
|
|
35
|
+
"witness_set_properties",
|
|
36
|
+
{
|
|
37
|
+
"owner": "XGT0000000000000",
|
|
38
|
+
"maximum_block_size": 65536,
|
|
39
|
+
"props": [
|
|
40
|
+
"new_signing_key": "5JANXuPvF1DuhEpf2AKCDhMgaY7ZhYj6qM6HtKUfvnLkuZ6JwGZ",
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
]]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
signed = Xgt::Ruby::Auth.sign_transaction(rpc, txn, [recovery_wif], chain_id)
|
|
47
|
+
puts JSON.pretty_generate(signed)
|
|
48
|
+
puts "\n\n"
|
|
49
|
+
|
|
50
|
+
msg %(Registering witness "XGT272up7iTGKArE" with recovery private WIF "#{recovery_wif}"...)
|
|
51
|
+
msg %(Signing keypair is #{signing_private} (private) and #{signing_public} (public)...)
|
|
52
|
+
response = rpc.call('network_broadcast_api.broadcast_transaction_synchronous', [signed])
|
|
53
|
+
puts "\n\n"
|
|
54
|
+
puts JSON.pretty_generate(response)
|
|
55
|
+
|
|
56
|
+
{
|
|
57
|
+
signing_private: signing_private,
|
|
58
|
+
signing_public: signing_public
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
witness_set_properties
|
|
Binary file
|
data/lib/xgt/ruby.rb
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
require 'securerandom'
|
|
2
|
+
require 'faraday'
|
|
3
|
+
require 'faraday_middleware'
|
|
4
|
+
require 'bitcoin'
|
|
5
|
+
require 'base58'
|
|
6
|
+
require 'time'
|
|
7
|
+
require 'xgt/ruby/version'
|
|
8
|
+
|
|
9
|
+
module Xgt
|
|
10
|
+
module Ruby
|
|
11
|
+
class Error < StandardError; end
|
|
12
|
+
class RpcError < Error
|
|
13
|
+
attr_reader :response
|
|
14
|
+
def initialize(msg, response)
|
|
15
|
+
super(msg)
|
|
16
|
+
@response = response
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Rpc
|
|
21
|
+
def initialize(url, client: nil)
|
|
22
|
+
@url = url
|
|
23
|
+
@client = client || Faraday::Connection.new(url: @url) do |faraday|
|
|
24
|
+
faraday.request(:json)
|
|
25
|
+
faraday.request :retry,
|
|
26
|
+
max: 10,
|
|
27
|
+
interval: 0.05,
|
|
28
|
+
interval_randomness: 0.5,
|
|
29
|
+
backoff_factor: 2,
|
|
30
|
+
# TODO: Make this more specific
|
|
31
|
+
exceptions: ['Error']
|
|
32
|
+
faraday.response(:json)
|
|
33
|
+
faraday.response(:logger) if ENV['LOGGING_ENABLED']
|
|
34
|
+
faraday.adapter(Faraday.default_adapter)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def call(mthd, params)
|
|
39
|
+
id = SecureRandom.hex(6).to_i(16)
|
|
40
|
+
payload = {
|
|
41
|
+
'jsonrpc' => '2.0',
|
|
42
|
+
'method' => mthd,
|
|
43
|
+
'id' => id
|
|
44
|
+
}
|
|
45
|
+
payload['params'] = params unless params.nil?
|
|
46
|
+
|
|
47
|
+
response = @client.post('/', payload)
|
|
48
|
+
|
|
49
|
+
# TODO: Verify status code
|
|
50
|
+
unless response.body
|
|
51
|
+
raise RpcError.new(%(No response body!\n#{response.inspect}), response)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if response.body['error']
|
|
55
|
+
raise RpcError.new(%(Endpoint returned an error response!\n#{JSON.pretty_generate(response.body['error'])}), response)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
unless response.body['result']
|
|
59
|
+
raise RpcError.new(%(No result in response body!\n#{response.inspect}), response)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# TODO: XXX: Breaking change!
|
|
63
|
+
response.body['result']
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def broadcast_transaction(txn, wifs, chain_id)
|
|
67
|
+
signed = Xgt::Ruby::Auth.sign_transaction(self, txn, wifs, chain_id)
|
|
68
|
+
response = self.call('transaction_api.broadcast_transaction', [signed])
|
|
69
|
+
response['id']
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def transaction_ready?(id)
|
|
73
|
+
begin
|
|
74
|
+
self.call('wallet_history_api.get_transaction', { 'id' => id })
|
|
75
|
+
true
|
|
76
|
+
rescue Xgt::Ruby::RpcError => e
|
|
77
|
+
message = e&.response
|
|
78
|
+
&.body
|
|
79
|
+
&.fetch('error', nil)
|
|
80
|
+
&.fetch('message', nil)
|
|
81
|
+
wait_regexps = Regexp.union(%r(transaction.*?>.*?trx_in_block))
|
|
82
|
+
raise e unless message.match(wait_regexps)
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class Auth
|
|
89
|
+
def self.sign_transaction(rpc, txn, wifs, chain_id)
|
|
90
|
+
# Get the last irreversible block number
|
|
91
|
+
response = rpc.call('database_api.get_dynamic_global_properties', {})
|
|
92
|
+
chain_date = response['time'] + 'Z'
|
|
93
|
+
last_irreversible_block_num = response['last_irreversible_block_num']
|
|
94
|
+
ref_block_num = (last_irreversible_block_num - 1) & 0xffff
|
|
95
|
+
# Get ref block info to append to the transaction
|
|
96
|
+
response = rpc.call('block_api.get_block_header', { 'block_num' => last_irreversible_block_num })
|
|
97
|
+
header = response['header']
|
|
98
|
+
head_block_id = (header && header['previous']) ? header['previous'] : '0000000000000000000000000000000000000000'
|
|
99
|
+
ref_block_prefix = [head_block_id].pack('H*')[4...8].unpack('V').first
|
|
100
|
+
expiration = (Time.parse(chain_date) + 600).iso8601.gsub(/Z$/, '')
|
|
101
|
+
# Append ref block info to the transaction
|
|
102
|
+
txn['ref_block_num'] = ref_block_num
|
|
103
|
+
txn['ref_block_prefix'] = ref_block_prefix
|
|
104
|
+
txn['expiration'] = expiration
|
|
105
|
+
# Get a hex digest of the transactioon
|
|
106
|
+
response = rpc.call('transaction_api.get_transaction_hex', [txn])
|
|
107
|
+
transaction_hex = response[0..-3]
|
|
108
|
+
unhexed = unhexlify(chain_id + transaction_hex)
|
|
109
|
+
digest_hex = Digest::SHA256.hexdigest(unhexed)
|
|
110
|
+
private_keys = wifs.map { |wif| Bitcoin::Key.from_base58(wif) }
|
|
111
|
+
ec = Bitcoin::OpenSSL_EC
|
|
112
|
+
count = 0
|
|
113
|
+
sig = nil
|
|
114
|
+
|
|
115
|
+
# Calculate signatures and add them to the transaction
|
|
116
|
+
txn['signatures'] ||= []
|
|
117
|
+
private_keys.each do |private_key|
|
|
118
|
+
loop do
|
|
119
|
+
count += 1
|
|
120
|
+
# TODO: Periodically check that count doesn't spin out of control
|
|
121
|
+
public_key_hex = private_key.pub
|
|
122
|
+
digest = unhexlify(digest_hex)
|
|
123
|
+
sig = ec.sign_compact(digest, private_key.priv, public_key_hex, false)
|
|
124
|
+
next if public_key_hex != ec.recover_compact(digest, sig)
|
|
125
|
+
break if canonical?(sig)
|
|
126
|
+
end
|
|
127
|
+
txn['signatures'] << hexlify(sig)
|
|
128
|
+
end
|
|
129
|
+
txn
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.random_wif()
|
|
133
|
+
private_key = unhexlify('80' + SecureRandom.hex(32))
|
|
134
|
+
checksum = Digest::SHA256.digest( Digest::SHA256.digest(private_key) ).byteslice(0, 4)
|
|
135
|
+
to_base_58(private_key + checksum)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def self.generate_wif(name, password, role)
|
|
139
|
+
brain_key = (name + role + password).strip.split(/[\t\n\v\f\r ]+/).join(' ')
|
|
140
|
+
key = "\x80".b + Digest::SHA256.digest(brain_key)
|
|
141
|
+
checksum = Digest::SHA256.digest(Digest::SHA256.digest(key))[0...4]
|
|
142
|
+
to_base_58(key + checksum)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def self.wif_to_public_key(wif, address_prefix)
|
|
146
|
+
private_wif = unhexlify(Bitcoin.decode_base58(wif))
|
|
147
|
+
version = private_wif[0]
|
|
148
|
+
checksum = private_wif[-4..-1]
|
|
149
|
+
# TODO: Verify version and checksum
|
|
150
|
+
private_key = private_wif[1...-4]
|
|
151
|
+
big_num = OpenSSL::BN.new(hexlify(private_key).to_i(16))
|
|
152
|
+
group = OpenSSL::PKey::EC::Group.new('secp256k1')
|
|
153
|
+
product = group.generator.mul(big_num).to_bn
|
|
154
|
+
public_key_buffer = OpenSSL::PKey::EC::Point.new(group, product).to_octet_string(:compressed)
|
|
155
|
+
checksum = Digest::RMD160.digest(public_key_buffer)
|
|
156
|
+
address_prefix + to_base_58(public_key_buffer + checksum[0...4])
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.generate_wallet_name(*public_keys)
|
|
160
|
+
hashed = Digest::SHA256.hexdigest(public_keys.join(''))
|
|
161
|
+
base58 = Base58.binary_to_base58([hashed].pack('H*'), :bitcoin, true)
|
|
162
|
+
address_prefix = 'XGT'
|
|
163
|
+
"#{address_prefix}#{base58[0...40]}"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def self.to_base_58(bytes)
|
|
167
|
+
Bitcoin.encode_base58(hexlify(bytes))
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def self.from_base_58(string)
|
|
171
|
+
unhexlify(Bitcoin.decode_base58(string))
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def self.hexlify(s)
|
|
175
|
+
a = []
|
|
176
|
+
if s.respond_to?(:each_byte)
|
|
177
|
+
s.each_byte { |b| a << sprintf('%02X', b) }
|
|
178
|
+
else
|
|
179
|
+
s.each { |b| a << sprintf('%02X', b) }
|
|
180
|
+
end
|
|
181
|
+
a.join.downcase
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def self.unhexlify(s)
|
|
185
|
+
s.split.pack('H*')
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def self.canonical?(sig)
|
|
189
|
+
sig = sig.unpack('C*')
|
|
190
|
+
|
|
191
|
+
!(
|
|
192
|
+
((sig[0] & 0x80 ) != 0) || ( sig[0] == 0 ) ||
|
|
193
|
+
((sig[1] & 0x80 ) != 0) ||
|
|
194
|
+
((sig[32] & 0x80 ) != 0) || ( sig[32] == 0 ) ||
|
|
195
|
+
((sig[33] & 0x80 ) != 0)
|
|
196
|
+
)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
data/payloads.txt
ADDED
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jsonrpc": "2.0",
|
|
3
|
+
"method": "database_api.find_accounts",
|
|
4
|
+
"params": {
|
|
5
|
+
"accounts": [
|
|
6
|
+
"foo45fb448c"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
"id": 18466466518669
|
|
10
|
+
}
|
|
11
|
+
{
|
|
12
|
+
"jsonrpc": "2.0",
|
|
13
|
+
"result": {
|
|
14
|
+
"accounts": [
|
|
15
|
+
{
|
|
16
|
+
"id": 13,
|
|
17
|
+
"name": "foo45fb448c",
|
|
18
|
+
"owner": {
|
|
19
|
+
"weight_threshold": 1,
|
|
20
|
+
"account_auths": [
|
|
21
|
+
|
|
22
|
+
],
|
|
23
|
+
"key_auths": [
|
|
24
|
+
[
|
|
25
|
+
"TST7xue5ESY1xHhDZj6dw2igXCwoHobA3cnxffacvp4XMzwfzLZu4",
|
|
26
|
+
1
|
|
27
|
+
]
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"active": {
|
|
31
|
+
"weight_threshold": 1,
|
|
32
|
+
"account_auths": [
|
|
33
|
+
|
|
34
|
+
],
|
|
35
|
+
"key_auths": [
|
|
36
|
+
[
|
|
37
|
+
"TST6Yp3zeaYNU7XJF2MxoHhDcWT4vGgVkzTLEvhMY6g5tvmwzn3tN",
|
|
38
|
+
1
|
|
39
|
+
]
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"posting": {
|
|
43
|
+
"weight_threshold": 1,
|
|
44
|
+
"account_auths": [
|
|
45
|
+
|
|
46
|
+
],
|
|
47
|
+
"key_auths": [
|
|
48
|
+
[
|
|
49
|
+
"TST5Q7ZdopjQWZMwiyZk11W5Yhvsfu1PG3f4qsQN58A7XfHP34Hig",
|
|
50
|
+
1
|
|
51
|
+
]
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"memo_key": "TST5u69JnHZ3oznnwn71J6VA4r5oVJX6Xu3dpbFVoHpJoZXnbDfaW",
|
|
55
|
+
"json_metadata": "",
|
|
56
|
+
"proxy": "",
|
|
57
|
+
"last_owner_update": "1970-01-01T00:00:00",
|
|
58
|
+
"last_account_update": "1970-01-01T00:00:00",
|
|
59
|
+
"created": "2019-04-24T06:44:48",
|
|
60
|
+
"mined": false,
|
|
61
|
+
"recovery_account": "initminer",
|
|
62
|
+
"last_account_recovery": "1970-01-01T00:00:00",
|
|
63
|
+
"reset_account": "null",
|
|
64
|
+
"comment_count": 0,
|
|
65
|
+
"lifetime_vote_count": 0,
|
|
66
|
+
"post_count": 0,
|
|
67
|
+
"can_vote": true,
|
|
68
|
+
"voting_manabar": {
|
|
69
|
+
"current_mana": 0,
|
|
70
|
+
"last_update_time": 1556088288
|
|
71
|
+
},
|
|
72
|
+
"balance": {
|
|
73
|
+
"amount": "0",
|
|
74
|
+
"precision": 3,
|
|
75
|
+
"nai": "@@000000021"
|
|
76
|
+
},
|
|
77
|
+
"savings_balance": {
|
|
78
|
+
"amount": "0",
|
|
79
|
+
"precision": 3,
|
|
80
|
+
"nai": "@@000000021"
|
|
81
|
+
},
|
|
82
|
+
"sbd_balance": {
|
|
83
|
+
"amount": "0",
|
|
84
|
+
"precision": 3,
|
|
85
|
+
"nai": "@@000000013"
|
|
86
|
+
},
|
|
87
|
+
"sbd_seconds": "0",
|
|
88
|
+
"sbd_seconds_last_update": "1970-01-01T00:00:00",
|
|
89
|
+
"sbd_last_interest_payment": "1970-01-01T00:00:00",
|
|
90
|
+
"savings_sbd_balance": {
|
|
91
|
+
"amount": "0",
|
|
92
|
+
"precision": 3,
|
|
93
|
+
"nai": "@@000000013"
|
|
94
|
+
},
|
|
95
|
+
"savings_sbd_seconds": "0",
|
|
96
|
+
"savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
|
|
97
|
+
"savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
|
|
98
|
+
"savings_withdraw_requests": 0,
|
|
99
|
+
"reward_sbd_balance": {
|
|
100
|
+
"amount": "0",
|
|
101
|
+
"precision": 3,
|
|
102
|
+
"nai": "@@000000013"
|
|
103
|
+
},
|
|
104
|
+
"reward_steem_balance": {
|
|
105
|
+
"amount": "0",
|
|
106
|
+
"precision": 3,
|
|
107
|
+
"nai": "@@000000021"
|
|
108
|
+
},
|
|
109
|
+
"reward_vesting_balance": {
|
|
110
|
+
"amount": "0",
|
|
111
|
+
"precision": 6,
|
|
112
|
+
"nai": "@@000000037"
|
|
113
|
+
},
|
|
114
|
+
"reward_vesting_steem": {
|
|
115
|
+
"amount": "0",
|
|
116
|
+
"precision": 3,
|
|
117
|
+
"nai": "@@000000021"
|
|
118
|
+
},
|
|
119
|
+
"vesting_shares": {
|
|
120
|
+
"amount": "0",
|
|
121
|
+
"precision": 6,
|
|
122
|
+
"nai": "@@000000037"
|
|
123
|
+
},
|
|
124
|
+
"delegated_vesting_shares": {
|
|
125
|
+
"amount": "0",
|
|
126
|
+
"precision": 6,
|
|
127
|
+
"nai": "@@000000037"
|
|
128
|
+
},
|
|
129
|
+
"received_vesting_shares": {
|
|
130
|
+
"amount": "0",
|
|
131
|
+
"precision": 6,
|
|
132
|
+
"nai": "@@000000037"
|
|
133
|
+
},
|
|
134
|
+
"vesting_withdraw_rate": {
|
|
135
|
+
"amount": "0",
|
|
136
|
+
"precision": 6,
|
|
137
|
+
"nai": "@@000000037"
|
|
138
|
+
},
|
|
139
|
+
"next_vesting_withdrawal": "1969-12-31T23:59:59",
|
|
140
|
+
"withdrawn": 0,
|
|
141
|
+
"to_withdraw": 0,
|
|
142
|
+
"withdraw_routes": 0,
|
|
143
|
+
"curation_rewards": 0,
|
|
144
|
+
"posting_rewards": 0,
|
|
145
|
+
"proxied_vsf_votes": [
|
|
146
|
+
0,
|
|
147
|
+
0,
|
|
148
|
+
0,
|
|
149
|
+
0
|
|
150
|
+
],
|
|
151
|
+
"witnesses_voted_for": 0,
|
|
152
|
+
"last_post": "1970-01-01T00:00:00",
|
|
153
|
+
"last_root_post": "1970-01-01T00:00:00",
|
|
154
|
+
"last_vote_time": "1970-01-01T00:00:00",
|
|
155
|
+
"post_bandwidth": 0,
|
|
156
|
+
"pending_claimed_accounts": 0,
|
|
157
|
+
"is_smt": false
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
"id": "7133625920894"
|
|
162
|
+
}
|
|
163
|
+
{
|
|
164
|
+
"jsonrpc": "2.0",
|
|
165
|
+
"method": "database_api.get_dynamic_global_properties",
|
|
166
|
+
"params": {
|
|
167
|
+
},
|
|
168
|
+
"id": 275146661212172
|
|
169
|
+
}
|
|
170
|
+
{
|
|
171
|
+
"jsonrpc": "2.0",
|
|
172
|
+
"id": 275146661212172,
|
|
173
|
+
"result": {
|
|
174
|
+
"time": "2019-04-30T00:34:12",
|
|
175
|
+
"last_irreversible_block_num": 32482872
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
{
|
|
179
|
+
"jsonrpc": "2.0",
|
|
180
|
+
"method": "block_api.get_block_header",
|
|
181
|
+
"params": {
|
|
182
|
+
"block_num": 32482872
|
|
183
|
+
},
|
|
184
|
+
"id": 249008441062077
|
|
185
|
+
}
|
|
186
|
+
{
|
|
187
|
+
"jsonrpc": "2.0",
|
|
188
|
+
"id": 249008441062077,
|
|
189
|
+
"result": {
|
|
190
|
+
"header": {
|
|
191
|
+
"previous": "01efa63783c4180b05e39fa94dde4febca9cc91d"
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
{
|
|
196
|
+
"jsonrpc": "2.0",
|
|
197
|
+
"method": "network_broadcast_api.get_transaction_hex",
|
|
198
|
+
"params": [
|
|
199
|
+
{
|
|
200
|
+
"extensions": [
|
|
201
|
+
|
|
202
|
+
],
|
|
203
|
+
"operations": [
|
|
204
|
+
[
|
|
205
|
+
"account_create",
|
|
206
|
+
{
|
|
207
|
+
"fee": "0.000 TESTS",
|
|
208
|
+
"creator": "initminer",
|
|
209
|
+
"new_account_name": "foo41700a44",
|
|
210
|
+
"owner": {
|
|
211
|
+
"weight_threshold": 1,
|
|
212
|
+
"account_auths": [
|
|
213
|
+
|
|
214
|
+
],
|
|
215
|
+
"key_auths": [
|
|
216
|
+
[
|
|
217
|
+
"TST7xue5ESY1xHhDZj6dw2igXCwoHobA3cnxffacvp4XMzwfzLZu4",
|
|
218
|
+
1
|
|
219
|
+
]
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
"active": {
|
|
223
|
+
"weight_threshold": 1,
|
|
224
|
+
"account_auths": [
|
|
225
|
+
|
|
226
|
+
],
|
|
227
|
+
"key_auths": [
|
|
228
|
+
[
|
|
229
|
+
"TST6Yp3zeaYNU7XJF2MxoHhDcWT4vGgVkzTLEvhMY6g5tvmwzn3tN",
|
|
230
|
+
1
|
|
231
|
+
]
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
"posting": {
|
|
235
|
+
"weight_threshold": 1,
|
|
236
|
+
"account_auths": [
|
|
237
|
+
|
|
238
|
+
],
|
|
239
|
+
"key_auths": [
|
|
240
|
+
[
|
|
241
|
+
"TST5Q7ZdopjQWZMwiyZk11W5Yhvsfu1PG3f4qsQN58A7XfHP34Hig",
|
|
242
|
+
1
|
|
243
|
+
]
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
"memo_key": "TST5u69JnHZ3oznnwn71J6VA4r5oVJX6Xu3dpbFVoHpJoZXnbDfaW",
|
|
247
|
+
"json_metadata": "",
|
|
248
|
+
"extensions": [
|
|
249
|
+
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
],
|
|
254
|
+
"ref_block_num": 42551,
|
|
255
|
+
"ref_block_prefix": 186172547,
|
|
256
|
+
"expiration": "2019-04-30T00:44:12"
|
|
257
|
+
}
|
|
258
|
+
],
|
|
259
|
+
"id": 116156454840173
|
|
260
|
+
}
|
|
261
|
+
{
|
|
262
|
+
"jsonrpc": "2.0",
|
|
263
|
+
"id": 116156454840173,
|
|
264
|
+
"result": "37a683c4180b5c9ac75c01090000000000000000035445535453000009696e69746d696e65720b666f6f343137303061343401000000000103951f1e294b4f9e535708bcfa85d8d21240bda7585424b2e6fa0d0f1e9a756e8c010001000000000102dab63701259352fa01048a97ac76d44def848552518c7991e4bb2feb893e6eef0100010000000001024343ff4fcd3a2ddfbb53fbd178b09ed02c457dbd88d1ff2f49ce967d7c3f5637010002850edf288f0e9fdc4bf83839d352d3b9e65bdefb309147ad3642b4a63e0a6c660000ff"
|
|
265
|
+
}
|
|
266
|
+
{
|
|
267
|
+
"jsonrpc": "2.0",
|
|
268
|
+
"method": "condenser_api.get_chain_properties",
|
|
269
|
+
"params": [
|
|
270
|
+
|
|
271
|
+
],
|
|
272
|
+
"id": 113281388192823
|
|
273
|
+
}
|
|
274
|
+
{
|
|
275
|
+
"jsonrpc": "2.0",
|
|
276
|
+
"error": {
|
|
277
|
+
"code": -32002,
|
|
278
|
+
"message": "Assert Exception:method_itr != api_itr->second.end(): Could not find method get_chain_properties",
|
|
279
|
+
"data": {
|
|
280
|
+
"code": 10,
|
|
281
|
+
"name": "assert_exception",
|
|
282
|
+
"message": "Assert Exception",
|
|
283
|
+
"stack": [
|
|
284
|
+
{
|
|
285
|
+
"context": {
|
|
286
|
+
"level": "error",
|
|
287
|
+
"file": "json_rpc_plugin.cpp",
|
|
288
|
+
"line": 209,
|
|
289
|
+
"method": "find_api_method",
|
|
290
|
+
"hostname": "",
|
|
291
|
+
"timestamp": "2020-04-01T19:44:15"
|
|
292
|
+
},
|
|
293
|
+
"format": "method_itr != api_itr->second.end(): Could not find method ${method}",
|
|
294
|
+
"data": {
|
|
295
|
+
"method": "get_chain_properties"
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"id": "113281388192823"
|
|
302
|
+
}
|
|
303
|
+
{
|
|
304
|
+
"jsonrpc": "2.0",
|
|
305
|
+
"method": "condenser_api.get_chain_properties",
|
|
306
|
+
"params": [
|
|
307
|
+
|
|
308
|
+
],
|
|
309
|
+
"id": 197736107532241
|
|
310
|
+
}
|
|
311
|
+
{
|
|
312
|
+
"jsonrpc": "2.0",
|
|
313
|
+
"method": "condenser_api.get_chain_properties",
|
|
314
|
+
"params": [
|
|
315
|
+
|
|
316
|
+
],
|
|
317
|
+
"id": 168893335992264
|
|
318
|
+
}
|
|
319
|
+
{
|
|
320
|
+
"jsonrpc": "2.0",
|
|
321
|
+
"method": "condenser_api.get_chain_properties",
|
|
322
|
+
"params": [
|
|
323
|
+
|
|
324
|
+
],
|
|
325
|
+
"id": 159203180196081
|
|
326
|
+
}
|
|
327
|
+
{
|
|
328
|
+
"jsonrpc": "2.0",
|
|
329
|
+
"method": "condenser_api.get_chain_properties",
|
|
330
|
+
"params": [
|
|
331
|
+
|
|
332
|
+
],
|
|
333
|
+
"id": 162443573580019
|
|
334
|
+
}
|
|
335
|
+
{
|
|
336
|
+
"jsonrpc": "2.0",
|
|
337
|
+
"method": "condenser_api.get_chain_properties",
|
|
338
|
+
"params": [
|
|
339
|
+
|
|
340
|
+
],
|
|
341
|
+
"id": 265628521302471
|
|
342
|
+
}
|
|
343
|
+
{
|
|
344
|
+
"jsonrpc": "2.0",
|
|
345
|
+
"method": "condenser_api.get_chain_properties",
|
|
346
|
+
"params": [
|
|
347
|
+
|
|
348
|
+
],
|
|
349
|
+
"id": 23335772442202
|
|
350
|
+
}
|
|
351
|
+
{
|
|
352
|
+
"jsonrpc": "2.0",
|
|
353
|
+
"method": "condenser_api.get_chain_properties",
|
|
354
|
+
"params": [
|
|
355
|
+
|
|
356
|
+
],
|
|
357
|
+
"id": 189541321007961
|
|
358
|
+
}
|
|
359
|
+
{
|
|
360
|
+
"jsonrpc": "2.0",
|
|
361
|
+
"error": {
|
|
362
|
+
"code": -32002,
|
|
363
|
+
"message": "Assert Exception:method_itr != api_itr->second.end(): Could not find method get_chain_properties",
|
|
364
|
+
"data": {
|
|
365
|
+
"code": 10,
|
|
366
|
+
"name": "assert_exception",
|
|
367
|
+
"message": "Assert Exception",
|
|
368
|
+
"stack": [
|
|
369
|
+
{
|
|
370
|
+
"context": {
|
|
371
|
+
"level": "error",
|
|
372
|
+
"file": "json_rpc_plugin.cpp",
|
|
373
|
+
"line": 209,
|
|
374
|
+
"method": "find_api_method",
|
|
375
|
+
"hostname": "",
|
|
376
|
+
"timestamp": "2020-04-03T22:18:41"
|
|
377
|
+
},
|
|
378
|
+
"format": "method_itr != api_itr->second.end(): Could not find method ${method}",
|
|
379
|
+
"data": {
|
|
380
|
+
"method": "get_chain_properties"
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
]
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
"id": "189541321007961"
|
|
387
|
+
}
|
|
388
|
+
{
|
|
389
|
+
"jsonrpc": "2.0",
|
|
390
|
+
"method": "condenser_api.get_chain_properties",
|
|
391
|
+
"params": [
|
|
392
|
+
|
|
393
|
+
],
|
|
394
|
+
"id": 251458499472850
|
|
395
|
+
}
|
|
396
|
+
{
|
|
397
|
+
"jsonrpc": "2.0",
|
|
398
|
+
"error": {
|
|
399
|
+
"code": -32002,
|
|
400
|
+
"message": "Assert Exception:method_itr != api_itr->second.end(): Could not find method get_chain_properties",
|
|
401
|
+
"data": {
|
|
402
|
+
"code": 10,
|
|
403
|
+
"name": "assert_exception",
|
|
404
|
+
"message": "Assert Exception",
|
|
405
|
+
"stack": [
|
|
406
|
+
{
|
|
407
|
+
"context": {
|
|
408
|
+
"level": "error",
|
|
409
|
+
"file": "json_rpc_plugin.cpp",
|
|
410
|
+
"line": 209,
|
|
411
|
+
"method": "find_api_method",
|
|
412
|
+
"hostname": "",
|
|
413
|
+
"timestamp": "2020-04-03T22:50:20"
|
|
414
|
+
},
|
|
415
|
+
"format": "method_itr != api_itr->second.end(): Could not find method ${method}",
|
|
416
|
+
"data": {
|
|
417
|
+
"method": "get_chain_properties"
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
]
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
"id": "251458499472850"
|
|
424
|
+
}
|
|
425
|
+
{
|
|
426
|
+
"jsonrpc": "2.0",
|
|
427
|
+
"method": "condenser_api.get_chain_properties",
|
|
428
|
+
"params": [
|
|
429
|
+
|
|
430
|
+
],
|
|
431
|
+
"id": 66742030768951
|
|
432
|
+
}
|
|
433
|
+
{
|
|
434
|
+
"jsonrpc": "2.0",
|
|
435
|
+
"error": {
|
|
436
|
+
"code": -32002,
|
|
437
|
+
"message": "Assert Exception:method_itr != api_itr->second.end(): Could not find method get_chain_properties",
|
|
438
|
+
"data": {
|
|
439
|
+
"code": 10,
|
|
440
|
+
"name": "assert_exception",
|
|
441
|
+
"message": "Assert Exception",
|
|
442
|
+
"stack": [
|
|
443
|
+
{
|
|
444
|
+
"context": {
|
|
445
|
+
"level": "error",
|
|
446
|
+
"file": "json_rpc_plugin.cpp",
|
|
447
|
+
"line": 209,
|
|
448
|
+
"method": "find_api_method",
|
|
449
|
+
"hostname": "",
|
|
450
|
+
"timestamp": "2020-04-03T23:02:56"
|
|
451
|
+
},
|
|
452
|
+
"format": "method_itr != api_itr->second.end(): Could not find method ${method}",
|
|
453
|
+
"data": {
|
|
454
|
+
"method": "get_chain_properties"
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
"id": "66742030768951"
|
|
461
|
+
}
|