/**
  * @param                                $primaryMnemonic
  * @param                                $primaryPassphrase
  * @param                                $backupMnemonic
  * @param array                          $blocktrailPublicKeys
  * @param BlockchainDataServiceInterface $bitcoinClient
  * @param string                         $network
  * @param bool                           $testnet
  * @throws \Exception
  */
 public function __construct($primaryMnemonic, $primaryPassphrase, $backupMnemonic, array $blocktrailPublicKeys, BlockchainDataServiceInterface $bitcoinClient, $network = 'btc', $testnet = false)
 {
     // normalize network and set bitcoinlib to the right magic-bytes
     list($this->network, $this->testnet) = $this->normalizeNetwork($network, $testnet);
     BitcoinLib::setMagicByteDefaults($this->network . ($this->testnet ? '-testnet' : ''));
     //create BIP32 keys for the Blocktrail public keys
     foreach ($blocktrailPublicKeys as $blocktrailKey) {
         $this->blocktrailPublicKeys[$blocktrailKey['keyIndex']] = BIP32Key::create($blocktrailKey['pubkey'], $blocktrailKey['path']);
     }
     //set the unspent output finder, using the given bitcoin data service provider
     $this->bitcoinClient = $bitcoinClient;
     $this->utxoFinder = new UnspentOutputFinder($this->bitcoinClient);
     // cleanup copy paste errors from mnemonics
     $primaryMnemonic = str_replace("  ", " ", str_replace("\r\n", " ", str_replace("\n", " ", trim($primaryMnemonic))));
     $backupMnemonic = str_replace("  ", " ", str_replace("\r\n", " ", str_replace("\n", " ", trim($backupMnemonic))));
     // convert the primary and backup mnemonics to seeds (using BIP39), then create private keys (using BIP32)
     $primarySeed = BIP39::mnemonicToSeedHex($primaryMnemonic, $primaryPassphrase);
     $backupSeed = BIP39::mnemonicToSeedHex($backupMnemonic, "");
     $this->primaryPrivateKey = BIP32Key::create(BIP32::master_key($primarySeed, $this->network, $this->testnet));
     $this->backupPrivateKey = BIP32Key::create(BIP32::master_key($backupSeed, $this->network, $this->testnet));
 }
 /**
  * generate a new mnemonic from some random entropy (512 bit)
  *
  * @param string    $forceEntropy           forced entropy instead of random entropy for testing purposes
  * @return string
  * @throws \Exception
  */
 protected function generateNewMnemonic($forceEntropy = null)
 {
     if ($forceEntropy === null) {
         $entropy = BIP39::generateEntropy(512);
     } else {
         $entropy = $forceEntropy;
     }
     return BIP39::entropyToMnemonic($entropy);
 }
示例#3
0
 public function testNewBlankWithoutMnemonicsWallet()
 {
     $client = $this->setupBlocktrailSDK();
     $identifier = $this->getRandomTestIdentifier();
     $primaryPrivateKey = BIP32::master_key(BIP39::mnemonicToSeedHex(BIP39::entropyToMnemonic(BIP39::generateEntropy(512)), "password"), 'bitcoin', true);
     $backupPublicKey = BIP32::extended_private_to_public(BIP32::master_key(BIP39::mnemonicToSeedHex(BIP39::entropyToMnemonic(BIP39::generateEntropy(512)), "password"), 'bitcoin', true));
     /**
      * @var $wallet \Blocktrail\SDK\Wallet
      */
     $e = null;
     try {
         $wallet = $client->initWallet(["identifier" => $identifier]);
     } catch (ObjectNotFound $e) {
         list($wallet, $primaryMnemonic, $backupMnemonic, $blocktrailPublicKeys) = $client->createNewWallet(["identifier" => $identifier, "primary_private_key" => $primaryPrivateKey, "backup_public_key" => $backupPublicKey, "key_index" => 9999]);
     }
     $this->assertTrue(!!$e, "New wallet with ID [{$identifier}] already exists...");
     $wallet = $client->initWallet(["identifier" => $identifier, "primary_private_key" => $primaryPrivateKey]);
     $this->wallets[] = $wallet;
     // store for cleanup
     $this->assertEquals(0, $wallet->getBalance()[0]);
     $e = null;
     try {
         $wallet->pay(["2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy" => BlocktrailSDK::toSatoshi(0.001)]);
     } catch (\Exception $e) {
     }
     $this->assertTrue(!!$e, "Wallet without balance is able to pay...");
 }
示例#4
0
 /**
  * unlock wallet so it can be used for payments
  *
  * @param          $options ['primary_private_key' => key] OR ['passphrase' => pass]
  * @param callable $fn
  * @return bool
  * @throws \Exception
  */
 public function unlock($options, callable $fn = null)
 {
     // explode the wallet data
     $password = isset($options['passphrase']) ? $options['passphrase'] : (isset($options['password']) ? $options['password'] : null);
     $primaryMnemonic = $this->primaryMnemonic;
     $primaryPrivateKey = isset($options['primary_private_key']) ? $options['primary_private_key'] : null;
     if ($primaryMnemonic && $primaryPrivateKey) {
         throw new \InvalidArgumentException("Can't specify Primary Mnemonic and Primary PrivateKey");
     }
     if (!$primaryMnemonic && !$primaryPrivateKey) {
         throw new \InvalidArgumentException("Can't init wallet with Primary Mnemonic or Primary PrivateKey");
     }
     if ($primaryMnemonic && !$password) {
         throw new \InvalidArgumentException("Can't init wallet with Primary Mnemonic without a passphrase");
     }
     if ($primaryPrivateKey) {
         if (is_string($primaryPrivateKey)) {
             $primaryPrivateKey = [$primaryPrivateKey, "m"];
         }
     } else {
         // convert the mnemonic to a seed using BIP39 standard
         $primarySeed = BIP39::mnemonicToSeedHex($primaryMnemonic, $password);
         // create BIP32 private key from the seed
         $primaryPrivateKey = BIP32::master_key($primarySeed, $this->network, $this->testnet);
     }
     $this->primaryPrivateKey = BIP32Key::create($primaryPrivateKey);
     // create checksum (address) of the primary privatekey to compare to the stored checksum
     $checksum = BIP32::key_to_address($primaryPrivateKey[0]);
     if ($checksum != $this->checksum) {
         throw new \Exception("Checksum [{$checksum}] does not match [{$this->checksum}], most likely due to incorrect password");
     }
     $this->locked = false;
     // if the response suggests we should upgrade to a different blocktrail cosigning key then we should
     if (isset($data['upgrade_key_index'])) {
         $this->upgradeKeyIndex($data['upgrade_key_index']);
     }
     if ($fn) {
         $fn($this);
         $this->lock();
     }
 }
 public function testGenerate()
 {
     for ($i = 0; $i < 100; $i++) {
         $entropy = BIP39::generateEntropy(128);
         $this->assertTrue(!!$entropy);
         $mnemonic = BIP39::entropyToMnemonic($entropy);
         $this->assertTrue(!!$entropy);
         $entropy2 = BIP39::mnemonicToEntropy($mnemonic);
         $this->assertTrue(!!$entropy2);
         $this->assertEquals($entropy, $entropy2);
         $bip32 = BIP32::master_key(BIP39::mnemonicToSeedHex($mnemonic, 'PASSWORD'));
         $this->assertTrue(!!$bip32);
     }
     for ($i = 0; $i < 100; $i++) {
         $entropy = BIP39::generateEntropy(256);
         $this->assertTrue(!!$entropy);
         $mnemonic = BIP39::entropyToMnemonic($entropy);
         $this->assertTrue(!!$entropy);
         $entropy2 = BIP39::mnemonicToEntropy($mnemonic);
         $this->assertTrue(!!$entropy2);
         $this->assertEquals($entropy, $entropy2);
         $bip32 = BIP32::master_key(BIP39::mnemonicToSeedHex($mnemonic, 'PASSWORD'));
         $this->assertTrue(!!$bip32);
     }
     for ($i = 0; $i < 100; $i++) {
         $entropy = BIP39::generateEntropy(512);
         $this->assertTrue(!!$entropy);
         $mnemonic = BIP39::entropyToMnemonic($entropy);
         $this->assertTrue(!!$entropy);
         $entropy2 = BIP39::mnemonicToEntropy($mnemonic);
         $this->assertTrue(!!$entropy2);
         $this->assertEquals($entropy, $entropy2);
         $bip32 = BIP32::master_key(BIP39::mnemonicToSeedHex($mnemonic, 'PASSWORD'));
         $this->assertTrue(!!$bip32);
     }
 }
示例#6
0
<?php

use BitWasp\BitcoinLib\BIP32;
use BitWasp\BitcoinLib\BIP39\BIP39;
require_once __DIR__ . '/../vendor/autoload.php';
$password = "******";
$entropy = BIP39::generateEntropy(256);
$mnemonic = BIP39::entropyToMnemonic($entropy);
$seed = BIP39::mnemonicToSeedHex($mnemonic, $password);
unset($entropy);
// ignore, forget about this, don't use it!
var_dump($mnemonic);
// this is what you print on a piece of paper, etc
var_dump($password);
// this is secret of course
var_dump($seed);
// this is what you use to generate a key
$key = BIP32::master_key($seed);
// enjoy