MCPcopy Create free account
hub / github.com/ElementsProject/elements / DeriveNewChildKey

Method DeriveNewChildKey

src/wallet/scriptpubkeyman.cpp:1097–1150  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1095}
1096
1097void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, CHDChain& hd_chain, bool internal)
1098{
1099 // for now we use a fixed keypath scheme of m/0'/0'/k
1100 CKey seed; //seed (256bit)
1101 CExtKey masterKey; //hd master key
1102 CExtKey accountKey; //key at m/0'
1103 CExtKey chainChildKey; //key at m/0'/0' (external) or m/0'/1' (internal)
1104 CExtKey childKey; //key at m/0'/0'/<n>'
1105
1106 // try to get the seed
1107 if (!GetKey(hd_chain.seed_id, seed))
1108 throw std::runtime_error(std::string(__func__) + ": seed not found");
1109
1110 masterKey.SetSeed(seed);
1111
1112 // derive m/0'
1113 // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
1114 masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
1115
1116 // derive m/0'/0' (external chain) OR m/0'/1' (internal chain)
1117 assert(internal ? m_storage.CanSupportFeature(FEATURE_HD_SPLIT) : true);
1118 accountKey.Derive(chainChildKey, BIP32_HARDENED_KEY_LIMIT+(internal ? 1 : 0));
1119
1120 // derive child key at next index, skip keys already known to the wallet
1121 do {
1122 // always derive hardened keys
1123 // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
1124 // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
1125 if (internal) {
1126 chainChildKey.Derive(childKey, hd_chain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1127 metadata.hdKeypath = "m/0'/1'/" + ToString(hd_chain.nInternalChainCounter) + "'";
1128 metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1129 metadata.key_origin.path.push_back(1 | BIP32_HARDENED_KEY_LIMIT);
1130 metadata.key_origin.path.push_back(hd_chain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1131 hd_chain.nInternalChainCounter++;
1132 }
1133 else {
1134 chainChildKey.Derive(childKey, hd_chain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1135 metadata.hdKeypath = "m/0'/0'/" + ToString(hd_chain.nExternalChainCounter) + "'";
1136 metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1137 metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1138 metadata.key_origin.path.push_back(hd_chain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1139 hd_chain.nExternalChainCounter++;
1140 }
1141 } while (HaveKey(childKey.key.GetPubKey().GetID()));
1142 secret = childKey.key;
1143 metadata.hd_seed_id = hd_chain.seed_id;
1144 CKeyID master_id = masterKey.key.GetPubKey().GetID();
1145 std::copy(master_id.begin(), master_id.begin() + 4, metadata.key_origin.fingerprint);
1146 metadata.has_key_origin = true;
1147 // update the chain model in the database
1148 if (hd_chain.seed_id == m_hd_chain.seed_id && !batch.WriteHDChain(hd_chain))
1149 throw std::runtime_error(std::string(__func__) + ": writing HD chain model failed");
1150}
1151
1152void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
1153{

Callers

nothing calls this directly

Calls 9

HaveKeyFunction · 0.85
WriteHDChainMethod · 0.80
ToStringFunction · 0.50
SetSeedMethod · 0.45
DeriveMethod · 0.45
push_backMethod · 0.45
GetIDMethod · 0.45
GetPubKeyMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected