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");