Okay thanks. This seems like something that could be easily optimised no? Instead of having a tonne of duplicated data that is both in the utxo db and blocks db. You could have each block, and each tx that tries to spend utxo's (instead of referencing a previous tx hash), references a block number and position in the block of the tx he is trying to spend. then the client finds the tx and position of the utxo inside the tx and checks the lockscript/unlockscript.
The chainstate database is the optimization. You can now run a pruned node that only stores a few hundred blocks and with chainstate you still have a fully validating node.