在PHP中从公钥哈希到比特币地址
我试图遵循使用
PHP将65字节公钥转换为比特币地址所需的指令.说明非常明确.任何人都可以帮助我在PHP中实现这一点的实用性?
说明是 1 – 获取用它生成的相应公钥(65字节,1字节0x04,32坐标对应X坐标,32字节对应Y坐标) 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6 2 – 对公钥执行SHA-256哈希处理 600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408 3 – 对SHA-256的结果执行RIPEMD-160散列 010966776006953D5567439E5E39F86A0D273BEE 4 – 在RIPEMD-160散列前添加版本字节(主网络为0x00) 00010966776006953D5567439E5E39F86A0D273BEE 5 – 对扩展的RIPEMD-160结果执行SHA-256哈希 445C7A8007A93D8733188288BB320A8FE2DEBD2AE1B47F0F50BC10BAE845C094 6 – 对先前SHA-256哈希的结果执行SHA-256哈希 D61967F63C7DD183914A4AE452C9F6AD5D462CE3D277798075B107615C1A8A30 7 – 获取第二个SHA-256哈希的前4个字节.这是地址校验和 D61967F6 8 – 在点4的扩展RIPEMD-160哈希结尾处从点7添加4个校验和字节.这是25字节的二进制比特币地址. 00010966776006953D5567439E5E39F86A0D273BEED61967F6 9 – 使用Base58Check编码将结果从字节字符串转换为base58字符串.这是最常用的比特币地址格式 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM 我的第一次尝试是 // step 1 $publickey='0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'; $step1=$publickey; echo "step1 ".$publickey."<br>"; // step 2 $step2=hash("sha256",$step1); echo "step2 ".$step2."<br>"; // step 3 $step3=hash('ripemd160',$step2); echo "step3 ".$step3."<br>"; // step 4 $step4="00".$step3; echo "step4 ".$step4."<br>"; // step 5 $step5=hash("sha256",$step4); echo "step5 ".$step5."<br>"; // step 6 $step6=hash("sha256",$step5); echo "step6 ".$step6."<br>"; // step 7 $checksum=substr($step6,8); echo "step7 ".$checksum."<br>"; // step 8 $step8=$step4.$checksum; echo "step8 ".$step8."<br>"; //step 9 $step9=base58_encode($step8); echo "step9 ".$step9."<br><br>"; 这在第一步失败了.任何帮助赞赏. 这是输出 step1 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6 step2 32511e82d56dcea68eb774094e25bab0f8bdd9bc1eca1ceeda38c7a43aceddce step3 7528c664cdc34c5ce809778eb688d32f89a538c0 step4 007528c664cdc34c5ce809778eb688d32f89a538c0 step5 86e76f4ff0bf0387339ac70a552e0fed615f7def34cc4809df1429e243f6c1fa step6 b885b7225b370e7ff27ee0afb4f89b52b8675d5dc342d63de3abe7535f86cadb step7 b885b722 step8 007528c664cdc34c5ce809778eb688d32f89a538c0b885b722 step9 1 Base58的功能是 function base58_encode($input) { $alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'; $base_count = strval(strlen($alphabet)); $encoded = ''; while (floatval($input) >= floatval($base_count)) { $div = bcdiv($input,$base_count); $mod = bcmod($input,$base_count); $encoded = substr($alphabet,intval($mod),1) . $encoded; $input = $div; } if (floatval($input) > 0) { $encoded = substr($alphabet,intval($input),1) . $encoded; } return($encoded); } 解决方法
感谢Sammitch发现语法并提供基本转换,下面的解决方案.
<?php // step 1 $publickey='0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'; $step1=hexStringToByteString($publickey); echo "step1 ".$publickey."<br>"; // step 2 $step2=hash("sha256",hexStringToByteString($step2)); echo "step3 ".$step3."<br>"; // step 4 $step4="00".$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($step6,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="1".bc_base58_encode(bc_hexdec($step8)); echo "step9 ".$step9."<br><br>"; ?> hash需要字节字符串而不是十六进制字符串. hexStringToByteString是 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; } 基本转换(感谢Sammitch – 修改为使用比特币base58) // 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'); } 最终输出 step1 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6 step2 600ffe422b4e00731a59557a5cca46cc183944191006324a447bdb2d98d4b408 step3 010966776006953d5567439e5e39f86a0d273bee step4 00010966776006953d5567439e5e39f86a0d273bee step5 445c7a8007a93d8733188288bb320a8fe2debd2ae1b47f0f50bc10bae845c094 step6 d61967f63c7dd183914a4ae452c9f6ad5d462ce3d277798075b107615c1a8a30 step7 d61967f6 step8 00010966776006953d5567439e5e39f86a0d273beed61967f6 step9 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |