Backport of
https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/commit/472118a0da52c480f18430cc97ea31950d48324e
with a number of fixups that:
* Reduce code ownership where unnecessary ownership was taken.
* Keeps API reasonably consistent with original UniValue code.
* Various minor formatting, comments, and style fixes.
Depends on D5981 for the test plan