Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make getDerivedHDAddress return address, not key #218

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/dogecoin/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ LIBDOGECOIN_API dogecoin_hdnode* getHDNodeAndExtKeyByPath(const char* masterkey,
/* generate an extended hd public/private child address */
LIBDOGECOIN_API int getDerivedHDAddress(const char* masterkey, uint32_t account, bool ischange, uint32_t addressindex, char* outaddress, bool outprivkey);

/* generate an extended hd public/private child address as a P2PKH */
LIBDOGECOIN_API int getDerivedHDAddressAsP2PKH(const char* masterkey, uint32_t account, bool ischange, uint32_t addressindex, char* outp2pkh);

/* generate an extended hd public/private child address with a more flexible derived path */
LIBDOGECOIN_API int getDerivedHDAddressByPath(const char* masterkey, const char* derived_path, char* outaddress);

Expand Down
30 changes: 30 additions & 0 deletions src/address.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,36 @@ int getDerivedHDAddress(const char* masterkey, uint32_t account, bool ischange,
return ret;
}

/**
* @brief This function generates a derived child address from a masterkey using
* a BIP44 standardized static, non hardened path comprised of an account, a change or
* receiving address and an address index.
*
* @param masterkey The master key from which children are derived from.
* @param account The account that the derived address would belong to.
* @param ischange Boolean value representing either a change or receiving address.
* @param addressindex The index of the receiving/change address per account.
* @param outp2pkh The derived address in P2PSH form.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: P2PKH

*
* @return 1 if a derived address was successfully generated, 0 otherwise.
*/
int getDerivedHDAddressAsP2PKH(const char* masterkey, uint32_t account, bool ischange, uint32_t addressindex, char* outp2pkh) {
if (!masterkey) {
debug_print("%s", "no extended key\n");
return false;
}

char derived_path[DERIVED_PATH_STRINGLEN];
int derived_path_size = snprintf(derived_path, sizeof(derived_path), "m/44'/3'/%u'/%u/%u", account, ischange, addressindex);

if (derived_path_size >= (int)sizeof(derived_path)) {
debug_print("%s", "derivation path overflow\n");
return false;
}

return getDerivedHDAddressByPath(masterkey, derived_path, outp2pkh);
}

/**
* @brief This function generates a new dogecoin address from a mnemonic by the slip44 key path.
*
Expand Down
26 changes: 26 additions & 0 deletions test/address_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,32 @@ void test_address()
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "dgub8wfrZMXz8ojFcPziSubEoQ65sB4PYPyYTMo3PqFwf2Vx5zZ6ia17Nk2Py25c3dvq1e7ZnfBrurCS5wuagzRoBCXhJ2NeGU54NBytvuUuRyA");

/* ckd p2pkh generation */
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 0, false, 0, extout);
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "DCm7oSg95sxwn3sWxYUDHgKKbB2mDmuR3B");
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 0, true, 0, extout);
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "D91jVi3CVGhRmyt83fhMdL4UJWtDuiTZET");
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 0, false, 0, extout);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: L144-148 and L156-161 are duplicate test cases

u_assert_int_eq(res, true);
u_assert_str_eq(extout, "DCm7oSg95sxwn3sWxYUDHgKKbB2mDmuR3B");
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 0, true, 0, extout);
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "D91jVi3CVGhRmyt83fhMdL4UJWtDuiTZET");
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 1, false, 1, extout);
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "D5Se361tds246n9Bm6diMQwkg7PfQrME65");
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 1, true, 1, extout);
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "DD5ztaSL3pscXYL6XXcRFTvbdghKppsKDn");
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 1, false, 1, extout);
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "D5Se361tds246n9Bm6diMQwkg7PfQrME65");
res = getDerivedHDAddressAsP2PKH(masterkey_main_ext, 1, true, 1, extout);
u_assert_int_eq(res, true);
u_assert_str_eq(extout, "DD5ztaSL3pscXYL6XXcRFTvbdghKppsKDn");

// hardened paths (unabstracted as this is called by getDerivedHDAddress)
res = getDerivedHDKeyByPath(masterkey_main_ext, "m/44'/3'/0'/0/0", extout, true);
u_assert_int_eq(res, true);
Expand Down
Loading