兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析Word下载.docx
《兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析Word下载.docx》由会员分享,可在线阅读,更多相关《兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析Word下载.docx(41页珍藏版)》请在冰豆网上搜索。
=eth.New(ctx,cfg)
iffullNode!
=nil&
&
cfg.LightServ>
0{
ls,_:
=les.NewLesServer(fullNode,cfg)
fullNode.AddLesServer(ls)
returnfullNode,err
iferr!
=nil{
Fatalf("
FailedtoregistertheEthereumservice:
%v"
err)
以太坊协议的数据结构
//EthereumimplementstheEthereumfullnodeservice.
typeEthereumstruct{
config*Config
配置
chainConfig*params.ChainConfig
链配置
//Channelforshuttingdowntheservice
shutdownChanchanbool//Channelforshuttingdowntheethereum
stopDbUpgradefunc()error//stopchaindbsequentialkeyupgrade
//Handlers
txPool*core.TxPool
交易池
blockchain*core.BlockChain
区块链
protocolManager*ProtocolManager
协议管理
lesServerLesServer
轻量级客户端服务器
//DBinterfaces
chainDbethdb.Database//Blockchaindatabase
区块链数据库
eventMux*event.TypeMux
engineconsensus.Engine
一致性引擎。
应该是Pow部分
accountManager*accounts.Manager
账号管理
bloomRequestschanchan*bloombits.Retrieval//Channelreceivingbloomdataretrievalrequests
接收bloom过滤器数据请求的通道
bloomIndexer*core.ChainIndexer//Bloomindexeroperatingduringblockimports//在区块import的时候执行Bloomindexer操作暂时不清楚是什么
ApiBackend*EthApiBackend
//提供给RPC服务使用的API后端
miner*miner.Miner
//矿工
gasPrice*big.Int
//节点接收的gasPrice的最小值。
比这个值更小的交易会被本节点拒绝
etherbasecommon.Address
//矿工地址
networkIduint64
//网络IDtestnet是0mainnet是1
netRPCService*ethapi.PublicNetAPI
//RPC的服务
locksync.RWMutex//Protectsthevariadicfields(e.g.gaspriceandetherbase)
以太坊协议的创建New.暂时先不涉及core的内容。
只是大概介绍一下。
core里面的内容后续会分析。
//NewcreatesanewEthereumobject(includingthe
//initialisationofthecommonEthereumobject)
funcNew(ctx*node.ServiceContext,config*Config)(*Ethereum,error){
ifconfig.SyncMode==downloader.LightSync{
returnnil,errors.New("
can'
truneth.Ethereuminlightsyncmode,useles.LightEthereum"
)
if!
config.SyncMode.IsValid(){
returnnil,fmt.Errorf("
invalidsyncmode%d"
config.SyncMode)
//创建leveldb。
打开或者新建chaindata目录
chainDb,err:
=CreateDB(ctx,config,"
chaindata"
returnnil,err
//数据库格式升级
stopDbUpgrade:
=upgradeDeduplicateData(chainDb)
//设置创世区块。
如果数据库里面已经有创世区块那么从数据库里面取出(私链)。
或者是从代码里面获取默认值。
chainConfig,genesisHash,genesisErr:
=core.SetupGenesisBlock(chainDb,config.Genesis)
if_,ok:
=genesisErr.(*params.ConfigCompatError);
genesisErr!
!
ok{
returnnil,genesisErr
log.Info("
Initialisedchainconfiguration"
"
config"
chainConfig)
eth:
=&
Ethereum{
config:
config,
chainDb:
chainDb,
chainConfig:
chainConfig,
eventMux:
ctx.EventMux,
accountManager:
ctx.AccountManager,
engine:
CreateConsensusEngine(ctx,config,chainConfig,chainDb),//一致性引擎。
这里我理解是Pow
shutdownChan:
make(chanbool),
stopDbUpgrade:
stopDbUpgrade,
networkId:
config.NetworkId,//网络ID用来区别网路。
测试网络是0.主网是1
gasPrice:
config.GasPrice,//可以通过配置--gasprice客户端接纳的交易的gasprice最小值。
如果小于这个值那么会被节点丢弃。
etherbase:
config.Etherbase,//挖矿的受益者
bloomRequests:
make(chanchan*bloombits.Retrieval),//bloom的请求
bloomIndexer:
NewBloomIndexer(chainDb,params.BloomBitsBlocks),
InitialisingEthereumprotocol"
versions"
ProtocolVersions,"
network"
config.NetworkId)
config.SkipBcVersionCheck{//检查数据库里面存储的BlockChainVersion和客户端的BlockChainVersion的版本是否一致
bcVersion:
=core.GetBlockChainVersion(chainDb)
ifbcVersion!
=core.BlockChainVersion&
bcVersion!
=0{
BlockchainDBversionmismatch(%d/%d).Rungethupgradedb.\n"
bcVersion,core.BlockChainVersion)
core.WriteBlockChainVersion(chainDb,core.BlockChainVersion)
vmConfig:
=vm.Config{EnablePreimageRecording:
config.EnablePreimageRecording}
//使用数据库创建了区块链
eth.blockchain,err=core.NewBlockChain(chainDb,eth.chainConfig,eth.engine,vmConfig)
//Rewindthechainincaseofanincompatibleconfigupgrade.
ifcompat,ok:
ok{
log.Warn("
Rewindingchaintoupgradeconfiguration"
err"
compat)
eth.blockchain.SetHead(compat.RewindTo)
core.WriteChainConfig(chainDb,genesisHash,chainConfig)
//bloomIndexer暂时不知道是什么东西这里面涉及得也不是很多。
暂时先不管了
eth.bloomIndexer.Start(eth.blockchain.CurrentHeader(),eth.blockchain.SubscribeChainEvent)
ifconfig.TxPool.Journal!
="
"
{
config.TxPool.Journal=ctx.ResolvePath(config.TxPool.Journal)
//创建交易池。
用来存储本地或者在网络上接收到的交易。
eth.txPool=core.NewTxPool(config.TxPool,eth.chainConfig,eth.blockchain)
//创建协议管理器
ifeth.protocolManager,err=NewProtocolManager(eth.chainConfig,config.SyncMode,config.NetworkId,eth.eventMux,eth.txPool,eth.engine,eth.blockchain,chainDb);
err!
//创建矿工
eth.miner=miner.New(eth,eth.chainConfig,eth.EventMux(),eth.engine)
eth.miner.SetExtra(makeExtraData(config.ExtraData))
//ApiBackend用于给RPC调用提供后端支持
eth.ApiBackend=&
EthApiBackend{eth,nil}
//gpoParamsGPOGasPriceOracle的缩写。
GasPrice预测。
通过最近的交易来预测当前的GasPrice的值。
这个值可以作为之后发送交易的费用的参考。
gpoParams:
=config.GPO
ifgpoParams.Default==nil{
gpoParams.Default=config.GasPrice
eth.ApiBackend.gpo=gasprice.NewOracle(eth.ApiBackend,gpoParams)
returneth,nil
ApiBackend定义在api_backend.go文件中。
封装了一些函数。
//EthApiBackendimplementsethapi.Backendforfullnodes
typeEthApiBackendstruct{
eth*Ethereum
gpo*gasprice.Oracle
func(b*EthApiBackend)SetHead(numberuint64){
b.eth.protocolManager.downloader.Cancel()
b.eth.blockchain.SetHead(number)
New方法中除了core中的一些方法,有一个ProtocolManager的对象在以太坊协议中比较重要,以太坊本来是一个协议。
ProtocolManager中又可以管理多个以太坊的子协议。
//NewProtocolManagerreturnsanewethereumsubprotocolmanager.TheEthereumsubprotocolmanagespeerscapable
//withtheethereumnetwork.
funcNewProtocolManager(config*params.ChainConfig,modedownloader.SyncMode,networkIduint64,mux*event.TypeMux,txpooltxPool,engineconsensus.Engine,blockchain*core.BlockChain,chaindbethdb.Database)(*ProtocolManager,error){
//Createtheprotocolmanagerwiththebasefields
manager:
ProtocolManager{
networkId,
mux,
txpool:
txpool,
blockchain:
blockchain,
chaindb:
chaindb,
chainconfig:
peers:
newPeerSet(),
newPeerCh:
make(chan*peer),
noMorePeers:
make(chanstruct{}),
txsyncCh:
make(chan*txsync),
quitSync:
//Figureoutwhethertoallowfastsyncornot
ifmode==downloader.FastSync&
blockchain.CurrentBlock().NumberU64()>
Blockchainnotempty,fastsyncdisabled"
mode=downloader.FullSync
ifmode==downloader.FastSync{
manager.fastSync=uint32
(1)
//Initiateasub-protocolforeveryimplementedversionwecanhandle
manager.SubProtocols=make([]p2p.Protocol,0,len(ProtocolVersions))
fori,version:
=rangeProtocolVersions{
//Skipprotocolversionifincompatiblewiththemodeofoperation
version<
eth63{
continue
//Compatible;
initialisethesub-protocol
version:
=version//Closurefortherun
manager.SubProtocols=ap