1
1
How is the vout address derived for a P2PK transaction? I am using the Python API that ships with the bitcoin source code, in directory bitcoin/test/functional. I'm using regtest.
I have written a unit test. It creates a transaction, writes the CTransaction object to the log file, then appends a CTxOut object to the vout array, and writes the CTransaction object to the log again. The second log entry shows that the item in the vout array includes an array of addresses containing a single value, 'muXtVbAXxTdAdaS9HQLnexRvsfgVteZcv8'. How was that value derived?
Here is the relevant code fragment:
addr1 = w0_rpc.getnewaddress()
self.log.info(f"\n DEBUG addr1={addr1}")
a1 = w0_rpc.getaddressinfo(addr1)
pubkey1 = hex_str_to_bytes(a1['pubkey'])
self.log.info(f"\n DEBUG pubkey1={pubkey1}")
p2pk1 = CScript([pubkey1, OP_CHECKSIG])
self.log.info(f"\n DEBUG bytes_to_hex_str(p2pk1)={bytes_to_hex_str(p2pk1)}")
tx1 = CTransaction()
tx1.vin.append(CTxIn(COutPoint(int(txid0, 16), v), b""))
s = pprint.pformat(w0_rpc.decoderawtransaction(ToHex(tx1)))
self.log.info(f"\n DEBUG tx={s}")
tx1.vout.append(CTxOut(int(9 * COIN), p2pk1))
s = pprint.pformat(w0_rpc.decoderawtransaction(ToHex(tx1)))
self.log.info(f"\n DEBUG tx={s}")
Below is the log output from that code. You can see at the end that the vout array contains an item which includes an array of addresses containing a single value, 'muXtVbAXxTdAdaS9HQLnexRvsfgVteZcv8'. I did not explicitly provide that value, at least not knowingly. It seems to me that the value was derived somewhere, under the hood. Where did this happen? How was the value calculated?
DEBUG addr1=2NGYQt1CxwSCdGbj8mpxMtLaTZtxHsmbqWM
2019-10-10T12:13:06.176000Z TestFramework (INFO):
DEBUG pubkey1=b'\x02#\x9c\xabCVRL\xc1\xd1o8}\x0e\x85Z myQ-&\x06\xb2\xc2\xea \xfa\xf0(\xd3e\x98'
2019-10-10T12:13:06.176000Z TestFramework (INFO):
DEBUG bytes_to_hex_str(p2pk1)=2102239cab4356524cc1d16f387d0e855a206d79512d2606b2c2ea20faf028d36598ac
2019-10-10T12:13:06.177000Z TestFramework (INFO):
DEBUG tx={'hash': '0abb1fa572d89323429fc231fcede74af58f77469a3b383ee856db60ecee41a4',
'locktime': 0,
'size': 51,
'txid': '0abb1fa572d89323429fc231fcede74af58f77469a3b383ee856db60ecee41a4',
'version': 1,
'vin': [{'scriptSig': {'asm': '', 'hex': ''},
'sequence': 0,
'txid': '9d177bb43b76dcbbf52fad079c4fd98986b32034d91ea12bcb4e67d32dc20f9b',
'vout': 0}],
'vout': [],
'vsize': 51,
'weight': 204}
2019-10-10T12:13:06.179000Z TestFramework (INFO):
DEBUG tx={'hash': 'd86153fc539e699289dc8f7f4e20d10f6378fa4f10dad131f5c8b2d4bc7e5c76',
'locktime': 0,
'size': 95,
'txid': 'd86153fc539e699289dc8f7f4e20d10f6378fa4f10dad131f5c8b2d4bc7e5c76',
'version': 1,
'vin': [{'scriptSig': {'asm': '', 'hex': ''},
'sequence': 0,
'txid': '9d177bb43b76dcbbf52fad079c4fd98986b32034d91ea12bcb4e67d32dc20f9b',
'vout': 0}],
'vout': [{'n': 0,
'scriptPubKey': {'addresses': ['muXtVbAXxTdAdaS9HQLnexRvsfgVteZcv8'],
'asm': '02239cab4356524cc1d16f387d0e855a206d79512d2606b2c2ea20faf028d36598 '
'OP_CHECKSIG',
'hex': '2102239cab4356524cc1d16f387d0e855a206d79512d2606b2c2ea20faf028d36598ac',
'reqSigs': 1,
'type': 'pubkey'},
'value': Decimal('9.00000000')}],
'vsize': 95,
'weight': 380}
Edit: Thanks to the response below, I was able to work out how the value of the address is derived. This code does the trick:
from test_framework.script import hash160
from test_framework.address import byte_to_base58
addr1_hash160 = hash160(pubkey1)
self.log.info(f"\n DEBUG addr1_hash160={addr1_hash160}")
addr1_base58 = byte_to_base58(addr1_hash160, 111)
self.log.info(f"\n DEBUG addr1_base58={addr1_base58}")
So for the given example, this code prints out 'muXtVbAXxTdAdaS9HQLnexRvsfgVteZcv8', the value of the address that appears in the output from decoderawtransaction(). As mentioned below, this value is not actually relevant for a P2PK transaction.
The script inside the transaction output contains the address because this is a unique method for check the owner of the transaction. ps: not only the script P2PKH contains the address but also P2SH, P2WPKH, P2WSH. Only the script P2PK does not contain the address but the real public key. – vincenzopalazzo – 2019-10-10T12:40:28.933
How was the value derived? – eric – 2019-10-10T13:02:43.540
The address derived to the parsing and apply the correct codify to the hex propriety inside the ScriptPubKey. so if you parsering this
2102239cab4356524cc1d16f387d0e855a206d79512d2606b2c2ea20faf028d36598acit contains the address – vincenzopalazzo – 2019-10-10T16:42:10.693