Does it look reasonable?
Yes.
What about change addresses?
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:
getnewaddress
bcrt1qt3g6gh0j0ry2j837jm0wgv726arcxvehulkk6a
getaddressinfo bcrt1qt3g6gh0j0ry2j837jm0wgv726arcxvehulkk6a
{
"address": "bcrt1qt3g6gh0j0ry2j837jm0wgv726arcxvehulkk6a",
"scriptPubKey": "00145c51a45df278c8a91e3e96dee433cad747833337",
"ismine": true,
"solvable": true,
"desc": "wpkh([cb4cc245/84h/1h/0h/0/0]0252b21103c4875db871378a804c32b28432e7aa258b6c9faf947f4ac562257f72)#9kjzpwfl",
"parent_desc": "wpkh([cb4cc245/84h/1h/0h]tpubDCinLkxqJCQE4Bqj9UC4nmsrVrWQJFTMh5uT3LwsuU9PNA8QW6MZE9Gr6oLMRnMJpUqHvY8BkjKP8ECZBvhwFda52pXgamyJ1czQ8APe9ca/0/*)#l34fcp03",
"iswatchonly": false,
"isscript": false,
"iswitness": true,
"witness_version": 0,
"witness_program": "5c51a45df278c8a91e3e96dee433cad747833337",
"pubkey": "0252b21103c4875db871378a804c32b28432e7aa258b6c9faf947f4ac562257f72",
"ischange": false,
"timestamp": 1733986112,
"hdkeypath": "m/84h/1h/0h/0/0",
"hdseedid": "0000000000000000000000000000000000000000",
"hdmasterfingerprint": "cb4cc245",
"labels": [
""
]
}
This is change address:
decoderawtransaction 02000000000101977f70fe8d23e93b3c864a2e21f97962c7c2ac38aeefb374cf17a18d7e3ddf560000000000fdffffff0200ca9a3b00000000160014f150d5a0c1153deb36e96dd8cc912852529d5e8173276bee00000000160014d7ba14dab01391b5b10d22ccff306e3995a5caaa02473044022052d8131d43c7131b8430e28a14d79d2626357f1754187ab4b19b4097f739648e022026bb5b9d5c4541541922b57186f076a495e72c67e22acf974b54f8853b0be77801210252b21103c4875db871378a804c32b28432e7aa258b6c9faf947f4ac562257f7265000000
{
"txid": "2e7ad6ee50db4d4505097e4815e50abd9fc12614388bd1ec90748b779e3902b6",
"hash": "0189c8f460d3731f0fc47758517863f1591450d590867eba9b6511d88452342d",
"version": 2,
"size": 222,
"vsize": 141,
"weight": 561,
"locktime": 101,
"vin": [
{
"txid": "56df3d7e8da117cf74b3efae38acc2c76279f9212e4a863c3be9238dfe707f97",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"txinwitness": [
"3044022052d8131d43c7131b8430e28a14d79d2626357f1754187ab4b19b4097f739648e022026bb5b9d5c4541541922b57186f076a495e72c67e22acf974b54f8853b0be77801",
"0252b21103c4875db871378a804c32b28432e7aa258b6c9faf947f4ac562257f72"
],
"sequence": 4294967293
}
],
"vout": [
{
"value": 10.00000000,
"n": 0,
"scriptPubKey": {
"asm": "0 f150d5a0c1153deb36e96dd8cc912852529d5e81",
"desc": "addr(bcrt1q79gdtgxpz577kdhfdhvveyfg2fff6h5ptdzuyt)#9yhcs8hc",
"hex": "0014f150d5a0c1153deb36e96dd8cc912852529d5e81",
"address": "bcrt1q79gdtgxpz577kdhfdhvveyfg2fff6h5ptdzuyt",
"type": "witness_v0_keyhash"
}
},
{
"value": 39.99999859,
"n": 1,
"scriptPubKey": {
"asm": "0 d7ba14dab01391b5b10d22ccff306e3995a5caaa",
"desc": "addr(bcrt1q67apfk4szwgmtvgdytx07vrw8x26tj4260jefq)#5jcwue40",
"hex": "0014d7ba14dab01391b5b10d22ccff306e3995a5caaa",
"address": "bcrt1q67apfk4szwgmtvgdytx07vrw8x26tj4260jefq",
"type": "witness_v0_keyhash"
}
}
]
}
getaddressinfo bcrt1q67apfk4szwgmtvgdytx07vrw8x26tj4260jefq
{
"address": "bcrt1q67apfk4szwgmtvgdytx07vrw8x26tj4260jefq",
"scriptPubKey": "0014d7ba14dab01391b5b10d22ccff306e3995a5caaa",
"ismine": true,
"solvable": true,
"desc": "wpkh([cb4cc245/84h/1h/0h/1/0]032f34c09c0d3d8f0e5ddc1291d26d4f4678d2204d97c1fe5bfc2d1b9d8e06af86)#qwg0al2l",
"parent_desc": "wpkh([cb4cc245/84h/1h/0h]tpubDCinLkxqJCQE4Bqj9UC4nmsrVrWQJFTMh5uT3LwsuU9PNA8QW6MZE9Gr6oLMRnMJpUqHvY8BkjKP8ECZBvhwFda52pXgamyJ1czQ8APe9ca/1/*)#w9sg95lf",
"iswatchonly": false,
"isscript": false,
"iswitness": true,
"witness_version": 0,
"witness_program": "d7ba14dab01391b5b10d22ccff306e3995a5caaa",
"pubkey": "032f34c09c0d3d8f0e5ddc1291d26d4f4678d2204d97c1fe5bfc2d1b9d8e06af86",
"ischange": true,
"timestamp": 1733986112,
"hdkeypath": "m/84h/1h/0h/1/0",
"hdseedid": "0000000000000000000000000000000000000000",
"hdmasterfingerprint": "cb4cc245",
"labels": [
]
}
As you can see, they are similar:
"parent_desc": "wpkh([cb4cc245/84h/1h/0h]tpubDCinLkxqJCQE4Bqj9UC4nmsrVrWQJFTMh5uT3LwsuU9PNA8QW6MZE9Gr6oLMRnMJpUqHvY8BkjKP8ECZBvhwFda52pXgamyJ1czQ8APe9ca/0/*)#l34fcp03" regular address
"parent_desc": "wpkh([cb4cc245/84h/1h/0h]tpubDCinLkxqJCQE4Bqj9UC4nmsrVrWQJFTMh5uT3LwsuU9PNA8QW6MZE9Gr6oLMRnMJpUqHvY8BkjKP8ECZBvhwFda52pXgamyJ1czQ8APe9ca/1/*)#w9sg95lf" change address
Should I also "pre-generate" change addresses?
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.
deriveaddresses "wpkh([cb4cc245/84h/1h/0h]tpubDCinLkxqJCQE4Bqj9UC4nmsrVrWQJFTMh5uT3LwsuU9PNA8QW6MZE9Gr6oLMRnMJpUqHvY8BkjKP8ECZBvhwFda52pXgamyJ1czQ8APe9ca/0/*)#l34fcp03" "[0,1]"
[
"bcrt1qt3g6gh0j0ry2j837jm0wgv726arcxvehulkk6a",
"bcrt1q79gdtgxpz577kdhfdhvveyfg2fff6h5ptdzuyt"
]
deriveaddresses "wpkh([cb4cc245/84h/1h/0h]tpubDCinLkxqJCQE4Bqj9UC4nmsrVrWQJFTMh5uT3LwsuU9PNA8QW6MZE9Gr6oLMRnMJpUqHvY8BkjKP8ECZBvhwFda52pXgamyJ1czQ8APe9ca/1/*)#w9sg95lf" 0
[
"bcrt1q67apfk4szwgmtvgdytx07vrw8x26tj4260jefq"
]
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.
Is using "getnewaddress" the proper way to do it?
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.
Why oh why is there not an option to set a change address in "sendtoaddress"?
I don't know. But usually, I just do things manually, by using "createrawtransaction", and then "signrawtransactionwithwallet", to control everything.
Is it me or dealing with crypto daemons only gets more complex as time passes, instead of getting simpler?
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).