Wie kann ich die Von- und Bis-Wallet-Adressen einer Transaktion abrufen?

Angesichts der Ein- und Ausgänge einer Transaktion möchte ich in der Lage sein, die Brieftaschenadresse (oder Adressen) zu extrahieren, die die Transaktion gesendet haben, sowie die Adresse/Adressen, die die Transaktion erhalten.

  • Welcher Teil / Feld der Eingabe bezieht sich auf den Hash der Ausgabe?

  • Und welcher Teil / welches Feld der Ausgabe bezieht sich auf die Adresse, die die Ausgabe erhalten soll?

Ich verwende bitcoinj. Ich habe versucht, die scriptSigEingänge und scriptPubKeydie Ausgänge zu betrachten, aber es macht für mich nicht viel Sinn.

ZB für die Genesis-Transaktion: https://blockchain.info/tx/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b?show_adv=true

Der scriptPubKey der Ausgabe lautet[04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f] CHECKSIG

Aber die Empfängeradresse ist1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

Wie kann ich extrahieren, dass die Empfängeradresse die aus diesem scriptPubKey ist?

Antworten (2)

  • Welcher Teil / Feld der Eingabe bezieht sich auf den Hash der Ausgabe?

Der Outpoint enthält eine txid (32 Byte) und eine vout (4 Byte), die die Ausgabe angeben, die Sie ausgeben.

Dies ist nicht die Absenderadresse!

Was Sie tun (wenn Sie es nicht mit einer Coinbase-Transaktion zu tun haben), ist, dass Sie die Transaktion mit der txid nachschlagen und sich die Transaktionsausgabe ansehen, die vout entspricht. Wenn also beispielsweise vout 3 wäre, würden Sie sich die vierte Ausgabe der entsprechenden Transaktion ansehen. Wenn vout 0 wäre, würden Sie sich die erste Ausgabe ansehen. Die Adresse, die diese Ausgabe ausgeben kann, ist die Absenderadresse der ursprünglichen Transaktion.

Die Genesis-Transaktion ist eine Coinbase-Transaktion, also besteht die txid ausschließlich aus Nullen und die vout ausschließlich aus Einsen.

  • Und welcher Teil / welches Feld der Ausgabe bezieht sich auf die Adresse, die die Ausgabe erhalten soll?

Es hängt vom Format der Ausgabe ab, aber hier sind die allgemeinen Regeln:

  • Wenn es sich wie hier um P2PK handelt, führen Sie HASH160 auf dem ersten Element des scriptPubKey aus und codieren Sie es dann als Adresse.
  • Wenn es sich um P2PKH handelt, nehmen Sie das dritte Element des scriptPubKey und codieren Sie den Pubkeyhash als Adresse.
  • Wenn es sich um P2SH handelt, nehmen Sie das zweite Element des scriptPubKey und codieren Sie es als Adresse mit Address.fromP2SHHash.

Auf mögliche Arten von Adressen gehe ich hier näher ein: Welche Bitcoin-Skriptformen sollen beim Tracking des Wallet-Guthabens erkannt werden?

Wie kann ich extrahieren, dass die Empfängeradresse die aus diesem scriptPubKey ist?

Mach das:

import org.bitcoinj.core.*;
import org.bitcoinj.params.MainNetParams;

import org.spongycastle.crypto.digests.RIPEMD160Digest;

import java.nio.file.Files;
import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Test {
    public static void main(String[] args) throws Exception {
        byte[] b;
        NetworkParameters np = MainNetParams.get();
        Context.propagate(new Context(np));
        b = Files.readAllBytes(new File("genesis.bin").toPath());
        Transaction tx1 = new Transaction(np, b);
        System.out.println(tx1);
        byte[] pk = tx1.getOutput(0).getScriptPubKey().getPubKey();
        System.out.println(bytesToHex(pk));
        System.out.println(bytesToHex(hash160(pk)));
        Address a = new Address(np, hash160(pk));
        System.out.println(a);
    }
    static byte[] hash160(byte[] in) {
        MessageDigest d1;
        try {
            d1 = MessageDigest.getInstance("SHA-256");
        } catch(NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        d1.update(in);
        byte[] digest = d1.digest();
        RIPEMD160Digest d2 = new RIPEMD160Digest();
        d2.update(digest, 0, 32);
        byte[] ret = new byte[20];
        d2.doFinal(ret, 0);
        return ret;
    }
    final protected static char[] hexArray = "0123456789abcdef".toCharArray();
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
}

(Beachten Sie, dass ich in meinem aktuellen Arbeitsverzeichnis eine Datei mit dem Namen genesis.bin habe, die die Rohbytes für die Genesis-Transaktion enthält.)

Und Sie erhalten:

  4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
     == COINBASE TXN (scriptSig PUSHDATA(4)[ffff001d] PUSHDATA(1)[04] PUSHDATA(69)[5468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73])  (scriptPubKey PUSHDATA(65)[04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f] CHECKSIG)

04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f
62e907b15cbf27d5425399ebf6f0fb50ebb88f18
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

Das ist die Adresse, die wir bekommen wollten.

Danke, sehr hilfreich. Woher weiß ich, ob eine Ausgabe P2PK, P2PKH oder P2SH ist? Und decken diese 3 Formate alle möglichen Formate ab, die es haben kann? Wie würde ich auch wissen, ob es sich um eine Mining-Gebühr ohne Adresse handelt? Zu guter Letzt, um die txid der Eingaben mit Bitcoinj zu erhalten, würde ich die Methode input.getParentTransaction verwenden?
Ich habe Ihre Antwort unter bitcoin.stackexchange.com/questions/35456/… gesehen , die meine erste Frage beantwortet. Bleibende Fragen: 1) Ich gehe davon aus, dass die Absenderadresse von Multi-Sig-Txns nicht abgerufen werden kann? 2) Kennen Sie zufällig die Hashes von txns, die P2PKH und P2SH verwenden, damit ich sie testen kann? 3) Wie kann ich die txId und vout von Eingaben über Bitcoinj abrufen?. Wenn ich das zum Laufen bekomme, werde ich dies als PR bei BitcoinJ einreichen. Vielen Dank.
Wäre es besser, wenn ich für jede dieser Fragen eine neue Frage erstellen würde?
@ClickUpvote 1) Das ist möglich. Sie könnten meinen, „welche Adressen diese Bitcoin zuvor besessen haben“ oder „welche Adressen dies tatsächlich signiert haben“. Die erste kann durch einen Blick auf prev scriptPubKey beantwortet werden, die zweite erfordert prev scriptPubKey und current scriptSig. 2) P2PKH/P2SH 3) tx.getInput(vin).getOutpoint() gefolgt von getHash oder getIndex. PR) Cool! Es wäre schön, das in Bitcoinj zu sehen. PS) Ich würde separate Fragen stellen. Es gibt ein Limit von 600 Zeichen für Kommentare
Bezieht sich auf die txn input.getOutput.getHash-ID und getIndexauf den vout der Ausgabe dieses txn? PS Vielen Dank, ich versuche seit ein paar Tagen, Antworten auf diese Fragen zu bekommen, Sie sind die erste Person, die sie beantworten konnte. :)
Ist es möglich, die Binärdaten dieser txns von blockchain.info oder einer anderen Methode herunterzuladen, ohne die Kette durchlaufen zu müssen, um danach zu suchen?
@ClickUpvote Sie sollten in der Lage sein, die Webseite anzufordern https://blockchain.info/tx/<txid here>?format=hex, um eine hex-codierte Version zu erhalten. Andere APIs haben etwas Ähnliches.
Also zB blockchain.info/tx/… , die als .bin-Datei gespeichert und wie in Ihrem Beispielcode an Transaction weitergegeben werden kann? Oder muss noch etwas an den Hexdaten gemacht werden?
@ClickUpvote Es muss von Hex in Raw Bytes konvertiert werden. stackoverflow.com/questions/8890174/…

Der scriptPubKey enthält den öffentlichen Schlüssel, der zum Synthetisieren der öffentlichen Adresse verwendet wird. Hier sind zwei pedantische Ansätze, die Bitcoin nicht verwenden und bx -Befehle anwenden , um die öffentliche Adresse von Interesse oben zu synthetisieren.

% echo 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f | bx sha256 | bx ripemd160 | bx base58check-encode

1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

% echo 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f | bx ec-to-address

1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa