Bit-Wasp / bitcoin-php

Bitcoin implementation in PHP
The Unlicense
1.04k stars 416 forks source link

can not get private key and address even I know the extended private masterkey. #680

Closed passionofvc closed 6 years ago

passionofvc commented 6 years ago

I test for recovery bitcoind wallet(wallet.dat), dumpwallet command to get mastekey info, and retrieve private key info from extended private masterkey, but it gave me the wrong output address info.

$key="xprv9s21ZrQH143K4YFY8z2JysNbKzrHtB3rFRSdbiFmDvKQdRtYYW31MVbFQvqFqWgMjfCTpnCtc7d2Vk9CzCxCzJRyaA1i3aCsuonwR6RMHit";
$master = HierarchicalKeyFactory::fromExtended($key, Bitcoin::getNetwork());
$publicKey = $master->getPublicKey();
$hashAddress = new PayToPubKeyHashAddress($publicKey->getPubKeyHash());
$address = $hashAddress->getAddress().PHP_EOL;

I can use http://bip32.org to convert it and it show me correct private key and address.

■input custom path [m/0'/0'/1'] ■output Private Key (WIF) : KzKviwwgNiQHeD22inCw3B18aR9xLHrK3Eu5oDPTTuFjNHQLJo6J Address : 1PcEG477xuZXMR76Szo79joxu4hzdxxNmH

■dump wallet from bitcoins wallet.dat


# Wallet dump created by Bitcoin v0.15.1
 # * Created on 2018-03-18T14:53:54Z
 # * Best block at time of backup was 0 (000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f),
 #   mined on 2009-01-03T18:15:05Z

 # extended private masterkey: xprv9s21ZrQH143K4YFY8z2JysNbKzrHtB3rFRSdbiFmDvKQdRtYYW31MVbFQvqFqWgMjfCTpnCtc7d2Vk9CzCxCzJRyaA1i3aCsuonwR6RMHit

 KzFh3u38AeQDu5oAsd54Ue5k3KA2q5qZkWeihecpU6ZDjyubVjGW 2018-03-18T14:53:42Z label= # addr=1B1L8bXQos2BFZQGdxC7tz6h3rzgBMwBe7 hdkeypath=m/0'/0'/0'
 L18CMUaKx6TgfHdgqhSd6DeR5nNGmUavEewxpJSiEawa1wPf3ZTe 2018-03-18T14:53:42Z hdmaster=1 # addr=1GA2uxYBL8fks3WNCKXfqnEzWKHjdQtNWn hdkeypath=m
 L3n63GWiLjdsdFRbmvojKRbaaobPZEegD6tWP6RWu25MgFzYoBNc 2018-03-18T14:53:42Z reserve=1 # addr=1H5Ng7NM1zNJxSou78cLkNZnGEvWym283W hdkeypath=m/0'/1'/0'
 KzKviwwgNiQHeD22inCw3B18aR9xLHrK3Eu5oDPTTuFjNHQLJo6J 2018-03-18T14:53:42Z reserve=1 # addr=1PcEG477xuZXMR76Szo79joxu4hzdxxNmH hdkeypath=m/0'/0'/1'

 # End of dump
afk11 commented 6 years ago

Here's it decoded, looks like you posted the main key, but haven't derived anything from it. Try calling derivePath("0'/0'/1'") first!

+---------------+--------------------------------------------------------------------+
| bytes         | 0488ade4                                                           |
| depth         | 0                                                                  |
| fpr           | 0                                                                  |
| hardened      | false                                                              |
| address index | 0                                                                  |
| chain code    | f930708ef20817f04c5a5c5c0ff2c7f295ccb4da28fef6ec3136dac21c2ae2ae   |
| public key    | 033f3e7e1bf7aa5935aa1ae566854e71cc4e258f985655ca8008588d97ae24d9b1 |
| private key   | 2bb86ddb0dd6cd314ccb1a88b86cd74c55e905baf0cd7f0d02a3e538992bb6de   |
+---------------+--------------------------------------------------------------------+

$key="xprv9s21ZrQH143K4YFY8z2JysNbKzrHtB3rFRSdbiFmDvKQdRtYYW31MVbFQvqFqWgMjfCTpnCtc7d2Vk9CzCxCzJRyaA1i3aCsuonwR6RMHit";
$master = HierarchicalKeyFactory::fromExtended($key, Bitcoin::getNetwork());
$c = $master->derivePath("0'/0'/1'");
echo $c->getAddress(new AddressCreator())->getAddress().PHP_EOL;

this example works on 0.0.35 (getAddress on HierarchicalKey is new), otherwise just derive the addess as you did from the public key.

passionofvc commented 6 years ago

hi @afk11 thanks, I will add derive path and test above code again.

passionofvc commented 6 years ago

hi @afk11 it work perfectly. Incidentally I use "bitwasp/bitcoin": "0.0.35.0".

php test.php 
1PcEG477xuZXMR76Szo79joxu4hzdxxNmH
KzKviwwgNiQHeD22inCw3B18aR9xLHrK3Eu5oDPTTuFjNHQLJo6J
f7fc64f86a997c4c16a907632aa68c8e0168c3a1
afk11 commented 6 years ago

Ah, great, then you can do it the easy way as of that version, HierarchicalKey now exposes getAddress, in case you decide to use some of the zpub/ypub/etc proposals

$master = HierarchicalKeyFactory::fromExtended($key, Bitcoin::getNetwork());
$child = $master->derivePath("0'/0'/1'");
$address = $child->getAddress(new AddressCreator())->getAddress().PHP_EOL;