Class: Bitcoin::Client
- Inherits:
-
Object
- Object
- Bitcoin::Client
- Defined in:
- lib/bc.rb
Instance Attribute Summary collapse
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#jr ⇒ Object
readonly
Returns the value of attribute jr.
-
#password ⇒ Object
readonly
Returns the value of attribute password.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#ssl ⇒ Object
readonly
Returns the value of attribute ssl.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
Instance Method Summary collapse
-
#accounts ⇒ Object
Get an Array of every Account we have.
-
#addresses ⇒ Object
Get an Array of every Address we have.
-
#backup_wallet(path) ⇒ Object
Safely copies our wallet to destination at
path
. -
#balance ⇒ Object
Get the total balance of all our accounts.
-
#bitcoind_version ⇒ Object
This [Fixnum] is the version of bitcoind we’re connecting to.
-
#block_count ⇒ Object
How many blocks are there (that we know about) in the block chain?.
-
#change_wallet_passwd(old_passwd, new_passwd) ⇒ Object
Change the wallet’s passphrase from
old_passwd
tonew_passwd
. -
#connection_count ⇒ Object
How many peers are we connected to?.
-
#difficulty ⇒ Object
This is a Float representing the difficulty associated with finding the next block.
-
#donate(amount) ⇒ Object
Donate
amount
to katmagic (bc’s author). -
#each_transaction_since(block) ⇒ Object
Call the (Ruby) block passed for every transaction that has occurred since
block
(which may be a Block, a block ID, or a block height). -
#encrypt_wallet(passwd) ⇒ Object
Encrypt the wallet with
passwd
and stop bitcoind. -
#generate=(should_generate) ⇒ Object
If
should_generate
istrue
, we instruct bitcoind to begin (or continue) to generate a block. -
#generate? ⇒ Boolean
(also: #generate)
Are we trying to generate a block?.
-
#get_account(label) ⇒ Object
(also: #[])
Get the account associated with the String
label
, or create it if it doesn’t already exist. -
#get_address(addr) ⇒ Object
Get the Address
addr
. -
#get_block(block_id) ⇒ Object
Get the Block with a hash of
block_id
, or ifblock_id
is a Fixnum, the Block with a height ofblock_id
. -
#get_transaction(transaction_id) ⇒ Object
Get the Transaction with the ID
transaction_id
. -
#has_account?(acct) ⇒ Boolean
Does
acct
have any associated addresses?. -
#hashes_per_second ⇒ Object
How many blocks are we hashing per second? This will be zero unless we’re trying to generate a block.
-
#import_private_key(key, label = nil) ⇒ Object
Import a Bitcoin private key.
-
#initialize(user, password, host = '127.0.0.1', port = 8331, ssl = false) ⇒ Client
constructor
A new instance of Client.
-
#is_valid?(addr) ⇒ Boolean
Is
addr
a valid bitcoin address? If we’re using the testnet, normal addresses won’t be valid; if we’re not, testnet addresses won’t be valid. -
#key_pool_size ⇒ Object
This is the (Fixnum) size of our key pool.
-
#latest_block ⇒ Object
This is the latest Block we’ve processed.
-
#latest_remote_block_height ⇒ Object
This returns the height of the last processed block according to blockexplorer.com.
-
#lock_wallet ⇒ Object
Lock the wallet.
-
#memory_pool ⇒ Object
This is a Hash containing data about the next block that will be generated (c.f. the documentation regarding the getmemorypool API call in en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list).
-
#oldest_key ⇒ Object
This is the Time the oldest key in our key pool was created.
-
#percent_complete ⇒ Object
Return the percent of the blockchain we have downloaded according to the number fetched by latest_remote_block_height().
-
#protocol_version ⇒ Object
This (Fixnum) is the version of the Bitcoin RPC protocol we’re communicating in.
-
#proxy ⇒ Object
This is the proxy bitcoind is using, or
nil
if we’re not using a proxy. -
#proxy? ⇒ Boolean
Is bitcoind using a proxy?.
-
#refill_key_pool ⇒ Object
Refill our key pool.
-
#send(dest, amount) ⇒ Object
Send
amount
Bitcoin todest
. -
#stop ⇒ Object
Stop bitcoind.
-
#testnet? ⇒ Boolean
Are we on the testnet?.
-
#transaction_fee ⇒ Object
This is how much we’re configured to use as our transaction fee.
-
#transaction_fee=(fee) ⇒ Object
Set the transaction fee to
fee
. -
#transactions ⇒ Object
Get an Array of every Transaction involving one of our addresses.
-
#unlock_wallet(passwd, timeout = 300) ⇒ Object
Unlock the wallet with
passwd
fortimeout
seconds.
Constructor Details
#initialize(user, password, host = '127.0.0.1', port = 8331, ssl = false) ⇒ Client
Returns a new instance of Client.
563 564 565 566 567 568 569 570 571 572 573 574 |
# File 'lib/bc.rb', line 563 def initialize(user, password, host='127.0.0.1', port=8331, ssl=false) %w{user password host port ssl}.each do |var| instance_variable_set("@#{var}", eval(var)) end @jr = Jr::BigDecimalJr.new(@host, @port, @user, @password, ssl) @accounts = Hash.new @addresses = Hash.new @blocks = Hash.new @transactions = Hash.new end |
Instance Attribute Details
#host ⇒ Object (readonly)
Returns the value of attribute host.
559 560 561 |
# File 'lib/bc.rb', line 559 def host @host end |
#jr ⇒ Object (readonly)
Returns the value of attribute jr.
561 562 563 |
# File 'lib/bc.rb', line 561 def jr @jr end |
#password ⇒ Object (readonly)
Returns the value of attribute password.
559 560 561 |
# File 'lib/bc.rb', line 559 def password @password end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
559 560 561 |
# File 'lib/bc.rb', line 559 def port @port end |
#ssl ⇒ Object (readonly)
Returns the value of attribute ssl.
559 560 561 |
# File 'lib/bc.rb', line 559 def ssl @ssl end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
559 560 561 |
# File 'lib/bc.rb', line 559 def user @user end |
Instance Method Details
#accounts ⇒ Object
Get an Array of every Account we have.
584 585 586 587 588 |
# File 'lib/bc.rb', line 584 def accounts @jr.listreceivedbyaccount(0, true).map do |acct_info| get_account(acct_info.fetch('account')) end end |
#addresses ⇒ Object
Get an Array of every Address we have.
577 578 579 580 581 |
# File 'lib/bc.rb', line 577 def addresses @jr.listreceivedbyaddress(0, true).map do |addr_info| get_address(addr_info.fetch('address')) end end |
#backup_wallet(path) ⇒ Object
Safely copies our wallet to destination at path
. If path
is a directory, we will copy our wallet to path
/wallet.dat.
731 732 733 |
# File 'lib/bc.rb', line 731 def backup_wallet(path) @jr.backupwallet(path) end |
#balance ⇒ Object
Get the total balance of all our accounts. (This includes all transactions with at least 1 confirmation.)
773 774 775 |
# File 'lib/bc.rb', line 773 def balance @jr.getbalance() end |
#bitcoind_version ⇒ Object
This [Fixnum] is the version of bitcoind we’re connecting to.
815 816 817 |
# File 'lib/bc.rb', line 815 def bitcoind_version @jr.getinfo().fetch('version') end |
#block_count ⇒ Object
How many blocks are there (that we know about) in the block chain?
778 779 780 |
# File 'lib/bc.rb', line 778 def block_count @jr.getblockcount() end |
#change_wallet_passwd(old_passwd, new_passwd) ⇒ Object
Change the wallet’s passphrase from old_passwd
to new_passwd
.
741 742 743 744 745 746 747 748 749 750 751 |
# File 'lib/bc.rb', line 741 def change_wallet_passwd(old_passwd, new_passwd) begin @jr.walletpassphrasechange(old_passwd, new_passwd) rescue Jr::ServerError => ex if ex.code == -14 raise InvalidPassphrase, passwd else raise end end end |
#connection_count ⇒ Object
How many peers are we connected to?
783 784 785 |
# File 'lib/bc.rb', line 783 def connection_count @jr.getconnectioncount() end |
#difficulty ⇒ Object
This is a Float representing the difficulty associated with finding the next block. The higher the number, the more difficult it is. (c.f. en.bitcoin.it/wiki/Difficulty)
790 791 792 |
# File 'lib/bc.rb', line 790 def difficulty @jr.getdifficulty() end |
#donate(amount) ⇒ Object
Donate amount
to katmagic (bc’s author).
719 720 721 722 723 724 725 726 727 |
# File 'lib/bc.rb', line 719 def donate(amount) tx = send('1LzDffumxiCSh8wEpxWE8fUozb2LUTcL8L', amount) if STDOUT.tty? puts('katmagic l♥ves y♥u ♥♥dles!') end tx end |
#each_transaction_since(block) ⇒ Object
Call the (Ruby) block passed for every transaction that has occurred since block
(which may be a Block, a block ID, or a block height). We return the last Block processed.
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 |
# File 'lib/bc.rb', line 639 def each_transaction_since(block) unless block.is_a?(Block) block = get_block(block) end info = @jr.listsinceblock(block.block_id) txes = info.fetch('transactions') txes.map!{ |tx| tx.fetch('txid') } txes.uniq! txes.each do |txid| transaction = get_transaction(txid) yield(transaction) end get_block(info.fetch('lastblock')) end |
#encrypt_wallet(passwd) ⇒ Object
Encrypt the wallet with passwd
and stop bitcoind.
736 737 738 |
# File 'lib/bc.rb', line 736 def encrypt_wallet(passwd) @jr.encryptwallet(passwd) end |
#generate=(should_generate) ⇒ Object
If should_generate
is true
, we instruct bitcoind to begin (or continue) to generate a block. If it is false
, we do the opposite.
803 804 805 806 |
# File 'lib/bc.rb', line 803 def generate=(should_generate) @jr.setgenerate(should_generate) should_generate end |
#generate? ⇒ Boolean Also known as: generate
Are we trying to generate a block?
795 796 797 |
# File 'lib/bc.rb', line 795 def generate? @jr.getgenerate() end |
#get_account(label) ⇒ Object Also known as: []
Get the account associated with the String label
, or create it if it doesn’t already exist. The result of this function is cached.
598 599 600 |
# File 'lib/bc.rb', line 598 def get_account(label) @accounts[label] ||= Account.new(self, label) end |
#get_address(addr) ⇒ Object
Get the Address addr
. If addr
is invalid, we raise InvalidAddress. The result of this function is cached.
592 593 594 |
# File 'lib/bc.rb', line 592 def get_address(addr) @addresses[addr] ||= Address.new(self, addr) end |
#get_block(block_id) ⇒ Object
Get the Block with a hash of block_id
, or if block_id
is a Fixnum, the Block with a height of block_id
. If block_id
is an unknown block ID, we raise UnknownBlock+; if block_id
is a Fixnum and there is no associated block, we raise RangeError. The result of this function is cached.
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
# File 'lib/bc.rb', line 613 def get_block(block_id) if block_id.is_a?(Fixnum) begin block_id = @jr.getblockhash(block_id) rescue Jr::ServerError => ex if ex.code == -1 raise RangeError, "block_id #{block_id.inspect} is out of range." else raise end end end @blocks[block_id] ||= Block.new(self, block_id) end |
#get_transaction(transaction_id) ⇒ Object
Get the Transaction with the ID transaction_id
. We raise UnknownTransaction if we don’t know about a Transaction with that ID. The result of this function is cached.
632 633 634 |
# File 'lib/bc.rb', line 632 def get_transaction(transaction_id) @transactions[transaction_id] ||= Transaction.new(self, transaction_id) end |
#has_account?(acct) ⇒ Boolean
Does acct
have any associated addresses?
604 605 606 |
# File 'lib/bc.rb', line 604 def has_account?(acct) !get_account(acct).addresses.empty? end |
#hashes_per_second ⇒ Object
How many blocks are we hashing per second? This will be zero unless we’re trying to generate a block.
810 811 812 |
# File 'lib/bc.rb', line 810 def hashes_per_second @jr.gethashespersec() end |
#import_private_key(key, label = nil) ⇒ Object
Import a Bitcoin private key. We will fail if the key already exists in our wallet. We return an Address. (c.f. get_private_key())
869 870 871 872 |
# File 'lib/bc.rb', line 869 def import_private_key(key, label=nil) label ||= '' @jr.get_address( @jr.importprivkey(key, label) ) end |
#is_valid?(addr) ⇒ Boolean
Is addr
a valid bitcoin address? If we’re using the testnet, normal addresses won’t be valid; if we’re not, testnet addresses won’t be valid.
894 895 896 |
# File 'lib/bc.rb', line 894 def is_valid?(addr) @jr.validateaddress(addr.to_s)['isvalid'] end |
#key_pool_size ⇒ Object
This is the (Fixnum) size of our key pool. The key pool is a pre-generated set of Bitcoin keys which are then allocated through the other address allocation mechanisms. It exists so that backups will (hopefully) contain all the private keys we actually used.
856 857 858 |
# File 'lib/bc.rb', line 856 def key_pool_size @jr.getinfo().fetch('keypoolsize') end |
#latest_block ⇒ Object
This is the latest Block we’ve processed.
670 671 672 |
# File 'lib/bc.rb', line 670 def latest_block get_block( @jr.getinfo().fetch('blocks') ) end |
#latest_remote_block_height ⇒ Object
This returns the height of the last processed block according to blockexplorer.com. Be cautious—this information is provided by a third party! This method may raise exceptions of numerous different types.
677 678 679 680 681 682 |
# File 'lib/bc.rb', line 677 def latest_remote_block_height con = Net::HTTP.new('blockexplorer.com', 443) con.use_ssl = true con.get((testnet? ? '/testnet' : '') + '/q/getblockcount').body.to_i end |
#lock_wallet ⇒ Object
Lock the wallet.
767 768 769 |
# File 'lib/bc.rb', line 767 def lock_wallet() @jr.walletlock() end |
#memory_pool ⇒ Object
This is a Hash containing data about the next block that will be generated (c.f. the documentation regarding the getmemorypool API call in en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list)
863 864 865 |
# File 'lib/bc.rb', line 863 def memory_pool @jr.getmemorypool() end |
#oldest_key ⇒ Object
This is the Time the oldest key in our key pool was created. (c.f. key_pool_size())
848 849 850 |
# File 'lib/bc.rb', line 848 def oldest_key Time.at(@jr.getinfo().fetch('keypoololdest')) end |
#percent_complete ⇒ Object
Return the percent of the blockchain we have downloaded according to the number fetched by latest_remote_block_height(). The warnings there apply here, too.
687 688 689 |
# File 'lib/bc.rb', line 687 def percent_complete (latest_block.height / latest_remote_block_height) * 100 end |
#protocol_version ⇒ Object
This (Fixnum) is the version of the Bitcoin RPC protocol we’re communicating in.
821 822 823 |
# File 'lib/bc.rb', line 821 def protocol_version @jr.getinfo().fetch('protocolversion') end |
#proxy ⇒ Object
This is the proxy bitcoind is using, or nil
if we’re not using a proxy.
826 827 828 |
# File 'lib/bc.rb', line 826 def proxy @jr.getinfo().fetch('proxy') end |
#proxy? ⇒ Boolean
Is bitcoind using a proxy?
831 832 833 |
# File 'lib/bc.rb', line 831 def proxy? !!proxy end |
#refill_key_pool ⇒ Object
Refill our key pool. (c.f. key_pool_size())
875 876 877 |
# File 'lib/bc.rb', line 875 def refill_key_pool() @jr.keypoolrefill() end |
#send(dest, amount) ⇒ Object
Send amount
Bitcoin to dest
. amount
should be a positive real number; dest
can either be a String bitcoin address, or an Address instance. We return a Transaction.
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 |
# File 'lib/bc.rb', line 694 def send(dest, amount) dest = dest.to_s begin txid = @jr.sendtoaddress(dest, amount) rescue Jr::ServerError => ex case ex.code when -13 raise LockedWallet when -6 raise InsufficientFunds.new(amount, balance) when -5 raise InvalidAddress, dest else raise end end get_transaction(txid) end |
#stop ⇒ Object
Stop bitcoind.
888 889 890 |
# File 'lib/bc.rb', line 888 def stop() @jr.stop() end |
#testnet? ⇒ Boolean
Are we on the testnet?
836 837 838 |
# File 'lib/bc.rb', line 836 def testnet? @jr.getinfo().fetch('testnet') end |
#transaction_fee ⇒ Object
This is how much we’re configured to use as our transaction fee. (c.f. en.bitcoin.it/wiki/Transaction_fees)
842 843 844 |
# File 'lib/bc.rb', line 842 def transaction_fee @jr.getinfo().fetch('paytxfee') end |
#transaction_fee=(fee) ⇒ Object
Set the transaction fee to fee
. (c.f. en.bitcoin.it/wiki/Transaction_fees)
881 882 883 884 885 |
# File 'lib/bc.rb', line 881 def transaction_fee=(fee) fee = fee.to_d @jr.settxfee(fee) fee end |
#transactions ⇒ Object
Get an Array of every Transaction involving one of our addresses.
659 660 661 662 663 664 665 666 667 |
# File 'lib/bc.rb', line 659 def transactions transactions = Array.new each_transaction_since(0) do |tx| transactions << tx end transactions end |
#unlock_wallet(passwd, timeout = 300) ⇒ Object
Unlock the wallet with passwd
for timeout
seconds.
754 755 756 757 758 759 760 761 762 763 764 |
# File 'lib/bc.rb', line 754 def unlock_wallet(passwd, timeout=300) begin @jr.walletpassphrase(passwd, timeout) rescue Jr::ServerError => ex if ex.code == -14 raise InvalidPassphrase, passwd else raise end end end |