Closed tulang3587 closed 5 years ago
Hi, thanks for the question
I think if you check chainparams.cpp for the version of dash-testnet you're using, you'll see it's different (or decode the result of dash-cli getnewaddress and check it's bytes). Maybe they changed the version since we merged that, or we were wrong to begin with.
Simply extending DashTestnet in your project would be a really simple way of fixing it for you. Or there's a project @dan-da which provides up to date prefixes for multiple networks with a NetworkInterface implementation https://github.com/dan-da/coinparams-bitwasp-addon
I think my 'solution' to this long term is to delete implementations for other networks, and point devs to implementing NetworkInterface themselves, or to require a certain version of coinparams as a dependency. Every time we fix it in the library, we need to tag it as a new major version, since the change is for some users a BC break, and I'm getting pretty tired of doing that when the change doesn't affect logic, just a single data point in the lib
I think I'll remove these objects from the main library, please feel free to copy them to your codebase and make whatever modifications are necessary. Or look into the project I linked above!
Maybe they changed the version since we merged that
Exactly my thoughts.
And yeah, I've been thinking of making my own DashTestnet by extending the Network class to solve this, but I have no idea how to obtain the values for the network itself.
Is there any guide to do this? I've also looked at dan-da/coinparams, but even the 'magic' from your Dash implementation and dan-da's are completely different:
protected $p2pMagic = "bd6b0cbf";
and (from coinparams.json)
"magic": "0xbf0c6bbd"
yea it should match whatevers in this file: https://github.com/dashpay/dash/blob/master/src/chainparams.cpp
Can you give me some guidance for which values I need to find? I'm still not sure which values are needed for any custom network.
I'm trying to compare using Bitcoin network since it works fine. This is from the Bitcoin Network class:
protected $base58PrefixMap = [
self::BASE58_ADDRESS_P2PKH => "00",
self::BASE58_ADDRESS_P2SH => "05",
self::BASE58_WIF => "80",
];
And from Bitcoin's chainparams:
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
I can't find the "00", "05" or "80" anywhere, and it's the same for the other variables as well. Searching for the p2p magic value even resulted in nothing.
It's a difference in encoding. For addresses, chainparams.cpp uses decimal integers, whereas we use hex strings (0 = "00", 128 = "80")
And for extended pubkey stuff, they used hexadecimal notation for the numbers, so it's easy to compare against our hex strings.
Thanks a lot for the information! I think I can probably make this work now.
I'll leave this as a handy note if anyone ever wanted to create their own custom network, and gets stuck like me. I haven't known where that pubkeyhash / p2pkh is from though.
protected $base58PrefixMap = [
self::BASE58_ADDRESS_P2PKH => "00",
self::BASE58_ADDRESS_P2SH => "05",
self::BASE58_WIF => "80",
];
// bitcoin/src/chainparams.cpp
// convert to hex
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
protected $bech32PrefixMap = [
self::BECH32_PREFIX_SEGWIT => "bc",
];
// bitcoin/src/chainparams.cpp
bech32_hrp = "bc";
protected $bip32PrefixMap = [
self::BIP32_PREFIX_XPUB => "0488b21e",
self::BIP32_PREFIX_XPRV => "0488ade4",
];
// bitcoin/src/chainparams.cpp
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
protected $bip32ScriptTypeMap = [
self::BIP32_PREFIX_XPUB => ScriptType::P2PKH,
self::BIP32_PREFIX_XPRV => ScriptType::P2PKH,
];
// ????
protected $signedMessagePrefix = "Bitcoin Signed Message";
// bitcoin/src/validation.cpp
const std::string strMessageMagic = "Bitcoin Signed Message:\n";
protected $p2pMagic = "d9b4bef9";
// bitcoin/src/chainparams.cpp
// reversed order
pchMessageStart[0] = 0xf9;
pchMessageStart[1] = 0xbe;
pchMessageStart[2] = 0xb4;
pchMessageStart[3] = 0xd9;
Almost forgot, this is my custom DashTestnet network class:
class DashTestnet extends Network
{
/**
* {@inheritdoc}
* @see Network::$base58PrefixMap
*/
protected $base58PrefixMap = [
self::BASE58_ADDRESS_P2PKH => "8c",
self::BASE58_ADDRESS_P2SH => "13",
self::BASE58_WIF => "ef",
];
/**
* {@inheritdoc}
* @see Network::$bip32PrefixMap
*/
protected $bip32PrefixMap = [
self::BIP32_PREFIX_XPUB => "043587cf",
self::BIP32_PREFIX_XPRV => "04358394",
];
/**
* {@inheritdoc}
* @see Network::$bip32ScriptTypeMap
*/
protected $bip32ScriptTypeMap = [
self::BIP32_PREFIX_XPUB => ScriptType::P2PKH,
self::BIP32_PREFIX_XPRV => ScriptType::P2PKH,
];
/**
* {@inheritdoc}
* @see Network::$signedMessagePrefix
*/
protected $signedMessagePrefix = "DarkCoin Signed Message";
/**
* {@inheritdoc}
* @see Network::$p2pMagic
*/
protected $p2pMagic = "ffcae2ce";
}
When generating a Dash address, mainnet returns a valid address. But it's always invalid for testnet.
I've tried using both v0.0.35.1 and v1.0.0:
v0.0.35.1
Bitcoin::setNetwork(NetworkFactory::dashTestnet()); $network = Bitcoin::getNetwork(); $keyFactory = PrivateKeyFactory::create(true); $addressHash = new PayToPubKeyHashAddress($keyFactory->getPublicKey()->getPubKeyHash()); $privateKey = $keyFactory->toWif($network); $address = $addressHash->getAddress($network);
v1.0.0
Bitcoin::setNetwork(NetworkFactory::dashTestnet()); $network = Bitcoin::getNetwork(); $keyFactory = new PrivateKeyFactory(); $privateKey = $keyFactory->generateCompressed(new Random()); $addressHash = new PayToPubKeyHashAddress($privateKey->getPublicKey()->getPubKeyHash()); $privateKeyWif = $privateKey->toWif($network); $address = $addressHash->getAddress($network);
The resulting address is always invalid for
NetworkFactory::dashTestnet()
, butNetworkFactory::dash()
is fine. One of the generated address is:y26JSBDLEPbRD7iVWPz4Ck16uSKuqQ13Q8
I've tried searching the resulting testnet address on chain.so and importing them on my local Dash Core and it always fails: