Your browser (Internet Explorer 6) is out of date. It has known security flaws and may not display all features of this and other websites. Learn how to update your browser.
X

Generating Bitcoin Wallet Address from Public Key with PHP

Recently, I have been working on some interesting Bitcoin projects and I ran into the issue of converting my public key to a wallet address. I was initially using bitwasp/bitcoin module to achieve this but when I moved the project to a shared host it wasn't working because it needed a PHP Library my host will not allow me install because it is shared. Below is a solution to this. It follows the algorithm stated in Bitcoin documentation on step by step way of generating wallet address from public key.


<?php
/**
 * Class BitcoinUtils
 * @author Akinyele Olubodun
 */

class BitcoinUtils
{
    public function address_from_master_pub($public_key)
    {
        $step1= $this->hexStringToByteString($public_key);

        $step2=hash("sha256",$step1);

        $step3=hash('ripemd160', $this->hexStringToByteString($step2));

        $step4="00".$step3;

        $step5=hash("sha256", $this->hexStringToByteString($step4));

        $step6=hash("sha256", $this->hexStringToByteString($step5));

        $checksum=substr($step6,0,8);

        $step8 = $step4.$checksum;
        $step9 = "1".$this->bc_base58_encode($this->bc_hexdec($step8));

        return $step9;
    }

    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 $this->bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
    }
    function bc_base58_decode($num) {
        return $this->bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
    }

    //hexdec with BCmath
    function bc_hexdec($num) {
        return $this->bc_arb_decode(strtolower($num), '0123456789abcdef');
    }
    function bc_dechex($num) {
        return $this->bc_arb_encode($num, '0123456789abcdef');
    }

}


comments powered by Disqus