Study on the source code of Ethereum go-ethereum (1) Start with the custom types and structures related to the Process function

written in front

Now my understanding of some of the codes is not enough, and I will come back and modify them after I gradually study in depth.
The understanding of some codes refers to the contents of the Ethereum Yellow Paper.
Link: https://ethereum.github.io/yellowpaper/paper.pdf

some custom types

type name Location definition
Hash common/types.go 32bytes
Address common/types.go 20byte
Bloom core/types/bloom9.go 256byte(filter)
GasPool core/gaspool.go uint64

some structs

Receipt

Located at core\types\receipt.go
In order to facilitate indexing, searching transactions and zero-knowledge proofs of transactions, some information in transaction execution is encoded to form Receipt
insert image description here
Reference Yellow Book 4.3.1

name definition
Type Transaction Type
PostState The MPT tree root of StateDB is equivalent to the status of all accounts after the execution of the current Block transaction
Status The status of the current transaction
CumulativeGasUsed Cumulative gas usage
Bloom Bloom filter, used to quickly verify whether a given Log is generated for this transaction
Logs Log collection generated during transaction execution
TxHash Transaction hash value
ContractAddress The transaction corresponds to the smart contract address
GasUsed Amount of Gas used
BlockHash block hash
BlockNumber block number
TransactionIndex transaction index

Log

Located in core\types\log.go,
the event and log mechanisms are defined in Ethereum, which are used to represent the log of a contract.
insert image description here

name definition
Address The contract address corresponding to the event
Topics For retrieving logs use
Data The ABI-encoded content provided by the contract
BlockNumber block number
TxHash transaction hash
TxIndex The index of the transaction corresponding to the Log in the block
BlockHash The block hash of the transaction corresponding to the Log
Index The index of the log in the block
Removed This field is true when a chain reorganization has occurred and the log has been restored. Therefore, if you query the log through the filter, you should pay more attention to this field.

Header

insert image description here
Located in core\types\block.go
represents the block header

name definition
ParentHash The hash value of the parent block
UncleHash Uncle block RLP code hash
Coinbase miner address
Root The root hash of the world state
TxHash Root hash of transaction information
ReceiptHash The root hash of the receipt information
Bloom bloom filter
Difficulty Difficulty factor of mining
Number block number
GasLimit Gas consumption limit in the block
GasUsed The total amount of Gas consumed after the block transaction is completed
Time The time when the block was generated (it seems not very accurate)
Extra Information recorded by block creators (miners)
MixDigest The hash value generated by the digest generated by the hashimotoFull function can be used to combine nonce for workload proof
Nonce Pow enumeration guessed value
BaseFee The new block header option of EIP-1559 allows the agreement to enforce the minimum fee without incentivizing miners and transaction parties to trade off-chain and form an off-chain market.

ChainConfig

Located in params\config.go
represents the configuration of the blockchain
insert image description here

name definition
DAOForkBlock The block number of the DAO hard fork
DAOForkSupport Does the current node support DAO hard fork?

BlockChain

insert image description here

位于core\blockchain.go
待补充

Transaction

insert image description here
insert image description here
位于core\types\transaction.go
其中txdata是一个接口,定义如下,位于相同位置
insert image description here

位于core\types\transaction.go

名字 定义
inner 交易相关共识内容
time 交易时间
hash 交易hash值
size 交易大小
from 交易发起方

Block


位于core\types\block.go
表示区块

名字 定义
ParentHash 父区块的hash值
UncleHash 叔区块RLP编码hash
Coinbase 矿工地址
Root 世界状态的根hash
TxHash 交易信息的根hash
ReceiptHash 收据信息的根hash
Bloom 布隆过滤器
Difficulty 挖矿的难度系数

StateProcessor

insert image description here
位于core\state_processor.go

名字 定义
config 区块配置
bc 区块链
engine 用于区块奖励的共识引擎

BlockContext

位于core\vm\evm.go
表示区块上下文,很多属性和前面是重复的。
insert image description here

名字 定义
CoinBase 矿工地址
GasLimit Gas的限制量
BlockNumber 区块号
Time 时间
Difficulty 难度
BaseFee 协议执行最低费用

evm

位于core\vm\evm.go
待补充
insert image description here

名字 定义
interpreter 解释编译程序

Message

insert image description here
位于core\types\transaction.go
派生的事务(待补充)

名字 定义
nonce 即为交易中的nonce,用来交易排序,交易校验以避免双花
gasLimit 当前消息gas最大限制
gasPrice 油价
gasFeeCap 用户所能支付给矿工的最大单价限额
gasTipCap 小费,即在网络拥堵的情况下支付给矿工的小费,这个也意味着矿工有优先选择权。支付该费用,则优先打包区块

StateDB

insert image description here
位于core\state\statedb.go
StateDB结构用于存储所有的与Merkle trie相关的存储, 包括一些循环state结构

accessList

insert image description here
位于core\state\access_list.go
每个事务的访问列表,在某些形式的 EVM 执行过程中会触及的账户和合约存储位置的列表

Engine

insert image description here
位于consensus\consensus.go
engine是一个算法无关的用作共识层面的引擎

相关函数

Process

位于core\state_processor.go

func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
    
    
	var (
		receipts    types.Receipts
		usedGas     = new(uint64)
		header      = block.Header()
		blockHash   = block.Hash()
		blockNumber = block.Number()
		allLogs     []*types.Log
		gp          = new(GasPool).AddGas(block.GasLimit())
	)
	// Mutate the block and state according to any hard-fork specs
	if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
    
    
		misc.ApplyDAOHardFork(statedb)
	}
	blockContext := NewEVMBlockContext(header, p.bc, nil)
	vmenv := vm.NewEVM(blockContext, vm.TxContext{
    
    }, statedb, p.config, cfg)
	// Iterate over and process the individual transactions
	for i, tx := range block.Transactions() {
    
    
		msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee)
		if err != nil {
    
    
			return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
		}
		statedb.Prepare(tx.Hash(), i)
		receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
		if err != nil {
    
    
			return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
		}
		receipts = append(receipts, receipt)
		allLogs = append(allLogs, receipt.Logs...)
	}
	// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
	p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles())

	return receipts, allLogs, *usedGas, nil
}

首先该函数判断当前区块是否为DAO硬分叉的区块,若是则调用ApplyDAOHardFork函数(待补充)。
然后调用NewEVMBlockContext函数为当前区块创立一个运行上下文。
随后调用NewEVM函数建立一个以太坊虚拟机,准备编译执行程序。
然后枚举区块中的交易并把它转换为消息格式,随后调用Prepare函数设置当前状态的交易hash和序号,随后调用applyTransaction在虚拟机中执行交易相关指令(见以太坊go-ethereum源码研读(二)进一步分析),得到返回的收据后,加入到列表中,并获取其中的日志加入到列表中,最后调用共识引擎的Finalize函数计算区块奖励并加入到最终状态中。

NewEVMBlockContext

位于core\evm.go
根据区块头信息,建立并返回一个BlockContext区块上下文信息结构体

func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext {
    
    
	var (
		beneficiary common.Address
		baseFee     *big.Int
	)

	// If we don't have an explicit author (i.e. not mining), extract from the header
	if author == nil {
    
    
		beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation
	} else {
    
    
		beneficiary = *author
	}
	if header.BaseFee != nil {
    
    
		baseFee = new(big.Int).Set(header.BaseFee)
	}
	return vm.BlockContext{
    
    
		CanTransfer: CanTransfer,
		Transfer:    Transfer,
		GetHash:     GetHashFn(header, chain),
		Coinbase:    beneficiary,
		BlockNumber: new(big.Int).Set(header.Number),
		Time:        new(big.Int).SetUint64(header.Time),
		Difficulty:  new(big.Int).Set(header.Difficulty),
		BaseFee:     baseFee,
		GasLimit:    header.GasLimit,
	}
}

NewEVM

Located in core/vm/evm.go,
it builds a virtual machine based on previous context information, other configurations and content, and calls NewEVMInterpreterfunctions to build a corresponding interpreter.

// NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*.
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM {
    
    
	evm := &EVM{
    
    
		Context:     blockCtx,
		TxContext:   txCtx,
		StateDB:     statedb,
		Config:      config,
		chainConfig: chainConfig,
		chainRules:  chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil),
	}
	evm.interpreter = NewEVMInterpreter(evm, config)
	return evm
}

NewEVMInterpreter

Establish the corresponding EVM interpreter according to the different chain rules adopted

// NewEVMInterpreter returns a new instance of the Interpreter.
func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
    
    
	// If jump table was not initialised we set the default one.
	if cfg.JumpTable == nil {
    
    
		switch {
    
    
		case evm.chainRules.IsLondon:
			cfg.JumpTable = &londonInstructionSet
		case evm.chainRules.IsBerlin:
			cfg.JumpTable = &berlinInstructionSet
		case evm.chainRules.IsIstanbul:
			cfg.JumpTable = &istanbulInstructionSet
		case evm.chainRules.IsConstantinople:
			cfg.JumpTable = &constantinopleInstructionSet
		case evm.chainRules.IsByzantium:
			cfg.JumpTable = &byzantiumInstructionSet
		case evm.chainRules.IsEIP158:
			cfg.JumpTable = &spuriousDragonInstructionSet
		case evm.chainRules.IsEIP150:
			cfg.JumpTable = &tangerineWhistleInstructionSet
		case evm.chainRules.IsHomestead:
			cfg.JumpTable = &homesteadInstructionSet
		default:
			cfg.JumpTable = &frontierInstructionSet
		}
		for i, eip := range cfg.ExtraEips {
    
    
			copy := *cfg.JumpTable
			if err := EnableEIP(eip, &copy); err != nil {
    
    
				// Disable it, so caller can check if it's activated or not
				cfg.ExtraEips = append(cfg.ExtraEips[:i], cfg.ExtraEips[i+1:]...)
				log.Error("EIP activation failed", "eip", eip, "error", err)
			}
			cfg.JumpTable = &copy
		}
	}

	return &EVMInterpreter{
    
    
		evm: evm,
		cfg: cfg,
	}
}

AsMessage

Located in core\types\transaction.go
returns the transaction as a message format

// AsMessage returns the transaction as a core.Message.
func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
    
    
	msg := Message{
    
    
		nonce:      tx.Nonce(),
		gasLimit:   tx.Gas(),
		gasPrice:   new(big.Int).Set(tx.GasPrice()),
		gasFeeCap:  new(big.Int).Set(tx.GasFeeCap()),
		gasTipCap:  new(big.Int).Set(tx.GasTipCap()),
		to:         tx.To(),
		amount:     tx.Value(),
		data:       tx.Data(),
		accessList: tx.AccessList(),
		isFake:     false,
	}
	// If baseFee provided, set gasPrice to effectiveGasPrice.
	if baseFee != nil {
    
    
		msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.gasTipCap, baseFee), msg.gasFeeCap)
	}
	var err error
	msg.from, err = Sender(s, tx)
	return msg, err
}

Prepare

Located in core\state\statedb.go,
this function is called when the EVM needs to generate a new state to set the hash and sequence number of the current transaction

// Prepare sets the current transaction hash and index which are
// used when the EVM emits new state logs.
func (s *StateDB) Prepare(thash common.Hash, ti int) {
    
    
	s.thash = thash
	s.txIndex = ti
	s.accessList = newAccessList()
}

Finalize

// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
// setting the final state on the header
func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
    
    
	// Accumulate any block and uncle rewards and commit the final state root
	accumulateRewards(chain.Config(), state, header, uncles)
	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
}

Located in consensus\ethash\consensus.go
This function accumulates block and uncle block rewards and sets them in the final state of the head.

Guess you like

Origin blog.csdn.net/eliforsharon/article/details/126094636