Class: OnChain::BlockChain
- Inherits:
-
Object
- Object
- OnChain::BlockChain
- Defined in:
- lib/onchain/providers/bitcoind_api.rb,
lib/onchain/block_chain.rb,
lib/onchain/providers/blockr_api.rb,
lib/onchain/providers/insight_api.rb,
lib/onchain/providers/blockchaininfo_api.rb
Overview
This only works with nodes that have addrindex patch applied. i.e. github.com/dexX7/bitcoin
Constant Summary collapse
- ALL_SUPPLIERS =
[ :blockinfo, :insight, :blockr, :bitcoind ]
- BALANCE_CACHE_FOR =
120- API_CACHE_FOR =
60- SERVICE_DOWN_FOR =
60- @@cache =
{}
Class Method Summary collapse
-
.bitcoind_address_history(address, network = :bitcoin) ⇒ Object
Get last 20 transactions.
- .bitcoind_get_all_balances(addresses, network = :bitcoin) ⇒ Object
- .bitcoind_get_balance(address, network = :bitcoin) ⇒ Object
- .bitcoind_get_transaction(txhash, network = :bitcoin) ⇒ Object
- .bitcoind_get_unspent_outs(address, network = :bitcoin) ⇒ Object
- .bitcoind_send_tx(tx_hex, network = :bitcoin) ⇒ Object
- .block_chain(cmd, address, params = "") ⇒ Object
- .blockinfo_address_history(address, network = :bitcoin) ⇒ Object
- .blockinfo_get_address_info(address) ⇒ Object
- .blockinfo_get_all_balances(addresses) ⇒ Object
- .blockinfo_get_balance(address) ⇒ Object
- .blockinfo_get_transaction(txhash) ⇒ Object
- .blockinfo_get_unspent_outs(address) ⇒ Object
- .blockinfo_parse_address_tx(address, json) ⇒ Object
- .blockr(cmd, address, network, params = "") ⇒ Object
- .blockr_address_history(address, network = :bitcoin) ⇒ Object
- .blockr_get_address_info(address, network = :bitcoin) ⇒ Object
- .blockr_get_all_balances(addresses, network = :bitcoin) ⇒ Object
- .blockr_get_balance(address, network = :bitcoin) ⇒ Object
- .blockr_get_transaction(txhash, network = :bitcoin) ⇒ Object
- .blockr_get_transactions(address, network = :bitcoin) ⇒ Object
- .blockr_get_unspent_outs(address, network = :bitcoin) ⇒ Object
- .blockr_send_tx(tx_hex, network = :bitcoin) ⇒ Object
- .cache_read(key) ⇒ Object
- .cache_write(key, data, max_age = 0) ⇒ Object
-
.execute_remote_command(cmd, network) ⇒ Object
Run the command via ssh.
- .fetch_response(url, do_json = true) ⇒ Object
- .get_available_suppliers(method_name, network) ⇒ Object
- .get_balance_satoshi(address, network = :bitcoin) ⇒ Object
- .get_history_for_addresses(addresses, network = :bitcoin) ⇒ Object
- .get_insight_url(network) ⇒ Object
-
.get_uncached_addresses(addresses) ⇒ Object
Given a list of addresses, return those that don’t have balances in the cahce.
- .get_unspent_for_amount(addresses, amount_in_satoshi, network = :bitcoin) ⇒ Object
- .get_url(network) ⇒ Object
- .insight_address_history(address, network = :bitcoin) ⇒ Object
- .insight_get_all_balances(addresses, network = :bitcoin) ⇒ Object
- .insight_get_balance(address, network = :bitcoin) ⇒ Object
- .insight_get_transaction(txhash, network = :bitcoin) ⇒ Object
- .insight_get_unspent_outs(address, network = :bitcoin) ⇒ Object
- .insight_send_tx(tx_hex, network = :bitcoin) ⇒ Object
- .method_missing(method_name, *args, &block) ⇒ Object
- .parse_address_tx(address, json, network) ⇒ Object
- .parse_bitcoind_address_tx(address, json, network) ⇒ Object
- .parse_insight_address_tx(address, json, network) ⇒ Object
- .reverse_blockchain_tx(hash) ⇒ Object
Class Method Details
.bitcoind_address_history(address, network = :bitcoin) ⇒ Object
Get last 20 transactions
7 8 9 10 11 12 13 14 15 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 7 def bitcoind_address_history(address, network = :bitcoin) result = execute_remote_command('searchrawtransactions ' + address + ' 1 0 20 0', network) json = JSON.parse result return parse_bitcoind_address_tx(address, json, network) end |
.bitcoind_get_all_balances(addresses, network = :bitcoin) ⇒ Object
94 95 96 97 98 99 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 94 def bitcoind_get_all_balances(addresses, network = :bitcoin) addresses.each do |address| bitcoind_get_balance(address, network) end end |
.bitcoind_get_balance(address, network = :bitcoin) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 70 def bitcoind_get_balance(address, network = :bitcoin) if cache_read(address) == nil outs = bitcoind_get_unspent_outs(address, network) puts outs.to_s bal = 0 outs.each do |out| bal += out[3].to_i end cache_write(address, bal, BALANCE_CACHE_FOR) end bal = cache_read(address) if bal.class == Fixnum bal = bal.to_f end return bal end |
.bitcoind_get_transaction(txhash, network = :bitcoin) ⇒ Object
121 122 123 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 121 def bitcoind_get_transaction(txhash, network = :bitcoin) return execute_remote_command('getrawtransaction ' + txhash, network) end |
.bitcoind_get_unspent_outs(address, network = :bitcoin) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 101 def bitcoind_get_unspent_outs(address, network = :bitcoin) result = execute_remote_command('listallunspent ' + address + ' 1', network) json = JSON.parse result unspent = [] json.each do |data| line = [] line << data['txid'] line << data['vout'] line << data['scriptPubKey']['hex'] line << (data['amount'].to_f * 100000000).to_i unspent << line end return unspent end |
.bitcoind_send_tx(tx_hex, network = :bitcoin) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 56 def bitcoind_send_tx(tx_hex, network = :bitcoin) remote = execute_remote_command('sendrawtransaction ' + tx_hex, network) #res = JSON.parse(remote) mess = 'Unknown' stat = 'Unknown' tx_hash = 'Unknown' ret = "{\"status\":\"#{stat}\",\"data\":\"#{tx_hash}\",\"code\":200,\"message\":\"#{mess}\"}" return JSON.parse(ret) end |
.block_chain(cmd, address, params = "") ⇒ Object
124 125 126 127 128 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 124 def block_chain(cmd, address, params = "") base_url = "https://blockchain.info/#{cmd}/#{address}?format=json" + params fetch_response(base_url, true) end |
.blockinfo_address_history(address, network = :bitcoin) ⇒ Object
4 5 6 7 8 9 10 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 4 def blockinfo_address_history(address, network = :bitcoin) base_url = "https://blockchain.info/address/#{address}?format=json" json = fetch_response(base_url, true) blockinfo_parse_address_tx(address, json) end |
.blockinfo_get_address_info(address) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 51 def blockinfo_get_address_info(address) base = "https://blockchain.info/multiaddr?&simple=true&active=" + address json = fetch_response(URI::encode(base)) return { received: json[address]['total_received'], balance: json[address]['final_balance'], confirmed: json[address]['final_balance'] } end |
.blockinfo_get_all_balances(addresses) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 63 def blockinfo_get_all_balances(addresses) base = "https://blockchain.info/multiaddr?&simple=true&active=" addr = get_uncached_addresses(addresses) if addr.length == 0 return end addr.each do |address| base = base + address + '|' end json = fetch_response(URI::encode(base)) addresses.each do |address| bal = json[address]['final_balance'] / 100000000.0 cache_write(address, bal, BALANCE_CACHE_FOR) end end |
.blockinfo_get_balance(address) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 102 def blockinfo_get_balance(address) if cache_read(address) == nil json = block_chain('address', address, "&limit=0") if json.key?('final_balance') bal = json['final_balance'] / 100000000.0 cache_write(address, bal, BALANCE_CACHE_FOR) else cache_write(address, 'Error', BALANCE_CACHE_FOR) end end bal = cache_read(address) if bal.class == Fixnum bal = bal.to_f end return bal end |
.blockinfo_get_transaction(txhash) ⇒ Object
119 120 121 122 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 119 def blockinfo_get_transaction(txhash) base = "https://blockchain.info/rawtx/#{txhash}?format=hex" return fetch_response(URI::encode(base)) end |
.blockinfo_get_unspent_outs(address) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 84 def blockinfo_get_unspent_outs(address) base_url = "https://blockchain.info/unspent?active=#{address}" json = fetch_response(base_url, true) unspent = [] json['unspent_outputs'].each do |data| line = [] line << reverse_blockchain_tx(data['tx_hash']) line << data['tx_output_n'] line << data['script'] line << data['value'] unspent << line end return unspent end |
.blockinfo_parse_address_tx(address, json) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 12 def blockinfo_parse_address_tx(address, json) hist = [] if json.key?('txs') txs = json['txs'] txs.each do |tx| row = {} row[:time] = tx["time"] row[:addr] = {} row[:outs] = {} inputs = tx['inputs'] val = 0 recv = "Y" inputs.each do |input| row[:addr][input["prev_out"]["addr"]] = input["prev_out"]["addr"] if input["prev_out"]["addr"] == address recv = "N" end end tx["out"].each do |out| row[:outs][out["addr"]] = out["addr"] if recv == "Y" and out["addr"] == address val = val + out["value"].to_f / 100000000.0 elsif recv == "N" and out["addr"] != address val = val + out["value"].to_f / 100000000.0 end end row[:total] = val row[:recv] = recv row[:hash] = tx["hash"] hist << row end return hist else 'Error' end return hist end |
.blockr(cmd, address, network, params = "") ⇒ Object
167 168 169 170 171 172 |
# File 'lib/onchain/providers/blockr_api.rb', line 167 def blockr(cmd, address, network, params = "") base_url = get_url(network) + "#{cmd}/#{address}" + params fetch_response(base_url, true) end |
.blockr_address_history(address, network = :bitcoin) ⇒ Object
11 12 13 14 15 16 |
# File 'lib/onchain/providers/blockr_api.rb', line 11 def blockr_address_history(address, network = :bitcoin) json = blockr('address/txs', address, network) return parse_address_tx(address, json, network) end |
.blockr_get_address_info(address, network = :bitcoin) ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'lib/onchain/providers/blockr_api.rb', line 95 def blockr_get_address_info(address, network = :bitcoin) json = blockr('address/balance', address, network) return { received: json[address]['total_received'], balance: json[address]['final_balance'], confirmed: json[address]['final_balance'] } end |
.blockr_get_all_balances(addresses, network = :bitcoin) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/onchain/providers/blockr_api.rb', line 139 def blockr_get_all_balances(addresses, network = :bitcoin) addr = get_uncached_addresses(addresses) if addr.length == 0 return end base = get_url(network) + "address/balance/" addr.each do |address| base = base + address + ',' end json = fetch_response(URI::encode(base)) json['data'].each do |data| bal = data['balance'].to_f addr = data['address'] cache_write(addr, bal, BALANCE_CACHE_FOR) end end |
.blockr_get_balance(address, network = :bitcoin) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/onchain/providers/blockr_api.rb', line 82 def blockr_get_balance(address, network = :bitcoin) if cache_read(address) == nil json = blockr('address/balance', address, network) if json.key?('data') bal = json['data']['balance'].to_f cache_write(address, bal, BALANCE_CACHE_FOR) else cache_write(address, 'Error', BALANCE_CACHE_FOR) end end return cache_read(address) end |
.blockr_get_transaction(txhash, network = :bitcoin) ⇒ Object
162 163 164 165 |
# File 'lib/onchain/providers/blockr_api.rb', line 162 def blockr_get_transaction(txhash, network = :bitcoin) base = get_url(network) + "tx/raw/" + txhash return fetch_response(URI::encode(base))['data']['tx']['hex'] end |
.blockr_get_transactions(address, network = :bitcoin) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/onchain/providers/blockr_api.rb', line 105 def blockr_get_transactions(address, network = :bitcoin) base_url = get_url(network) + "address/txs/#{address}" json = fetch_response(base_url, true) unspent = [] json['data']['txs'].each do |data| line = [] line << data['tx'] line << data['amount'].to_f unspent << line end return unspent end |
.blockr_get_unspent_outs(address, network = :bitcoin) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/onchain/providers/blockr_api.rb', line 121 def blockr_get_unspent_outs(address, network = :bitcoin) base_url = get_url(network) + "address/unspent/#{address}" json = fetch_response(base_url, true) unspent = [] json['data']['unspent'].each do |data| line = [] line << data['tx'] line << data['n'] line << data['script'] line << (data['amount'].to_f * 100000000).to_i unspent << line end return unspent end |
.blockr_send_tx(tx_hex, network = :bitcoin) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/onchain/providers/blockr_api.rb', line 61 def blockr_send_tx(tx_hex, network = :bitcoin) uri = URI.parse(get_url(network) + "tx/push") http = Net::HTTP.new(uri.host, uri.port) request = Net::HTTP::Post.new(uri.request_uri) request.body = '{"hex":"' + tx_hex + '"}' response = http.request(request) res = JSON.parse(response.body) mess = res["message"] stat = res["status"] if stat == 'fail' stat = 'failure' end tx_hash = res["data"] ret = "{\"status\":\"#{stat}\",\"data\":\"#{tx_hash}\",\"code\":200,\"message\":\"#{mess}\"}" return JSON.parse(ret) end |
.cache_read(key) ⇒ Object
181 182 183 184 185 186 187 |
# File 'lib/onchain/block_chain.rb', line 181 def cache_read(key) # if the API URL exists as a key in cache, we just return it # we also make sure the data is fresh if @@cache.has_key? key return @@cache[key][1] if Time.now-@@cache[key][0] < @@cache[key][2] end end |
.cache_write(key, data, max_age = 0) ⇒ Object
177 178 179 |
# File 'lib/onchain/block_chain.rb', line 177 def cache_write(key, data, max_age=0) @@cache[key] = [Time.now, data, max_age] end |
.execute_remote_command(cmd, network) ⇒ Object
Run the command via ssh. For this to work you need to create the follwing ENV vars.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 127 def execute_remote_command(cmd, network) host = ENV[network.to_s.upcase + '_HOST'] username = ENV[network.to_s.upcase + '_USER'] password = ENV[network.to_s.upcase + '_PASSWORD'] cmd = ENV[network.to_s.upcase + '_CLI_CMD'] + ' ' + cmd stdout = "" stderr = "" begin Net::SSH.start(host, username, :password => password, :auth_methods => [ 'password' ], :number_of_password_prompts => 0) do |ssh| ssh.exec! cmd do |channel, stream, data| stdout << data if stream == :stdout stderr << data if stream == :stderr end end rescue Timeout::Error return "{ 'error':'Timed out' }" rescue Errno::EHOSTUNREACH return "{ 'error':'Host unreachable' }" rescue Errno::ECONNREFUSED return "{ 'error':'Connection refused }" rescue Net::SSH::AuthenticationFailed return "{ 'error':'Authentication failure' }" end return stdout.chomp end |
.fetch_response(url, do_json = true) ⇒ Object
189 190 191 192 193 194 195 196 197 198 |
# File 'lib/onchain/block_chain.rb', line 189 def fetch_response(url, do_json=true) resp = Net::HTTP.get_response(URI.parse(url)) data = resp.body if do_json result = JSON.parse(data) else data end end |
.get_available_suppliers(method_name, network) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/onchain/block_chain.rb', line 124 def get_available_suppliers(method_name, network) available = [] ALL_SUPPLIERS.each do |supplier| if cache_read(supplier.to_s) == nil if supplier == :blockinfo and ! [:bitcoin].include? network next end if supplier == :blockr and ! [:bitcoin, :testnet3].include? network next end if supplier == :insight and ! [:bitcoin, :testnet3].include? network next end if supplier == :bitcoind and ENV[network.to_s.upcase + '_HOST'] == nil next end if supplier == :blockinfo and method_name.to_s == 'send_tx' next end if supplier == :blockinfo and method_name.to_s == 'get_transactions' next end if supplier == :blockr and network == :bitcoin and method_name.to_s == 'address_history' next end if supplier == :blockr and method_name.to_s == 'get_address_info' next end if supplier == :blockr and network == :bitcoin and method_name.to_s == 'get_history_for_addresses' next end available << supplier end end return available end |
.get_balance_satoshi(address, network = :bitcoin) ⇒ Object
120 121 122 |
# File 'lib/onchain/block_chain.rb', line 120 def get_balance_satoshi(address, network = :bitcoin) return (get_balance(address, network = :bitcoin).to_f * 100000000).to_i end |
.get_history_for_addresses(addresses, network = :bitcoin) ⇒ Object
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/onchain/block_chain.rb', line 66 def get_history_for_addresses(addresses, network = :bitcoin) history = [] addresses.each do |address| res = address_history(address, network) res.each do |r| history << r end end return history end |
.get_insight_url(network) ⇒ Object
4 5 6 7 8 9 10 11 |
# File 'lib/onchain/providers/insight_api.rb', line 4 def get_insight_url(network) if network == :bitcoin return "https://insight.bitpay.com/api/" elsif network == :zcash_testnet return "https://explorer.testnet.z.cash/api/" end return "https://test-insight.bitpay.com/api/" end |
.get_uncached_addresses(addresses) ⇒ Object
Given a list of addresses, return those that don’t have balances in the cahce.
79 80 81 82 83 84 85 86 87 |
# File 'lib/onchain/block_chain.rb', line 79 def get_uncached_addresses(addresses) ret = [] addresses.each do |address| if cache_read(address) == nil ret << address end end return ret end |
.get_unspent_for_amount(addresses, amount_in_satoshi, network = :bitcoin) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/onchain/block_chain.rb', line 89 def get_unspent_for_amount(addresses, amount_in_satoshi, network = :bitcoin) unspents = [] indexes = [] amount_so_far = 0 addresses.each_with_index do |address, index| if amount_so_far >= amount_in_satoshi break end unspent_outs = get_unspent_outs(address, network) unspent_outs.each do |spent| unspents << spent indexes << index amount_so_far = amount_so_far + spent[3].to_i if amount_so_far >= amount_in_satoshi break end end end change = amount_so_far - amount_in_satoshi return unspents, indexes, change end |
.get_url(network) ⇒ Object
4 5 6 7 8 9 |
# File 'lib/onchain/providers/blockr_api.rb', line 4 def get_url(network) if network == :bitcoin return "http://btc.blockr.io/api/v1/" end return "http://tbtc.blockr.io/api/v1/" end |
.insight_address_history(address, network = :bitcoin) ⇒ Object
13 14 15 16 17 18 19 20 |
# File 'lib/onchain/providers/insight_api.rb', line 13 def insight_address_history(address, network = :bitcoin) base_url = get_insight_url(network) + "addr/" + address json = fetch_response(base_url, true) return parse_insight_address_tx(address, json, network) end |
.insight_get_all_balances(addresses, network = :bitcoin) ⇒ Object
105 106 107 108 109 110 |
# File 'lib/onchain/providers/insight_api.rb', line 105 def insight_get_all_balances(addresses, network = :bitcoin) addresses.each do |address| insight_get_balance(address, network) end end |
.insight_get_balance(address, network = :bitcoin) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/onchain/providers/insight_api.rb', line 92 def insight_get_balance(address, network = :bitcoin) if cache_read(address + network.to_s) == nil base_url = get_insight_url(network) + "addr/#{address}/balance" bal_string = fetch_response(base_url, false) bal = bal_string.to_i / 100000000.0 cache_write(address + network.to_s, bal, BALANCE_CACHE_FOR) end return cache_read(address + network.to_s) end |
.insight_get_transaction(txhash, network = :bitcoin) ⇒ Object
131 132 133 134 |
# File 'lib/onchain/providers/insight_api.rb', line 131 def insight_get_transaction(txhash, network = :bitcoin) base = get_insight_url(network) + "rawtx/" + txhash return fetch_response(URI::encode(base))['rawtx'] end |
.insight_get_unspent_outs(address, network = :bitcoin) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/onchain/providers/insight_api.rb', line 112 def insight_get_unspent_outs(address, network = :bitcoin) base_url = get_insight_url(network) + "addr/#{address}/utxo" json = fetch_response(base_url, true) unspent = [] json.each do |data| line = [] line << data['txid'] line << data['vout'] line << data['scriptPubKey'] line << (data['amount'].to_f * 100000000).to_i unspent << line end return unspent end |
.insight_send_tx(tx_hex, network = :bitcoin) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/onchain/providers/insight_api.rb', line 69 def insight_send_tx(tx_hex, network = :bitcoin) return OnChain::BlockChain.blockr_send_tx(tx_hex, network) #uri = URI.parse(get_url(network) + "tx/send") #http = Net::HTTP.new(uri.host, uri.port) #request = Net::HTTP::Post.new(uri.request_uri) #request.body = '{"rawtx":"' + tx_hex + '"}' #response = http.request(request) #res = JSON.parse(response.body) #mess = 'Unknown' #stat = 'Unknown' #tx_hash = res["txid"] #puts 'Call insight_send_tx ' + tx_hex.to_s #ret = "{\"status\":\"#{stat}\",\"data\":\"#{tx_hash}\",\"code\":200,\"message\":\"#{mess}\"}" #return JSON.parse(ret) end |
.method_missing(method_name, *args, &block) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/onchain/block_chain.rb', line 33 def method_missing (method_name, *args, &block) network = :bitcoin # List of allowable networks. if args.length > 0 if [:testnet3, :zcash_testnet, :zcash, :zclassic].include? args[args.length - 1] network = args[args.length - 1] end end get_available_suppliers(method_name, network).each do |supplier| real_method = "#{supplier.to_s}_#{method_name}" begin method = self.method(real_method) begin result = method.call(*args) return result rescue => e2 # We have the method but it errored. Assume # service is down. cache_write(supplier.to_s, 'down', SERVICE_DOWN_FOR) puts e2.to_s end rescue => e puts "there's no method called '#{real_method}'" puts e.backtrace end end end |
.parse_address_tx(address, json, network) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/onchain/providers/blockr_api.rb', line 18 def parse_address_tx(address, json, network) hist = [] if json.key?('data') txs = json['data']['txs'] txs.each do |tx| row = {} row[:time] = DateTime.parse(tx["time_utc"]).to_time.to_i row[:addr] = {} row[:outs] = {} row[:hash] = tx["tx"] # OK, go and get the actual transaction tx_json = blockr('tx/info', tx["tx"], network) inputs = tx_json['data']['trade']['vins'] val = 0 recv = "Y" inputs.each do |input| row[:addr][input["address"]] = input["address"] if input["address"] == address recv = "N" end end tx_json['data']['trade']["vouts"].each do |out| row[:outs][out["address"]] = out["address"] if recv == "Y" and out["address"] == address val = val + out["amount"].to_f elsif recv == "N" and out["address"] != address val = val + out["amount"].to_f end end row[:total] = val row[:recv] = recv hist << row end return hist else 'Error' end return hist end |
.parse_bitcoind_address_tx(address, json, network) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 17 def parse_bitcoind_address_tx(address, json, network) hist = [] json.each do |tx| row = {} row[:hash] = tx['txid'] row[:time] = tx['time'] row[:addr] = {} row[:outs] = {} inputs = tx['vin'] val = 0 recv = "Y" inputs.each do |input| row[:addr][input["addr"]] = input["addr"] if input["addr"] == address recv = "N" end end tx['vout'].each do |out| out_addr = out["scriptPubKey"]["addresses"][0] row[:outs][out_addr] = out_addr if recv == "Y" and out_addr == address val = val + out["value"].to_f elsif recv == "N" and out_addr != address val = val + out["value"].to_f end end row[:total] = val row[:recv] = recv hist << row end return hist end |
.parse_insight_address_tx(address, json, network) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/onchain/providers/insight_api.rb', line 22 def parse_insight_address_tx(address, json, network) hist = [] if json.key?('transactions') txs = json['transactions'] txs.each do |tx| row = {} row[:hash] = tx[tx] # OK, go and get the actual transaction base_url = get_insight_url(network) + "tx/" + tx tx_json = fetch_response(base_url, true) row[:time] = tx_json["time"] row[:addr] = {} row[:outs] = {} inputs = tx_json['vin'] val = 0 recv = "Y" inputs.each do |input| row[:addr][input["addr"]] = input["addr"] if input["addr"] == address recv = "N" end end tx_json["vout"].each do |out| out_addr = out["scriptPubKey"]["addresses"][0] row[:outs][out_addr] = out_addr if recv == "Y" and out_addr == address val = val + out["value"].to_f elsif recv == "N" and out_addr != address val = val + out["value"].to_f end end row[:total] = val row[:recv] = recv hist << row end return hist else 'Error' end return hist end |
.reverse_blockchain_tx(hash) ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 130 def reverse_blockchain_tx(hash) bytes = hash.scan(/../).map { |x| x.hex.chr }.join bytes = bytes.reverse return hash.scan(/../).reverse.join end |