Open melaxon opened 4 years ago
hi @melaxon . Thx for the report.
The first one is meaningless for those who wish to generate the same addresses in Electrum because Electrum will never generate 3bitcoinaddres... addresses from XPRV (or XPUB). There is no such an option (currently)
Good observation. The --preset, aka Path Preset is only an aid for choosing the bip32 path. It's not attempting to emulate a particular wallet in every regard.
The second command will generate the same addresses and public keys as Electrum does from given YPRV (or YPUB) but pubkeyhash seems to be WRONG (or maybe I'm wrong and missed something).
I will need to look into this in more detail. It would be helpful if you can post an example YPRV or YPUB (without funds!) along with electrum and hd-wallet-derive derived value(s) that demonstrate the discrepancy.
I guess I have to look into Bitwasp code (?)
maybe. It's been pretty solid though.
ypub6Z5GQFUWdyxxA6cKP8ZKacJTvtpk6ao3P54tvvzPSPevYH752rYWW6REEd5u5R77VdmkcrzWJmDHGKwx3qRmA9m39T26FJg5LngyQKSnokw
The address with index 15 contains 0.00022 BTC
This key was used to generate addresses in my app. The addresses and public keys are identical with electrum
./hd-wallet-derive.php -g --key="ypub6Z5GQFUWdyxxA6cKP8ZKacJTvtpk6ao3P54tvvzPSPevYH752rYWW6REEd5u5R77VdmkcrzWJmDHGKwx3qRmA9m39T26FJg5LngyQKSnokw" --addr-type=p2sh-segwit --preset=electrum --numderive=20 > electrum-p2sh-segwit-xpub.txt
I cannot see pubkeyhash in electrum unfortunately.
The function that calculates the "correct" pubkeyhashes:
function fn_get_hash160($addressInput, $addrCreator, $network)
{
$address = null;
try {
$address = $addrCreator->fromString($addressInput, $network)->getHash();
} catch ( \BitWasp\Bitcoin\Exceptions\UnrecognizedAddressException $e) {
$errormessage = 'The address you entered is not valid: ' . $addressInput;
echo "Error message: ".$errormessage;
}
$hash160 = bin2hex(getProtectedValue($address, 'buffer'));
return $hash160;
}
function getProtectedValue($obj,$name)
{
$array = (array)$obj;
$prefix = chr(0).'*'.chr(0);
return !empty($array[$prefix.$name]) ? $array[$prefix.$name] : false;
}
ok, so what are the "correct" and "incorrect" pubkeyhash values you are seeing for index 0? (assuming that your fn_get_hash160() is producing correct results).
address 0 3Eezg77r6TK4rd9gHSDSyCJTLrpStzbn3i 616d3566dc438763b59480512e1a08db35e6e4e2 - incorrect (derived with hd-wallet-derive) 8e37c2be6eb697c05ab109f7c7e38bea12477dd4 - correct (calculated)
address 15 3HCvCZMV4Y4jYV59yVT3Lb4GehJLH3EzPu e2b3802c91e9926f7ce91226d15d72d7584e952e aa319669fca81e0fc8ada49f29490d8f0c06c806
examples of P2PKH:
1NR4KPhzQagzSUBGunPSuKbWN7vnS6r77Z eae764bd4d55cd53eab21991e56cb5f9e859ae5d eae764bd4d55cd53eab21991e56cb5f9e859ae5d
Did not try bc1 yet
bach32 is also okay bc1quauz4ymap0wstrt8vn4lcnxj0wug6lnc6zsas5 e7782a937d0bdd058d6764ebfc4cd27bb88d7e78 - the same pabkeyhash calculated and derived
hmm, I took a brief look at this. I was trying to compare with output from other tools, but I couldn't seem to find one supports ypub and also outputs the pubkeyhash. So, it's not immediately obvious which implementation is correct.
The hd-wallet-derive code that gets the pubkeyhas is pretty straight-forward, ie:
$pubkey = $key->getPublicKey()->getHex();
$pubkeyhash = $key->getPublicKey()->getPubKeyHash()->getHex();
So this is just calling into the Bitwasp bitcoin-php lib to do the heavy lifting. One would think that if pubkey is correct, then pubkeyhash should be also, but I haven't investigated further yet.
Now I'm pretty sure that the problem resides is Bitwasp code. First, I will search through their PRs as the version of bitcoin-php you use is far not the latest one and maybe the problem is already solved in later releases.
fwiw, I updated composer require to latest bitwasp release (1.0.4), found one issue, and determined that hd-wallet-derive still generates the "incorrect" pubkeyhash.
$ ./hd-wallet-derive.php -g --key="ypub6Z5GQFUWdyxxA6cKP8ZKacJTvtpk6ao3P54tvvzPSPevYH752rYWW6REEd5u5R77VdmkcrzWJmDHGKwx3qRmA9m39T26FJg5LngyQKSnokw" --addr-type=p2sh-segwit --path='0/x' --numderive=1 --cols=address,pubkeyhash
+------------------------------------+------------------------------------------+
| address | pubkeyhash |
+------------------------------------+------------------------------------------+
| 3Eezg77r6TK4rd9gHSDSyCJTLrpStzbn3i | 616d3566dc438763b59480512e1a08db35e6e4e2 |
+------------------------------------+------------------------------------------+
Hello I noticed 2 things when I run such commands:
./hd-wallet-derive.php -g --key="xprv......" --addr-type=p2sh-segwit --preset=electrum
./hd-wallet-derive.php -g --key="yprv......" --addr-type=p2sh-segwit --preset=electrum
The first one is meaningless for those who wish to generate the same addresses in Electrum because Electrum will never generate 3bitcoinaddres... addresses from XPRV (or XPUB). There is no such an option (currently)
The second command will generate the same addresses and public keys as Electrum does from given YPRV (or YPUB) but pubkeyhash seems to be WRONG (or maybe I'm wrong and missed something).
To get the address balance I inquire electrumx using this code:
In case of XPRV everything is okay. For YPRV, if I use pubkeyhashes generated by hd-wallet-derive ($array['pubkeyhash']) the balance is always zero. If I delete pubkeyhashes and calculate them with some function fn_get_hash160 it works smoothly. I guess I have to look into Bitwasp code (?)