bitcoin-php icon indicating copy to clipboard operation
bitcoin-php copied to clipboard

How to get addresses from outputs of raw transaction?

Open Vasiliy-Bondarenko opened this issue 7 years ago • 5 comments

Here is real transaction - i need to extract all output addresses there is no method like getAdrress() or similar on the output object...

            $tx = TransactionFactory::fromHex("0100000001476a9d32181de5381c18c3c5aad36fcb78cbadfd1ae69e2659e1d22cea805ffd010000006b48304502210092bb009c9fd961310f7d4b4538c4e9bb9c9020398b9820b5b65c77d2f1b7dfea0220609947199c8d4c857ad7cfce7a0e6bf335f384ddaf6dbf60304bb77701736f33012102947388504d6969d581cc72bc6824a3045f3e9805d9c954f8a5401492c923c678feffffff04006cdc02000000001976a9149bfedc6be7f80062ca77a49a8f6d9604398023fc88ac7ce10b00000000001976a9145e8f7daea735fb6ddb1796b1ae8eeda40234728388ac546af122000000001976a914d43967f1ff57716d38519f02563b6b6b20ef039788ac00a60e00000000001976a91406f93b94aab2a912d9335756dd02cdcff1796f5188aced980700");
            $addresses = [];

            foreach ($tx->getOutputs() as $output) {
                $addresses[] = $output->???
            }

This transaction on the network: https://live.blockcypher.com/btc/tx/e9cc2041e5b7a8733aa3706586c27a935d593c4dbf4178ebff0b24716d1d62d2/

Vasiliy-Bondarenko avatar Dec 06 '17 12:12 Vasiliy-Bondarenko

Check out the AddressFactory class, it has functions for parsing addresses from various things: https://github.com/Bit-Wasp/bitcoin-php/blob/7ac9fbe477ac437883cd180bc01006ecb6b6c5f9/src/Address/AddressFactory.php

try {
    $address = AddressFactory::fromOutputScript($output->getScript());
    echo $address->getAddress(/*$network*/); // defaults to globally set network, otherwise pass one to encode for that network specifically.
    $addresses[] = $address;

} catch (\Exception $e) {
}

or copy some code from that function if you're doing it in a long running process (so you can reuse the OutputClassifier), and instead of throwing an exception just skip parsing the address if it's not P2PKH/P2SH.

afk11 avatar Dec 06 '17 20:12 afk11

Thank you. I've got my error. I was decoding on testnet instead of real network. silly me :)

By the way - in AddressFactory some \RuntimeException's are thrown. And it's not very good solution.

F.ex. i call fromOutputScript() and i want to just skip the script not associated with address. But now i must check the text of the exception message because i can not rely on general-type exception like \RuntimeException - it can be thrown by any other part of the code (because i have more then one method call in try-catch block). It would be better to throw more specific exceptions like ScriptNotAssociatedWithAddress which can extend the same \RuntimeException (for backwards compatibility). And the same is true for every other general type exceptions.

At first it looks too verbose, but works much better when you actually use this code.

Vasiliy-Bondarenko avatar Dec 07 '17 03:12 Vasiliy-Bondarenko

Oops, thought I responded to this already! You're definitely right, I'll work on this. Probably just add it to master, but as mentioned in the litecoin bytes thread I'm not sure if we need an 0.0.35? If it's worth considering before master, again let me know.

afk11 avatar Jan 26 '18 14:01 afk11

to me both are definitely not urgent. I’m easily extending NetworkFactory with my own settings and this issue is also not critical.

Vasiliy-Bondarenko avatar Jan 28 '18 06:01 Vasiliy-Bondarenko

in current version

bitwasp/bitcoin                       v1.0.4             PHP Bitcoin library with functions for transactions, signatures, serialization, Random/Deterministic ECDSA keys, blocks, RPC bindings

it will be

$addressReader = new AddressCreator();
$address = $addressReader->fromOutputScript($output->getScript())->getAddress();

but will throw exception if has invalid script ,don't forget catch the exception.

toknT avatar Jan 10 '20 05:01 toknT