兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析.docx
- 文档编号:4839284
- 上传时间:2022-12-10
- 格式:DOCX
- 页数:41
- 大小:34.61KB
兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析.docx
《兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析.docx》由会员分享,可在线阅读,更多相关《兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析.docx(41页珍藏版)》请在冰豆网上搜索。
兄弟连Go语言+区块链技术培训以太坊源码分析37eth以太坊协议分析
兄弟连Go语言+区块链技术培训以太坊源码分析(37)eth以太坊协议分析
node中的服务的定义,eth其实就是实现了一个服务。
typeServiceinterface{
//ProtocolsretrievestheP2Pprotocolstheservicewishestostart.
Protocols()[]p2p.Protocol
//APIsretrievesthelistofRPCdescriptorstheserviceprovides
APIs()[]rpc.API
//Startiscalledafterallserviceshavebeenconstructedandthenetworking
//layerwasalsoinitializedtospawnanygoroutinesrequiredbytheservice.
Start(server*p2p.Server)error
//Stopterminatesallgoroutinesbelongingtotheservice,blockinguntilthey
//areallterminated.
Stop()error
}
goethereum的eth目录是以太坊服务的实现。
以太坊协议是通过node的Register方法注入的。
//RegisterEthServiceaddsanEthereumclienttothestack.
funcRegisterEthService(stack*node.Node,cfg*eth.Config){
varerrerror
ifcfg.SyncMode==downloader.LightSync{
err=stack.Register(func(ctx*node.ServiceContext)(node.Service,error){
returnles.New(ctx,cfg)
})
}else{
err=stack.Register(func(ctx*node.ServiceContext)(node.Service,error){
fullNode,err:
=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")
iferr!
=nil{
returnnil,err
}
//数据库格式升级
stopDbUpgrade:
=upgradeDeduplicateData(chainDb)
//设置创世区块。
如果数据库里面已经有创世区块那么从数据库里面取出(私链)。
或者是从代码里面获取默认值。
chainConfig,genesisHash,genesisErr:
=core.SetupGenesisBlock(chainDb,config.Genesis)
if_,ok:
=genesisErr.(*params.ConfigCompatError);genesisErr!
=nil&&!
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),
}
log.Info("InitialisingEthereumprotocol","versions",ProtocolVersions,"network",config.NetworkId)
if!
config.SkipBcVersionCheck{//检查数据库里面存储的BlockChainVersion和客户端的BlockChainVersion的版本是否一致
bcVersion:
=core.GetBlockChainVersion(chainDb)
ifbcVersion!
=core.BlockChainVersion&&bcVersion!
=0{
returnnil,fmt.Errorf("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)
iferr!
=nil{
returnnil,err
}
//Rewindthechainincaseofanincompatibleconfigupgrade.
ifcompat,ok:
=genesisErr.(*params.ConfigCompatError);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!
=nil{
returnnil,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:
networkId,
eventMux:
mux,
txpool:
txpool,
blockchain:
blockchain,
chaindb:
chaindb,
chainconfig:
config,
peers:
newPeerSet(),
newPeerCh:
make(chan*peer),
noMorePeers:
make(chanstruct{}),
txsyncCh:
make(chan*txsync),
quitSync:
make(chanstruct{}),
}
//Figureoutwhethertoallowfastsyncornot
ifmode==downloader.FastSync&&blockchain.CurrentBlock().NumberU64()>0{
log.Warn("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
ifmode==downloader.FastSync&&version continue } //Compatible;initialisethesub-protocol version: =version//Closurefortherun manager.SubProtocols=ap
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 兄弟连 Go 语言 区块 技术培训 以太 源码 分析 37 eth 协议