headzoo / bitcoin-wallet-api
支持与 Bitcoin 钱包 JSON-RPC API 通信的 PHP 库。
Requires
- php: >=5.4.0
- ext-simplexml: *
- headzoo/web-tools: dev-master
- psr/log: dev-master
This package is not auto-updated.
Last update: 2024-09-28 13:09:38 UTC
README
PHP 库,便于与 Bitcoin JSON-RPC API 通信。本文档的其他部分提到 Bitcoin 钱包,但此库与任何 Bitcoin 钱包后裔兼容。包括 Litecoin 和 Dogecoin 的钱包。
概述
本项目旨在提供比简单的 PHP 包装器更强大的 Bitcoin JSON-RPC API;有大量 PHP 库用于此目的。本库通过以下功能旨在比其他库更强大:
- 为每个 API 调用定义了具体的方
- 检查每个 API 调用的参数类型和格式是否正确,这在开发和调试期间非常有用。
- 抽象化了一些 Bitcoin API 的复杂性和不一致性,同时尽量接近原始 API。
- 更好的错误处理和报告。
- RPCPool 管理以实现钱包集群,并将查询均匀分布到集群。
- 遵循 PSR 标准。
- 从头开始设计,便于进行单元测试。
- 为每个 API 调用提供详尽的文档,通常直接从 Bitcoin 源代码中获取。
有关每个方法的详细信息,请参阅 Bitcoin API 维基。
需求
安装
将项目添加到您的 composer.json 中作为依赖项。
"require": {
"headzoo/bitcoin-wallet-api" : "dev-master"
}
然后运行 composer update
。
钱包配置
在开始使用此库之前,您需要将钱包配置为服务器。这通过向 bitcoin.conf
文件添加一些配置值来完成。如果钱包正在运行,请先将其关闭,并找到您的 Bitcoin 数据目录。默认情况下,在 Linux 系统上,数据目录位于 /home/[user]/.bitcoin
,在 Windows 系统上,位于 /Users/[user]/AppData/Roaming/Bitcoin
。如果尚不存在,则在数据目录中创建 bitcoin.conf
文件。
添加以下行
rpcuser=testuser
rpcpassword=testpass
rpcallowip=127.0.0.1
rpcport=9335
server=1
当然,您希望选择一个强大的用户名和密码组合。非 Bitcoin 钱包的配置方式相同。例如,在 Linux 系统上,Litecoin 的数据目录位于 /home/[user]/.litecoin
,在 Windows 系统上,位于 /Users/[user]/AppData/Roaming/Litecoin
,配置文件命名为 litecoin.conf。
注意:如果想要查询非钱包交易,还需要将 txindex=1
添加到配置中。您可能需要在第一次添加此配置指令后使用 -rescan
开关启动钱包。
快速开始
<?php use Headzoo\Bitcoin\Wallet\Api\JsonRPC; use Headzoo\Bitcoin\Wallet\Api\Wallet; use Headzoo\Bitcoin\Wallet\Api\RPCException; // These configuration settings must match those from the bitcoin.conf file. $conf = [ "user" => "testuser", "pass" => "testpass", "host" => "127.0.0.1", "port" => 9332 ]; // Begin by creating a Wallet instance, which needs an instance of JsonRPC passed to it's constructor. $wallet = new Wallet(new JsonRPC($conf)); try { // Get some basic information from the wallet. $info = $wallet->getInfo(); print_r($info); } catch (RPCException $e) { echo $e->getTraceAsString(); die(); } // Example output: // [ // "version" => 90000, // "protocolversion" => 70002, // "walletversion" => 60000, // "balance" => 6.02730425, // "blocks" => 292075, // "timeoffset" => -1, // "connections" => 65, // "proxy" => "", // "difficulty" => 4250217919.86953540, // "testnet" => false, // "keypoololdest" => 1387569300, // "keypoolsize" => 101, // "paytxfee" => 0, // "mininput" => 0.00100000, // "unlocked_until" => 0, // "errors" => "" // ] try { // Get information about a specific block from the block chain. $block = $wallet->getBlock("00000000000000005242ff2ddc9a407d67632ae7ee97f8c472358931b8bfc679"); print_r($block); } catch (RPCException $e) { echo $e->getTraceAsString(); die(); } // Example output: // [ // "hash" => "00000000000000005242ff2ddc9a407d67632ae7ee97f8c472358931b8bfc679", // "confirmations" => 6, // "size" => 76575, // "height" => 292068, // "version" => 2, // "merkleroot" => "2520dd58da8b7e8d9f416db0c2d6669e63eb722a6bc6c344abfcfe64ac0ab024", // "tx" => [ // "38c78866705c623615c502f13dff5da60cdfee74ec77025bbc0cd419b215bf5d", // "46f551c0ba5822410c2349c6114dfb668adab827180eb5489a289b940e996682" // ], // "time" => 1395587882, // "nonce" => 1796742204, // "bits" => "190102b1", // "difficulty" => 4250217919.86953540, // "chainwork" => "000000000000000000000000000000000000000000002c6e31ad55d7fe8c8665", // "previousblockhash" => "0000000000000000fa0424195c23ca1078d04011796f382778f211bde0a08ae5", // "nextblockhash" => "0000000000000000c965941f8821c858c882414f0819aeccf1593076f97cb150" // ] // Signing a message using an address from the wallet, and then verifying the signature. $address = "16sycWcsHDM1iedeLs11jDmryqHwsz8Bfd"; $message = "Mary had a little lamb."; try { // Encrypted wallets must be unlocked first. $wallet->unlock("asd3sd945DS3a8D"); $signature = $wallet->signMessage($address, $message); var_dump($signature); } catch (RPCException $e) { echo $e->getTraceAsString(); die(); } // Example output: // "IEE8F4Idkqt/q4qN4dXrMQBwrpetyrbAtPYptw+PM8As+XhSjo3qedsrlCccjaX7W+Gm9uXFz/MfLonwObgJkYw=" try { $is_valid = $wallet->isSignedMessageValid($address, $signature, $message); var_dump($is_valid); } catch (RPCException $e) { echo $e->getTraceAsString(); die(); } // Example output: // bool(true)
类文档
完整的类 API 文档可在 /docs 目录中找到。
Headzoo\Bitcoin\Wallet\Api\JsonRPC
与支持JSON-RPC API的比特币钱包直接通信的核心类。该类通过Headzoo\Bitcoin\Wallet\Api\JsonRPCInterface
接口提供单个query($method, array $params = [])
方法。尽管您可以直接使用此类查询钱包,但最好使用Headzoo\Bitcoin\Wallet\Api\Wallet
的实例。
<?php use Headzoo\Bitcoin\Wallet\Api\JsonRPC; use Headzoo\Bitcoin\Wallet\Api\RPCException; $conf = [ "user" => "testuser", "pass" => "testpass", "host" => "127.0.0.1", "port" => 9332 ]; $rpc = new JsonRPC($conf); try { $info = $rpc->query("getinfo"); } catch (RPCException $e) { echo $e->getTraceAsString(); die(); }
Headzoo\Bitcoin\Wallet\Api\Wallet
封装了Headzoo\Bitcoin\Wallet\Api\JsonRPCInterface
的实例,以提供对钱包API的高级接口。此类具有针对每个API调用的方法,例如Headzoo\Bitcoin\Wallet\Api\Wallet::getInfo()
、Headzoo\Bitcoin\Wallet\Api\Wallet::backup($destination)
、Headzoo\Bitcoin\Wallet\Api\Wallet::getAccount($account)
等。使用此类而不是直接使用Headzoo\Bitcoin\Wallet\Api\JsonRPC
可以更容易地捕获编程错误,并允许IDE提供自动完成和类型提示。
<?php use Headzoo\Bitcoin\Wallet\Api\JsonRPC; use Headzoo\Bitcoin\Wallet\Api\Wallet; use Headzoo\Bitcoin\Wallet\Api\RPCException; $conf = [ "user" => "testnet", "pass" => "testnet", "host" => "localhost", "port" => 9332 ]; try { $wallet = new Wallet(JsonRPC($conf)); $info = $wallet->getInfo(); $account = $wallet->getAccount("personal"); $count = $wallet->getBlockCount(); } catch (RPCException $e) { echo $e->getTraceAsString(); die(); }
Headzoo\Bitcoin\Wallet\Api\RPCPool
可以使用Headzoo\Bitcoin\Wallet\Api\RPCPool
类将钱包服务器进行集群并随机查询。无论是Headzoo\Bitcoin\Wallet\Api\JsonRPC
还是Headzoo\Bitcoin\Wallet\Api\RPCPool
,都实现了Headzoo\Bitcoin\Wallet\Api\JsonRPCInterface
,这意味着它们都可以传递给Headzoo\Bitcoin\Wallet\Api\Wallet
构造函数。
<?php use Headzoo\Bitcoin\Wallet\Api\RPCPool; use Headzoo\Bitcoin\Wallet\Api\JsonRPC; use Headzoo\Bitcoin\Wallet\Api\RPCException; // Start by creating a new pool, adding JsonRPCInterface instances to it, and then pass the pool // to the Wallet constructor. $conf = [ "wallet1" => [ "user" => "testnet", "pass" => "testnet", "host" => "localhost", "port" => 9332 ], "wallet2" => [ "user" => "testnet", "pass" => "testnet", "host" => "localhost", "port" => 9333 ] ]; $pool = new RPCPool(); $pool->add(new JsonRPC($conf["wallet1"])); $pool->add(new JsonRPC($conf["wallet2"])); $wallet = new Wallet($pool); // A different server will be chosen by the pool for each method call. try { $info = $wallet->getInfo(); $balance = $wallet->getBalance(); $accounts = $wallet->getAccounts(); } catch (Headzoo\Bitcoin\Wallet\Api\RPCException $e) { echo $e->getTraceAsString(); die(); }
变更日志
v0.4.0 - 2014/03/23
- 将最低PHP版本提高到5.5。
- 将项目重命名为Bitcoin Wallet API。
- 将命名空间
Headzoo\CoinTalk
重命名为Headzoo\Bitcoin\Wallet\Api
。 - 重构了单元测试以使用更多的模拟。
- 使用headzoo/web-tools进行HTTP请求。
v0.3.0 - 2014/03/23
- 将类
Headzoo\CoinTalk\Api
重命名为Headzoo\CoinTalk\Wallet
。 - 将类
Headzoo\CoinTalk\Server
重命名为Headzoo\CoinTalk\JsonRPC
。 - 将类
Headzoo\CoinTalk\IServer
重命名为Headzoo\CoinTalk\JsonRPCInterface
。 - 将类
Headzoo\CoinTalk\Pool
重命名为Headzoo\CoinTalk\RPCPool
。 - 将类
Headzoo\CoinTalk\Wallet
中以list
开头的所有方法重命名为get
,例如将listAccounts()
重命名为getAccounts()
。 - 将以下方法重命名,以使方法名更加一致,并符合我的命名规范
Headzoo\CoinTalk\Wallet::sendRawTransaction()
重命名为Headzoo\CoinTalk\Wallet::submitRawTransaction()
。Headzoo\CoinTalk\Wallet::submitBlock()
重命名为Headzoo\CoinTalk\Wallet::submitRawBlock()
。Headzoo\CoinTalk\Wallet::getRawMemPool()
重命名为Headzoo\CoinTalk\Wallet::getTransactionsFromMemoryPool()
。Headzoo\CoinTalk\Wallet::dumpPrivKey()
重命名为Headzoo\CoinTalk\Wallet::getPrivateKeyByAddress()
。Headzoo\CoinTalk\Wallet::importPrivKey()
重命名为Headzoo\CoinTalk\Wallet::addPrivateKey()
。Headzoo\CoinTalk\Wallet::lockUnspent()
重命名为Headzoo\CoinTalk\Wallet::setLockUnspent()
。Headzoo\CoinTalk\Wallet::sendToAddress()
重命名为Headzoo\CoinTalk\Wallet::send()
。Headzoo\CoinTalk\Wallet::sendFrom()
重命名为Headzoo\CoinTalk\Wallet::sendFromAccount()
。Headzoo\CoinTalk\Wallet::sendMany()
重命名为Headzoo\CoinTalk\Wallet::sendManyFromAccount()
。Headzoo\CoinTalk\Wallet::verifyMessage()
重命名为Headzoo\CoinTalk\Wallet::isSignedMessageValid()
。Headzoo\CoinTalk\Wallet::validateAddress()
重命名为Headzoo\CoinTalk\Wallet::getAddressInfo()
。Headzoo\CoinTalk\Wallet::encryptWallet()
重命名为Headzoo\CoinTalk\Wallet::encrypt()
。Headzoo\CoinTalk\Wallet::walletLock()
重命名为Headzoo\CoinTalk\Wallet::lock()
。Headzoo\CoinTalk\Wallet::walletPassPhrase()
重命名为Headzoo\CoinTalk\Wallet::unlock()
。Headzoo\CoinTalk\Wallet::walletPassPhraseChange()
重命名为Headzoo\CoinTalk\Wallet::changePassPhrase()
。Headzoo\CoinTalk\Wallet::keyPoolRefill()
重命名为Headzoo\CoinTalk\Wallet::fillKeyPool()
。Headzoo\CoinTalk\Wallet::stop()
重命名为Headzoo\CoinTalk\Wallet::stop()
。Headzoo\CoinTalk\Wallet::setTxFee()
重命名为Headzoo\CoinTalk\Wallet::setTransactionFee()
。Headzoo\CoinTalk\Wallet::getReceivedByAddress()
重命名为Headzoo\CoinTalk\Wallet::getBalanceByAddress()
。Headzoo\CoinTalk\Wallet::getAccount()
重命名为Headzoo\CoinTalk\Wallet::getAccountByAddress()
。Headzoo\CoinTalk\Wallet::getAccountAddress()
重命名为Headzoo\CoinTalk\Wallet::getAddressByAccount()
。Headzoo\CoinTalk\Wallet::createMultiSig()
重命名为Headzoo\CoinTalk\Wallet::getNewMultiSignatureAddress()
。Headzoo\CoinTalk\Wallet::addMultiSigAddress()
重命名为Headzoo\CoinTalk\Wallet::addMultiSignatureAddress()
。Headzoo\CoinTalk\Wallet::getTxOut()
重命名为Headzoo\CoinTalk\Wallet::getTransactionOut()
。Headzoo\CoinTalk\Wallet::getTxOutSetInfo()
重命名为Headzoo\CoinTalk\Wallet::getTransactionOutSet()
。Headzoo\CoinTalk\Wallet::getAddedNodeInfo()
修改为Headzoo\CoinTalk\Wallet::getNodeInfo()
.
- 删除了以下方法
Headzoo\CoinTalk\Wallet::getReceivedByAccount()
.Headzoo\CoinTalk\Wallet::listReceivedByAccount()
.
v0.2.0 - 2013/12/31
- 一些小调整。
v0.1.0 - 2013/12/18
- 创世导入!
待办事项
- 确保钱包服务器版本支持特定调用。
- 记录需要解锁钱包的方法。
- 创建表示以下内容的类
- 区块
- 密钥(公钥/私钥)
- 交易
- 等等
许可证
本内容发布在MIT许可证下。有关更多信息,请参阅包含的LICENSE文件。
我编写代码因为我喜欢编写代码,编写代码本身就是一种回报,但捐赠总是受欢迎。
比特币:1Headz2mYtpBRo6KFaaUEtcm5Kce6BZRJM
莱特币:LheadzBgTNAitxYxUTUTTQ3RT7zR5jnkfq