My process for generating bitcoin addresses

4 replies 485 views
nonce2009Member
Posts: 2 · Reputation: 55
#1Oct 12, 2017, 09:17 PM
Hey everyone, I’m bringing back a project I had on hold, and it involves getting bitcoin deposits from users, with each user getting their own unique deposit address. My main worry is how to back up the private keys properly in case the bitcoin node goes down. A few years back, when I was using a basic BDB wallet, I created a bunch of addresses with "getnewaddress", assigning about half of them to the "change" label, then I used "dumpprivkey" for all of them, encrypted the file, and stashed it somewhere safe. If something went horribly wrong, I could just import those private keys onto a new server and regain access to all UTXOs. Now, let’s talk about descriptor wallets. I truly believe descriptors are way better than what we used to have (I completely missed the hdseed phase), but there’s a clear challenge they’re a lot more complex if you’re not super familiar with bitcoin core. After spending a few days digging through documentation, StackExchange, and random articles here and there, I’ve come up with a workflow and would love some input from someone who knows their stuff. My big concern is making sure I don’t lose any UTXOs because of a server or disk failure. I’ll be using "test" as the wallet name since I’m working on the testnet. I imagine that everything should move over to mainnet without issues. I’m on Bitcoin core version 28.0. For example, let’s say I want to create 10k deposit addresses. A. GETTING A SET OF DESCRIPTORS start bitcoind bitcoin-cli createwallet test bitcoin-cli listdescriptors true save the JSON output from the last command in a safe place, name it descri
8 Reply Quote Share
gr3g.0rbitHero Member
Posts: 1025 · Reputation: 2646
#2Oct 13, 2017, 12:09 AM
Reasonable, yes. In your descriptors, those active descriptors with "internal: true" result are used for generating your change addresses, those are never used when using getnewaddress command. Notice that each has "range" values, those indicate how many keys Bitcoin Core will check upon scanning for related transactions. The default is 1000 from the last used key, so when importing the descriptor, you may increase the range based from the number of change address that you think you've used before. Considering the info above, you can set the range when importing the descriptors to: "range": [0,10000] or more so Bitcoin Core will scan 10,000 addresses per descriptor which will be included in listreceivedbyaddress command result. (after a rescan) The experimental send command has it but as stated in its help tooltip, it may change in future releases.
0 Reply Quote Share
sage777Full Member
Posts: 102 · Reputation: 305
#3Oct 13, 2017, 05:56 PM
Yes. They are similar, but they just use a little bit different descriptors. You import them in a similar way, as regular ones, just put a different path here (as far as I remember, replacing "0" with "1" in derivation path, should do the trick). This is regular address: This is change address: As you can see, they are similar: In case of descriptor wallets, you don't have to "pre-generate" anything. As long as you have non-hardened derivation, and you know the master public key, you can derive public keys from that. One important thing: compromising the master public key, and a child private key, will compromise all private keys, derived from this particular public key. But: if you never reveal those private keys, you shouldn't worry about that. As shown above, if you know the descriptor, then you can derive keys from any range. But: if you call "getnewaddress", then it will be marked as "used", so the next call to "getnewaddress" will give you the next one in the queue. I don't know. But usually, I just do things manually, by using "createrawtransaction", and then "signrawtransactionwithwallet", to control everything. Yes, things are getting more and more complex. In the past, you could just stick with P2PK, and not worry too much about it. And there was also just "generate" command, which was enough to mine some blocks, without connecting to any mining pool. But: as more people are jumping into the crypto world, it will be more and more complex, because they will create new systems, new layers, and sooner or later, you won't even have a single UTXO per user, because it would be too expensive, to do that on-chain (and then, you would need another API, to join and split many keys and signatures into single addresses and coins, and to handle multi-user transaction, just moving a single coin, from one UTXO to another).
3 Reply Quote Share
nonce2009Member
Posts: 2 · Reputation: 55
#4Oct 13, 2017, 09:46 PM
Thanks for your replies. I think my descriptors are precisely "hardened", ie: they have single quotes in them. Does it still mean that if I save that "listdescriptors true" output, I can always get all my coins back from it, change or not? Do I understand correctly that the best is to use "fundrawtransaction" in between, in order to let the wallet decide on the best UTXO set to use? Might as well just make the effort and ditch "sendtoaddress" alltogether at this point.
2 Reply Quote Share
sage777Full Member
Posts: 102 · Reputation: 305
#5Oct 14, 2017, 12:50 AM
Yes. But: if you use default settings, then probably not all keys are hardened. And the last keys are probably non-hardened. You can compare it with my example. You should get the same results, even if no wallet is loaded: Which means, that if you put your results from "listdescriptors" here, then you can check, if it works for your keys. For deriving keys, you need only "tpub" (testnet master public keys), because "tprv" (testnet master private keys) are needed only for spending. Well, I always manually pick all inputs and outputs. Also because Core wallet usually gives too huge fee estimates, or pick UTXOs differently, than I want. But: in case of automating things, I would probably batch as many things, as possible, which means collecting all withdrawal requests, and handling them every sometimes (once per 6 hours, once per day, or something similar). It is also possible to offer faster processing, but then, fees will naturally be higher, because then, transactions are not batched, if you send coins to a single user. I remember, when as a customer, I paid for example only 80 satoshis, when my withdrawal was batched in a group of hundreds of users, and when mempools were below 4vMB, and accepted 1 sat/vB fees. As a single user, if I would handle it manually, I would probably pay at least 110 satoshis, if not more. So: batching is the way to go, if customers are not in a hurry.
5 Reply Quote Share

Related topics