I was trying to get an address from an outputscript using address.fromOutputScript; but when I try it with a pubkey script (OP_DATA() + OP_CHECKSIG), the library fails with the error:
02397df78c9c3fecbcbcee12025230fc4b30e6e617f5fc9c10513eebd0cf4b327d OP_CHECKSIG has no matching Address
Inspecting the library code I found the problem here: https://github.com/bitcoinjs/bitcoinjs-lib/blob/413495b101e6dec80b4a310a52ab1a28cd9f7bec/src/address.js#L51 the pubkey template is not used. I know that pubkey addresses are deprecated, but they are used on coinbase transactions. How should I do to decode these type of addresses?
My solution is this, but it seems too tricky:
let s = bitcoinjs.script.pubKey.output.decode(txout.script);
s = bitcoinjs.crypto.sha256(s);
s = bitcoinjs.crypto.ripemd160(s);
spendableby = bitcoinjs.address.toBase58Check(bitcoinjs.script.compile(s), _network.pubKeyHash);
the pubkey template is not used. I know that pubkey addresses are deprecated
They aren't deprecated, they aren't even a thing.
Blame block explorers for this.
An address is a user-space convention for wrapping up an output script for sharing.
It is a two way encoding, it can be encoded (for sharing), and decoded (for sending to!).
Deriving an address from a P2PK script isn't wrapping it up, or encoding it.
It is simply the derivation of a P2PKH script (and address) from the public key, ignoring the context.
If you send to an address derived from a P2PK script, you are sending to a P2PKH script.
P2PK does not have an equivalent base58 address.
Your "solution" additionally shouldn't work, as you are taking the HASH_160 of {pubKey} OP_CHECKSIG.
Be careful to always verify you can spend your output scripts before funding them.
See https://github.com/bitcoinjs/bitcoinjs-lib/issues/586#issuecomment-224508501
<> represents data or script{} represents data that must prefixed by OP_PUSHDATA[] represents multiple {}PubKey (pay-to-pubkey / P2PK)
Address: N/A
scriptPubKey: {pubKey} OP_CHECKSIG
scriptSig: {signature}
PubKeyHash (pay-to-pubkeyhash / P2PKH)
Address: Base58(0x00 <hash160 pubKey> <checksum>)
scriptPubKey: OP_DUP OP_HASH160 {hash160(pubKey)} OP_EQUALVERIFY OP_CHECKSIG
scriptSig: {signature} {pubKey}
ScriptHash (pay-to-scripthash / P2SH)
Address: Base58(0x05 <hash160 script> <checksum>)
scriptPubKey: OP_HASH160 {hash160(scriptPubKey2)} OP_EQUAL
scriptSig: [scriptSig2 ...] {scriptPubKey2}
MultiSig (pay-to-multisig / P2MS)
Address: N/A
scriptPubKey: m [pubKeys ...] n OP_CHECKMULTISIG
scriptSig: OP_0 [signatures ...]
Witness PubKeyHash (pay-to-witness-pubkeyhash / P2WPKH)
Address: Bech32('bc' {hash160(pubKey)})
scriptPubKey: 0 {hash160(pubKey)}
scriptSig: (empty)
witness: {signature} {pubKey}
Witness ScriptHash (pay-to-witness-scripthash / P2WSH)
Address: Bech32('bc' {sha256(script)})
scriptPubKey: 0 {sha256(scriptPubKey2)}
scriptSig: (empty)
witness: [scriptSig2 ...] {scriptPubKey2}
OP_RETURN
Address: N/A
scriptPubKey: OP_RETURN {data}
scriptSig: N/A
Anyone-can-spend
Address: N/A
scriptPubKey: N/A
scriptSig: OP_TRUE
Transaction-puzzle
Address: N/A
scriptPubKey: OP_HASH256 {hash} OP_EQUAL
scriptSig: <data>
ok got it
@dakk would you mind posting final solution for this ?
Most helpful comment
<>represents data or script{}represents data that must prefixed by OP_PUSHDATA[]represents multiple{}Standard Scripts
PubKey (pay-to-pubkey / P2PK)
PubKeyHash (pay-to-pubkeyhash / P2PKH)
ScriptHash (pay-to-scripthash / P2SH)
MultiSig (pay-to-multisig / P2MS)
Witness PubKeyHash (pay-to-witness-pubkeyhash / P2WPKH)
Witness ScriptHash (pay-to-witness-scripthash / P2WSH)
Non-standard Scripts
OP_RETURN
Anyone-can-spend
Transaction-puzzle
Ref https://gist.github.com/dcousens/1d8c24d01e3f34bee453