| Notation | Description |
|---|---|
| / | Indicate a new branch with number of new child. |
| ' | Hardened Child means that no new child can be derived by extended public key, unless you derived from extended private key. Index range from 2147483648 to 4294967296. |
| without ' | Normal Child is the inverse of Hardened Child. Index range from 0 to 2147483647. |
<?php
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Crypto\Random\Random;
use BitWasp\Bitcoin\Key\Factory\HierarchicalKeyFactory;
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39Mnemonic;
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator;
use BitWasp\Bitcoin\Mnemonic\MnemonicFactory;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey;
include_once "../libraries/vendor/autoload.php";
include_once("html_iframe_header.php");
$result = 0;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
try {
$hdFactory = new HierarchicalKeyFactory();
$bip32Root = $hdFactory->fromExtended($_POST['extended_priv']);
if ($_POST['relative_path']) {
$key = $bip32Root->derivePath($_POST['relative_path']);
$displayPubkey = $key->getPublicKey()->getHex();
$displayPrikey = $key->getPrivateKey()->getHex();
$displayExtendedPrikey = $key->toExtendedKey();
$displayExtendedPubkey = $key->toExtendedPublicKey();
}
$result = 1;
} catch (Exception $e) {
$errmsg .= "Problem found. " . $e->getMessage();
}
}
if ($errmsg) {
?>
<div class="alert alert-danger">
<strong>Error!</strong> <?php echo $errmsg?>
</div>
<?php
}
if ($result) {
?>
<h5>Derivation</h5>
<div class="table-responsive">
<table border=0 class='table'>
<tr><td>Relative Path</td><td><?php echo $_POST['relative_path']?></td></tr>
<tr><td>Public Key</td><td><?php echo $displayPubkey?></td></tr>
<tr><td>Private Key</td><td><?php echo $displayPrikey?></td></tr>
<tr><td>Bip32 Extended Private Key</td><td><?php echo $displayExtendedPrikey?></td></tr>
<tr><td>Bip32 Extended Public Key</td><td><?php echo $displayExtendedPubkey?></td></tr>
</table>
</div>
<?php
}
?>
<form action='' method='post'>
<div class="form-group">
<label for="extended_priv">Bip32 Extended Private Key (Extend From):</label>
<div class="input-group mb-3">
<input class="form-control" type='text' name='extended_priv' id='extended_priv' value='<?php echo $_POST['extended_priv']?>'>
</div>
</div>
<div class="form-group">
<label for="relative_path">Relative Path (Extend To):</label>
<input class="form-control" type='text' name='relative_path' id='relative_path' value='<?php echo htmlentities($_POST['relative_path'],ENT_QUOTES)?>'>
* Do not start with /
</div>
<input type='submit' class="btn btn-success btn-block"/>
</form>
<?php
include_once("html_iframe_footer.php");
<?php
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Key\Factory\HierarchicalKeyFactory;
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39Mnemonic;
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator;
use BitWasp\Bitcoin\Mnemonic\MnemonicFactory;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey;
use BitWasp\Bitcoin\Network\NetworkFactory;
use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress;
use \BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Key\PublicKey;
use kornrunner\Keccak;
include_once "../libraries/vendor/autoload.php";
include_once("html_iframe_header.php");
function toChecksumAddress($address)
{
$address = strtolower(str_replace('0x', '', $address));
$hash = Keccak::hash(strtolower($address), 256);
$checksumAddress = '0x';
for($i=0;$i<strlen($address);$i++) {
if (intval($hash{$i}, 16) > 7) {
$checksumAddress .= strtoupper($address{$i});
} else {
$checksumAddress .= $address{$i};
}
}
return $checksumAddress;
}
$details = [];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
try {
$networkClass = ($_POST['network'] == "ethereum" ? "bitcoin": $_POST['network']);
Bitcoin::setNetwork(NetworkFactory::$networkClass());
$network = Bitcoin::getNetwork();
$hdFactory = new HierarchicalKeyFactory();
$key = $hdFactory->fromExtended($_POST['xpub'], $network);
$indexes = range((int)$_POST['from_index'],(int)$_POST['to_index']);
$ecAdapter = Bitcoin::getEcAdapter();
foreach($indexes as $index) {
$relativePath = strlen($_POST['relative_path']) >0 ? $_POST['relative_path'] . "/" : "";
$childKey = $key->derivePath( $relativePath . $index);
$publicKey = $childKey->getPublicKey();
//decompress public key
$dePublicKey = new PublicKey($ecAdapter,$publicKey->getPoint(),false);
if ($_POST['network'] == 'ethereum') {
$madeUpEthAddress = substr($dePublicKey->getHex(), 2);
$hash = Keccak::hash(hex2bin($madeUpEthAddress), 256);
$ethAddress = toChecksumAddress('0x' . substr($hash, -40));
$details[$relativePath . $index] = ["decompressed_pub"=>$dePublicKey->getHex(), "compressed_pub"=>$publicKey->getHex(),"address"=>$ethAddress];
} else {
$pubKeyHash = $childKey->getPublicKey()->getPubKeyHash();
$details[$relativePath . $index] = ["decompressed_pub"=>$dePublicKey->getHex(), "compressed_pub"=>$publicKey->getHex(),"address"=>(new PayToPubKeyHashAddress($pubKeyHash))->getAddress()];
}
}
} catch (Exception $e) {
$errmsg .= "Problem found. " . $e->getMessage();
}
}
if ($errmsg) {
?>
<div class="alert alert-danger">
<strong>Error!</strong> <?php echo $errmsg?>
</div>
<?php
}
if ($details) {
?>
<h5>Address Array</h5>
<div class="table-responsive">
<table class="table table-bordered">
<tr><th>Full Relative Path</th><th>Address</th><th>Public Key</th></tr>
<?php
foreach($details as $index => $detail) {
?>
<tr><td><?php echo $index?></td><td><?php echo $detail['address']?></td><td><p>Compressed:<br/><?php echo $detail['compressed_pub']?></p><p>Decompressed:<br/><?php echo $detail['decompressed_pub']?></p></td></tr>
<?php
}
?>
</table>
</div>
<?php
}
?>
<form action='' method='post'>
<div class="form-group">
<label for="network">Network *:</label>
<select id="network" name="network" class="form-control" >
<?php
$networks = get_class_methods(new NetworkFactory());
foreach($networks as $network) {
echo "<option value='{$network}'".($network == $_POST['network'] ? " selected": "").">{$network}</option>";
}
$network = "ethereum";
echo "<option value='{$network}'".($network == $_POST['network'] ? " selected": "").">{$network}</option>";
?>
</select>
</div>
<div class="form-group">
<label for="xpub">Bip32 Extended Public Key (Xpub) *:</label>
<div class="input-group mb-3">
<input class="form-control" type='text' name='xpub' id='xpub' value='<?php echo $_POST['xpub']?>'>
</div>
</div>
<div class="form-group">
<label for="from_index">From Index *:</label>
<input class="form-control" type='text' name='from_index' id='from_index' value='<?php echo $_POST['from_index']?>'>
</div>
<div class="form-group">
<label for="to_index">To Index *:</label>
<input class="form-control" type='text' name='to_index' id='to_index' value='<?php echo $_POST['to_index']?>'>
</div>
<div class="form-group">
<label for="relative_path">Relative Path :</label>
<input class="form-control" type='text' name='relative_path' id='relative_path' value='<?php echo htmlentities($_POST['relative_path'],ENT_QUOTES)?>'>
* Do not start with /, this field is optional.
</div>
<input type='submit' class="btn btn-success btn-block"/>
</form>
<?php
include_once("html_iframe_footer.php");