0
If I want to recreate the command decodescript of bitcoin core? how is the process for decode the script P2PK?
So I'm writing for personal exercise the Bitcoin script decompiler, form moment I have a version alpha of the process decodifier of the script P2PK script.
In my example, I get the scriptPubKey of the codebase block, so the data are
The hex of the script: 4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac
So the decoded script is
04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac OP_CHECKSIG
The result of the command decodescript of bitcoin core
{
"asm": "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG",
"reqSigs": 1,
"type": "pubkey",
"addresses": [
"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
],
"p2sh": "3DjjKyU38gSfuVxajV43MUy4vHkg1JVL7T"
}
So the my process decode is
I get the type of transaction with this code
string hex(argv[1]); BitcoinOPCode bitcoinOpCode; string opcode = hex.substr(0, 2); int32_t optValue = std::stoul(opcode, nullptr, 16); auto optMap = bitcoinOpCode.opCodeList.find(optValue); string optCode = optMap->second; //Not are all type script if (optCode == "OP_HASH160") { cout << "Finded the P2SHA"; } else if (optCode == "OP_DUP") { cout << "Finded the P2PKH"; } else { cout << "Finded the old style script\n"; }
The script is a script old style so I decode the hex script with this code
string key = hex.substr(2, optValue * 2); opcode = hex.substr(2 + optValue * 2, hex.length()); cout << "Hex key is: " << key << " op code: " << opcode << endl; optValue = std::stoul(opcode, nullptr, 16); optMap = bitcoinOpCode.opCodeList.find(optValue); opcode = optMap->second;
The result is 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG
- Find the key to this hex string
04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f
I try with this code
Bytes bytes = hexBytes(key.c_str());
//Ripemd160
uint8_t result[Ripemd160::HASH_LEN];
Ripemd160::getHash(bytes.data(), key.length(), result);
char address[36];
Base58Check::pubkeyHashToBase58Check(result, 0x00, address);
cout << "The script public key is: " << address << " " << opcode << endl;
But the result is wrong 1NXtFSm6h4QAVBQ7ezaDc3ZvSKFj9GTfoV
I looked the code bitcoin, so I think the bitcoin core decode the script with this code GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0].begin(), solutions_data[0].end())));
but in the my logic exist an bug, can you help me to find it? thanks
Two comments: 1) the fact that Bitcoin Core shows a 1... address for P2PK output is considered a historical mistake. There is no need to perpetuate it. 2) You should convert everything from hex to bytes, and then work on the byte data. If you feed the hex encoded form to hash functions you'll get the wrong result. – Pieter Wuille – 2019-09-22T17:09:35.517
Thanks, @PieterWuille, on your 1 comment, the historical mistake of the P2PK is because inside the script is insert the pure public key? on the 2 comments, to the function
Base58Check::pubkeyHashToBase58CheckI must pass the bytes, right? – vincenzopalazzo – 2019-09-22T17:48:25.240Yes, 1... addresses should refer purely to P2PKH addresses to avoid ambiguity. P2PK outputs simply don't have a corresponding address. – Pieter Wuille – 2019-09-22T18:00:36.473
Sorry @PieterWuille if I reopen this question, can you help me to understand the problem with the P2PK script? what does it mean P2PK outputs simply don't have a corresponding address? – vincenzopalazzo – 2019-09-25T16:16:01.113
Addresses are shorthand notations for specific scripts. But not every script has a corresponding address. P2PK scripts don't have one. P2PKH ones do. – Pieter Wuille – 2019-09-25T16:25:44.730
So, if in my example
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNanot is the Key but the result of the process command decode, so sha256 -> Ripemd160 -> Base58Check, What data is entered in the script to unlock the transaction? – vincenzopalazzo – 2019-09-25T16:35:29.3401That's a completely unrelated question. I think you should go through some reference material (the bitcoin.org developer documentation, maybe a book on Bitcoin, ...) and if you have specific questions, ask them here. – Pieter Wuille – 2019-09-25T16:42:13.170
yes, thanks so much – vincenzopalazzo – 2019-09-25T17:06:30.203