Full-Node

從全節點獲取交易數據

  • May 4, 2020

背景資料

我正在建構一個應用程序,該應用程序需要能夠查詢任何比特幣完整節點(從使用原始 tcp 套接字的 python 腳本)以讀取以下事務中列出的 OP_Return 值(https://live.blockcypher.com/btc-測試網/tx/2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1/ )

迄今為止我所做的

我已經成功地建立了版本+ verack,但是我遇到了兩個問題。

  1. 當我為必要的交易發送一個getdataIdit 不返回結果。我已經確定這是因為我最初的假設 getdata 返回必要的數據是不正確的,相反它只會返回仍在記憶體池中的事務的事務數據。
  2. 這導致了我的主要問題,我希望在我的 python 腳本上複製初始塊下載,從包含我感興趣的事務的塊開始。但是,當我這樣做時getblocks/getheaders無論我似乎在雜湊中放入了什麼filter 我得到了 500(或 2000)個塊/標題的轉儲。下面是我正在發出的請求的十六進制轉儲(只是比特幣協議框架):
  • getblocks 0b110907676574626c6f636b00000000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5
  • getheaders 0b110907676574686561646572730000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5

我正在尋找以下幫助:

  1. 如果無法使用getdata消息,如何在不使用比特幣 RPC 的情況下查詢交易數據?
  2. 如何讓我的塊或標題響應僅包含 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 和你的過濾器允許的誤報。

引用自:https://bitcoin.stackexchange.com/questions/92322