Closed sobhan-m94 closed 2 years ago
Hey @smm993,
For the 1st question: Okay both are the same keys but the difference is when you come to root_x(private/public)_key
is not derived key but x(private/public)_key
is already derived by path/indexes value.
You can also check both root keys on the above keys
from hdwallet.utils import is_root_xprivate_key, is_root_xpublic_key
# Checking root xprivate key
print(is_root_xprivate_key(xprivate_key="xprv9s21ZrQH143K2qMHU8aghJ4MoQR5g5mowXbeP2vCP937bseZGX929dmJudL7u4xRxtKvh58pxz1PhtCbWW2yUH14jdduKVMV9FkBMpM2Hyw", symbol="BTC"))
# True
print(is_root_xprivate_key(xprivate_key="xprvA2YyMZWyPK2xo4eZgyypp2CzcHnxNzGbruGg7vmgaAVCtBtrjwzuhXJBNM3FrwBh85ajxHErNR6ByN77WJARpC1HDC7kTwa2yr7Mu9Pz5Qq", symbol="BTC"))
# False
# Checking root xpublic key
print(is_root_xpublic_key(xpublic_key="xpub661MyMwAqRbcFKRkaA7h4S16MSFa5YVfJkXFBRKowUa6Ufyhp4TGhS5nkvkLXSmdNjoszzDkU26WW2rg1zBsQBt6Pv3T8oLEAExGHD3hcQs", symbol="BTC"))
# True
print(is_root_xpublic_key(xpublic_key="xpub6FYKm53sDgbG1Yj2o1WqBA9jAKdSnSzTE8CGvKBJ8W2BkzE1HVKAFKcfDcCHKpL5BQRg2HjbNSt55jpFshY7W1KFtp7zjB3DhNAmiFv6kzB", symbol="BTC"))
# False
For the 2nd question: To get account extended private/public keys; you have to understand the path-levels after that to get account extended keys; when you generate hdwallet, you have to stop the derivation path/indexes at account index then you can get it.
So, to get account extended keys you have to use this path
m / purpose' / coin_type' / account'
For example, to get account extended keys on above generated hdwallet
{
"cryptocurrency": "Bitcoin",
"symbol": "BTC",
"network": "mainnet",
"strength": 160,
"entropy": "c5b0d0ee698f3f72b6265f1bc591f8f2d7afa6dd",
"mnemonic": "주일 액수 명단 천둥 해수욕장 전망 추천 직업 그룹 단위 신체 파란색 시청 천천히 스트레스",
"language": "korean",
"passphrase": null,
"seed": "5a9b9667ccd07b3c641b1ba95e9119dd1d5a3034fd46cd2f27fc1f160c7dcd824fc0ab4710a9ae90582dffc3b0803bcbc0a8160feeaab4c70511c5035859decf",
"root_xprivate_key": "xprv9s21ZrQH143K2qMHU8aghJ4MoQR5g5mowXbeP2vCP937bseZGX929dmJudL7u4xRxtKvh58pxz1PhtCbWW2yUH14jdduKVMV9FkBMpM2Hyw",
"root_xpublic_key": "xpub661MyMwAqRbcFKRkaA7h4S16MSFa5YVfJkXFBRKowUa6Ufyhp4TGhS5nkvkLXSmdNjoszzDkU26WW2rg1zBsQBt6Pv3T8oLEAExGHD3hcQs",
"xprivate_key": "xprv9yZDeH96FLVfvvcihoZUQC8PYsiRzC6QTfyZ93GSBcVXWd5f2rRrfB9UBRtYFwPHtQzwjjoUNzuL9LNdeyX24jnNjsUgQf9VCUC3A7GjXnv",
"xpublic_key": "xpub6CYa3nfz5i3y9QhBoq6UmL586uYvPepFptu9wRg3jx2WPRQoaPk7CyTx2h3rK5yKMwCGT5a3si8xARmoFKDWDhXK5PrN8D67QqfhJodcLvh",
"uncompressed": "34dc1719aa67271d9fbca5d16731259546827dd5c2195a0faf0cef262de1c547f70c83d4c4e7386b416940ff782d0c07eae57a207dd83552c3badc071d4ccbee",
"compressed": "0234dc1719aa67271d9fbca5d16731259546827dd5c2195a0faf0cef262de1c547",
"chain_code": "49d06dafa9c930c7f28a89ee642643f7125a1d1520af23361eeea74e3596a2e4",
"private_key": "23ba50c0af0a3c6e36b3b8ac31e3ffbba496ca1d33663c47c0ca7a27b69e5687",
"public_key": "0234dc1719aa67271d9fbca5d16731259546827dd5c2195a0faf0cef262de1c547",
"wif": "KxRAJ1ZAPWwgg6Q4KZyuVM9K1FdszrgbFphJCvGRu3QHq8HBA5Hq",
"finger_print": "eee64ac8",
"semantic": "p2pkh",
"path": "m/44'/0'/0'",
"hash": "eee64ac8c8c54998a077814792d595e418db2f6a",
"addresses": {
"p2pkh": "1NnBhdihfXbjDz4fAmETp38ewYc2xGFhYb",
"p2sh": "3FLJC2ygV4MuvTTdYkiDqQ4v7CLvpGsFfz",
"p2wpkh": "bc1qamny4jxgc4ye3grhs9re94v4usvdktm2sl5zwq",
"p2wpkh_in_p2sh": "3Ppx4CcxLN9Wn4MQp4TYu7Yf8JVWAuD4A7",
"p2wsh": "bc1ql8m4kepda9v6f87pkxqam847nmf8qhdqfkmlpnth7a4tfl8kjheq887a20",
"p2wsh_in_p2sh": "3BZqrUnm1RFuE61oc1D742QwqFkMXpQMGA"
}
}
Both xprivate_key
and xpublic_key
are now account extended private key and account extended public key.
For more test and check out here https://iancoleman.io/bip39
Thanks!
What about this?
from hdwallet import BIP44HDWallet
from hdwallet.cryptocurrencies import TronMainnet
from typing import Optional
import json
hdwallet: BIP44HDWallet = BIP44HDWallet(cryptocurrency=TronMainnet)
hdwallet.from_mnemonic(
mnemonic='imitate minute bulk rapid eager captain case envelope submit bike birth unfold', language="english", passphrase=None
)
hdwallet.clean_derivation()
hdwallet.from_index(44, hardened=True)
hdwallet.from_index(195, hardened=True)
hdwallet.from_index(0, hardened=True)
hdwallet.from_index(0)
hdwallet.from_index(0)
print(json.dumps(hdwallet.dumps(), indent=4, ensure_ascii=False))
{
"cryptocurrency": "Tron",
"symbol": "TRX",
"network": "mainnet",
"strength": 128,
"entropy": "7171a87858f44e4448ca5ed802c45af6",
"mnemonic": "imitate minute bulk rapid eager captain case envelope submit bike birth unfold",
"language": "english",
"passphrase": null,
"seed": "be5b3d22a5b56346d5b2e8b80190a16c266fe87ff7ff45317422423b4d0632ab2f2a4ae8c0905d85a2799ecf85e601e03de08c68e307ab8f2a7904b4ee53f343",
"root_xprivate_key": "xprv9s21ZrQH143K3jfX39z2VtxEXNbjtv6Yi7nhfKqmc3XUNTrkKwWAWpTfBPTgz8e5wcWEcq2P7Es6t78gHsHx96HxuzYCqz8uSmVfnV6pY3k",
"root_xpublic_key": "xpub661MyMwAqRbcGDjz9BX2s2ty5QSEJNpQ5LiJTiFPAP4TFGBtsUpR4cn92hMUZACfgSu5NPPtGPsFPZU97fPFRQF5MQSSZwkr3Xrq4zy8CHA",
"xprivate_key": "xprvA2dttGszXzcuWpMwk4pTF31AgHX1JmCPvEsjWbSUiXXqmjhE2WRakeyvGTdAEtBF6MmTjXfmBsKV9g6KLE4Cda7DYS3M4vdEA8ehFyvuuPi",
"xpublic_key": "xpub6FdFHnQtNNBCjJSQr6MTcAwuEKMViDvFHToLJyr6Gs4peY2Na3jqJTJQ7jCScix5CHngFM1RMAzkzTjhhVsKZUWzToPqy3i5achTNWfGxUL",
"uncompressed": "1d5c4eb2954afeb2bde7f277adb6a5928d6a827e3b61ba71635ae65908841285de6aec82fa32601fe5e935bcfc3b2a103f0c4b412acc64ebc25ec85beb880d5d",
"compressed": "031d5c4eb2954afeb2bde7f277adb6a5928d6a827e3b61ba71635ae65908841285",
"chain_code": "63b49b7da86d3956eb0839aea3bd475d1b64e4956af564d371ee67fdc4890f2e",
"private_key": "d5cca4a23c07b680c2d843e440815f0848acb09a7d884b7f64ee3ff1050282fb",
"public_key": "031d5c4eb2954afeb2bde7f277adb6a5928d6a827e3b61ba71635ae65908841285",
"wif": "L4PJsZr7HDHUxJJ4FMfDuSvCZAWdWwiWVgBRTKuvt8sxsebYBAhZ",
"finger_print": "ede0a921",
"semantic": "p2pkh",
"path": "m/44'/195'/0'/0/0",
"hash": "ede0a921abcc9463ad7dcfdcd76d8dba2a721276",
"addresses": {
"p2pkh": "TYM2d84UfSC5uRR9EuTexjZ9sGzeu9HTZh",
"p2sh": "3MBUWhzVJmE2trmoVAZyM8D1ER3TG9aphc",
"p2wpkh": "bc1qahs2jgdtej2x8ttaelwdwmvdhg48yynkaec9mg",
"p2wpkh_in_p2sh": "3ET69JrnaQrXfLrRDncuc2stPFPBNHNLmR",
"p2wsh": "bc1qaju7kgk5uqnml3treqe7pmcaxfg98zs9y9qzt46z8n8vh5sjldwqa4zgmf",
"p2wsh_in_p2sh": "34ajXFn4oipFzLoeMBBu6MMuw8mjxzbYKX"
}
}
Can you give me sample in python to get account extended private/public keys ? Also bip32 extended private/public keys.
Just remove the last two derivation indexes from
hdwallet.from_index(44, hardened=True) # purpose
hdwallet.from_index(195, hardened=True) # coin_type
hdwallet.from_index(0, hardened=True) # account
hdwallet.from_index(0) # change (external/internal)
hdwallet.from_index(0) # address_index
to
hdwallet.from_index(44, hardened=True) # purpose
hdwallet.from_index(195, hardened=True) # coin_type
hdwallet.from_index(0, hardened=True) # account
then you will get account extended private/public keys.
Imagine I have a website to sell things. I need the website(API) to be able to generate addresses, but I don't want it to be able to spend from them. With which key should I generate the addresses? xpublic_key ? and how can I get private key of addresses generated by API (xpublic_key ) ?
It's depend on you. But, my recommendation is use root xprivate and xpublic keys. You can drive it in what ever you want derivations.
And also to generate addresses use BIP44 default path because most of wallets are uses BIP44 default paths. For example MetaMask wallet to generate addresses; it uses this Ethereum m/44'/60'/0'/0/0
default BIP44 path.
my recommendation is use root xprivate and xpublic keys.
generate addresses use BIP44 default path.
bip44 default path is hardened. we cant generate addresses with xpublic key.
Yes man, BIP44 requires hardened keys. In BIP44 purpose
, coin_type
and account
are hardened keys and also all are requires xprivate key for derivation but change (external/internal)
and address_index
are not hardened keys and both are not requires xprivate key for derivation. So, in this case; if you want to use BIP44; my recommendation is use account extended (xprivate and xpublic keys). after you get both account extended x keys then you can generate addresses by account extended xpublic key.
I will consider to add account extended x keys on BIP44HDWallet but it's very slow down the generation time.
after you get both account extended x keys then you can generate addresses by account extended xpublic key.
I cant generate addresses by account extended xpublic key.
from hdwallet import BIP44HDWallet
from hdwallet.cryptocurrencies import TronMainnet
from hdwallet import HDWallet as HDWallet
from hdwallet.symbols import TRX as SYMBOL
import json
hdwallet: BIP44HDWallet = BIP44HDWallet(cryptocurrency=TronMainnet)
hdwallet.from_mnemonic(
mnemonic='imitate minute bulk rapid eager captain case envelope submit bike birth unfold', language="english", passphrase=None
)
hdwallet.clean_derivation()
hdwallet.from_index(44, hardened=True)
hdwallet.from_index(195, hardened=True)
hdwallet.from_index(0, hardened=True)
xpublic_key=hdwallet.xpublic_key()
hdwallet: HDWallet = HDWallet(symbol=SYMBOL)
hdwallet.from_xpublic_key(xpublic_key=xpublic_key)
hdwallet.clean_derivation()
hdwallet.from_index(44, hardened=True)
hdwallet.from_index(195, hardened=True)
hdwallet.from_index(0, hardened=True)
hdwallet.from_index(0)
hdwallet.from_index(0)
print(json.dumps(hdwallet.dumps(), indent=4, ensure_ascii=False))
Error :
hdwallet.exceptions.DerivationError: Hardened derivation path is invalid for xpublic key.
The error is correct because, Hardened key requires xprivate key
but you have only xpublic key
.
After you get account extended xpublic key, that means you already dived it by purpose
, coin_type
and account
hardened keys. So now, in BIP44 there is only two derivations left change (external/internal)
and address_index
and both are not hardened or not requires xprivate key.
from hdwallet import BIP44HDWallet
from hdwallet.cryptocurrencies import TronMainnet
from hdwallet import HDWallet as HDWallet
from hdwallet.symbols import TRX as SYMBOL
import json
hdwallet: BIP44HDWallet = BIP44HDWallet(cryptocurrency=TronMainnet)
hdwallet.from_mnemonic(
mnemonic='imitate minute bulk rapid eager captain case envelope submit bike birth unfold', language="english", passphrase=None
)
hdwallet.clean_derivation()
hdwallet.from_index(44, hardened=True) # purpose
hdwallet.from_index(195, hardened=True) # coin_type
hdwallet.from_index(0, hardened=True) # account
xpublic_key=hdwallet.xpublic_key()
hdwallet: HDWallet = HDWallet(symbol=SYMBOL)
hdwallet.from_xpublic_key(xpublic_key=xpublic_key)
hdwallet.clean_derivation()
hdwallet.from_index(0) # change (external/internal)
hdwallet.from_index(0) # address_index
print(json.dumps(hdwallet.dumps(), indent=4, ensure_ascii=False))
what is the difference between root_xprivate_key and xprivate_key OR root_xpublic_key and xpublic_key ? where is account extended private key and account extended public key ?