You should update your Bitcoin core client, 0.19.0.1 and latest version won't derive an address from P2PK outputs using
decoderawtransaction or
getrawtransaction "TXID" "true".
For example Block #1 coinbase:
output scriptPubKey (HEX) --> base 58 address, i.e.,
410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac -->12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX
If you want to get the address despite the fact that it shouldn't be converted into an address,
you can convert it through any "
pub key to address" code that supports uncompressed pub key using the public key which is in that scriptPubKey (
highlighted):
41 - push 65 bytes to stack
0496.............58ee - Public key
ac - OP_CHECKSIG
Thank you nc50lc and pooya87 for the help. I am not using bitcoin core client, but instead I am trying to learn about bitcoin's
early blockchain at a lower level by parsing the blockchain files. It was real early uncompressed pubic key usage that was throwing me off, but with your pointers I was able to figure it out. It is unfortunate that all blockchain viewing websites use the 'address' label so often. I think I understand now what they call an 'address' (i.e., 12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX) is really a
Base 58 encoded rendering of the 160-bit (i.e, 20 byte) ripemd160 hash of the public ECDSA key with network byte prefix. Is that getting closer?
In any case it was the really early uncompressed 64 byte public key (with '04' prefix) that was confusing me, but your tips and the following useful site helped me to write the python code that works for the early blockchain files. I know it won't work beyond the first couple of years. After the initial uncompressed 64 byte public key usage, the pubkey appeared to transition quickly to the 20 byte ripemd160 hash so my decode entry point for those was #4 instead of #2 below:
http://gobittest.appspot.com/Address1 - Public ECDSA Key
0496B538E853519C726A2C91E61EC11600AE1390813A627C66FB8BE7947BE63C52DA7589379515D 4E0A604F8141781E62294721166BF621E73A82CBF2342C858EE2 - SHA-256 hash of 1
6527751DD9B3C2E5A2EE74DB57531AE419C786F5B54C165D21CDDDF04735281F
3 - RIPEMD-160 Hash of 2
119B098E2E980A229E139A9ED01A469E518E6F264 - Adding network bytes to 3
00119B098E2E980A229E139A9ED01A469E518E6F26
5 - SHA-256 hash of 4
D304D9060026D2C5AED09B330B85A8FF10926AC432C7A7AEE384E47B2FA1A670
6 - SHA-256 hash of 5
90AFE11C54D3BF6BACD6BF92A3F46EECBE9316DC1AF9287791A25D340E67F535
7 - First four bytes of 6
90AFE11C
8 - Adding 7 at the end of 4
00119B098E2E980A229E139A9ED01A469E518E6F2690AFE11C
9 - Base58 encoding of 8
12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJXJust in case anyone else is interested in the python code the mirrors the above logic that seems to work well for the outputs scripts found in the EARLY blockchain file. It takes 160-bit RIPEMD-160 hash as an input adds the network bytes prefix for mainnet ('00') and outputs the base 58 rendition:
import hashlib
import binascii
import base58
def Ripe160HashtoBase58(ripemd160hash):
d = int('00' + ripemd160hash+ hashlib.sha256(hashlib.sha256(binascii.unhexlify('00' + ripemd160hash)).digest()).hexdigest()[0:8],16)
return '1' + str(base58.b58encode(d.to_bytes((d.bit_length() + 7) // 8, 'big')))[2:-1]
Ripe160HashtoBase58('
119B098E2E980A229E139A9ED01A469E518E6F26') --> '
12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX'
when faced with the uncompressed pubkey starting with the '04' (following the '41' size byte) like the above example I extract the 130 hex byte public key and generate the ripemd160hash (steps 2 & 3) before feeding it to the function above.
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(hashlib.sha256(binascii.unhexlify(130hexbytePK)).digest())
ripemd160hash = ripemd160.hexdigest ()