How to Generate Bitcoin Receive Address with Extended Public Key in PHP

By | May 5, 2020

Let me repeat, I’m not a programmer. But sometimes I have to resolve tasks, related to programming, when it comes to quite simple things to do. Here is one of them.

You have an Extended Public Key of your bitcoin wallet. How do you generate receive addresses from them with PHP? Here is the short code I had to write to perform this task.

First of all, you need the Extended Public Key. Depending on the wallet type, it can be named xpub (if addresses in your wallet are starting with “1”), ypub for addresses, starting with “3” and zpub for bc1 addresses.

The easiest way to get an Extended Public Key for testing purposes is to generate it here. Then copy the contents of

<?

// Generating receive addresses with public key

require_once('vendor/autoload.php');

use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Address\AddressCreator;
use BitWasp\Bitcoin\Key\Deterministic\HdPrefix\GlobalPrefixConfig;
use BitWasp\Bitcoin\Key\Deterministic\HdPrefix\NetworkConfig;
use BitWasp\Bitcoin\Network\Slip132\BitcoinRegistry;
use BitWasp\Bitcoin\Key\Deterministic\Slip132\Slip132;
use BitWasp\Bitcoin\Key\KeyToScript\KeyToScriptHelper;
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory;
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeySequence;
use BitWasp\Bitcoin\Network\NetworkFactory;
use BitWasp\Bitcoin\Serializer\Key\HierarchicalKey\ExtendedKeySerializer;
use BitWasp\Bitcoin\Serializer\Key\HierarchicalKey\Base58ExtendedKeySerializer;

// Extended public key comes here
$pubkey = 'ypub...';

// Deviation path (0/0, 0/1, 0/2, etc)
$path = '0/17';

// Determining the type of public key given
$pubkeytype=substr($pubkey, 0, 4);

$bitcoin_prefixes = new BitcoinRegistry();

$adapter = Bitcoin::getEcAdapter();
$slip132 = new Slip132(new KeyToScriptHelper($adapter));

if ($pubkeytype=='xpub') $pubPrefix = $slip132->p2pkh($bitcoin_prefixes);
if ($pubkeytype=='ypub') $pubPrefix = $slip132->p2shP2wpkh($bitcoin_prefixes);
if ($pubkeytype=='zpub') $pubPrefix = $slip132->p2wpkh($bitcoin_prefixes);

$config = new GlobalPrefixConfig([
      new NetworkConfig(NetworkFactory::bitcoin(), [
        $pubPrefix,
      ])
    ]);


$serializer = new Base58ExtendedKeySerializer(new ExtendedKeySerializer($adapter, $config));
$key = $serializer->parse(NetworkFactory::bitcoin(), $pubkey);
$child_key = $key->derivePath($path);

echo $child_key->getAddress(new AddressCreator())->getAddress();

?>

Please, see your Bitcoin wallet documentation to find out how to extract the Extended Public Key (it’s a common functionality for hardware, software and mobile wallets). Now you can create as many addresses as you like!

Leave a Reply

Your email address will not be published. Required fields are marked *