Documentation ¶
Overview ¶
• Adding new transactions to Mempool • Validating transactions against the current State (sufficient sender balance) • Changing the state • Persisting transactions to disk • Calculating accounts balances by replaying all transactions since Genesis in a sequence
Index ¶
- Constants
- func ApplySimpleTx(tx SimpleTx, s *State) error
- func ApplyTx(tx SignedTx, s *State) error
- func InitDataDirIfNotExists(dataDir string, genesis []byte) error
- func IsBlockHashValid(hash Hash, miningDifficulty uint) bool
- func NewAccount(value string) common.Address
- func ValidateSimpleTx(tx SimpleTx, s *State) error
- func ValidateTx(tx SignedTx, s *State) error
- type Address
- type Block
- type BlockFS
- type BlockHeader
- type Genesis
- type Hash
- type SignedTx
- type SimpleBlock
- type SimpleBlockFS
- type SimpleTx
- type State
- func (s *State) AddSimpleBlock(b SimpleBlock) error
- func (s *State) AddSimpleTx(tx SimpleTx) error
- func (s *State) ChangeMiningDifficulty(newDifficulty uint)
- func (s *State) Close() error
- func (s *State) Copy() State
- func (s *State) GetNextAccountNonce(account Address) uint
- func (s *State) IsTIP1Fork() bool
- func (s *State) LatestBlock() SimpleBlock
- func (s *State) LatestBlockHash() Hash
- func (s *State) NextBlockNumber() uint64
- func (s *State) Persist() (Hash, error)
- type Tx
Constants ¶
const ( // HashLength is the expected length of the hash HashLength = 32 // AddressLength is the expected length of the address AddressLength = 20 A0 string = "0x0000000000000000000000000000000000000009" A1 string = "0x0000000000000000000000000000000000000001" A2 string = "0x0000000000000000000000000000000000000002" A3 string = "0x0000000000000000000000000000000000000003" )
Lengths of hashes and addresses in bytes.
const BlockReward = 100
const TxFee = uint(50)
const TxGas = 21
const TxGasPriceDefault = 1
Variables ¶
This section is empty.
Functions ¶
func ApplySimpleTx ¶
func InitDataDirIfNotExists ¶
func IsBlockHashValid ¶
func NewAccount ¶
func ValidateSimpleTx ¶
func ValidateTx ¶
Types ¶
type Address ¶
type Address [AddressLength]byte
func (Address) MarshalText ¶
func (*Address) UnmarshalJSON ¶
UnmarshalJSON parses a hash in hex syntax.
func (*Address) UnmarshalText ¶
type Block ¶
type Block struct { Header BlockHeader `json:"header"` // metadata (parent block hash + time) TXs []SignedTx `json:"payload"` // new transactions only (payload) }
type BlockHeader ¶
type SignedTx ¶
func NewSignedTx ¶
func (SignedTx) IsAuthentic ¶
func (SignedTx) MarshalJSON ¶
MarshalJSON is the main source of truth for encoding a TX for hash calculation (backwards compatible for TIPs).
The logic is bit ugly and hacky but prevents infinite marshaling loops of embedded objects and allows the structure to change with new TIPs.
type SimpleBlock ¶
type SimpleBlock struct { Header BlockHeader `json:"header"` TXs []SimpleTx `json:"payload"` // new transactions only (payload) }
func NewSimpleBlock ¶
func NewSimpleBlock(parent Hash, number uint64, miner Address, txs []SimpleTx) SimpleBlock
func (SimpleBlock) GasReward ¶
func (b SimpleBlock) GasReward() uint
func (SimpleBlock) Hash ¶
func (b SimpleBlock) Hash() (Hash, error)
type SimpleBlockFS ¶
type SimpleBlockFS struct { Key Hash `json:"hash"` Value SimpleBlock `json:"block"` }
type SimpleTx ¶
type SimpleTx struct { From Address `json:"from"` To Address `json:"to"` Value uint `json:"value"` Nonce uint `json:"nonce"` Data string `json:"data"` Time uint64 `json:"time"` }
func (SimpleTx) IsAuthentic ¶
type State ¶
type State struct { Balances map[Address]uint Account2Nonce map[Address]uint HashCache map[string]int64 HeightCache map[uint64]int64 // contains filtered or unexported fields }
func NewStateFromDisk ¶
func (*State) AddSimpleBlock ¶
func (s *State) AddSimpleBlock(b SimpleBlock) error
func (s *State) AddBlocks(blocks []Block) error { for _, b := range blocks { _, err := s.AddBlock(b) if err != nil { return err } } return nil }
func (s *State) AddBlock(b Block) (Hash, error) { pendingState := s.Copy() err := applyBlock(b, &pendingState) if err != nil { return Hash{}, err } blockHash, err := b.Hash() if err != nil { return Hash{}, err } blockFs := BlockFS{blockHash, b} blockFsJson, err := json.Marshal(blockFs) if err != nil { return Hash{}, err } fmt.Printf("\nPersisting new Block to disk:\n") fmt.Printf("\t%s\n", blockFsJson) // get file pos for cache fs, _ := s.dbFile.Stat() filePos := fs.Size() + 1 _, err = s.dbFile.Write(append(blockFsJson, '\n')) if err != nil { return Hash{}, err } // set search caches s.HashCache[blockFs.Key.Hex()] = filePos s.HeightCache[blockFs.Value.Header.Number] = filePos s.Balances = pendingState.Balances s.Account2Nonce = pendingState.Account2Nonce s.latestBlockHash = blockHash s.latestBlock = b s.hasGenesisBlock = true s.miningDifficulty = pendingState.miningDifficulty return blockHash, nil }
func (*State) AddSimpleTx ¶
func (*State) ChangeMiningDifficulty ¶
func (*State) GetNextAccountNonce ¶
func (*State) IsTIP1Fork ¶
func (*State) LatestBlock ¶
func (s *State) LatestBlock() SimpleBlock
func (*State) LatestBlockHash ¶
func (*State) NextBlockNumber ¶
type Tx ¶
type Tx struct { From Address `json:"from"` To Address `json:"to"` Gas uint `json:"gas"` GasPrice uint `json:"gasPrice"` Value uint `json:"value"` Nonce uint `json:"nonce"` Data string `json:"data"` Time uint64 `json:"time"` }
func (Tx) MarshalJSON ¶
MarshalJSON is the main source of truth for encoding a TX for hash calculation from expected attributes.
The logic is bit ugly and hacky but prevents infinite marshaling loops of embedded objects and allows the structure to change with new TIPs.