package entity import ( "fmt" "time" ) // Block is the aggregate root representing an indexed blockchain block. type Block struct { Height int64 `json:"height"` Hash string `json:"hash"` Timestamp time.Time `json:"timestamp"` TxCount int `json:"txCount"` } // NewBlock is the factory method that creates a validated Block entity. func NewBlock(height int64, hash string, timestamp time.Time, txCount int) (*Block, error) { if height < 0 { return nil, fmt.Errorf("block height must be non-negative, got %d", height) } if hash == "" { return nil, fmt.Errorf("block hash must not be empty") } if txCount < 0 { return nil, fmt.Errorf("transaction count must be non-negative, got %d", txCount) } return &Block{ Height: height, Hash: hash, Timestamp: timestamp, TxCount: txCount, }, nil } // Validate checks all invariants on an existing Block. func (b *Block) Validate() error { if b.Height < 0 { return fmt.Errorf("block height must be non-negative") } if b.Hash == "" { return fmt.Errorf("block hash must not be empty") } if b.TxCount < 0 { return fmt.Errorf("transaction count must be non-negative") } return nil } // IsGenesis reports whether this is the genesis block (height 0). func (b *Block) IsGenesis() bool { return b.Height == 0 } // HasTransactions reports whether this block contains any transactions. func (b *Block) HasTransactions() bool { return b.TxCount > 0 } // ChainTransaction represents an indexed on-chain transaction. type ChainTransaction struct { Hash string `json:"hash"` BlockHeight int64 `json:"blockHeight"` From string `json:"from"` To string `json:"to"` Amount string `json:"amount"` Status string `json:"status"` Timestamp time.Time `json:"timestamp"` } // NewChainTransaction is the factory method that creates a validated ChainTransaction. func NewChainTransaction(hash string, blockHeight int64, from, to, amount, status string, timestamp time.Time) (*ChainTransaction, error) { if hash == "" { return nil, fmt.Errorf("transaction hash must not be empty") } if blockHeight < 0 { return nil, fmt.Errorf("block height must be non-negative") } if from == "" { return nil, fmt.Errorf("from address must not be empty") } return &ChainTransaction{ Hash: hash, BlockHeight: blockHeight, From: from, To: to, Amount: amount, Status: status, Timestamp: timestamp, }, nil } // Validate checks all invariants on an existing ChainTransaction. func (tx *ChainTransaction) Validate() error { if tx.Hash == "" { return fmt.Errorf("transaction hash must not be empty") } if tx.BlockHeight < 0 { return fmt.Errorf("block height must be non-negative") } if tx.From == "" { return fmt.Errorf("from address must not be empty") } return nil } // IsConfirmed reports whether the transaction has a "confirmed" status. func (tx *ChainTransaction) IsConfirmed() bool { return tx.Status == "confirmed" } // IsPending reports whether the transaction has a "pending" status. func (tx *ChainTransaction) IsPending() bool { return tx.Status == "pending" }