我希望有人可以帮助我应对这一挑战。我想知道用于转换a的过程 hex-130字符将Peercoin公钥转换为Peercoin地址。如果您可以阅读C ++,那么在这里阅读源代码https://github.com/ppcoin/ppcoin/blob/master/src/base58.h#L1将会有所帮助。我需要帮助调整此代码以适用于Peercoin(我从此网站上的上一个问题获得此代码)。 我们以此为例, 130个字符公钥:04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E
以上的Base58编码的Peercoin地址是:PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe
注意:这是一个有效的公钥,我从http://tizop.com/peercoin.htm获得了此密钥,并使用ppcoind对其进行了测试。
<?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>";
?>
这是我的输出,因为你可以看到我的最后一行 不匹配: PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe
step1 04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E
step2 6cf59dae61a5b2a4ca2990c644fa7d444928175f1c454f0cf2f4d98081dc6f63
step3 c07de396ef663b22ccab46fc87d067eaad408aa3
step4 55c07de396ef663b22ccab46fc87d067eaad408aa3
step5 12c5b0698d8dd8bd9a9d653c6d09beaf67cb0b967107f835537f0ebd4e97df0d
step7 12c5b069
step8 55c07de396ef663b22ccab46fc87d067eaad408aa312c5b069
step9 PbWH5Ez522wiao4Lrgh6j6Vz2uMHSDNMRbe
答案 0 :(得分:2)
好的!我自己最终解决了这个问题。最大的问题是我使用55作为小数,我应该将55decimal转换为十六进制,即'37'。我也只使用sha256而不是sha256d收回我对PPC的评论.Peercoin使用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>";
?>
请记住,base58公钥是 PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe 。
step1 04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E
step2 6cf59dae61a5b2a4ca2990c644fa7d444928175f1c454f0cf2f4d98081dc6f63
step3 c07de396ef663b22ccab46fc87d067eaad408aa3
step4 37c07de396ef663b22ccab46fc87d067eaad408aa3
step5 a4237928cd0a9cbb001325a9b4726633ed67fd0ce15bf50c7d19260a297f488b
step6 443e1443a9fbdc855b88865e621fc5b35fe4515bc35229460ccb9f277dd35c21
step7 443e1443
step8 37c07de396ef663b22ccab46fc87d067eaad408aa3443e1443
step9 PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe
正如你可能看到的,他们匹配!