cstring *wallet_new_address(struct wallet *wlt) { struct hd_path_seg hdpath[] = { { 44, true }, // BIP 44 { 0, true }, // chain: BTC { 0, true }, // acct# { 0, false }, // change? { 0, false }, // key index }; struct wallet_account *acct = account_byname(wlt, wlt->def_acct->str); if (!acct) return NULL; // patch HD path based on account settings hdpath[2].index = acct->acct_idx; hdpath[4].index = acct->next_key_idx; assert(wlt->hdmaster && (wlt->hdmaster->len > 0)); struct hd_extended_key *master = parr_idx(wlt->hdmaster, 0); assert(master != NULL); struct hd_extended_key child; hd_extended_key_init(&child); if (!hd_derive(&child, master, hdpath, ARRAY_SIZE(hdpath))) { hd_extended_key_free(&child); return NULL; } acct->next_key_idx++; cstring *rs = bp_pubkey_get_address(&child.key,wlt->chain->addr_pubkey); hd_extended_key_free(&child); return rs; }
int main(int argc, char* argv[]) { int long_index = 0; int opt = 0; char* pkey = 0; char* pubkey = 0; char* cmd = 0; char* keypath = 0; const btc_chainparams* chain = &btc_chainparams_main; /* get arguments */ while ((opt = getopt_long_only(argc, argv, "p:k:m:c:trv", long_options, &long_index)) != -1) { switch (opt) { case 'p': pkey = optarg; if (strlen(pkey) < 50) return showError("Private key must be WIF encoded"); break; case 'c': cmd = optarg; break; case 'm': keypath = optarg; break; case 'k': pubkey = optarg; break; case 't': chain = &btc_chainparams_test; break; case 'r': chain = &btc_chainparams_regtest; break; case 'v': print_version(); exit(EXIT_SUCCESS); break; default: print_usage(); exit(EXIT_FAILURE); } } if (!cmd) { /* exit if no command was provided */ print_usage(); exit(EXIT_FAILURE); } /* start ECC context */ btc_ecc_start(); const char *pkey_error = "Missing extended key (use -p)"; if (strcmp(cmd, "pubfrompriv") == 0) { /* output compressed hex pubkey from hex privkey */ size_t sizeout = 128; char pubkey_hex[sizeout]; if (!pkey) return showError(pkey_error); if (!pubkey_from_privatekey(chain, pkey, pubkey_hex, &sizeout)) return showError("Operation failed"); /* clean memory of private key */ memset(pkey, 0, strlen(pkey)); /* give out hex pubkey */ printf("pubkey: %s\n", pubkey_hex); /* give out p2pkh address */ char address[sizeout]; address_from_pubkey(chain, pubkey_hex, address); printf("p2pkh address: %s\n", address); /* clean memory */ memset(pubkey_hex, 0, strlen(pubkey_hex)); memset(address, 0, strlen(address)); } else if (strcmp(cmd, "addrfrompub") == 0 || strcmp(cmd, "p2pkhaddrfrompub") == 0) { /* get p2pkh address from pubkey */ size_t sizeout = 128; char address[sizeout]; if (!pubkey) return showError("Missing public key (use -k)"); if (!address_from_pubkey(chain, pubkey, address)) return showError("Operation failed, invalid pubkey"); printf("p2pkh address: %s\n", address); memset(pubkey, 0, strlen(pubkey)); memset(address, 0, strlen(address)); } else if (strcmp(cmd, "genkey") == 0) { size_t sizeout = 128; char newprivkey_wif[sizeout]; char newprivkey_hex[sizeout]; /* generate a new private key */ gen_privatekey(chain, newprivkey_wif, sizeout, newprivkey_hex); printf("privatekey WIF: %s\n", newprivkey_wif); printf("privatekey HEX: %s\n", newprivkey_hex); memset(newprivkey_wif, 0, strlen(newprivkey_wif)); memset(newprivkey_hex, 0, strlen(newprivkey_hex)); } else if (strcmp(cmd, "hdgenmaster") == 0) { size_t sizeout = 128; char masterkey[sizeout]; /* generate a new hd master key */ hd_gen_master(chain, masterkey, sizeout); printf("masterkey: %s\n", masterkey); memset(masterkey, 0, strlen(masterkey)); } else if (strcmp(cmd, "hdprintkey") == 0) { if (!pkey) return showError(pkey_error); if (!hd_print_node(chain, pkey)) return showError("Failed. Probably invalid extended key.\n"); } else if (strcmp(cmd, "hdderive") == 0) { if (!pkey) return showError(pkey_error); if (!keypath) return showError("Missing keypath (use -m)"); size_t sizeout = 128; char newextkey[sizeout]; if (!hd_derive(chain, pkey, keypath, newextkey, sizeout)) return showError("Deriving child key failed\n"); else hd_print_node(chain, newextkey); } btc_ecc_stop(); return 0; }