從全節點獲取交易數據
背景資料
我正在建構一個應用程序,該應用程序需要能夠查詢任何比特幣完整節點(從使用原始 tcp 套接字的 python 腳本)以讀取以下事務中列出的 OP_Return 值(https://live.blockcypher.com/btc-測試網/tx/2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1/ )
迄今為止我所做的
我已經成功地建立了版本+ verack,但是我遇到了兩個問題。
- 當我為必要的交易發送一個
getdata
Idit 不返回結果。我已經確定這是因為我最初的假設 getdata 返回必要的數據是不正確的,相反它只會返回仍在記憶體池中的事務的事務數據。- 這導致了我的主要問題,我希望在我的 python 腳本上複製初始塊下載,從包含我感興趣的事務的塊開始。但是,當我這樣做時
getblocks
/getheaders
無論我似乎在雜湊中放入了什麼filter 我得到了 500(或 2000)個塊/標題的轉儲。下面是我正在發出的請求的十六進制轉儲(只是比特幣協議框架):
- getblocks 0b110907676574626c6f636b00000000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5
- getheaders 0b110907676574686561646572730000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5
我正在尋找以下幫助:
- 如果無法使用
getdata
消息,如何在不使用比特幣 RPC 的情況下查詢交易數據?- 如何讓我的塊或標題響應僅包含 1 個 inv 項目而不是 500/5000
編輯(2020 年 4 月 5 日) 這裡沒有明確說明的隱含要求是,我們需要使用區塊鏈 RPC api 或等效的方式以分散的方式這樣做。
我在 Blockcypher API 文件中沒有看到任何端點來獲取整個事務,所以我使用了 blockstream.info API:
>https://blockstream.info/testnet/api/tx/2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1 { "txid":"2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1", "version":2, "locktime":0, "vin":[ { "txid":"382bda6ee2bac22afd051104af16146436895ecca382a76c2d66535a837254bc", "vout":1, "prevout":{ "scriptpubkey":"00144ecdb2867150ff16c7d6e3258adca9ed8bac3ac1", "scriptpubkey_asm":"OP_0 OP_PUSHBYTES_20 4ecdb2867150ff16c7d6e3258adca9ed8bac3ac1", "scriptpubkey_type":"v0_p2wpkh", "scriptpubkey_address":"tb1qfmxm9pn32rl3d37kuvjc4h9fak96cwkpjyyjmk", "value":2948920 }, "scriptsig":"", "scriptsig_asm":"", "witness":[ "304402205e9b17758d1daf2a501a1fabe06bdbf15adaadfcf6ff80c4cfb34176bd988c0c02207450185bde5c20e06270b3b7e681e0042072c6af25fc10c62430df0f04ec5bf201", "023532fa6b866f37729719a3615ef3a776407048989736ac2b7fafa5678a519df3" ], "is_coinbase":false, "sequence":4294967295 } ], "vout":[ { "scriptpubkey":"6a0e3132372e302e302e313a38313831", "scriptpubkey_asm":"OP_RETURN OP_PUSHBYTES_14 3132372e302e302e313a38313831", "scriptpubkey_type":"op_return", "value":0 }, { "scriptpubkey":"a914171f697fe358f7d7238b6128930bb1fa7363b44d87", "scriptpubkey_asm":"OP_HASH160 OP_PUSHBYTES_20 171f697fe358f7d7238b6128930bb1fa7363b44d OP_EQUAL", "scriptpubkey_type":"p2sh", "scriptpubkey_address":"2MuMVAFK2gbTDNVBhLtpZfA4Xi62mWh6bU5", "value":948920 }, { "scriptpubkey":"0014af8abd63a00c40ad75e47870b1b0a1ddb2ba7e66", "scriptpubkey_asm":"OP_0 OP_PUSHBYTES_20 af8abd63a00c40ad75e47870b1b0a1ddb2ba7e66", "scriptpubkey_type":"v0_p2wpkh", "scriptpubkey_address":"tb1q479t6caqp3q26a0y0pctrv9pmket5lnx24twcx", "value":1500000 } ], "size":248, "weight":665, "fee":500000, "status":{ "confirmed":true, "block_height":1612110, "block_hash":"000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7", "block_time":1576024567 } }
您可以在這裡看到第一個輸出的數據是
3132372e302e302e313a38313831
,解碼為 ASCII 字元看起來像是一個本地 URL:hex = '3132372e302e302e313a38313831' decoded = binascii.unhexlify(hex).decode('ascii') print(decoded)
印刷:
127.0.0.1:8181
編輯:
要在不使用任何外部 API 的情況下獲得您感興趣的交易,您需要使用該
txindex=1
選項執行完整的比特幣節點。如果您的錢包跟踪此交易,則修剪節點就足夠了。然後您可以使用以下命令獲取有關交易的資訊:>bitcoin-cli getrawtransaction 2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1 true
你應該得到與我在上面粘貼的 blockstream 的 API 的答案非常相似的東西
比特幣 p2p 協議不允許以這種方式直接查找交易。也許一些布隆過濾器可以最大限度地減少佔用空間,但實現起來仍然相對複雜。
Electrum 伺服器可能是下一個最好的東西——它們確實支持你想要的查找,但它們的去中心化程度較低,而且如果你的應用程序正在做一些淘氣的事情,它們可能會串通並操縱你的結果。
如何讓我的塊或標題響應僅包含 1 個 inv 項目而不是 500/5000
我認為您不能限制標頭結果(您必須知道所有標頭才能這樣做)但是一旦有了標頭鏈,您就可以使用 start:HASH(n) end:HASH(n+ 1)你可以下載一個塊。
重新布隆過濾,如果你找到帶有 BLOOM_SERVICE 位的節點,你可以告訴他們你的過濾器,塊數據只包含你的 txs 和你的過濾器允許的誤報。