123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- package dgn
- import (
- "encoding/binary"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
- "golang.org/x/crypto/sha3"
- "math/big"
- "sync/atomic"
- "time"
- )
- type BHeader struct {
- ParentHash common.Hash `json:"parentHash" gencodec:"required"`
- UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"`
- Coinbase common.Address `json:"miner" gencodec:"required"`
- Root common.Hash `json:"stateRoot" gencodec:"required"`
- TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
- ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
- Bloom types.Bloom `json:"logsBloom" gencodec:"required"`
- Difficulty *big.Int `json:"difficulty" gencodec:"required"`
- Number *big.Int `json:"number" gencodec:"required"`
- GasLimit uint64 `json:"gasLimit" gencodec:"required"`
- GasUsed uint64 `json:"gasUsed" gencodec:"required"`
- Time uint64 `json:"timestamp" gencodec:"required"`
- Extra []byte `json:"extraData" gencodec:"required"`
- Election []byte `json:"election" gencodec:"required"`
- MixDigest common.Hash `json:"mixHash"`
- Nonce types.BlockNonce `json:"nonce"`
- // Signature values
- V *big.Int `json:"v" gencodec:"required"`
- R *big.Int `json:"r" gencodec:"required"`
- S *big.Int `json:"s" gencodec:"required"`
- }
- // Hash returns the block hash of the header, which is simply the keccak256 hash of its
- // RLP encoding.
- func (h *BHeader) Hash() common.Hash {
- return rlpHash(h)
- }
- func rlpHash(x interface{}) (h common.Hash) {
- hw := sha3.NewLegacyKeccak256()
- rlp.Encode(hw, x)
- hw.Sum(h[:0])
- return h
- }
- // Block represents an entire block in the Ethereum blockchain.
- type Block struct {
- header *BHeader
- uncles []*BHeader
- transactions types.Transactions
- // caches
- hash atomic.Value
- size atomic.Value
- // Td is used by package core to store the total difficulty
- // of the chain up to and including the block.
- td *big.Int
- // These fields are used by package eth to track
- // inter-peer block relay.
- ReceivedAt time.Time
- ReceivedFrom interface{}
- }
- func (b *Block) Uncles() []*BHeader { return b.uncles }
- func (b *Block) Transactions() types.Transactions { return b.transactions }
- func (b *Block) Transaction(hash common.Hash) *types.Transaction {
- for _, transaction := range b.transactions {
- if transaction.Hash() == hash {
- return transaction
- }
- }
- return nil
- }
- func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) }
- func (b *Block) GasLimit() uint64 { return b.header.GasLimit }
- func (b *Block) GasUsed() uint64 { return b.header.GasUsed }
- func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
- func (b *Block) Time() uint64 { return b.header.Time }
- func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() }
- func (b *Block) MixDigest() common.Hash { return b.header.MixDigest }
- func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
- func (b *Block) Bloom() types.Bloom { return b.header.Bloom }
- func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
- func (b *Block) Root() common.Hash { return b.header.Root }
- func (b *Block) ParentHash() common.Hash { return b.header.ParentHash }
- func (b *Block) TxHash() common.Hash { return b.header.TxHash }
- func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
- func (b *Block) UncleHash() common.Hash { return b.header.UncleHash }
- func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) }
- // WithBody returns a new block with the given transaction and uncle contents.
- func (b *Block) WithBody(transactions []*types.Transaction, uncles []*BHeader) *Block {
- block := &Block{
- header: CopyHeader(b.header),
- transactions: make([]*types.Transaction, len(transactions)),
- uncles: make([]*BHeader, len(uncles)),
- }
- copy(block.transactions, transactions)
- for i := range uncles {
- block.uncles[i] = CopyHeader(uncles[i])
- }
- return block
- }
- // Hash returns the keccak256 hash of b's header.
- // The hash is computed on the first call and cached thereafter.
- func (b *Block) Hash() common.Hash {
- if hash := b.hash.Load(); hash != nil {
- return hash.(common.Hash)
- }
- v := b.header.Hash()
- b.hash.Store(v)
- return v
- }
- // CopyHeader creates a deep copy of a block header to prevent side effects from
- // modifying a header variable.
- func CopyHeader(h *BHeader) *BHeader {
- cpy := *h
- if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
- cpy.Difficulty.Set(h.Difficulty)
- }
- if cpy.Number = new(big.Int); h.Number != nil {
- cpy.Number.Set(h.Number)
- }
- if len(h.Extra) > 0 {
- cpy.Extra = make([]byte, len(h.Extra))
- copy(cpy.Extra, h.Extra)
- }
- return &cpy
- }
- func NewBlockWithHeader(header *BHeader) *Block {
- return &Block{header: CopyHeader(header)}
- }
|