rpc php扫区块,怎样通过RPC命令实现区块链(blockchain)的查询?

本文介绍了如何使用RPC命令与区块链集成,实现类似blockexplorer.com和blockchain.info的功能。通过建立索引和解析交易数据,可以进行区块、交易和地址的查询。文章详细阐述了查询流程,包括根据区块高度或哈希查询、交易查询以及如何获取交易输入地址。此外,还分享了一个实际案例,展示了如何根据txid获取打款地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近体验了

blockexplorer.com

blockchain.info

qukuai.com

等基于区块链的查询工具,通过读代码发现

基本架构如下:

前端web基于socket.io或者REST实现,

后端加一层mongodb/mysql等数据库来代替单机leveldb做数据存储

目的应该是:

1. 加速查询

2. 做更高层的数据分析

3.做分布式数据库

思考:

这些online的查询固然可以方便我们的日常用, 那如何与相关应用集成呢? 我们是否可以通过简单的rpc命令实现同等的效果?

有几个用处:

1 . 大家都可以做自己的qukuai.com或blockchain.info的查询:)

2.  集成RPC命令到自己的店铺,收款后查询用

3.  集成到钱包应用

4.  其他应用场景

cmd分析:

根据高度height查block hash

./bitcoin-cli getblockhash 19999

00000000ba36eb929dc90170a96ee3efb76cbebee0e0e5c4da9eb0b6e74d9124

2. 然后根据block hash查block 信息

./bitcoin-cli getblock 00000000ba36eb929dc90170a96ee3efb76cbebee0e0e5c4da9eb0b6e74d9124

{

"hash" : "00000000ba36eb929dc90170a96ee3efb76cbebee0e0e5c4da9eb0b6e74d9124",

"confirmations" : 263032,

"size" : 215,

"height" : 19999,

"version" : 1,

"merkleroot" : "c1b09fa6bdc0b12b15cc1400d598ffed29dd33b2e282093a48646d1b7b380c98",

"tx" : [

"c1b09fa6bdc0b12b15cc1400d598ffed29dd33b2e282093a48646d1b7b380c98"

],

"time" : 1248291140,

"nonce" : 1085206531,

"bits" : "1d00ffff",

"difficulty" : 1.00000000,

"chainwork" : "00000000000000000000000000000000000000000000000000004e204e204e20",

"previousblockhash" : "000000006eb5c2799b0f5fafab6435daeecef8e7f609b731c9879c3f74f28c73",

"nextblockhash" : "00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886"

}

3. 根据tx查询单笔交易的信息:

没建index时,只能查询自己钱包的信息,若不是钱包的交易,则返回如下:

./bitcoin-cli getrawtransaction c1b09fa6bdc0b12b15cc1400d598ffed29dd33b2e282093a48646d1b7b380c98

error: {"code":-5,"message":"Invalid or non-wallet transaction id"}

那怎么办呢? 直接分析代码找原因:

// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock

bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)

{

CBlockIndex *pindexSlow = NULL;

{

LOCK(cs_main);

{

if (mempool.lookup(hash, txOut))

{

return true;

}

}

if (fTxIndex) {

CDiskTxPos postx;

if (pblocktree->ReadTxIndex(hash, postx)) {

CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);

CBlockHeader header;

try {

file >> header;

fseek(file, postx.nTxOffset, SEEK_CUR);

file >> txOut;

} catch (std::exception &e) {

return error("%s : Deserialize or I/O error - %s", __func__, e.what());

}

hashBlock = header.GetHash();

if (txOut.GetHash() != hash)

return error("%s : txid mismatch", __func__);

return true;

}

}

if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it

int nHeight = -1;

{

CCoinsViewCache &view = *pcoinsTip;

CCoins coins;

if (view.GetCoins(hash, coins))

nHeight = coins.nHeight;

}

if (nHeight > 0)

pindexSlow = chainActive[nHeight];

}

}

if (pindexSlow) {

CBlock block;

if (ReadBlockFromDisk(block, pindexSlow)) {

BOOST_FOREACH(const CTransaction &tx, block.vtx) {

if (tx.GetHash() == hash) {

txOut = tx;

hashBlock = pindexSlow->GetBlockHash();

return true;

}

}

}

}

return false;

}

我们可以看出若fTxIndex为true,则可以直接搜索index获取block信息

通过-reindex -txindex建立索引,调用:

./bitcoind -reindex -txindex

这个过程在我的mac上跑了数个小时。。。。。。

-txindex               Maintain a full transaction index (default: 0)

-reindex               Rebuild block chain index from current blk000??.dat files

再次查询

./bitcoin-cli getrawtransaction c1b09fa6bdc0b12b15cc1400d598ffed29dd33b2e282093a48646d1b7b380c98

01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0168ffffffff0100f2052a01000000434104cab13751ae7f0e0e49f8fb345e931bc6a6349502da0cbcad98e9d95110ebde5ca7af9eb09639c022ac251b44d0fa200b54011198a405984a8ff92ea9028d6d60ac00000000

解码交易数据

./bitcoin-cli decoderawtransaction 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0168ffffffff0100f2052a01000000434104cab13751ae7f0e0e49f8fb345e931bc6a6349502da0cbcad98e9d95110ebde5ca7af9eb09639c022ac251b44d0fa200b54011198a405984a8ff92ea9028d6d60ac00000000

{

"txid" : "c1b09fa6bdc0b12b15cc1400d598ffed29dd33b2e282093a48646d1b7b380c98",

"version" : 1,

"locktime" : 0,

"vin" : [

{

"coinbase" : "04ffff001d0168",

"sequence" : 4294967295

}

],

"vout" : [

{

"value" : 50.00000000,

"n" : 0,

"scriptPubKey" : {

"asm" : "04cab13751ae7f0e0e49f8fb345e931bc6a6349502da0cbcad98e9d95110ebde5ca7af9eb09639c022ac251b44d0fa200b54011198a405984a8ff92ea9028d6d60 OP_CHECKSIG",

"hex" : "4104cab13751ae7f0e0e49f8fb345e931bc6a6349502da0cbcad98e9d95110ebde5ca7af9eb09639c022ac251b44d0fa200b54011198a405984a8ff92ea9028d6d60ac",

"reqSigs" : 1,

"type" : "pubkey",

"addresses" : [

"1KWj3Jk8xvS6fDdhQBsfmerscSGsS6CMiS"

}

}

}

以上过程基本满足了大部分的查询需求:输入交易ID、区块高度或哈希值(BTC)

至于通过"地址"查询,需要通过搜集这个地址对应的交易输入输出存入数据库

部分代码如下:

function updateKeys($hash160,$pubkey,$blockhash)

{

global $db;

$address=hash160ToAddress($hash160);

$result=pg_fetch_assoc(pg_query_params($db,"SELECT pubkey,encode(hash160,'hex') AS hash160 FROM keys WHERE hash160=decode($1,'hex')",array($hash160)));

if(!$result && !is_null($pubkey))

{

pg_query_params($db, "INSERT INTO keys VALUES (decode($1,'hex'),$2,decode($3,'hex'),decode($4,'hex'));",array($hash160,$address,$pubkey,$blockhash));

}

else if(!$result)

{

pg_query_params($db, "INSERT INTO keys(hash160,address,firstseen) VALUES (decode($1,'hex'),$2,decode($3,'hex'));",array($hash160,$address,$blockhash));

}

else if($result && !is_null($pubkey) && is_null($result["pubkey"]))

{

if($result["hash160"]!=strtolower(hash160($pubkey)))

{

sleep(10);

die("Hashes don't match");

}

pg_query_params($db, "UPDATE keys SET pubkey = decode($1,'hex') WHERE hash160=decode($2,'hex');",array($pubkey,$hash160));

}

}

案例分析:如何获取一笔交易的输入地址?(此case可用在获取打款地址上)

如何根据txid获取打款地址呢?其实可以基于blockchain的链式结构逆向推导

首先 gettransaction  txid

[vin] => Array

(

[0] => Array

(

[txid] => 63876d10a13f3810a1d568c6ac7154f9b8a590cfc91cf8a17756fb099addf2b5

[vout] => 1

获取到此次的tx得信息详细,根据vin里的txid逆向查找, txid二次查询,gettransaction  vin->txid

然后根据vout索引得到输入address

[vout] => Array

(

[0] => Array

(

[value] => 0.16928006

[n] => 0

[scriptPubKey] => Array

(

[asm] => OP_DUP OP_HASH160 1715447427ac1cdfb7c5ba359154c37c5e9caa2b OP_EQUALVERIFY OP_CHECKSIG

[hex] => 76a9141715447427ac1cdfb7c5ba359154c37c5e9caa2b88ac

[reqSigs] => 1

[type] => pubkeyhash

[addresses] => Array

(

[0] => LML1HJvP8jfeiwgSVmYfNGsedYfDrzKmq3

)

)

本文纯属偶然,一个朋友要做个店铺应用支持BTC付款,欲根据txid获取打款地址,花了点时间研究了下,记录下来。

如有雷同,纯属巧合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值