4

I have been writing a php file intended to create a bitcoin private key and change it to wallet import format. The issue is when I try a command in a gnome-terminal such as:
bitcoin-cli importprivkey ygm8fAjomMyKVcb8vK8MPBByYpMDySY1vAxcpw6DUfPBHb8kv "" false
I get an error:
error: {"code":-5,"message":"Invalid private key encoding"}

From this I've infered that my code is flawed in creating a private key and changing it into wallet import format. But from what I see in the source code it should do what it says to at https://en.bitcoin.it/wiki/Wallet_import_format under "Private key to WIF"

Here are the php files:

test1.php:

<?php
require('devRand.php');
#require('base58.php');

$a = new btcMakePrivKey();
#echo $GLOBALS['base58oper'];
function decodeHex($hex) {
    $hexchars = "0123456789ABCDEF";

    $hex = strtoupper($hex);
    $return = "0";
    for ($i = 0; $i < strlen($hex); $i++) {
        $current = (string) strpos($hexchars, $hex[$i]);
        $return = (string) bcmul($return, "16", 0);
        $return = (string) bcadd($return, $current, 0);
    }
    return $return;
}
function encodeBase58($hex) 
{
    $base58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    if (strlen($hex) % 2 != 0) {
        die("encodeBase58: uneven number of hex characters");
    }
    $orighex = $hex;

    $hex = decodeHex($hex);
    $return = "";
    while (bccomp($hex, 0) == 1) {
        $dv = (string) bcdiv($hex, "58", 0);
        $rem = (integer) bcmod($hex, "58");
        $hex = $dv;
        $return = $return . $base58chars[$rem];
    }
    $return = strrev($return);

    //leading zeros
    for ($i = 0; $i < strlen($orighex) && substr($orighex, $i, 2) == "00"; $i += 2) {
        $return = "1" . $return;
    }
    return $return;
}
class btcMakePrivKey
{
    //$base58oper = new base58();
    public function __construct()
    {
        #$this->base58oper = new base58();
        $count = 0;  $privKey = "";
        while($count < 62)
        {
            $appendable = devurandom_rand(0,15);
            switch($appendable)
            {
                case 10:
                $appendable = 'A';
                break;
                case 11:
                $appendable = 'B';
                break;
                case 12:
                $appendable = 'C';
                break;
                case 13:
                $appendable = 'D';
                break;
                case 14:
                $appendable = 'E';
                break;
                case 15:
                $appendable = 'F';
                break;
                default:
                break;
            }
            $count = $count + 1;
            $privKey = $privKey . $appendable;
        }
        $privKey = $this->addLeadingByte($privKey);
        #echo $privKey . "\n\n";
        $pkHashed = $this->sha256Hash($this->sha256Hash($privKey) );
        $checksum = substr($pkHashed, 0, 8);
        $privKey = $privKey . $checksum;
        #$privKey = $this->base58oper->encode($privKey);
        $privKey = encodeBase58($privKey);
        echo $privKey;// . "\n\n" . $pkHashed . "\n\n" . $checksum;
    }
    private function addLeadingByte($privKey)
    {
        return '80' . $privKey;
    }
    private function sha256Hash($privKey)
    {
        return hash('sha256', $privKey, false);
    }
}

and devRand.php:

<?php
//equiv to rand, mt_rand
//returns int in *closed* interval [$min,$max]
function devurandom_rand($min = 0, $max = 0x7FFFFFFF) {
    $diff = $max - $min;
    if ($diff < 0 || $diff > 0x7FFFFFFF) {
    throw new RuntimeException("Bad range");
    }
    $bytes = mcrypt_create_iv(4, MCRYPT_DEV_URANDOM);
    if ($bytes === false || strlen($bytes) != 4) {
        throw new RuntimeException("Unable to get 4 bytes");
    }
    $ary = unpack("Nint", $bytes);
    $val = $ary['int'] & 0x7FFFFFFF;   // 32-bit safe
    $fp = (float) $val / 2147483647.0; // convert to [0,1]
    return round($fp * $diff) + $min;
}

I intend my code to create a bitcoin private key and convert it to a useable key in wallet import format, which can be used in bitcoin-cli importprivkey insertKeyHere "" false

0

1 Answer 1

0

Your code (as well as the instructions on the official Bitcoin Core Wiki, strangely enough) appear to be missing the compression flag (1 byte = 0x01) which is appended before the 4-byte checksum. This might be causing your problem.

Contrast with the steps/instructions found here: https://www.royalfork.org/2014/08/11/graphical-address-generator

1
  • 1
    There is nothing official in Bitcoin, and the bitcoin.it wiki is unrelated to Bitcoin Core (which does have a wiki for development on github.com/bitcoin-core/bitcoin-devwiki/wiki). Most of the information on bitcoin.it is very outdated. Commented Mar 6, 2021 at 4:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.