Base58编码Peercoin公钥的步骤

时间:2014-02-24 01:41:01

标签: php c++

我希望有人可以帮助我应对这一挑战。我想知道用于转换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

1 个答案:

答案 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

正如你可能看到的,他们匹配!