class OpenAssets::Provider::BitcoinCoreProvider

The implementation of BlockChain provider using Bitcoin Core.

Attributes

config[R]

Public Class Methods

new(config) click to toggle source
# File lib/openassets/provider/bitcoin_core_provider.rb, line 11
def initialize(config)
  @config = config

  commands = request(:help).split("\n").inject([]) do |memo_ary, line|
    if !line.empty? && !line.start_with?('==')
      memo_ary << line.split(' ').first.to_sym
    end
    memo_ary
  end
  BitcoinCoreProvider.class_eval do
    commands.each do |command|
      define_method(command) do |*params|
        request(command, *params)
      end
    end
  end
end

Public Instance Methods

get_transaction(transaction_hash, verbose = 0) click to toggle source

Get raw transaction. @param [String] transaction_hash The transaction hash. @param [String] verbose Whether to get the serialized or decoded transaction. 0: serialized transaction (Default). 1: decode transaction. @return [String] (if verbose=0)—the serialized transaction. (if verbose=1)—the decoded transaction. (if transaction not found)—nil.

# File lib/openassets/provider/bitcoin_core_provider.rb, line 41
def get_transaction(transaction_hash, verbose = 0)
  begin
    getrawtransaction(transaction_hash, verbose)
  rescue OpenAssets::Provider::ApiError => e
    nil
  end
end
import_address(address) click to toggle source

Adds an address or pubkey script to the wallet without the associated private key, allowing you to watch for transactions affecting that address or pubkey script without being able to spend any of its outputs. @param [String] address Either a P2PKH or P2SH address encoded in base58check, or a pubkey script encoded as hex.

# File lib/openassets/provider/bitcoin_core_provider.rb, line 67
def import_address(address)
  importaddress(address)
end
list_unspent(addresses = [], min = 1 , max = 9999999) click to toggle source

Get an array of unspent transaction outputs belonging to this wallet. @param [Array] addresses If present, only outputs which pay an address in this array will be returned. @param [Integer] min The minimum number of confirmations the transaction containing an output must have in order to be returned. Default is 1. @param [Integer] max The maximum number of confirmations the transaction containing an output may have in order to be returned. Default is 9999999.

# File lib/openassets/provider/bitcoin_core_provider.rb, line 33
def list_unspent(addresses = [], min = 1 , max = 9999999)
  listunspent(min, max, addresses)
end
send_transaction(tx) click to toggle source

Validates a transaction and broadcasts it to the peer-to-peer network. @param [String] tx The serialized format transaction. @return [String] The TXID or error message.

# File lib/openassets/provider/bitcoin_core_provider.rb, line 61
def send_transaction(tx)
  sendrawtransaction(tx)
end
sign_transaction(tx) click to toggle source

Signs a transaction in the serialized transaction format using private keys. @param [String] tx The serialized format transaction. @return [Bitcoin::Protocol::Tx] The signed transaction.

# File lib/openassets/provider/bitcoin_core_provider.rb, line 52
def sign_transaction(tx)
  signed_tx = signrawtransaction(tx)
  raise OpenAssets::Error, 'Could not sign the transaction.' unless signed_tx['complete']
  Bitcoin::Protocol::Tx.new(signed_tx['hex'].htb)
end

Private Instance Methods

decode_tx_to_btc_tx(tx) click to toggle source

Convert decode tx string to Bitcion::Protocol::Tx

# File lib/openassets/provider/bitcoin_core_provider.rb, line 73
def decode_tx_to_btc_tx(tx)
  hash = {
    'version' => tx['version'],
    'lock_time' => tx['locktime'],
    'hex' => tx['hex'],
    'txid' => tx['txid'],
    'blockhash' => tx['blockhash'],
    'confirmations' => tx['confirmations'],
    'time' => tx['time'],
    'blocktime' => tx['blocktime'],
    'in' => tx['vin'].map{|input|
      {'output_index' => input['vout'], 'previous_transaction_hash' => input['txid'], 'coinbase' => input['coinbase'],
       'scriptSig' => input['scriptSig']['asm'], 'sequence' => input['sequence']}},
    'out' => tx['vout'].map{|out|
      {'amount' => out['value'], 'scriptPubKey' => out['scriptPubKey']['asm']}
    }
  }
  Bitcoin::Protocol::Tx.from_hash(hash)
end
post(url, timeout, open_timeout, payload, headers={}, &block) click to toggle source
# File lib/openassets/provider/bitcoin_core_provider.rb, line 118
def post(url, timeout, open_timeout, payload, headers={}, &block)
  RestClient::Request.execute(:method => :post, :url => url, :timeout => timeout, :open_timeout => open_timeout, :payload => payload, :headers => headers, &block)
end
request(command, *params) click to toggle source
# File lib/openassets/provider/bitcoin_core_provider.rb, line 104
def request(command, *params)
  data = {
    :method => command,
    :params => params,
    :id => 'jsonrpc'
  }
  post(server_url, @config[:timeout], @config[:open_timeout], data.to_json, content_type: :json) do |respdata, request, result|
    raise ApiError, result.message if !result.kind_of?(Net::HTTPSuccess) && respdata.empty?
    response = JSON.parse(respdata.gsub(/\\u([\da-fA-F]{4})/) { [$1].pack('H*').unpack('n*').pack('U*').encode('ISO-8859-1').force_encoding('UTF-8') })
    raise ApiError, response['error'] if response['error']
    response['result']
  end
end
server_url() click to toggle source
# File lib/openassets/provider/bitcoin_core_provider.rb, line 94
def server_url
  url = "#{@config[:schema]}://"
  url.concat "#{@config[:user]}:#{@config[:password]}@"
  url.concat "#{@config[:host]}:#{@config[:port]}"
  if !@config[:wallet].nil? && !@config[:wallet].empty?
    url.concat "/wallet/#{@config[:wallet]}"
  end
  url
end