Transactions
如何檢索交易的錢包地址?
給定交易的輸入和輸出,我希望能夠提取發送交易的錢包地址(或多個地址),以及將接收交易的地址/地址。
- 輸入的哪個部分/欄位指的是輸出的雜湊?
- 輸出的哪個部分/欄位是指將接收輸出的地址?
我正在使用比特幣。我試過查看
scriptSig
輸入和scriptPubKey
輸出的值,但這對我來說沒有多大意義。輸出的 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
這是我們試圖獲取的地址。