Reputation: 8101
https://en.bitcoin.it/wiki/Wallet_import_format
Trying to follow this example here to do this in PHP, but I get stuck at step 3.
I can't seem to get the same SHA256 hash.
I take the extended key from step 2 800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D
and SHA256 it.
I should get 8147786C4D15106333BF278D71DADAF1079EF2D2440A4DDE37D747DED5403592
according to step 3 but I just get E2E4146A36E9C455CF95A4F259F162C353CD419CC3FD0E69AE36D7D1B6CD2C09
What am I doing wrong?
Upvotes: 0
Views: 2808
Reputation: 21
Here is the working PHP-code example:
<?php
//EXAMPLE INPUT: 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D
//EXAMPLE OUTPUT: 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ
//see https://en.bitcoin.it/wiki/Wallet_import_format for more info
function decodeHex($hex)
{
$hex = strtoupper($hex);
$chars = '0123456789ABCDEF';
$return = '0';
for($i = 0; $i < strlen($hex); $i++)
{
$current = (string)strpos($chars, $hex[$i]);
$return = (string)bcmul($return, '16', 0);
$return = (string)bcadd($return, $current, 0);
}
return $return;
}
function encodeBase58($hex)
{
$orighex = $hex;
$chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
$hex = decodeHex($hex);
$return = '';
while(bccomp($hex, 0) == 1)
{
$dv = (string)bcdiv($hex, '58', 0);
$rem = (integer)bcmod($hex, '58');
$hex = $dv;
$return = $return.$chars[$rem];
}
$return = strrev($return);
//leading zeros
for($i = 0; $i < strlen($orighex) && substr($orighex, $i, 2) == '00'; $i += 2)
{
$return = '1' . $return;
}
return $return;
}
if(!isset($_SERVER['argv'][1]))
{
exit("Usage: php convert_bitcoin_private_key_to_wif_format.php private_key\n");
}
$privateKey = $_SERVER['argv'][1];
//add a 0x80 byte in front of it
$buffer = '80' . $privateKey;
$extendedKey = $buffer;
//perform SHA-256 hash on the extended key
$buffer = strtoupper(hash('sha256', hex2bin($buffer)));
//perform SHA-256 hash on result of SHA-256 hash
$buffer = strtoupper(hash('sha256', hex2bin($buffer)));
//take the first 4 bytes of the second SHA-256 hash, this is the checksum
$checksum = substr($buffer, 0, 8);
//add the checksum at the end of the extended key
$buffer = $extendedKey . $checksum;
//convert the result from a byte string into a base58 string
$buffer = encodeBase58($buffer);
echo($buffer . "\n");
?>
Upvotes: 0
Reputation: 227180
This is because you are hashing the literal string
"800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D"
This is not what what needs to happen. This is a string of bytes. It's in HEX format just to make viewing it easier. In reality, this represents a binary string. That's what you need to be hashing.
hex2bin
is your friend here.
<?php
$hex = '800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D';
echo hash('sha256', hex2bin($hex));
DEMO: https://eval.in/69440
Another example:
<?php
$key = '0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D';
$binKey = hex2bin($key);
$binKey = hex2bin(80).$binKey;
echo hash('sha256', $binKey);
DEMO: https://eval.in/69443
Upvotes: 3