headzoo/bitcoin-wallet-api

支持与 Bitcoin 钱包 JSON-RPC API 通信的 PHP 库。

0.4.0 2014-03-25 19:02 UTC

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