Php Base58编码Peercoin公钥的步骤
我希望有人能帮助我应对这个挑战。我想知道转换文件的过程 将十六进制130字符Peercoin公钥转换为Peercoin地址。如果你能读C++,在这里阅读源代码,会有帮助。我需要帮助调整这个代码为Peercoin工作(我从这个网站上的前一个问题得到了这个代码)。 举个例子, 130个字符的公钥:04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E 上述设备的Base58编码对等接口地址为:PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe 注意:这是一个有效的公钥,我从中获得了该密钥,并使用PPCOIN对其进行了测试Php Base58编码Peercoin公钥的步骤,php,c++,Php,C++,我希望有人能帮助我应对这个挑战。我想知道转换文件的过程 将十六进制130字符Peercoin公钥转换为Peercoin地址。如果你能读C++,在这里阅读源代码,会有帮助。我需要帮助调整这个代码为Peercoin工作(我从这个网站上的前一个问题得到了这个代码)。 举个例子, 130个字符的公钥:04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E5374E573FA570D8EA94FC44905
<?php
function hexStringToByteString($hexString){
$len=strlen($hexString);
$byteString="";
for ($i=0;$i<$len;$i=$i+2){
$charnum=hexdec(substr($hexString,$i,2));
$byteString.=chr($charnum);
}
return $byteString;
}
// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$rep = '';
while( true ){
if( strlen($num) < 2 ) {
if( intval($num) <= 0 ) {
break;
}
}
$rem = bcmod($num, $base);
$rep = $basestr[intval($rem)] . $rep;
$num = bcdiv(bcsub($num, $rem), $base);
}
return $rep;
}
function bc_arb_decode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$dec = '0';
$num_arr = str_split((string)$num);
$cnt = strlen($num);
for($i=0; $i < $cnt; $i++) {
$pos = strpos($basestr, $num_arr[$i]);
if( $pos === false ) {
Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
}
$dec = bcadd(bcmul($dec, $base), $pos);
}
return $dec;
}
// base 58 alias
function bc_base58_encode($num) {
return bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
function bc_base58_decode($num) {
return bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
//hexdec with BCmath
function bc_hexdec($num) {
return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {
return bc_arb_encode($num, '0123456789abcdef');
}
// step 1
$publickey='04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E';
$step1=hexStringToByteString($publickey);
//echo "step1 ".$step1."<br>";
// step 2
$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";
// step 3
$step3=hash('ripemd160',hexStringToByteString($step2));
echo "step3 ".$step3."<br>";
// step 4
$step4='55'.$step3;
echo "step4 ".$step4."<br>";
// step 5
$step5=hash("sha256",hexStringToByteString($step4));
echo "step5 ".$step5."<br>";
// step 6
// $step6=hash("sha256",hexStringToByteString($step5));
// echo "step6 ".$step6."<br>";
// step 7
$checksum=substr($step5,0,8);
echo "step7 ".$checksum."<br>";
// step 8
$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";
// step 9
// base conversion is from hex to base58 via decimal.
// Leading hex zero converts to 1 in base58 but it is dropped
// in the intermediate decimal stage. Simply added back manually.
$step9='P'.bc_base58_encode(bc_hexdec($step8));
echo "step9 ".$step9."<br><br>";
?>
好的!最后我自己解决了这个问题。最大的问题是我用55作为十进制,而我本应该把55转换成十六进制,也就是“37”。我还收回了我对PPC的评论,只使用sha256而不是sha256d。公钥的base58编码方式与比特币相同,但不是使用版本号1,而是55,十六进制的55是37(我在上面提到过)。这是最后的代码和输出 干杯
<?php
function hexStringToByteString($hexString){
$len=strlen($hexString);
$byteString="";
for ($i=0;$i<$len;$i=$i+2){
$charnum=hexdec(substr($hexString,$i,2));
$byteString.=chr($charnum);
}
return $byteString;
}
// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$rep = '';
while( true ){
if( strlen($num) < 2 ) {
if( intval($num) <= 0 ) {
break;
}
}
$rem = bcmod($num, $base);
$rep = $basestr[intval($rem)] . $rep;
$num = bcdiv(bcsub($num, $rem), $base);
}
return $rep;
}
function bc_arb_decode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$dec = '0';
$num_arr = str_split((string)$num);
$cnt = strlen($num);
for($i=0; $i < $cnt; $i++) {
$pos = strpos($basestr, $num_arr[$i]);
if( $pos === false ) {
Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
}
$dec = bcadd(bcmul($dec, $base), $pos);
}
return $dec;
}
// base 58 alias
function bc_base58_encode($num) {
return bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
function bc_base58_decode($num) {
return bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
//hexdec with BCmath
function bc_hexdec($num) {
return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {
return bc_arb_encode($num, '0123456789abcdef');
}
$publickey='04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E';
//step1 is just converting the 130-hex-character publickey in bytes
$step1=hexStringToByteString($publickey);
echo "step1 ".$publickey."<br>";
// step 2 sha256 hashes the publickey from step 1
$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";
// step 3 ripemd160 hashes step2
$step3=hash('ripemd160',hexStringToByteString($step2));
echo "step3 ".$step3."<br>";
// step 4 is the tricky part: add 37(hexadecimal of 55)the
// version number to step 3
$step4='37'.$step3;
echo "step4 ".$step4."<br>";
// step 5 sha256 hash step4
$step5=hash("sha256",hexStringToByteString($step4));
echo "step5 ".$step5."<br>";
// step 6 sha256 hash step 5
$step6=hash("sha256",hexStringToByteString($step5));
echo "step6 ".$step6."<br>";
// step 7 takes the first 8 characters (4 bytes) of step 6 as a checksum
$checksum=substr($step6,0,8);
echo "step7 ".$checksum."<br>";
// step 8 adds the checksum to step 4
$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";
//step 9 converts step 8 into decimal
$step9=bc_hexdec($step8);
//step 10 encodes step 9 into base58
$step10=bc_base58_encode($step9);
echo "step9 ".$step10."<br><br>";
?>
正如你可能看到的,它们是匹配的 你知道第一个错误大概发生在哪里吗?知道散列步骤是否正确吗?@ChristopherRoicles,不,这是我的问题,但我认为到第4步为止,这个过程是正确的。我不太熟悉C++,所以我不确定开发人员是如何设计哈希过程的。另外,我想指出的是,这段代码对于比特币公钥的编码非常有效(将'55'更改为'0'),因此由于Peercoin是基于比特币的,我认为这个过程是类似的。好吧,我取得了一些进展。首先,我发现Peercoin不使用SHA256D,它只使用SHA256,这意味着它不会对ripemd160进行双重哈希。因此,您可以看到,在代码中,我在步骤5和6之间对SHA256进行了双重哈希,这是一个错误。但是,即使我注释掉第二个SHA256哈希并继续处理,我仍然得到了错误的编码公钥地址。。。
<?php
function hexStringToByteString($hexString){
$len=strlen($hexString);
$byteString="";
for ($i=0;$i<$len;$i=$i+2){
$charnum=hexdec(substr($hexString,$i,2));
$byteString.=chr($charnum);
}
return $byteString;
}
// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$rep = '';
while( true ){
if( strlen($num) < 2 ) {
if( intval($num) <= 0 ) {
break;
}
}
$rem = bcmod($num, $base);
$rep = $basestr[intval($rem)] . $rep;
$num = bcdiv(bcsub($num, $rem), $base);
}
return $rep;
}
function bc_arb_decode($num, $basestr) {
if( ! function_exists('bcadd') ) {
Throw new Exception('You need the BCmath extension.');
}
$base = strlen($basestr);
$dec = '0';
$num_arr = str_split((string)$num);
$cnt = strlen($num);
for($i=0; $i < $cnt; $i++) {
$pos = strpos($basestr, $num_arr[$i]);
if( $pos === false ) {
Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
}
$dec = bcadd(bcmul($dec, $base), $pos);
}
return $dec;
}
// base 58 alias
function bc_base58_encode($num) {
return bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
function bc_base58_decode($num) {
return bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
//hexdec with BCmath
function bc_hexdec($num) {
return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {
return bc_arb_encode($num, '0123456789abcdef');
}
$publickey='04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E';
//step1 is just converting the 130-hex-character publickey in bytes
$step1=hexStringToByteString($publickey);
echo "step1 ".$publickey."<br>";
// step 2 sha256 hashes the publickey from step 1
$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";
// step 3 ripemd160 hashes step2
$step3=hash('ripemd160',hexStringToByteString($step2));
echo "step3 ".$step3."<br>";
// step 4 is the tricky part: add 37(hexadecimal of 55)the
// version number to step 3
$step4='37'.$step3;
echo "step4 ".$step4."<br>";
// step 5 sha256 hash step4
$step5=hash("sha256",hexStringToByteString($step4));
echo "step5 ".$step5."<br>";
// step 6 sha256 hash step 5
$step6=hash("sha256",hexStringToByteString($step5));
echo "step6 ".$step6."<br>";
// step 7 takes the first 8 characters (4 bytes) of step 6 as a checksum
$checksum=substr($step6,0,8);
echo "step7 ".$checksum."<br>";
// step 8 adds the checksum to step 4
$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";
//step 9 converts step 8 into decimal
$step9=bc_hexdec($step8);
//step 10 encodes step 9 into base58
$step10=bc_base58_encode($step9);
echo "step9 ".$step10."<br><br>";
?>
step1 04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E
step2 6cf59dae61a5b2a4ca2990c644fa7d444928175f1c454f0cf2f4d98081dc6f63
step3 c07de396ef663b22ccab46fc87d067eaad408aa3
step4 37c07de396ef663b22ccab46fc87d067eaad408aa3
step5 a4237928cd0a9cbb001325a9b4726633ed67fd0ce15bf50c7d19260a297f488b
step6 443e1443a9fbdc855b88865e621fc5b35fe4515bc35229460ccb9f277dd35c21
step7 443e1443
step8 37c07de396ef663b22ccab46fc87d067eaad408aa3443e1443
step9 PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe