Transaktionsdaten vom vollständigen Knoten abrufen

Hintergrundinformation

Ich baue eine Anwendung, die die Fähigkeit erfordert, jeden Bitcoin-Vollknoten (von einem Python-Skript mit rohen TCP-Sockets) abzufragen, um den OP_Return-Wert zu lesen, der in der folgenden Transaktion aufgeführt ist ( https://live.blockcypher.com/btc- testnet/tx/2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1/ )

Was ich bisher gemacht habe

Ich habe es erfolgreich geschafft, die Version + Verack zu etablieren, aber ich war mit zwei Problemen konfrontiert.

  1. Wenn ich eine getdatafür die notwendige Transaktion sende, gibt Idit das Ergebnis nicht zurück. Ich habe festgestellt, dass dies daran liegt, dass meine anfänglichen Annahmen, dass getdata die erforderlichen Daten zurückgibt, falsch waren und stattdessen nur Transaktionsdaten für Transaktionen zurückgeben, die sich noch im Mempool befinden.
  2. Dies führte mich zu meinem Hauptproblem. Ich hatte gehofft, den anfänglichen Block-Download in meinem Python-Skript zu replizieren, beginnend mit dem Block, der die Transaktion enthält, an der ich interessiert bin. Wenn ich jedoch tue / egal, was ich in den Hash getblockseinzufügen getheadersscheine filter bekomme ich einen Dump von 500 (oder 2000) Blöcken/Headern. Unten ist ein Hex-Dump der Anfragen, die ich mache (nur der Bitcoin-Protokollrahmen):

    • getblocks 0b110907676574626c6f636b00000000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5

    • getheaders 0b110907676574686561646572730000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5

Ich suche folgende Hilfe:

  1. Wie kann ich Transaktionsdaten abfragen, ohne Bitcoin RPC zu verwenden, wenn ich die getdataNachricht nicht verwenden kann?
  2. Wie erhalte ich, dass meine Block- oder Header-Antwort nur 1 Inv-Element anstelle von 500/5000 enthält

BEARBEITEN (05.04.20) Die implizite Anforderung, die hier nicht klargestellt wurde, war, dass wir dies dezentral mithilfe der Blockchain-RPC-API oder einer gleichwertigen Methode tun mussten.

Sie möchten 250 GB Blöcke von einem Remote-Peer herunterladen, um eine einzelne Ausgabe zu finden?
Nein, das möchte ich nicht, aber es scheint nicht so viele Alternativen zu geben. Ich versuche so zu tun, als wäre ich ein vollständiger Bitcoin-Knoten, der versucht, zu synchronisieren (aber wenn ich versuche, von dem erforderlichen Block zu synchronisieren, den ich brauche, würde ich auf diese Weise nur Daten im Wert von 1 Block synchronisieren). Ich verwende die API richtig
Wenn Ihre beste Wahl darin besteht, etwas Absurdes zu tun, überdenken Sie vielleicht Ihre Strategie. Das P2P-Netzwerk ist nicht für willkürlichen Datenzugriff ausgelegt, wie Sie es versuchen.
Ich bin einige Alternativen durchgegangen, aber das Hauptziel hier ist es, die Daten dezentral und zensurresistent nachschlagen zu können. Ich kann mich also nicht darauf verlassen, mir die Blockchain-Explorer-APIs anzusehen. Auch wenn ich Bitcoin RPC verwende, müsste ich eine Verbindung zu einem bestimmten Bitcoin Full Node herstellen, der heruntergefahren werden könnte.
Wenn Sie etwas Zensurresistentes wollen, besteht Ihre einzige Wahl darin, Ihren eigenen Knoten zu betreiben, die Blöcke in seinen Daten selbst zu indizieren und diese dann abzufragen.
Gibt es keine Möglichkeit für mich zu verspotten, was ein vollständiger Knoten tut (aber nur für einen Teil des Synchronisierungsprozesses)? Sicherlich kann ich sagen, hey, ich bin ein Full Node und ich möchte den anfänglichen Block-Download von X-Block starten und dann die Transaktionen dort validieren. Wird dies nicht über BitcoinP2P abgewickelt? Entschuldigung im Voraus, wenn ich hier irgendwelche Fehler gemacht habe
@PieterWuille Ich verstehe Ihren Kommentar vom Dezember vielleicht nicht ganz, aber tatsächlich habe ich es geschafft, das zu tun, was ich mir erhofft hatte. Theoretisch können Sie eine vollständige Knotenfunktionalität vollkommen "mocken", wenn Sie die anfänglichen Ver-Ack-Nachrichten simulieren. Den vollständigen Quellcode können Sie hier einsehen: github.com/dummytree/blockchain-botnet-poc/blob/master/…

Antworten (3)

Ich sehe keinen Endpunkt, um die gesamte Transaktion in der Blockcypher-API-Dokumentation abzurufen, also habe ich die blockstream.info-API verwendet:

>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
   }
}

Sie können hier sehen, dass die erste Ausgabe die Daten hat 3132372e302e302e313a38313831, deren Dekodierung in ASCII-Zeichen wie eine lokale URL aussieht:

hex = '3132372e302e302e313a38313831'
decoded = binascii.unhexlify(hex).decode('ascii')
print(decoded)

Drucke:127.0.0.1:8181

BEARBEITEN:

Um die Transaktion zu erhalten, die Sie interessiert, ohne eine externe API zu verwenden, müssen Sie einen vollständigen Bitcoin-Knoten mit der txindex=1Option ausführen. Wenn diese Transaktion von Ihrer Brieftasche verfolgt wird, würde ein beschnittener Knoten ausreichen. Dann können Sie die Informationen über die Transaktion mit diesem Befehl abrufen:

>bitcoin-cli getrawtransaction 2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1 true

Sie sollten etwas sehr Ähnliches wie die Antwort von der Blockstream-API erhalten, die ich oben eingefügt habe

Entschuldigung, wenn es nicht klar war, aber ich musste dies dezentral tun, ohne mich auf gespeicherte Daten von einem API-Server zu verlassen (z. B. wenn sie nur mit den falschen Daten antworten). Ich versuche, diese Daten direkt aus der Blockchain zu lesen und finde keine Möglichkeit, dies zu tun
Überprüfen Sie die Bearbeitung im letzten Teil meiner Antwort, sie erklärt, wie das ohne eine externe API geht

Das Bitcoin-P2P-Protokoll erlaubt auf diese Weise keine direkte Transaktionssuche. Vielleicht würde ein Bloom-Filter den Footprint minimieren, aber es ist immer noch relativ komplex zu implementieren.

Electrum-Server sind vielleicht das Nächstbeste - sie unterstützen die gewünschten Suchvorgänge, sind aber weniger dezentralisiert, und wenn Ihre Anwendung unanständige Dinge tut, könnten sie sich verschwören und nur Ihre Ergebnisse manipulieren.

Wie erhalte ich, dass meine Block- oder Header-Antwort nur 1 Inv-Element anstelle von 500/5000 enthält

Ich glaube nicht, dass Sie die Header-Ergebnisse einschränken können (dazu müssen Sie alle Header kennen). Aber sobald Sie die Header-Kette haben, können Sie mit start:HASH(n) end:HASH(n+ 1) und Sie können einen einzelnen Block herunterladen.

Bezüglich der Bloom-Filterung: Wenn Sie Knoten mit dem BLOOM_SERVICE-Bit finden, können Sie ihnen Ihren Filter mitteilen, und die Blockdaten enthalten nur Ihre TXS und die von Ihrem Filter zugelassenen Fehlalarme.

Es stellte sich heraus, dass das Hauptproblem mit dem obigen Code darin bestand, dass die Endianness in Python standardmäßig dazu führte, dass meine Hex-Nutzlast durcheinander gebracht wurde. Ich musste lediglich die Reihenfolge der Nutzdaten korrigieren. Der korrekte Code kann hier eingesehen werden: https://github.com/dummytree/blockchain-botnet-poc/blob/master/MalwareManager.py#L284-L299