Учитывая входы и выходы транзакции, я хотел бы иметь возможность извлечь адрес кошелька (или адреса), который отправил транзакцию, а также адрес/адреса, которые получат транзакцию.
Какая часть/поле ввода относится к хешу вывода?
И какая часть/поле вывода относится к адресу, на который будет получен вывод?
Я использую биткойн. Я пробовал смотреть на 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 — это все единицы.
- И какая часть/поле вывода относится к адресу, на который будет получен вывод?
Это зависит от формата вывода, но вот общие правила:
Я более подробно расскажу о возможных типах адресов здесь: Какие формы биткойн-скриптов следует обнаруживать при отслеживании баланса кошелька?
Как я могу извлечь адрес получателя из этого 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
Это адрес, который мы пытались получить.
scriptPubKey содержит открытый ключ, используемый для синтеза публичного адреса. Вот два педантичных подхода, не использующих биткойн, применяющих команды bx для синтеза интересующего публичного адреса выше.
% echo 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f | bx sha256 | bx ripemd160 | bx base58check-encode
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
% echo 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f | bx ec-to-address
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
Нажмите Проголосовать
Нажмите Проголосовать
Нажмите Проголосовать
Ник Оделл
Нажмите Проголосовать
input.getOutput.getHash
к идентификатору txn иgetIndex
к vout вывода этого txn? PS большое спасибо, я несколько дней пытался получить ответы на эти вопросы, вы первый, кто смог на них ответить. :)Нажмите Проголосовать
Ник Оделл
https://blockchain.info/tx/<txid here>?format=hex
, чтобы получить версию в шестнадцатеричном кодировании. Другие API имеют нечто подобное.Нажмите Проголосовать
Ник Оделл