国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

以太坊go-ethereum源碼研讀(二)applyTransaction相關(guān)

這篇具有很好參考價(jià)值的文章主要介紹了以太坊go-ethereum源碼研讀(二)applyTransaction相關(guān)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

寫在前面

在前面以太坊go-ethereum源碼研讀(一)中所討論的Process函數(shù)調(diào)用了該applyTransaction函數(shù)來執(zhí)行交易相關(guān)指令,于是進(jìn)一步對該函數(shù)進(jìn)行分析,以明晰以太坊交易的全過程。
分析過程中一些結(jié)構(gòu)體或函數(shù)在以太坊go-ethereum源碼研讀(一)中已經(jīng)討論到,對這些結(jié)構(gòu)體和函數(shù)則不在此文中過多贅述。
同時(shí)對于創(chuàng)建合約的create函數(shù)和進(jìn)一步執(zhí)行交易的call函數(shù)在下一篇研讀中繼續(xù)分析。

相關(guān)變量

名字 定義 解釋
TxGas uint64 = 21000 位于params\protocol_params.go,是交易所需的gas量
TxGasContractCreation uint64 = 53000 位于params\protocol_params.go,家園版本硬分叉將通過交易創(chuàng)建智能合約的費(fèi)用從21000提高到53000
TxDataZeroGas uint64 = 4 位于params\protocol_params.go,字節(jié)為0的數(shù)據(jù)的價(jià)格
TxDataNonZeroGasFrontier uint64 = 68 位于params\protocol_params.go,前沿版本字節(jié)不為0的數(shù)據(jù)的價(jià)格
TxDataNonZeroGasEIP2028 uint64 = 16 位于params\protocol_params.go,EIP2028版本字節(jié)不為0的數(shù)據(jù)的價(jià)格
TxAccessListAddressGas uint64 = 2400 位于params\protocol_params.go,訪問列表中指定地址的花費(fèi)
TxAccessListStorageKeyGas uint64 = 1900 位于params\protocol_params.go,訪問列表中合約存儲地址的花費(fèi)
RefundQuotient uint64 = 2 位于params\protocol_params.go,退款上限的最大除數(shù),即在EIP-3529前最多有一半的gas能被退回
RefundQuotientEIP3529 uint64 = 5 位于params\protocol_params.go,在EIP-3529后最多有五分之一的gas能被退回了

相關(guān)結(jié)構(gòu)體

TxContext

位于core\vm\evm.go

// TxContext provides the EVM with information about a transaction.
// All fields can change between transactions.
type TxContext struct {
	// Message information
	Origin   common.Address // Provides information for ORIGIN
	GasPrice *big.Int       // Provides information for GASPRICE
}
名字 定義
Origin 事務(wù)發(fā)起方的地址
GasPrice Gas的價(jià)格

事務(wù)信息相關(guān)結(jié)構(gòu)體。
BlockContext進(jìn)行對比,進(jìn)一步理解區(qū)塊信息和事務(wù)信息的不同所在。

StateTransition

位于core\state_transition.go

type StateTransition struct {
	gp         *GasPool
	msg        Message
	gas        uint64
	gasPrice   *big.Int
	gasFeeCap  *big.Int
	gasTipCap  *big.Int
	initialGas uint64
	value      *big.Int
	data       []byte
	state      vm.StateDB
	evm        *vm.EVM
}

事務(wù)狀態(tài)信息

名字 定義
GasPrice Gas的價(jià)格
gasFeeCap 用戶能支付給礦工的最大單價(jià)限額
gasTipCap 支付給礦工的消費(fèi),支付該費(fèi)用則礦工優(yōu)先打包你的交易

相關(guān)函數(shù)

applyTransaction

func applyTransaction(msg types.Message, config *params.ChainConfig, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
	// Create a new context to be used in the EVM environment.
	txContext := NewEVMTxContext(msg)
	evm.Reset(txContext, statedb)

	// Apply the transaction to the current state (included in the env).
	result, err := ApplyMessage(evm, msg, gp)
	if err != nil {
		return nil, err
	}

	// Update the state with pending changes.
	var root []byte
	if config.IsByzantium(blockNumber) {
		statedb.Finalise(true)
	} else {
		root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes()
	}
	*usedGas += result.UsedGas

	// Create a new receipt for the transaction, storing the intermediate root and gas used
	// by the tx.
	receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: *usedGas}
	if result.Failed() {
		receipt.Status = types.ReceiptStatusFailed
	} else {
		receipt.Status = types.ReceiptStatusSuccessful
	}
	receipt.TxHash = tx.Hash()
	receipt.GasUsed = result.UsedGas

	// If the transaction created a contract, store the creation address in the receipt.
	if msg.To() == nil {
		receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce())
	}

	// Set the receipt logs and create the bloom filter.
	receipt.Logs = statedb.GetLogs(tx.Hash(), blockHash)
	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
	receipt.BlockHash = blockHash
	receipt.BlockNumber = blockNumber
	receipt.TransactionIndex = uint(statedb.TxIndex())
	return receipt, err
}

位于core\state_processor.go
首先調(diào)用NewEVMTxContext函數(shù)根據(jù)已轉(zhuǎn)換為Message格式的事務(wù)信息建立虛擬機(jī)事務(wù)上下文信息,因前述Process函數(shù)中已根據(jù)區(qū)塊上下文信息建立了虛擬機(jī)整體的上下文信息,故需再調(diào)用Reset函數(shù)重設(shè)事務(wù)上下文信息。
然后調(diào)用ApplyMessage函數(shù)在當(dāng)前上下文下執(zhí)行事務(wù)。

NewEVMTxContext

位于core\evm.go

func NewEVMTxContext(msg Message) vm.TxContext {
	return vm.TxContext{
		Origin:   msg.From(),
		GasPrice: new(big.Int).Set(msg.GasPrice()),
	}
}

根據(jù)事務(wù)信息建立虛擬機(jī)上下文信息。

Reset

位于core\vm\evm.go

// Reset resets the EVM with a new transaction context.Reset
// This is not threadsafe and should only be done very cautiously.
func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) {
	evm.TxContext = txCtx
	evm.StateDB = statedb
}

重設(shè)虛擬機(jī)事務(wù)上下文,要注意該函數(shù)并不是線程安全的。

ApplyMessage

// ApplyMessage computes the new state by applying the given message
// against the old state within the environment.
//
// ApplyMessage returns the bytes returned by any EVM execution (if it took place),
// the gas used (which includes gas refunds) and an error if it failed. An error always
// indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block.
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) (*ExecutionResult, error) {
	return NewStateTransition(evm, msg, gp).TransitionDb()
}

位于core\state_transition.go
該函數(shù)通過應(yīng)用給定消息來計(jì)算新的狀態(tài),返回EVM執(zhí)行后的返回字節(jié)和使用的gas,執(zhí)行失敗的話還會返回error。
首先調(diào)用NewStateTransition初始化一個(gè)事務(wù)狀態(tài)對象,然后調(diào)用對象中的TransitionDb來應(yīng)用當(dāng)前消息并轉(zhuǎn)移狀態(tài),最后返回evm的執(zhí)行結(jié)果。

NewStateTransition

// NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
	return &StateTransition{
		gp:        gp,
		evm:       evm,
		msg:       msg,
		gasPrice:  msg.GasPrice(),
		gasFeeCap: msg.GasFeeCap(),
		gasTipCap: msg.GasTipCap(),
		value:     msg.Value(),
		data:      msg.Data(),
		state:     evm.StateDB,
	}
}

位于core\state_transition.go
初始化并返回一個(gè)事務(wù)狀態(tài)對象。

TransitionDb

// TransitionDb will transition the state by applying the current message and
// returning the evm execution result with following fields.
//
// - used gas:
//      total gas used (including gas being refunded)
// - returndata:
//      the returned data from evm
// - concrete execution error:
//      various **EVM** error which aborts the execution,
//      e.g. ErrOutOfGas, ErrExecutionReverted
//
// However if any consensus issue encountered, return the error directly with
// nil evm execution result.
func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
	// First check this message satisfies all consensus rules before
	// applying the message. The rules include these clauses
	//
	// 1. the nonce of the message caller is correct
	// 2. caller has enough balance to cover transaction fee(gaslimit * gasprice)
	// 3. the amount of gas required is available in the block
	// 4. the purchased gas is enough to cover intrinsic usage
	// 5. there is no overflow when calculating intrinsic gas
	// 6. caller has enough balance to cover asset transfer for **topmost** call

	// Check clauses 1-3, buy gas if everything is correct
	if err := st.preCheck(); err != nil {
		return nil, err
	}
	msg := st.msg
	sender := vm.AccountRef(msg.From())
	homestead := st.evm.ChainConfig().IsHomestead(st.evm.Context.BlockNumber)
	istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.Context.BlockNumber)
	london := st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber)
	contractCreation := msg.To() == nil

	// Check clauses 4-5, subtract intrinsic gas if everything is correct
	gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, homestead, istanbul)
	if err != nil {
		return nil, err
	}
	if st.gas < gas {
		return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas)
	}
	st.gas -= gas

	// Check clause 6
	if msg.Value().Sign() > 0 && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) {
		return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex())
	}

	// Set up the initial access list.
	if rules := st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber); rules.IsBerlin {
		st.state.PrepareAccessList(msg.From(), msg.To(), vm.ActivePrecompiles(rules), msg.AccessList())
	}
	var (
		ret   []byte
		vmerr error // vm errors do not effect consensus and are therefore not assigned to err
	)
	if contractCreation {
		ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value)
	} else {
		// Increment the nonce for the next transaction
		st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
		ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value)
	}

	if !london {
		// Before EIP-3529: refunds were capped to gasUsed / 2
		st.refundGas(params.RefundQuotient)
	} else {
		// After EIP-3529: refunds are capped to gasUsed / 5
		st.refundGas(params.RefundQuotientEIP3529)
	}
	effectiveTip := st.gasPrice
	if london {
		effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
	}
	st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip))

	return &ExecutionResult{
		UsedGas:    st.gasUsed(),
		Err:        vmerr,
		ReturnData: ret,
	}, nil
}

位于core\state_transition.go
該函數(shù)用于應(yīng)用消息,轉(zhuǎn)移狀態(tài),返回的執(zhí)行結(jié)果中包括使用的gas,返回的evm數(shù)據(jù),和報(bào)錯(cuò)。
該函數(shù)首先檢查消息是否滿足共識機(jī)制的規(guī)則。檢查項(xiàng)包括

消息的nonce是否正確
調(diào)用者是否有足夠余額支付油費(fèi)
區(qū)塊中g(shù)as量(即gaspool)是否滿足該交易使用
購買的gas是否足夠內(nèi)部使用
計(jì)算內(nèi)部gas時(shí)是否有溢出
調(diào)用者有足夠的余額支付交易費(fèi)用

該函數(shù)首先調(diào)用preCheck函數(shù)來檢查前3條條款是否滿足。
然后根據(jù)msg.To是否為空判斷該交易是否為創(chuàng)建合約。

隨后調(diào)用IntrinsicGas檢查購買的gas量是否足夠覆蓋內(nèi)部數(shù)據(jù)。對其返回的gas值進(jìn)行比較,不足則報(bào)錯(cuò),否則則減去其對應(yīng)的量。

隨后首先判斷是否有交易金額,若有則調(diào)用CanTransfer來檢查調(diào)用者是否有足夠余額支付交易金額。

接下來查詢需要滿足的規(guī)則,若為Berlin版本,則需要考慮預(yù)編譯的accessList來減輕了 EIP-2929 引入的一些 gas 成本增加。(可深究)
(參考鏈接: Ethereum Berlin Upgrade Announcement)

因?yàn)橐蛱摂M機(jī)產(chǎn)生的錯(cuò)誤并不屬于共識層面,故這里引入一個(gè)變量vmerr用于表示虛擬機(jī)層面的錯(cuò)誤。

若該交易為創(chuàng)建合約,則調(diào)用Create函數(shù),不然則設(shè)置交易nonce加1,調(diào)用Call函數(shù)來執(zhí)行。

隨后根據(jù)不同版本,以及剩余gas量調(diào)用refundGas進(jìn)行退款。

接下來計(jì)算小費(fèi)的值,取min(gasTipCap,最大可支付單價(jià)和強(qiáng)制執(zhí)行的最小單價(jià)的差值)為小費(fèi)單價(jià)值。最后乘上gasUsed并得到小費(fèi)總值并加在結(jié)算給礦工金額的Coinbase中。

最后返回執(zhí)行結(jié)果,即花費(fèi)的gas量,虛擬機(jī)的報(bào)錯(cuò),和虛擬機(jī)返回?cái)?shù)據(jù)。

preCheck

func (st *StateTransition) preCheck() error {
	// Only check transactions that are not fake
	if !st.msg.IsFake() {
		// Make sure this transaction's nonce is correct.
		stNonce := st.state.GetNonce(st.msg.From())
		if msgNonce := st.msg.Nonce(); stNonce < msgNonce {
			return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
				st.msg.From().Hex(), msgNonce, stNonce)
		} else if stNonce > msgNonce {
			return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
				st.msg.From().Hex(), msgNonce, stNonce)
		} else if stNonce+1 < stNonce {
			return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax,
				st.msg.From().Hex(), stNonce)
		}
		// Make sure the sender is an EOA
		if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) {
			return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
				st.msg.From().Hex(), codeHash)
		}
	}
	// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
	if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
		// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
		if !st.evm.Config.NoBaseFee || st.gasFeeCap.BitLen() > 0 || st.gasTipCap.BitLen() > 0 {
			if l := st.gasFeeCap.BitLen(); l > 256 {
				return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
					st.msg.From().Hex(), l)
			}
			if l := st.gasTipCap.BitLen(); l > 256 {
				return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
					st.msg.From().Hex(), l)
			}
			if st.gasFeeCap.Cmp(st.gasTipCap) < 0 {
				return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
					st.msg.From().Hex(), st.gasTipCap, st.gasFeeCap)
			}
			// This will panic if baseFee is nil, but basefee presence is verified
			// as part of header validation.
			if st.gasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
				return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
					st.msg.From().Hex(), st.gasFeeCap, st.evm.Context.BaseFee)
			}
		}
	}
	return st.buyGas()
}

位于core\state_transition.go
該函數(shù)首先檢查交易是否為假,而在上一篇文章提到的AsMessage函數(shù)中已將IsFake設(shè)置為false。同時(shí)還會檢查交易的nonce值是否正確,倘若出錯(cuò),則根據(jù)錯(cuò)誤中的nonce大小報(bào)不同的錯(cuò)誤類型。通過判斷它的codeHash值是否為空,來檢查發(fā)起方是否為一個(gè)外部賬戶(EOA)。
同時(shí)若為倫敦分叉,則要求最大可支付給單價(jià)必須大于其要求強(qiáng)制執(zhí)行的最低費(fèi)用,同時(shí)判斷單價(jià)和小費(fèi)是否有溢出,以及小費(fèi)是否比單價(jià)還要大,根據(jù)這些錯(cuò)誤報(bào)告不同的錯(cuò)誤類型。
最后調(diào)用buyGas函數(shù)檢查gas值的一些要求,同時(shí)購買gas。

buyGas

func (st *StateTransition) buyGas() error {
	mgval := new(big.Int).SetUint64(st.msg.Gas())
	mgval = mgval.Mul(mgval, st.gasPrice)
	balanceCheck := mgval
	if st.gasFeeCap != nil {
		balanceCheck = new(big.Int).SetUint64(st.msg.Gas())
		balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
		balanceCheck.Add(balanceCheck, st.value)
	}
	if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
		return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
	}
	if err := st.gp.SubGas(st.msg.Gas()); err != nil {
		return err
	}
	st.gas += st.msg.Gas()

	st.initialGas = st.msg.Gas()
	st.state.SubBalance(st.msg.From(), mgval)
	return nil
}

位于core\state_transition.go
該函數(shù)檢查了發(fā)起者賬戶余額是否足夠支付最大單價(jià)下的油費(fèi)即(gasFeeCap*gas量),同時(shí)檢查區(qū)塊的gaspool是否有足夠gas支持本次交易。都滿足后則將交易狀態(tài)中的初始gas值設(shè)為當(dāng)前消息中的gas值,同時(shí)從發(fā)起者賬戶中扣除油費(fèi)(gasPrice * gas量)。
最后無錯(cuò)誤即返回nil值。

IntrinsicGas

// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028 bool) (uint64, error) {
	// Set the starting gas for the raw transaction
	var gas uint64
	if isContractCreation && isHomestead {
		gas = params.TxGasContractCreation
	} else {
		gas = params.TxGas
	}
	// Bump the required gas by the amount of transactional data
	if len(data) > 0 {
		// Zero and non-zero bytes are priced differently
		var nz uint64
		for _, byt := range data {
			if byt != 0 {
				nz++
			}
		}
		// Make sure we don't exceed uint64 for all data combinations
		nonZeroGas := params.TxDataNonZeroGasFrontier
		if isEIP2028 {
			nonZeroGas = params.TxDataNonZeroGasEIP2028
		}
		if (math.MaxUint64-gas)/nonZeroGas < nz {
			return 0, ErrGasUintOverflow
		}
		gas += nz * nonZeroGas

		z := uint64(len(data)) - nz
		if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
			return 0, ErrGasUintOverflow
		}
		gas += z * params.TxDataZeroGas
	}
	if accessList != nil {
		gas += uint64(len(accessList)) * params.TxAccessListAddressGas
		gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas
	}
	return gas, nil
}

位于core\state_transition.go
首先它先判斷交易是否為創(chuàng)建合約以及是否為“家園”硬分叉來計(jì)算該交易的基礎(chǔ)價(jià)格。
(鏈接: 家園硬分叉的介紹)
同時(shí)枚舉數(shù)據(jù)中的為零字節(jié)量和非零字節(jié)量并記錄,根據(jù)對應(yīng)版本,計(jì)算各自所需gas量。并在計(jì)算過程中考慮了gas累加可能導(dǎo)致的上溢問題。同時(shí)計(jì)算EVM 執(zhí)行過程中會觸及的賬戶和合約存儲位置的gas花費(fèi)。
最后返回所需gas值。(奇怪的是,對于accessList產(chǎn)生的gas量累加不需要檢查溢出嗎?)

CanTransfer

// CanTransfer checks whether there are enough funds in the address' account to make a transfer.
// This does not take the necessary gas in to account to make the transfer valid.
func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
	return db.GetBalance(addr).Cmp(amount) >= 0
}

位于core\evm.go
檢查用戶的余額是否足夠支付交易金額。

Rules

位于params\config.go

// Rules ensures c's ChainID is not nil.
func (c *ChainConfig) Rules(num *big.Int) Rules {
	chainID := c.ChainID
	if chainID == nil {
		chainID = new(big.Int)
	}
	return Rules{
		ChainID:          new(big.Int).Set(chainID),
		IsHomestead:      c.IsHomestead(num),
		IsEIP150:         c.IsEIP150(num),
		IsEIP155:         c.IsEIP155(num),
		IsEIP158:         c.IsEIP158(num),
		IsByzantium:      c.IsByzantium(num),
		IsConstantinople: c.IsConstantinople(num),
		IsPetersburg:     c.IsPetersburg(num),
		IsIstanbul:       c.IsIstanbul(num),
		IsBerlin:         c.IsBerlin(num),
		IsLondon:         c.IsLondon(num),
	}
}

根據(jù)區(qū)塊號查詢并返回當(dāng)前需滿足的規(guī)則。

refundGas

func (st *StateTransition) refundGas(refundQuotient uint64) {
	// Apply refund counter, capped to a refund quotient
	refund := st.gasUsed() / refundQuotient
	if refund > st.state.GetRefund() {
		refund = st.state.GetRefund()
	}
	st.gas += refund

	// Return ETH for remaining gas, exchanged at the original rate.
	remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
	st.state.AddBalance(st.msg.From(), remaining)

	// Also return remaining gas to the block gas counter so it is
	// available for the next transaction.
	st.gp.AddGas(st.gas)
}

位于core\state_transition.go
根據(jù)不同版本,計(jì)算最大可退款gas數(shù),和當(dāng)前剩余量進(jìn)行比較,取最小值。
將當(dāng)前狀態(tài)的gas量加上該值,并根據(jù)當(dāng)前狀態(tài)的gas量計(jì)算需要退給調(diào)用者的eth,同時(shí)將區(qū)塊的gaspool里加上當(dāng)前狀態(tài)剩余gas量。文章來源地址http://www.zghlxwxcb.cn/news/detail-424859.html

到了這里,關(guān)于以太坊go-ethereum源碼研讀(二)applyTransaction相關(guān)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【區(qū)塊鏈 | 智能合約】Ethereum源代碼(2)- go-ethereum 客戶端入口代碼和Node分析

    上篇提到用 make geth 來編譯geth客戶端。我們來看看make file做了什么: 執(zhí)行了 ci.go 里面做了兩件事情 1,ln -s命令在build/_workspace/ 目錄上生成了go-etherum的一個(gè)文件鏡像,不占用磁盤空間,與源文件同步更新 2

    2024年02月03日
    瀏覽(29)
  • 【區(qū)塊鏈 | 智能合約】Ethereum源代碼(10)- 以太坊Downloader源碼分析

    上一節(jié)分析到Fetcher用于同步網(wǎng)絡(luò)節(jié)點(diǎn)的新區(qū)塊和新的交易數(shù)據(jù),如果新區(qū)塊和本地最新的區(qū)塊相隔距離較遠(yuǎn),說明本地區(qū)塊數(shù)據(jù)太舊,F(xiàn)etcher就不會同步這些區(qū)塊。這時(shí)候就要借助Downloader來同步完整的區(qū)塊數(shù)據(jù)。 一,啟動(dòng)Downloader handler 初始化的時(shí)候會進(jìn)行Downloader的初始化:

    2024年02月15日
    瀏覽(25)
  • 【區(qū)塊鏈 | 智能合約】Ethereum源代碼(8)- Ethereum服務(wù)和以太坊P2P協(xié)議發(fā)送廣播源碼分析

    【區(qū)塊鏈 | 智能合約】Ethereum源代碼(8)- Ethereum服務(wù)和以太坊P2P協(xié)議發(fā)送廣播源碼分析

    在“【區(qū)塊鏈 | 智能合約】Ethereum源代碼(2)- go-ethereum 客戶端入口代碼和Node分析”一文中,我們提到Ethereum作為一個(gè)service,被Node 注冊進(jìn)去。Node start的時(shí)候會啟動(dòng)其注冊的所有服務(wù),Ethereum service也是一樣。 初始化方法

    2024年01月21日
    瀏覽(41)
  • 【區(qū)塊鏈 | 智能合約】Ethereum源代碼(11)- 以太坊核心BlockChain源碼分析

    前面幾節(jié)都在分析以太坊的通信協(xié)議,怎么廣播,怎么同步,怎么下載。這一節(jié)講講以太坊的核心模塊BlockChain,也就是以太坊的區(qū)塊鏈。 一,BlockChain的初始化 Ethereum服務(wù)初始化func init() 的時(shí)候會調(diào)用core.SetupGenesisBlock來加載創(chuàng)始區(qū)塊。顧名思義,創(chuàng)始區(qū)塊就是以太坊區(qū)塊鏈中

    2024年02月08日
    瀏覽(44)
  • Go Ethereum源碼學(xué)習(xí)筆記000

    這個(gè)專欄的內(nèi)容是免費(fèi)的,因?yàn)樽约哼@邊都是基于開源庫和開源內(nèi)容整理的學(xué)習(xí)筆記,在這個(gè)過程中進(jìn)行增刪改查,將自己的理解融入其中,所以這里用開源的精神分享給大家:Free software, free knowledge。當(dāng)然,開源精神和軟件付費(fèi)/知識付費(fèi)并不沖突,而是求同存異。大家覺

    2024年02月14日
    瀏覽(23)
  • Go Ethereum源碼學(xué)習(xí)筆記 001 Geth Start

    Go Ethereum源碼學(xué)習(xí)筆記 001 Geth Start

    首先讀者需要具備Go語言基礎(chǔ),至少要通關(guān)菜鳥教程,知道Go語言的基本語法,這些基礎(chǔ)教程網(wǎng)絡(luò)上非常多,請大家自行學(xué)習(xí)。 具備語言基礎(chǔ)了,還需要在開始這一章之前做一些準(zhǔn)備工作: 安裝Go SDK,即Go語言的開發(fā)環(huán)境; 安裝GoLand,即Go語言的IDE,當(dāng)然也可以選擇VSCode等其

    2024年02月14日
    瀏覽(20)
  • Ethereum以太坊事件日志查詢參數(shù)

    Ethereum以太坊事件日志查詢參數(shù)

    詳見:https://www.quicknode.com/docs/ethereum/eth_getLogs address:合約地址 fromBlock:開始區(qū)塊 toBlock:結(jié)束區(qū)塊 topics:主題數(shù)組 blockHash:區(qū)塊哈希,優(yōu)先級高于fromBlock、toBlock 這里主要介紹topics參數(shù),其他參數(shù)都比較好理解,topics是長度為4的數(shù)組集合,topic分為2種:一種事件簽名topic,

    2024年02月07日
    瀏覽(19)
  • 118 以太坊 ethereum hardhat :編譯 artifacts

    ? 介紹 ? 構(gòu)建信息文件 ? 讀取artifacts ? 目錄結(jié)構(gòu) ? hardhat Tutorials , hardhat 教程 ? Contact 聯(lián)系方式 使用 Hardhat 編譯會為每個(gè)編譯的合約生成兩個(gè)文件(不是每個(gè) .sol 文件):一個(gè)工件和一個(gè)調(diào)試文件。 artifact 擁有部署和與合約交互所需的所有信息。這些與大多數(shù)工具兼容

    2023年04月08日
    瀏覽(19)
  • 什么是Ethereum以太坊(ETH)?以及以太坊的一些基礎(chǔ)知識

    什么是Ethereum以太坊(ETH)?以及以太坊的一些基礎(chǔ)知識

    Ethereum以太坊(ETH)是由Vitalik Buterin所創(chuàng)建,一種允許智能合約和去中心化應(yīng)用程序(dapps)在其網(wǎng)絡(luò)上運(yùn)行的加密貨幣。 以太坊是僅次于比特幣的第二大加密貨幣,它是一個(gè)基于區(qū)塊鏈的平臺,用于創(chuàng)建去中心化應(yīng)用程序(dapps)。 比特幣被設(shè)計(jì)成一種貨幣和價(jià)值儲存手段,而

    2024年02月03日
    瀏覽(22)
  • 11U 以太坊 ethereum OpenZeppelin : 升級智能合約

    ? 升級中有什么 ? 使用升級插件升級 ? 升級如何運(yùn)作 ? 初始化 ? 升級 ? 測試 ? OpenZeppelin Tutorials 教程 ? Contact 聯(lián)系方式 使用OpenZeppelin 升級插件部署的智能合約可以升級以修改其代碼,同時(shí)保留其地址、狀態(tài)和余額。這使您可以迭代地向項(xiàng)目添加新功能,或修復(fù)您在

    2023年04月08日
    瀏覽(33)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包