func ReadReceipt(receipts Receipts, index int) (*Receipt, error) {
	if len(receipts) <= index {
		return nil, common.ErrIllegalParams
	}
	return receipts[index], nil
}
ReadReceipt retrieves a specific transaction receipt from the database, along with
its added positional metadata.
package models
import (
	"bytes"
	"encoding/json"
	"fmt"
	"math/big"
	"github.com/ThinkiumGroup/go-common"
	dataBase "github.com/ThinkiumGroup/go-common/db"
	"github.com/ThinkiumGroup/go-common/hexutil"
	"github.com/ThinkiumGroup/go-common/log"
	"github.com/stephenfire/go-rtl"
)
const (
	ReceiptStatusFailed = uint64(0)
	ReceiptStatusSuccessful = uint64(1)
)
type Log struct {
	Address common.Address `json:"address" gencodec:"required"`
	Topics []common.Hash `json:"topics" gencodec:"required"`
	Data []byte `json:"data" gencodec:"required"`
	BlockNumber uint64 `json:"blockNumber" gencodec:"required"`
	TxHash common.Hash `json:"transactionHash" gencodec:"required"`
	TxIndex uint `json:"transactionIndex" gencodec:"required"`
	Index uint `json:"logIndex" gencodec:"required"`
}
type logMarshaling struct {
	Data        hexutil.Bytes
	BlockNumber hexutil.Uint64
	TxIndex     hexutil.Uint
	Index       hexutil.Uint
}
type Receipt struct {
	PostState         []byte `json:"root"`  
	Status            uint64 `json:"status"`
	CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"`
	Logs              []*Log `json:"logs" gencodec:"required"`
	TxHash          common.Hash     `json:"transactionHash" gencodec:"required"`
	ContractAddress *common.Address `json:"contractAddress"`
	GasUsed         uint64          `json:"gasUsed" gencodec:"required"`
	Out             []byte          `json:"out" gencodec:"required"`
	Error           string          `json:"error"`
}
type receiptMarshaling struct {
	PostState         hexutil.Bytes
	Status            hexutil.Uint64
	CumulativeGasUsed hexutil.Uint64
	GasUsed           hexutil.Uint64
	Out               hexutil.Bytes
}
type Receipts []*Receipt
func (r *Receipt) GasFeeString() string {
	ps := ParsePostState(r.PostState)
	if ps == nil {
		return ""
	}
	return ps.GasFee
}
func (r *Receipt) GetPostRoot() []byte {
	ps := ParsePostState(r.PostState)
	if ps == nil {
		return r.PostState
	}
	return ps.Root
}
func (r *Receipt) String() string {
	return fmt.Sprintf("Receipt{TxHash:%x Contract:%x Status:%d Gas:%d Fee:%s PostRoot:%x len(Logs):%d len(Out):%d}",
		r.TxHash[:], r.ContractAddress[:], r.Status, r.GasUsed, r.GasFeeString(), r.GetPostRoot(), len(r.Logs), len(r.Out))
}
func (r Receipts) Len() int { return len(r) }
func NewReceipt(gasFee *big.Int, root []byte, err error, cumulativeGasUsed uint64) *Receipt {
	ps := NewPostState(gasFee, root)
	psbytes, _ := ps.Bytes()
	r := &Receipt{PostState: psbytes, CumulativeGasUsed: cumulativeGasUsed}
	if err != nil {
		r.Status = ReceiptStatusFailed
		r.Error = err.Error()
	} else {
		r.Status = ReceiptStatusSuccessful
	}
	return r
}
func ReadReceipts(db dataBase.Database, hash common.Hash) Receipts {
	data, _ := db.Get(dataBase.ToBlockReceiptsKey(hash[:]))
	if len(data) == 0 {
		return nil
	}
	dataBuf := bytes.NewBuffer(data)
	receipts := make([]*Receipt, 0)
	if err := rtl.Decode(dataBuf, &receipts); err != nil {
		log.Error("Invalid receipt array", "hash", hash, "err", err)
		return nil
	}
	return receipts
}
func WriteReceipts(db dataBase.Database, receipts Receipts) ([]byte, error) {
	dataBuf := common.BytesBufferPool.Get().(*bytes.Buffer)
	defer common.BytesBufferPool.Put(dataBuf)
	dataBuf.Reset()
	err := rtl.Encode(receipts, dataBuf)
	if err != nil {
		log.Error("Failed to encode block receipts", "err", err)
		return nil, err
	}
	bs := dataBuf.Bytes()
	receiptHash, err := common.Hash256s(bs)
	if err != nil {
		return nil, err
	}
	if err := db.Put(dataBase.ToBlockReceiptsKey(receiptHash), bs); err != nil {
		log.Error("Failed to store block receipts", "err", err)
		return nil, err
	}
	return receiptHash, nil
}
func DeleteReceipts(db dataBase.Database, hash common.Hash, number uint64) {
	if err := db.Delete(dataBase.ToBlockReceiptsKey(hash[:])); err != nil {
		log.Error("Failed to delete block receipts", "err", err)
	}
}