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_history_for_addresses(addresses, 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_history_for_addresses(addresses, network = :bitcoin) ⇒ Object
- .blockinfo_get_transaction(txhash) ⇒ Object
- .blockinfo_get_unspent_outs(address, network = :bitcoin) ⇒ 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_history_for_addresses(addresses, 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(commands, 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_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_history_for_addresses(addresses, 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 16 17 18 19 20 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 7 def bitcoind_address_history(address, network = :bitcoin) if cache_read(network.to_s + ' history ' + address) == nil result = execute_remote_command('searchrawtransactions ' + address + ' 1 0 20 0', network) cache_write(network.to_s + ' history ' + address, result, BALANCE_CACHE_FOR) end result = cache_read(network.to_s + ' history ' + address) json = JSON.parse result return parse_bitcoind_address_tx(address, json, network) end |
.bitcoind_get_all_balances(addresses, network = :bitcoin) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 116 def bitcoind_get_all_balances(addresses, network = :bitcoin) # if first address is missing get them all. commands = [] if cache_read(network.to_s + ' ' + addresses[0]) == nil addresses.each do |address| commands << 'getallbalance ' + address + ' 0' end balances = OnChain::BlockChain.execute_remote_command(commands, :zclassic) index = 0 balances.each_line do |line| cache_write(network.to_s + ' ' + addresses[index], line.to_f, BALANCE_CACHE_FOR) index = index + 1 end end addresses.each do |address| bitcoind_get_balance(address, network) end end |
.bitcoind_get_balance(address, network = :bitcoin) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 99 def bitcoind_get_balance(address, network = :bitcoin) if cache_read(network.to_s + ' ' + address) == nil bal = execute_remote_command('getallbalance ' + address + ' 0', network) cache_write(network.to_s + ' ' + address, bal.to_f, BALANCE_CACHE_FOR) end bal = cache_read(network.to_s + ' ' + address) if bal.class == Fixnum bal = bal.to_f end return bal end |
.bitcoind_get_history_for_addresses(addresses, network = :bitcoin) ⇒ 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 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 22 def bitcoind_get_history_for_addresses(addresses, network = :bitcoin) commands = [] if cache_read(network.to_s + ' history ' + addresses[0]) == nil addresses.each do |address| commands << 'searchrawtransactions ' + address + ' 1 0 20 0' end histories = OnChain::BlockChain.execute_remote_command(commands, :zclassic) index = 0 histories.each_line do |history| cache_write(network.to_s + ' history ' + addresses[index], history, BALANCE_CACHE_FOR) index = index + 1 end end history = [] addresses.each do |address| res = bitcoind_address_history(address, network) res.each do |r| history << r end end return history end |
.bitcoind_get_transaction(txhash, network = :bitcoin) ⇒ Object
159 160 161 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 159 def bitcoind_get_transaction(txhash, network = :bitcoin) return execute_remote_command('getrawtransaction ' + txhash, network) end |
.bitcoind_get_unspent_outs(address, network = :bitcoin) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 139 def bitcoind_get_unspent_outs(address, network = :bitcoin) result = execute_remote_command('listallunspent ' + address + ' 1 0', 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
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 87 def bitcoind_send_tx(tx_hex, network = :bitcoin) execute_remote_command('sendrawtransaction ' + tx_hex, network) mess = 'Sent' stat = 'Sent' tx_hash = 'Unknown' ret = "{\"status\":\"#{stat}\",\"data\":\"#{tx_hash}\",\"code\":200,\"message\":\"#{mess}\"}" return JSON.parse(ret) end |
.block_chain(cmd, address, params = "") ⇒ Object
135 136 137 138 139 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 135 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
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 62 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
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 74 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
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 113 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_history_for_addresses(addresses, network = :bitcoin) ⇒ Object
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 12 def blockinfo_get_history_for_addresses(addresses, network = :bitcoin) history = [] addresses.each do |address| res = blockinfo_address_history(address, network) res.each do |r| history << r end end return history end |
.blockinfo_get_transaction(txhash) ⇒ Object
130 131 132 133 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 130 def blockinfo_get_transaction(txhash) base = "https://blockchain.info/rawtx/#{txhash}?format=hex" return fetch_response(URI::encode(base), false) end |
.blockinfo_get_unspent_outs(address, network = :bitcoin) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 95 def blockinfo_get_unspent_outs(address, network = :bitcoin) 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
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 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 23 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
178 179 180 181 182 183 |
# File 'lib/onchain/providers/blockr_api.rb', line 178 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
106 107 108 109 110 111 112 113 114 |
# File 'lib/onchain/providers/blockr_api.rb', line 106 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
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/onchain/providers/blockr_api.rb', line 150 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
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/onchain/providers/blockr_api.rb', line 93 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_history_for_addresses(addresses, network = :bitcoin) ⇒ Object
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/onchain/providers/blockr_api.rb', line 18 def blockr_get_history_for_addresses(addresses, network = :bitcoin) history = [] addresses.each do |address| res = blockr_address_history(address, network) res.each do |r| history << r end end return history end |
.blockr_get_transaction(txhash, network = :bitcoin) ⇒ Object
173 174 175 176 |
# File 'lib/onchain/providers/blockr_api.rb', line 173 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
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/onchain/providers/blockr_api.rb', line 116 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
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/onchain/providers/blockr_api.rb', line 132 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
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/onchain/providers/blockr_api.rb', line 72 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
174 175 176 177 178 179 180 |
# File 'lib/onchain/block_chain.rb', line 174 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
170 171 172 |
# File 'lib/onchain/block_chain.rb', line 170 def cache_write(key, data, max_age=0) @@cache[key] = [Time.now, data, max_age] end |
.execute_remote_command(commands, network) ⇒ Object
Run the command via ssh. For this to work you need to create the follwing ENV vars.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 165 def execute_remote_command(commands, network) host = ENV[network.to_s.upcase + '_HOST'] username = ENV[network.to_s.upcase + '_USER'] password = ENV[network.to_s.upcase + '_PASSWORD'] prefix = ENV[network.to_s.upcase + '_CLI_CMD'] stdout = "" begin Net::SSH.start(host, username, :password => password, :auth_methods => [ 'password' ], :number_of_password_prompts => 0) do |ssh| if ! commands.is_a?(Array) commands = [commands] end commands.each do |command| cmdout = "" ssh.exec! prefix + ' '+ command do |channel, stream, data| cmdout << data if stream == :stdout end stdout << cmdout.tr("\n","") stdout << "\n" 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
182 183 184 185 186 187 188 189 190 191 |
# File 'lib/onchain/block_chain.rb', line 182 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
113 114 115 116 117 118 119 120 121 122 123 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 |
# File 'lib/onchain/block_chain.rb', line 113 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].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 == :insight 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
109 110 111 |
# File 'lib/onchain/block_chain.rb', line 109 def get_balance_satoshi(address, network = :bitcoin) return (get_balance(address, network).to_f * 100000000).to_i 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.
68 69 70 71 72 73 74 75 76 |
# File 'lib/onchain/block_chain.rb', line 68 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
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/onchain/block_chain.rb', line 78 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
116 117 118 119 120 121 |
# File 'lib/onchain/providers/insight_api.rb', line 116 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
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/onchain/providers/insight_api.rb', line 103 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_history_for_addresses(addresses, network = :bitcoin) ⇒ Object
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/onchain/providers/insight_api.rb', line 22 def insight_get_history_for_addresses(addresses, network = :bitcoin) history = [] addresses.each do |address| res = insight_address_history(address, network) res.each do |r| history << r end end return history end |
.insight_get_transaction(txhash, network = :bitcoin) ⇒ Object
142 143 144 145 |
# File 'lib/onchain/providers/insight_api.rb', line 142 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
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/onchain/providers/insight_api.rb', line 123 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
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/onchain/providers/insight_api.rb', line 80 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
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 68 69 70 |
# File 'lib/onchain/providers/blockr_api.rb', line 29 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
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/onchain/providers/bitcoind_api.rb', line 48 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
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 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/onchain/providers/insight_api.rb', line 33 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
141 142 143 144 145 146 147 |
# File 'lib/onchain/providers/blockchaininfo_api.rb', line 141 def reverse_blockchain_tx(hash) bytes = hash.scan(/../).map { |x| x.hex.chr }.join bytes = bytes.reverse return hash.scan(/../).reverse.join end |