class VChainClient::BitcoindBlockchainAdapter
Public Class Methods
new(server, port, rpc_username, rpc_password, adapter_config, app_config)
click to toggle source
# File lib/vchain_client/bitcoind_blockchain_adapter.rb, line 16 def initialize(server, port, rpc_username, rpc_password, adapter_config, app_config) @server = server @port = port @rpc_username = rpc_username @rpc_password = rpc_password @config = app_config @log = Log4r::Logger["vchain_client"] end
Public Instance Methods
getName()
click to toggle source
# File lib/vchain_client/bitcoind_blockchain_adapter.rb, line 27 def getName() return "BitcoindBlockchainAdapter" end
getOpReturn(raw_tx)
click to toggle source
# File lib/vchain_client/bitcoind_blockchain_adapter.rb, line 258 def getOpReturn(raw_tx) if @log.debug? @log.debug("[Bitcoind.getOpReturn] input:") @log.debug("-> raw_tx:") @log.debug(raw_tx) end if raw_tx != nil tx_unpacked = {} tx_unpacked["vout"] = [] if raw_tx.key?("vout") if raw_tx["vout"].length > 0 raw_tx["vout"].each_with_index { |vout,index| vout_t = {} vout_t["value"] = 0 if vout.key?("value") vout_t["value"] = vout["value"] end vout_t["scriptPubKey"] = "" if vout.key?("scriptPubKey") if vout["scriptPubKey"].key?("hex") vout_t["scriptPubKey"] = vout["scriptPubKey"]["hex"] end end tx_unpacked["vout"][index] = vout_t; } tx_unpacked["vout"].each { |output| scriptPubKeyArr = output["scriptPubKey"].split() scriptPubKeyBinary = scriptPubKeyArr.pack("H*") if scriptPubKeyBinary[0] == "\x6a" first_ord = scriptPubKeyBinary[1].ord() if first_ord <= 75 return scriptPubKeyBinary[2..first_ord+1] elsif first_ord == 0x4c return scriptPubKeyBinary[3..scriptPubKeyBinary[2].ord()+1] elsif first_ord == 0x4d return scriptPubKeyBinary[4..scriptPubKeyBinary[2].ord()+1+256*scriptPubKeyBinary[3].ord()+1] end end } end end else if @log.error? @log.error("[Bitcoind.getOpReturn] raw_tx is nil") @log.error("-> raw_tx:") @log.error(raw_tx) end end return nil end
getRawTx(txid)
click to toggle source
# File lib/vchain_client/bitcoind_blockchain_adapter.rb, line 198 def getRawTx(txid) if @log.debug? @log.debug("[Bitcoind.getRawTx] input:") @log.debug("-> txid: #{txid}") @log.debug("-> server: #{@server}") @log.debug("-> port: #{@port}") end request = { "id" => Random.rand(0...999999), "method" => "getrawtransaction", "params" => [txid, 1] } url = "http://"+ @rpc_username +":"+ @rpc_password +"@"+ @server +":"+ @port +"/" begin req = RestClient.post(url, request.to_json) if req.code != 200 if @log.error? @log.error("[Bitcoind.getRawTx] RestClient.post return code "+ req.code) @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> request:") @log.error(request) end return nil end if @log.debug? @log.debug("[Bitcoind.getRawTx] response:") @log.debug(req.body) end raw_tx = JSON.parse req.body return raw_tx["result"] rescue => e if @log.error? @log.error("[Bitcoind.getRawTx] RestClient.post raised exception:") @log.error("#{e.class}, #{e.message}") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> request:") @log.error(request) end raise e end return nil end
getTx(txid)
click to toggle source
# File lib/vchain_client/bitcoind_blockchain_adapter.rb, line 31 def getTx(txid) if @@tx_cache.key?(txid) if @log.debug? @log.debug("[Bitcoind.getTx] '#{txid}' is in a cache") end return @@tx_cache[txid] end if @log.debug? @log.debug("[Bitcoind.getTx] input:") @log.debug("-> txid: #{txid}") @log.debug("-> server: #{@server}") @log.debug("-> port: #{@port}") end raw_tx = nil begin raw_tx = self.getRawTx(txid) rescue => e if @log.error? @log.error("[Bitcoind.getTx] getRawTx raised exception:") @log.error("#{e.class}, #{e.message}") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("--> txid: #{txid}") end raise e end confirmations_threshold = 5 if @config.key?("blockchain_confirmations") confirmations_threshold = @config["blockchain_confirmations"] end if raw_tx != nil if raw_tx.key?("confirmations") if raw_tx["confirmations"] > confirmations_threshold if raw_tx.key?("blockhash") if raw_tx.key?("blocktime") op_return = nil begin op_return = self.getOpReturn(raw_tx) rescue => e if @log.error? @log.error("[Bitcoind.getTx] getOpReturn raised exception:") @log.error("#{e.class}, #{e.message}") @log.error("-> txid: #{txid}") @log.error("--> raw_tx:") @log.error(raw_tx) end raise e end if op_return != nil prefix = op_return[0..2] if prefix == "VCH" op_return = op_return[5..op_return.length] out = { "size" => raw_tx["size"], "block_hash" => raw_tx["blockhash"], "block_timestamp" => raw_tx["blocktime"], "op_return" => op_return } @@tx_cache[txid] = out return out else if @log.error? @log.error("[Bitcoind.getTx] wrong prefix '#{prefix}'") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> raw_tx:") @log.error(raw_tx) end end else if @log.error? @log.error("[Bitcoind.getTx] failed to get OP_RETURN") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> raw_tx:") @log.error(raw_tx) end end else if @log.error? @log.error("[Bitcoind.getTx] no 'block_hash' field in response") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> raw_tx:") @log.error(raw_tx) end end else if @log.error? @log.error("[Bitcoind.getTx] no 'block_hash' field in response") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> raw_tx:") @log.error(raw_tx) end end else if @log.error? @log.error("[Bitcoind.getTx] less than 6 confirmations") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> raw_tx:") @log.error(raw_tx) end end else if @log.error? @log.error("[Bitcoind.getTx] no 'confirmations' field") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("-> raw_tx:") @log.error(raw_tx) end end else if @log.error? @log.error("[Bitcoind.getTx] empty raw_tx") @log.error("-> txid: #{txid}") @log.error("-> server: #{@server}") @log.error("-> port: #{@port}") @log.error("--> txid: #{txid}") end end return nil end