communitycart/bitcoin-wallet-api

支持与比特币钱包 JSON-RPC API 通信的 PHP 库。

0.4.0 2014-03-25 19:02 UTC

This package is not auto-updated.

Last update: 2024-09-29 05:14:46 UTC


README

PHP 库,便于与比特币 JSON-RPC API 进行通信。本文档的其余部分将提及比特币钱包,但此库与任何比特币钱包派生版本兼容。包括莱特币和狗狗币的钱包。

概览

本项目旨在提供比简单的 PHP 包装器更丰富的比特币 JSON-RPC API;为此目的的 PHP 库已经很多了。此库通过以下特性旨在比其他库更强大:

  • 为每个 API 调用定义了具体的方法,这意味着现代 IDE 可以提供自动完成和参数文档。
  • 检查每个 API 调用的参数是否具有正确的类型和格式,这在开发和调试期间非常有用。
  • 抽象了一些比特币 API 的复杂性和不一致性,同时尽量接近原始版本。
  • 更好的错误处理和报告。
  • RPCPool 管理以便钱包可以集群,并将查询均匀分布到集群中。
  • 遵循 PSR 标准。
  • 从头开始设计,便于单元测试。
  • 为每个 API 调用提供可靠的文档,通常直接来自比特币源代码。

有关每个方法的详细信息,请参阅 Bitcoin API 维基

要求

安装

将项目添加到 composer.json 中作为依赖项。

"require": {
    "headzoo/bitcoin-wallet-api" : "dev-master"
}

然后运行 composer update

钱包配置

在使用此库之前,您需要将钱包配置为作为服务器运行。这是通过在 bitcoin.conf 文件中添加一些配置值来完成的。如果钱包正在运行,请先关闭它,并找到您的比特币数据目录。在 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

当然,您希望选择一个强密码组合。非比特币钱包的配置方式相同。例如,在 Linux 系统上,莱特币的数据目录位于 /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 类对钱包服务器进行集群和随机查询。Both Headzoo\Bitcoin\Wallet\Api\JsonRPCHeadzoo\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 钱包 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