The data structure of receipts are no big difference from transactions. So why block headers have the receipts tree root? Is it unnecessary？
From the Ethereum's Yellow Paper the transaction receipt stores information that results from executing the transaction.
It is a tuple with four fields
- Block's cumulative gas used
- Logs produced during transaction execution
- Bloom filter from the logs
- Status code from transaction execution
The purpose of the receipt is to provide information to the outside world about the transaction execution.
The receipt trie root stored in the block header is used to verify the execution of all the contracts in the block. If a malicious miner executes a transaction incorrectly the resulting trie root will not match the execution of a good miner and the bad block will be rejected.