Bitcoin Forum
December 11, 2024, 08:30:21 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Base 58 address and public key hash  (Read 1667 times)
markbeek (OP)
Newbie
*
Offline Offline

Activity: 2
Merit: 0


View Profile
July 06, 2015, 12:43:49 AM
 #1

I'm trying to figure out the relationship between the base 58 address, the public key hash, and the scriptPubKey on a standard transaction output.

I know the base 58 address is basically a 25-byte wrapper for the 20-byte double hash of the public key (with version prefix and check sum suffix), encoded to a 17-byte address. I know the public key hash is also part of the scriptPubKey, but that's where my questions arise.

As an example, on testnet (block 487805), I had bitcoins sent to base 58 address mjj4MR1aeTjWSRqHuixfoCGRDRwabbK3zv

The raw transaction is

010000000105287a343ffb315b10c03574975535badbe801cf6ffdf73c79ac22da215d095b01000 0006a4730440220670ef406032cc1c20c284da8ccc2a40d5b135776dac672ce04e8cbb9036fec15 022011e6f589e5ca946f974b3ff69523497d06262a7e75be38ae99a85e493940ea8401210278072 1cc016aaf0434878f95bce130147ccdc4bd88478222bcba2018294e99d4ffffffff02c09e0a0000 0000001976a9142e2a8d353ea825de6bc2b081324f412764e53e5788ac85351931100000001976a914c73c92961d27fb399e1d408c94f1dade2860394588ac00000000

If the bold font comes through, you can see these bytes, which I believe are the scriptPubKey:

76a9142e2a8d353ea825de6bc2b081324f412764e53e5788ac

When I decode the transaction I see this output:

        {
            "value" : 0.00696000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 2e2a8d353ea825de6bc2b081324f412764e53e57 OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a9142e2a8d353ea825de6bc2b081324f412764e53e5788ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "mjj4MR1aeTjWSRqHuixfoCGRDRwabbK3zv"
                ]
            }
        },

There's the base 58 address again, along with the script in hex. Since the base 58 address isn't part of the raw transaction, and since the hex script is 25 bytes, I assumed that if I encoded the script, I'd get the base 58 address, and if I decoded the base 58 address, I'd get the script. But that doesn't work (at least using the Base58 class from bitcoinj).

So what is the relationship between the script and the base 58 address? How does the network even know about the base 58 address, when it's not part of the raw transaction? And what is the asm value, which looks like an actual script but with yet another set of bytes?

achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3570
Merit: 6927


Just writing some code


View Profile WWW
July 06, 2015, 01:49:55 AM
 #2

The hex part that you bolded is actually the asm encoded in hex. OP_DUP is 0x76, OP_HASH160 is 0xa9, OP_EQUALVERIFY is 0x88 and OP_CHECKSIG is 0xac. Immediately following OP_HASH160 is the hex of the RIPEMD-160 hash of the SHA-256 hash of the public key. Therefore, the actual public key part is 2e2a8d353ea825de6bc2b081324f412764e53e57 found immediately after a9 and immediately before 88. You perform the base58 encoding on this hash.

DannyHamilton
Legendary
*
Offline Offline

Activity: 3514
Merit: 4894



View Profile
July 06, 2015, 03:11:19 AM
Last edit: July 06, 2015, 12:41:20 PM by DannyHamilton
 #3

- snip -
The raw transaction is

010000000105287a343ffb315b10c03574975535badbe801cf6ffdf73c79ac22da215d095b01000 0006a4730440220670ef406032cc1c20c284da8ccc2a40d5b135776dac672ce04e8cbb9036fec15 022011e6f589e5ca946f974b3ff69523497d06262a7e75be38ae99a85e493940ea8401210278072 1cc016aaf0434878f95bce130147ccdc4bd88478222bcba2018294e99d4ffffffff02c09e0a0000 0000001976a9142e2a8d353ea825de6bc2b081324f412764e53e5788ac85351931100000001976a 914c73c92961d27fb399e1d408c94f1dade2860394588ac00000000

Lets break down the entire transaction.  It may help you some, and it may help others that stumble across this thread while investigating their own issues understanding how bitcoin transactions are built. Note that the values in the raw transaction are generally in little-endian byte order.

4 byte version number: 01000000
1 byte quantity of transaction inputs: 01
32 byte hash of the transaction that supplied the value being used in the input: 05287a343ffb315b10c03574975535badbe801cf6ffdf73c79ac22da215d095b
4 byte index indicating which output from that transaction is being used as input in this transaction: 01000000
1 byte value indicating the length of the scriptSig: 6a

6a in decimal is 106. In this case, the ScriptSig consists of a 73 byte signature followed by a 33 byte compressed public key both associated with the output in the earlier transaction that supplied the value for this transaction.

1 byte value indicating a number of bytes to push on to the stack when processing the ScriptSig: 47

47 in decimal is 71, therefore 71 bytes  are pushed on to the stack.  Those 71 bytes consist of a 70 byte DER encoded signature and a 1 byte OP_SIGHASHALL:

The 70 bytes DER encoded signature is:
1 byte sequence: 30
1 byte length of signature X & Y coordinates: 44
1 byte indication that the next value is intended to be an integer: 02
1 byte indication of the length of the X coordinate of the signature: 20
32 byte X coordinate: 670ef406032cc1c20c284da8ccc2a40d5b135776dac672ce04e8cbb9036fec15
1 byte indication that the next value is intended to be an integer: 02
1 byte indication of the length of the X coordinate of the signature: 20
32 byte Y coordinate: 11e6f589e5ca946f974b3ff69523497d06262a7e75be38ae99a85e493940ea84

Then we have the 1 byte OP_SIGHASHALL: 01

1 byte value indicating the length of the public key: 21

21 in decimal is 33, therefore the public key is 33 bytes long:

33 byte compressed public key: 02 780721cc016aaf0434878f95bce130147ccdc4bd88478222bcba2018294e99d4
4 byte sequence number: ffffffff

1 byte quantity of transaction inputs: 02

8 byte number of satoshis in the output representing 0.000696 BTC: c09e0a0000000000
1 byte value indicating the length of the scriptPubKey: 19

19 in decimal is 25. In this case the scriptPubKey consists of:

1 byte OP_DUP: 76
1 byte OP_HASH160: a9
1 byte value indicating the length of the pubKeyHash: 14

14 in decimal is 20. Therefore the next 20 bytes are the 160 bit pubKeyHash that can be acquired from the address.

pubKeyHash: 2e2a8d353ea825de6bc2b081324f412764e53e57

1 byte OP_EQUALVERIFY: 88
1 byte OP_CHECKSIG: ac


8 byte number of satoshis in the output representing 695.43212421 BTC: 8535193110000000
1 byte value indicating the length of the scriptPubKey: 19

19 in decimal is 25. In this case the scriptPubKey consists of:

1 byte OP_DUP: 76
1 byte OP_HASH160: a9
1 byte value indicating the length of the pubKeyHash: 14

14 in decimal is 20. Therefore the next 20 bytes are the 160 bit pubKeyHash that can be acquired from the address.

pubKeyHash: c73c92961d27fb399e1d408c94f1dade28603945

1 byte OP_EQUALVERIFY: 88
1 byte OP_CHECKSIG: ac

4 byte locktime: 00000000

If you take the pubKeyHash (2e2a8d353ea825de6bc2b081324f412764e53e57) then add the appropriate checksum and version number to it, and finally convert from base16 to base58, the result should be the bitcoin address (mjj4MR1aeTjWSRqHuixfoCGRDRwabbK3zv).

Reversing that, if you start with the bitcoin address (mjj4MR1aeTjWSRqHuixfoCGRDRwabbK3zv), then convert from base58 to base 16, and finally strip off the version number and checksum, the result should be the pubKeyHash (2e2a8d353ea825de6bc2b081324f412764e53e57)


EDIT:  I've gone back and broken the ScriptSig down into it's component parts.
markbeek (OP)
Newbie
*
Offline Offline

Activity: 2
Merit: 0


View Profile
July 06, 2015, 04:46:36 AM
 #4

Oh man, I can't tell you how many documents I've pored over trying to figure this out. I never quite got it . . . until now. In particular, I didn't get that the OPs are added as actual bytes to the pubKeyHash to form the scriptPubKey. This clears it all up.

I hope this starts showing up in Google searches under BITCOIN RAW TRANSACTION EXPLAINED.

Many thanks.
fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 287


View Profile
July 06, 2015, 03:56:08 PM
 #5

Just to add - the different address prefixes tell clients to form the script from the hash in a specific way.

0x0 means use the following hash in a pay-to-pubkey-hash script.
0x5 means use the following hash in a pay-to-script-hash script.

This is why wallets need explicit support of address types - not too long ago many refused to send to p2sh addresses.

Bitwasp Developer.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!