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.
557 558 559 560 561 562 563 564 565 566 567 568 |
# File 'lib/bc.rb', line 557 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::Jr.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.
553 554 555 |
# File 'lib/bc.rb', line 553 def host @host end |
#jr ⇒ Object (readonly)
Returns the value of attribute jr.
555 556 557 |
# File 'lib/bc.rb', line 555 def jr @jr end |
#password ⇒ Object (readonly)
Returns the value of attribute password.
553 554 555 |
# File 'lib/bc.rb', line 553 def password @password end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
553 554 555 |
# File 'lib/bc.rb', line 553 def port @port end |
#ssl ⇒ Object (readonly)
Returns the value of attribute ssl.
553 554 555 |
# File 'lib/bc.rb', line 553 def ssl @ssl end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
553 554 555 |
# File 'lib/bc.rb', line 553 def user @user end |
Instance Method Details
#accounts ⇒ Object
Get an Array of every Account we have.
578 579 580 581 582 |
# File 'lib/bc.rb', line 578 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.
571 572 573 574 575 |
# File 'lib/bc.rb', line 571 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.
725 726 727 |
# File 'lib/bc.rb', line 725 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.)
767 768 769 |
# File 'lib/bc.rb', line 767 def balance @jr.getbalance() end |
#bitcoind_version ⇒ Object
This [Fixnum] is the version of bitcoind we’re connecting to.
809 810 811 |
# File 'lib/bc.rb', line 809 def bitcoind_version @jr.getinfo().fetch('version') end |
#block_count ⇒ Object
How many blocks are there (that we know about) in the block chain?
772 773 774 |
# File 'lib/bc.rb', line 772 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
.
735 736 737 738 739 740 741 742 743 744 745 |
# File 'lib/bc.rb', line 735 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?
777 778 779 |
# File 'lib/bc.rb', line 777 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)
784 785 786 |
# File 'lib/bc.rb', line 784 def difficulty @jr.getdifficulty() end |
#donate(amount) ⇒ Object
Donate amount
to katmagic (bc’s author).
713 714 715 716 717 718 719 720 721 |
# File 'lib/bc.rb', line 713 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.
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 |
# File 'lib/bc.rb', line 633 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.
730 731 732 |
# File 'lib/bc.rb', line 730 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.
797 798 799 800 |
# File 'lib/bc.rb', line 797 def generate=(should_generate) @jr.setgenerate(should_generate) should_generate end |
#generate? ⇒ Boolean Also known as: generate
Are we trying to generate a block?
789 790 791 |
# File 'lib/bc.rb', line 789 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.
592 593 594 |
# File 'lib/bc.rb', line 592 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.
586 587 588 |
# File 'lib/bc.rb', line 586 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.
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
# File 'lib/bc.rb', line 607 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.
626 627 628 |
# File 'lib/bc.rb', line 626 def get_transaction(transaction_id) @transactions[transaction_id] ||= Transaction.new(self, transaction_id) end |
#has_account?(acct) ⇒ Boolean
Does acct
have any associated addresses?
598 599 600 |
# File 'lib/bc.rb', line 598 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.
804 805 806 |
# File 'lib/bc.rb', line 804 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())
863 864 865 866 |
# File 'lib/bc.rb', line 863 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.
888 889 890 |
# File 'lib/bc.rb', line 888 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.
850 851 852 |
# File 'lib/bc.rb', line 850 def key_pool_size @jr.getinfo().fetch('keypoolsize') end |
#latest_block ⇒ Object
This is the latest Block we’ve processed.
664 665 666 |
# File 'lib/bc.rb', line 664 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.
671 672 673 674 675 676 |
# File 'lib/bc.rb', line 671 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.
761 762 763 |
# File 'lib/bc.rb', line 761 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)
857 858 859 |
# File 'lib/bc.rb', line 857 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())
842 843 844 |
# File 'lib/bc.rb', line 842 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.
681 682 683 |
# File 'lib/bc.rb', line 681 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.
815 816 817 |
# File 'lib/bc.rb', line 815 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.
820 821 822 |
# File 'lib/bc.rb', line 820 def proxy @jr.getinfo().fetch('proxy') end |
#proxy? ⇒ Boolean
Is bitcoind using a proxy?
825 826 827 |
# File 'lib/bc.rb', line 825 def proxy? !!proxy end |
#refill_key_pool ⇒ Object
Refill our key pool. (c.f. key_pool_size())
869 870 871 |
# File 'lib/bc.rb', line 869 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.
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 |
# File 'lib/bc.rb', line 688 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.
882 883 884 |
# File 'lib/bc.rb', line 882 def stop() @jr.stop() end |
#testnet? ⇒ Boolean
Are we on the testnet?
830 831 832 |
# File 'lib/bc.rb', line 830 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)
836 837 838 |
# File 'lib/bc.rb', line 836 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)
875 876 877 878 879 |
# File 'lib/bc.rb', line 875 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.
653 654 655 656 657 658 659 660 661 |
# File 'lib/bc.rb', line 653 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.
748 749 750 751 752 753 754 755 756 757 758 |
# File 'lib/bc.rb', line 748 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 |