Transactions

如何檢索交易的錢包地址?

  • May 17, 2018

給定交易的輸入和輸出,我希望能夠提取發送交易的錢包地址(或多個地址),以及將接收交易的地址/地址。

  • 輸入的哪個部分/欄位指的是輸出的雜湊?
  • 輸出的哪個部分/欄位是指將接收輸出的地址?

我正在使用比特幣。我試過查看scriptSig輸入和scriptPubKey輸出的值,但這對我來說沒有多大意義。

例如,對於創世交易:https ://blockchain.info/tx/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b?show_adv=true

輸出的 scriptPubKey 是[04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f] CHECKSIG

但是接收地址是1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

如何從該 scriptPubKey 中提取接收者地址?

  • 輸入的哪個部分/欄位指的是輸出的雜湊?

outpoint 包含一個 txid(32 字節)和 vout(4 字節),它們指定了您要花費的輸出。

這不是發送地址!

您所做的(當您不處理 coinbase 交易時)是使用 txid 查找交易,並查看對應於 vout 的交易輸出。因此,例如,如果 vout 為 3,您將查看相應交易的第四個輸出。如果 vout 為 0,您將查看第一個輸出。可以花費該輸出的地址是原始交易的發送地址。

創世交易是 coinbase 交易,因此 txid 全為零,vout 全為 1。

  • 輸出的哪個部分/欄位是指將接收輸出的地址?

這取決於輸出的格式,但這裡是一般規則:

  • 如果是 P2PK,就像這裡一樣,在 scriptPubKey 的第一個元素上執行 HASH160,然後將其編碼為地址。
  • 如果是 P2PKH,則取 scriptPubKey 的第三個元素,並將 pubkeyhash 編碼為地址。
  • 如果是 P2SH,則取 scriptPubKey 的第二個元素,並使用 Address.fromP2SHHash 將其編碼為地址。

我在這裡更詳細地介紹了可能的地址類型:跟踪錢包餘額時應該檢測哪些比特幣腳本形式?

如何從該 scriptPubKey 中提取接收者地址?

做這個:

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

(請注意,我目前的工作目錄中有一個名為 genesis.bin 的文件,其中包含創世交易的原始字節。)

你得到:

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

04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f
62e907b15cbf27d5425399ebf6f0fb50ebb88f18
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

這是我們試圖獲取的地址。

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