tokenpocket官方下载中文版|以太坊挖矿重启

作者: tokenpocket官方下载中文版
2024-03-16 17:51:11

启动挖矿 :: 以太坊技术与实现

:: 以太坊技术与实现以太坊技术与实现前言开始以太坊术语第一章. 基础数据结构配置创世块账户交易区块交易回执Gas第二章. 挖矿核心交易池架构设计交易存储交易入队列内存限制挖矿架构启动挖矿挖矿信号挖矿流程叔块挖矿奖励区块存储共识算法代码结构Ethash基础Ethash算法实现第三章. 底层核心技术签名与校验MPTStateDBRLPEVM第四章. 功能集第五章. 区块同步第六章. 漏洞分析TheDao第七章. Dapp开发存储布局More Github 源码 深入浅出区块链 文章标签Star Fork作者:虞双齐| 主题:learn 我要编辑 > 挖矿核心 > 以太坊挖矿逻辑 > 启动挖矿挖矿参数实例化Miner启动挖矿参数方式自动开启挖矿控制台命令启动挖矿RPC API 启动挖矿挖矿启动细节Worker Start 信号启动挖矿挖矿模块只通过 Miner 实例对外提供数据访问。可以通过多种途径开启挖矿服务。程序运行时已经将 Miner 实例化,并进入等待挖矿状态,随时可以启动挖矿。挖矿参数矿工可以根据矿机的服务器性能,来定制化挖矿参数。下面是一份 geth 关于挖矿的运行时参数清单,全部定义在 cmd/utils/flags.go 文件中。参数默认值用途–minefalse是否自动开启挖矿–miner.threads0挖矿时可用并行PoW计算的协程(轻量级线程)数。兼容过时参数 —minerthreads。–miner.notify空挖出新块时用于通知远程服务的任意数量的远程服务地址。是用 ,分割的多个远程服务器地址。如:”http://api.miner.com,http://api2.miner.com“–miner.noverifyfalse是否禁用区块的PoW工作量校验。–miner.gasprice1000000000 wei矿工可接受的交易Gas价格,低于此GasPrice的交易将被拒绝写入交易池和不会被矿工打包到区块。–miner.gastarget8000000 gas动态计算新区块燃料上限(gaslimit)的下限值。兼容过时参数 —targetgaslimit。–miner.gaslimit8000000 gas动态技术新区块燃料上限的上限值。–miner.etherbase第一个账户用于接收挖矿奖励的账户地址,默认是本地钱包中的第一个账户地址。–miner.extradatageth版本号允许矿工自定义写入区块头的额外数据。–miner.recommit3s重新开始挖掘新区块的时间间隔。将自动放弃进行中的挖矿后,重新开始一次新区块挖矿。–minerthreads已过时—targetgaslimit已过时–gasprice已过时你可以通过执行程序 dgeth1 来查看参数。dgeth -h |grep "mine"

实例化Minergeth 程序运行时已经将 Miner 实例化,只需等待命令开启挖矿。//eth/backend.go:197

eth.miner = miner.New(eth, chainConfig, eth.EventMux(),

eth.engine, config.MinerRecommit,

config.MinerGasFloor, config.MinerGasCeil, eth.isLocalBlock)

eth.miner.SetExtra(makeExtraData(config.MinerExtraData))从上可看出,在实例化 miner 时所用到的配置项只有4项。实例化后,便可通过 API 操作 Miner。Miner API 分 public 和 private。挖矿属于隐私,不得让其他人任意修改。因此挖矿API全部定义在 Private 中,公共部分只有 Mining()。启动挖矿geth 运行时默认不开启挖矿。如果用户需要启动挖矿,则可以通过以下几种方式启动挖矿。参数方式自动开启挖矿使用参数 —mine,可以在启动程序时默认开启挖矿。下面我们用 dgeth1 在开发者模式启动挖矿为例:dgeth --dev --mine启动后,可以看到默认情况下已开启挖矿。开发者模式下已经挖出了一个高度为1的空块。![image-20190722215758989(https://img.learnblockchain.cn/book_geth/image-20190722215758989.png!de)当参数加入了--mine参数表示启用挖矿,此时将根据输入个各项挖矿相关的参数启动挖矿服务。// cmd/geth/main.go:369

if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { //❶

// Mining only makes sense if a full Ethereum node is running

if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {

utils.Fatalf("Light clients do not support mining")

}

var ethereum *eth.Ethereum

if err := stack.Service(ðereum); err != nil {

utils.Fatalf("Ethereum service not running: %v", err)

}

// Set the gas price to the limits from the CLI and start mining

gasprice := utils.GlobalBig(ctx, utils.MinerLegacyGasPriceFlag.Name)//❷

if ctx.IsSet(utils.MinerGasPriceFlag.Name) {

gasprice = utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)

}

ethereum.TxPool().SetGasPrice(gasprice)

threads := ctx.GlobalInt(utils.MinerLegacyThreadsFlag.Name)//❸

if ctx.GlobalIsSet(utils.MinerThreadsFlag.Name) {

threads = ctx.GlobalInt(utils.MinerThreadsFlag.Name)

}

if err := ethereum.StartMining(threads); err != nil {//❹

utils.Fatalf("Failed to start mining: %v", err)

}

}启动 geth 过程是,如果启用挖矿--mine或者属于开发者模式—dev,则将启动挖矿❶。在启动挖矿之前,还需要获取 —miner.gasprice 实时应用到交易池中❷。同时也需要指定将允许使用多少协程来并行参与PoW计算❸。然后开启挖矿,如果开启挖矿失败则终止程序运行并打印错误信息❹。控制台命令启动挖矿在实例化Miner后,已经将 miner 的操作API化。因此我们可以在 geth 的控制台中输入Start命令启动挖矿。调用API miner_start 将使用给定的挖矿计算线程数来开启挖矿。下面表格是调用 API 的几种方式。客户端调用方式Gominer.Start(threads *rpc.HexNumber) (bool, error)Consoleminer.start(number)RPC{"method": "miner_start", "params": [number]}首先,我们进入 geth 的 JavaScript 控制台,后输入命令miner.start(1)来启动挖矿。dgeth --maxpeers=0 console启动挖矿后,将开始出新区块。RPC API 启动挖矿因为 API 已支持开启挖矿,如上文所述,可以直接调用 RPC {"method": "miner_start", "params": [number]} 来启动挖矿。实际上在控制台所执行的 miner.start(1),则相对于 {"method": "miner_start", "params": [1]}。如,启动 geth 时开启RPC。dgeth --maxpeer 0 --rpc --rpcapi --rpcport 8080 "miner,admin,eth" console开启后,则可以直接调用API,开启挖矿服务。curl -d '{"id":1,"method": "miner_start", "params": [1]}' http://127.0.0.1:8080挖矿启动细节不管何种方式启动挖矿,最终通过调用 miner 对象的 Start 方法来启动挖矿。不过在开启挖矿前,geth 还处理了额外内容。当你通过控制台或者 RPC API 调用启动挖矿命令后,在程序都将引导到方法func (s *Ethereum) StartMining(threads int) error。// eth/backend.go:414

type threaded interface {

SetThreads(threads int)

}

if th, ok := s.engine.(threaded); ok {//❶

log.Info("Updated mining threads", "threads", threads)

if threads == 0 {

threads = -1 // Disable the miner from within

}

th.SetThreads(threads)//❷

}

if !s.IsMining() { //❸

//...

price := s.gasPrice

s.txPool.SetGasPrice(price) //❹

eb, err := s.Etherbase() //❺

if err != nil {

log.Error("Cannot start mining without etherbase", "err", err)

return fmt.Errorf("etherbase missing: %v", err)

}

if clique, ok := s.engine.(*clique.Clique); ok {

wallet, err := s.accountManager.Find(accounts.Account{Address: eb})//❻

if wallet == nil || err != nil {

log.Error("Etherbase account unavailable locally", "err", err)

return fmt.Errorf("signer missing: %v", err)

}

clique.Authorize(eb, wallet.SignData)//❼

}

atomic.StoreUint32(&s.protocolManager.acceptTxs, 1)//❽

go s.miner.Start(eb)//❾

}

return nil在此方法中,首先看挖矿的共识引擎是否支持设置协程数❶,如果支持,将更新此共识引擎参数 ❷。接着,如果已经是在挖矿中,则忽略启动,否则将开启挖矿 ❸。在启动前,需要确定两项配置:交易GasPrice下限❹,和挖矿奖励接收账户(矿工账户地址)❺。这里对于 clique.Clique 共识引擎(PoA 权限共识),进行了特殊处理,需要从钱包中查找对于挖矿账户❻。在进行挖矿时不再是进行PoW计算,而是使用认可的账户进行区块签名❼即可。可能由于一些原因,不允许接收网络交易。因此,在挖矿前将允许接收网络交易❽。随即,开始在挖矿账户下开启挖矿❾。此时,已经进入了miner实例的 Start 方法。// miner/miner.go:108

func (self *Miner) Start(coinbase common.Address) {

atomic.StoreInt32(&self.shouldStart, 1)

self.SetEtherbase(coinbase) //⑩

if atomic.LoadInt32(&self.canStart) == 0 { //⑪

log.Info("Network syncing, will start miner afterwards")

return

}

self.worker.start()

}

// miner/worker.go:268

func (w *worker) start() { //⑬

atomic.StoreInt32(&w.running, 1)

w.startCh <- struct{}{}

}存储coinbase 账户后⑩,有可能因为正在同步数据,此时将不允许启动挖矿⑪。如果能够启动挖矿,则立即开启worker 让其开始干活。只需要发送一个开启挖矿信号,worker 将会被自动触发挖矿工作。Worker Start 信号对 worker 发送 start 信号后,该信号将进入 startCh chain中。一旦获得信号,则立即重新开始commit新区块,重新开始干活。//miner/worker.go:342

for {

select {

case <-w.startCh:

clearPending(w.chain.CurrentBlock().NumberU64())

timestamp = time.Now().Unix()

commit(false, commitInterruptNewHead)

//...

}

}dgeth 是本电子书书写期初指导大家所编译的一个 geth 程序。具体见《开始》 [return]hi ,我录制了《说透以太坊技术》的视频课程,快快上

新手挖eth指南 - 知乎

新手挖eth指南 - 知乎切换模式写文章登录/注册新手挖eth指南区块链布道者区块链信仰者,未来互联网的风口将会是在区块链一:挖矿准备工作1、硬件平台既然是用PC挖矿,一套完整的PC平台是必不可少的,ETH挖矿对CPU、内存要求不高,需要注意的是显卡、主板、电源这些,其中显卡事关挖矿能力,是关键性的组件。显卡挖矿可以选AMD显卡或者NVIDIA显卡,不过建议选AMD显卡,具体的推荐下面会再单独说下。主板芯片组对挖矿没有影响,但是不建议选太低端的主板,稳定性及PCI-E插槽数量都有可能存在问题。挖矿显卡对PCI-E带宽要求不高,基本的PC-E x1都可以,所以要想上更多显卡,多PCI-E扩展插槽的主板是首选,华擎、映泰甚至有专为挖矿而生的主板。如果X16、X8插槽太少,可以考虑购买转接线、延长线使用PCI-E x1插槽,这些小东西淘宝都有售,可以自行搜索。由于挖矿需要长期运行,电源也需要好一点,尽量选择大品牌的高瓦数电源,具体要看显卡的数量及型号,建议500W-1000W的金牌电源。内存、硬盘等元件影响不大,建议4GB及以上内存、120 SSD及以上SSD,这样系统流畅性也有保证。2、挖矿显卡推荐前面说了PC挖矿的核心是GPU显卡,选择什么显卡型号及数量决定了硬件投入成本,也觉得了挖矿能力,也就是最终的收益。目前显卡挖矿可以用NVIDIA显卡,也可以用AMD显卡,N卡可以考虑GTX 1060、GTX 960、GTX 950、GTX 750 Ti等型号,高端卡不建议,而综合最好的还是AMD显卡,HASH计算能力更强。AMD显卡可选型号非常多,几年前比特币挖矿时流行的R9 280X/280到现在依然可选,但性能最强的是HD 7990、R9 295 X2等高端卡,不过这些显卡目前不易购买,优先考虑R9 280X/280、R9 390、R9 380X/380、RX 480/470等显卡。此外,显存容量最好高于2GB,2GB显存的也容易出问题。如果不太确定显卡的挖矿能力,网上已经有很多矿卡算力排行榜榜,可以参考这个排名。3、系统、驱动及软件装完硬件平台之后,就要考虑系统和软件了。GPU挖矿可以在Windows及Linux系统下运行,对大部分人来说首推还是Windows,推荐Windows 7系统,熟悉Linux系统的可以考虑用Linux系统。驱动程序可以去AMD、Intel、NVIDIA等官网上下载,也可以去主板厂商对应的主板支持页面下载,嫌麻烦的也可以通过驱动精灵、驱动人生及360硬件大师等第三方程序一件更新、安装驱动。不过显卡驱动不一定是越新越好,因为要涉及到挖矿软件的支持、优化问题,AMD显卡推荐催化剂15.12驱动甚至15.11驱动,更旧的显卡可以使用14.x驱动,前提是确保正确识别显卡,保证显卡稳定运行。除了必备软件之外,建议还要准备一些FQ软件,因为下载、安装挖矿软件、钱包有可能需要科学上网。二:以太币钱包及交易所跟比特币类似,以太币挖矿也需要电子钱包或者交易所获得钱包地址,这样才能看到你的收益。钱包的选择有图形客户端的MIST及命令行客户端的Geth,可以从https://github.com/ethereum/mist/releases及https://github.com/ethereum/go-ethereum/releases/两个页面下载钱包,不过对新手玩家来说,钱包使用有些复杂,建议去交易网站注册帐号,国内推荐云币网https://yunbi.com/,国外推荐https://poloniex.com/网站,按照提示注册生产充值地址。三:挖矿需要的程序GPU挖以太币有多种软件,有些矿池还提供了一键运行的挖矿软件,不过最常用最效率的还是ethminer,网上有很多网盘分流下载地址,不放心的可以去https://github.com/Genoil/cpp-ethereum/blob/master/releases/ethminer-0.9.41-genoil-1.1.7.zip下载最新的Windows客户端。除了挖矿软件本体之外,可能还要使用Stratum Proxy,这是一种代理软件,可以减少网络丢包、降低延迟,而且还还能降低拒绝率,提升收益。具体用不用取决于网络和需求,使用的话一个局域网只要运行一个Stratum Proxy软件就可以了。目前使用比较多的是eth-proxy Windows版,可以去https://github.com/Atrides/eth-proxy/releases下载。四:挖矿软件使用教程下载ethminer和代理软件之后,解压到非中文目录下,首先找到eth-proxy软件里的eth-proxy.conf文件,设置钱包地址和邮箱,然后运行eth-proxy程序检测能否正确连接到矿池。设置代理配置设置完代理就要设置ethminer,需要注意的是下载的原始版本ethminer程序是没有.bat脚本的,可以下载网上的设置好的脚本,Miniergate上提供了不同的CPU、GPU配置脚本,下载对应平台、对应显卡的脚本,然后修改自己的邮箱地址就可以了。当然,自己新建bat脚本文件,填写对应的配置信息也是一样的,不过这个对新手来说有一点难度。编辑ethminer配置文件,生成脚本运行程序ethminer软件的脚本设置是比较麻烦的一步,上面说的是比较原始的过程,大家可以尝试下。如果依然对此感觉难以上手,国内很多网站或者论坛都提供了打包好的程序和脚本,下载之后只要修改自己的钱包和邮箱就可以了,有关这点大家可以自行搜索。之后就可以正式运行了解决完以上步骤之后就可以启动脚本运行了,如果一切正常的话就会开始自动挖矿了,运行一段时间后可以去矿池查看自己的收益了。以上介绍的只是ETH比特币挖矿的简单过程,挖矿涉及的内容很广,这部分只是刚开始,除了ETH还有别的数字货币,而且还可以双挖,使用不同的挖矿软件,有机会的话我们会继续介绍。以太坊交流群147322075,群管理每日提供货币资讯,每日行情分析,大家提供交流的平台,有兴趣的可以进来交流下,打扰了。编辑于 2017-08-18 10:56挖矿区域链​赞同 60​​15 条评论​分享​喜欢​收藏​申请

以太坊 2.0 如期启动,PoW 矿工何去何从? - 知乎

以太坊 2.0 如期启动,PoW 矿工何去何从? - 知乎切换模式写文章登录/注册以太坊 2.0 如期启动,PoW 矿工何去何从?路远网PoS 挖矿时代来临,以太坊矿工还好吗?一、以太坊2.0火热上线以太坊 2.0 的上线是最近圈内关注度最高的热点事件,11 月 初 V 神放出了以太坊 2.0 Staking 存款合约地址,瞬间引爆了行业。12 月 1 日上线当天基本上全行业都在围观这一备受期待的主网上线事件,在区块链整个历史上都没有哪一条公链的上线获得过如此高的关注度。目前以太坊 2.0 上线的是阶段 0 信标链。信标链是以太坊 2.0 的核心组件。如下图所示,在阶段 0 信标链之外,以太坊 2.0 还有两个主要阶段,阶段 1 和阶段 2。近日以太坊基金会修改了路线图,下图中阶段 2 采用的分片方案被冻结,转而使用 Layer2 方案 Rollup 来解决以太坊至关重要的可扩展性问题。以太坊 2.0 主要解决的是以太坊面临的性能困境。其主要解决方案为基于 PoS 共识的一层网络+基于 Rollup 技术的二层网络,两者结合将会极大提升以太坊网络的的处理能力。路线图修改后,没有官方提供的 TPS 预估数据,但我们能够进行简单推测。目前行业内 PoS 机制的链,TPS 普遍都在 1500 以上,而 Layer2 理论上可以实现上万甚至更高的 TPS,当上百个 Layer2 在运行的时候,结合 PoS 网络的高 TPS,性能提升将是指数级的。目前性能是制约以太坊网络发展的最大问题, 倘若性能问题得到解决,势必将会带来以太坊生态的大爆发。【文章同步发布于漫兮网:https://www.manxinet.com】二、PoW还能挖吗?今年 DeFi 的火热数次造成了以太坊的超级大拥堵,即使正常时期 gas 费也高到让人难以接受。但同时以太坊高昂的 gas 费,让矿工赚的盆满钵满。QKL123 数据显示,5 月以来随着 DeFi 的火爆,以太坊网络手续费持续飙升,从下图可以看出增长幅度极大巨大,说矿工是 DeFi 热潮下的最大赢家,一点都不过分。而在以太坊 2.0 上线之后,以太坊 2.0 Staking 的进展也是飞快,目前以太坊 2.0 存款合约内已经存入了 128 万枚 ETH,增长迅猛。持币者已经纷纷开启了 Staking 挖矿模式,PoS 挖矿时代正式来临。这种情况下,可能很多人都会觉得既然以太坊 2.0 都上线了,PoW 挖矿是不是就搞不下去了?下面来聊一下这个问题。三、以太坊2.0的困难与DeFi的繁荣以太坊 2.0 的启动尽管非常顺利,但以太坊 2.0 的后续阶段依然面临着很多困难。以太坊基金会的设想是,使用 Rollup 扩容方案来解决以太坊性能问题,相比原定的分片方案,Rollup 方案的难度有所降低,也就是以太坊升级的难度有所降低。但事实上整体花费的的时间并不会减少很多,只是升级成功的确定性增加了很多。也让因为分片开发过于困难而对以太坊升级抱有疑虑的人大大减少,增加了以太坊繁荣发展的确定性。为什么时间不会减少很多?因为以太坊 2.0 本身的设计也是很复杂的,且 1.0 和 2.0 的融合需要进行非常严谨的测试,这都需要大量的时间。以太坊网络上跑着大量的应用,存储着大量的资产,在一个高速运转的网络上实现重大升级,一定是非常困难的。同时从以太坊往期历史来看,以太坊网络的升级几乎没有不延期就顺利上线的,在公链领域,上线延期是非常普遍的现象。而在同时,以太坊生态还在蓬勃发展,据 Dune Analytics 数据显示,目前 DeFi 用户数已经突破了 100 万,这证明了 DeFi 拥有的强大力量。DeFi 的火爆是从今年年年中开始的,而到了年末,用户数就突破了 100万。考虑到 DeFi 的高门槛特性,这可以说是非常迅猛地增长。在吸引资金方面,DeFi 同样增长迅猛,据 DeBank 数据显示,目前 DeFi 总锁仓量已经突破 170 亿美元。DeFi 从不到 10 亿美金到 170 亿美金,仅仅用了几个月的时间。而同时灰度等机构还在持续买入 ETH,下图为灰度 ETH 持仓图,目前已经接近 300 万枚,近日灰度买入的 ETH 数量已经在逐渐增加。从下图可以看出,仅 12 月 8 日灰度就买入了 13 万枚 ETH。随着 DeFi 的蓬勃发展,以太坊网络手续费将长期保持高位,这仍然将是矿工的红利期。且随着以太坊 2.0 Staking 及 DeFi 锁仓量的不断增加,以及灰度等机构的不断买入,ETH 的稀缺性正在快速提升,囤币、挖币的氛围正在不断升温。整体来看,目前依然是以太坊 PoW 挖矿的黄金时间。四、PoW矿工的应对之策那么 ETH 1.0 的 PoW 链,究竟还能挖多久?目前并没有一个明确的答案。但可以确定的是,在以太坊由 PoW 彻底转变为 PoS 之前,以太坊基金会必须用足够长的时间来向大家证明 PoS 链是安全的。这样才能让所有开发者和用户放心的完成切换,从而使整个价值超过 1000 亿美金的生态体系真正的、完全的运行在信标链上。【文章同步发布于漫兮网:https://www.manxinet.com】没有人知道完成工程的推进,需要花多长时间,这是个很大的未知数,并且这些未知数可能是以太坊 2.0 转换的很大阻力。因此,我们乐观估计 PoW 链至少还可以持续挖两到三年。PoW挖矿排行榜 2020年12月9日从 PoW 挖矿收益数据来看,在共识升级的这段时间中,以太坊这个市值和挖矿产出都仅次于比特币的 PoW 共识网络,依旧稳居显卡算力首位。可见以太坊目前仍然是显卡挖矿的最佳选择。【文章同步发布于漫兮网:https://www.manxinet.com】那对于正在挖矿或者即将加入以太坊挖矿的人来说,应该以怎样的姿势迎接以太坊 2.0?新手矿工又该如何入场呢?1、加快设备升级。由于 ETH 的 DAG 文件即将满 4G,4G 显卡矿机即将面临淘汰。对于老矿工来说,应该尽早升级设备至 8G 显卡,继续占据以太坊网络的主阵地。对于挖矿新手,也要避免在不知情的情况下接盘 4G 显卡矿机。2、占据成本优势。对于矿工来说,决定回本周期的关键因素就是挖矿成本,包括电费、托管费、维修费等等。在以太坊 2.0 来临之前,寻找更具成本优势和管理水平的矿场,尽快缩短回本周期,才能在享受红利的同时,最大程度减少风险。3、找准入场时机。以太坊由于 DeFi 的爆发,同时迎来转型 2.0 的关键时期,以太坊的价值正在被越来越多的人和机构发现。从目前时点来看,对于追求长期稳健收益的以太坊矿工来说,很可能是低成本获取筹码的最好机会,也是最后的入场时机。发布于 2020-12-12 15:03以太币挖矿​赞同 39​​3 条评论​分享​喜欢​收藏​申请

以太坊客户端geth的基本操作命令 - 知乎

以太坊客户端geth的基本操作命令 - 知乎切换模式写文章登录/注册以太坊客户端geth的基本操作命令郑鹏区块链研究员搭建了私有链环境之后,整理了一下客户端的一些基本的操作命令:启动命令重复上篇博客步骤,先将区块链客户端启动,命令如下:geth –datadir “%cd%\chain” console 看到启动页面之后,新开启一个终端,并执行一下命令,并把日志输出到文本文件当中:geth --dev console 2>> file_to_log_output在这里可以继续执行具体的操作命令。查看账户eth.accounts创建用户:personal.newAccount("111111")其中参数为此账户的密码。 也可以先创建账户,然后输入密码:personal.newAccount()查看区块数据eth.blockNumber 启动挖矿miner.start() 返回结果为true则启动成功,具体执行情况可查看日志。停止挖矿miner.stop()当在执行挖矿时日志会不停刷屏,不用管,只要命令输入全,执行即可停止挖矿。查看账户余额其中参数为区块链地址eth.getBalance("0x7d1f7be4112ce63b9de04a0bf95c1e87e430bd1b")转账从账户0x7d1f7be4112ce63b9de04a0bf95c1e87e430bd1b转账3个以太币到0x587e57a516730381958f86703b1f8e970ff445d9。eth.sendTransaction({from:"0x7d1f7be4112ce63b9de04a0bf95c1e87e430bd1b",to:"0x587e57a516730381958f86703b1f8e970ff445d9",value:web3.toWei(3,"ether")})当直接执行此方法时会抛出异常:account is locked

at web3.js:3119:20

at web3.js:6023:15

at web3.js:4995:36

at :1:1很明显,账户被锁。解锁转出账户其中第一个参数为转出账户,第二个参数为密码。也可以直填写第一个参数,然后通过命令行提示再输入密码。personal.unlockAccount("0x7d1f7be4112ce63b9de04a0bf95c1e87e430bd1b","111111") 解锁完成之后,即可执行转账操作。但此时查看时会发现接收账户依旧为原来数值。此时需要执行挖矿命令,才会把转账真正完成。查看geth帮助文档:github上的wiki文档geth -help

$ geth help

NAME:

geth - the go-ethereum command line interface

Copyright 2013-2017 The go-ethereum Authors

USAGE:

geth [options] command [command options] [arguments...]

VERSION:

1.7.3-stable

COMMANDS:

account Manage accounts

attach Start an interactive JavaScript environment (connect to node)

bug opens a window to report a bug on the geth repo

console Start an interactive JavaScript environment

copydb Create a local chain from a target chaindata folder

dump Dump a specific block from storage

dumpconfig Show configuration values

export Export blockchain into file

import Import a blockchain file

init Bootstrap and initialize a new genesis block

js Execute the specified JavaScript files

license Display license information

makecache Generate ethash verification cache (for testing)

makedag Generate ethash mining DAG (for testing)

monitor Monitor and visualize node metrics

removedb Remove blockchain and state databases

version Print version numbers

wallet Manage Ethereum presale wallets

help, h Shows a list of commands or help for one command

ETHEREUM OPTIONS:

--config value TOML configuration file

--datadir "/home/karalabe/.ethereum" Data directory for the databases and keystore

--keystore Directory for the keystore (default = inside the datadir)

--nousb Disables monitoring for and managing USB hardware wallets

--networkid value Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 1)

--testnet Ropsten network: pre-configured proof-of-work test network

--rinkeby Rinkeby network: pre-configured proof-of-authority test network

--syncmode "fast" Blockchain sync mode ("fast", "full", or "light")

--ethstats value Reporting URL of a ethstats service (nodename:secret@host:port)

--identity value Custom node name

--lightserv value Maximum percentage of time allowed for serving LES requests (0-90) (default: 0)

--lightpeers value Maximum number of LES client peers (default: 20)

--lightkdf Reduce key-derivation RAM & CPU usage at some expense of KDF strength

DEVELOPER CHAIN OPTIONS:

--dev Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled

--dev.period value Block period to use in developer mode (0 = mine only if transaction pending) (default: 0)

ETHASH OPTIONS:

--ethash.cachedir Directory to store the ethash verification caches (default = inside the datadir)

--ethash.cachesinmem value Number of recent ethash caches to keep in memory (16MB each) (default: 2)

--ethash.cachesondisk value Number of recent ethash caches to keep on disk (16MB each) (default: 3)

--ethash.dagdir "/home/karalabe/.ethash" Directory to store the ethash mining DAGs (default = inside home folder)

--ethash.dagsinmem value Number of recent ethash mining DAGs to keep in memory (1+GB each) (default: 1)

--ethash.dagsondisk value Number of recent ethash mining DAGs to keep on disk (1+GB each) (default: 2)

TRANSACTION POOL OPTIONS:

--txpool.nolocals Disables price exemptions for locally submitted transactions

--txpool.journal value Disk journal for local transaction to survive node restarts (default: "transactions.rlp")

--txpool.rejournal value Time interval to regenerate the local transaction journal (default: 1h0m0s)

--txpool.pricelimit value Minimum gas price limit to enforce for acceptance into the pool (default: 1)

--txpool.pricebump value Price bump percentage to replace an already existing transaction (default: 10)

--txpool.accountslots value Minimum number of executable transaction slots guaranteed per account (default: 16)

--txpool.globalslots value Maximum number of executable transaction slots for all accounts (default: 4096)

--txpool.accountqueue value Maximum number of non-executable transaction slots permitted per account (default: 64)

--txpool.globalqueue value Maximum number of non-executable transaction slots for all accounts (default: 1024)

--txpool.lifetime value Maximum amount of time non-executable transaction are queued (default: 3h0m0s)

PERFORMANCE TUNING OPTIONS:

--cache value Megabytes of memory allocated to internal caching (min 16MB / database forced) (default: 128)

--trie-cache-gens value Number of trie node generations to keep in memory (default: 120)

ACCOUNT OPTIONS:

--unlock value Comma separated list of accounts to unlock

--password value Password file to use for non-interactive password input

API AND CONSOLE OPTIONS:

--rpc Enable the HTTP-RPC server

--rpcaddr value HTTP-RPC server listening interface (default: "localhost")

--rpcport value HTTP-RPC server listening port (default: 8545)

--rpcapi value API's offered over the HTTP-RPC interface

--ws Enable the WS-RPC server

--wsaddr value WS-RPC server listening interface (default: "localhost")

--wsport value WS-RPC server listening port (default: 8546)

--wsapi value API's offered over the WS-RPC interface

--wsorigins value Origins from which to accept websockets requests

--ipcdisable Disable the IPC-RPC server

--ipcpath Filename for IPC socket/pipe within the datadir (explicit paths escape it)

--rpccorsdomain value Comma separated list of domains from which to accept cross origin requests (browser enforced)

--jspath loadScript JavaScript root path for loadScript (default: ".")

--exec value Execute JavaScript statement

--preload value Comma separated list of JavaScript files to preload into the console

NETWORKING OPTIONS:

--bootnodes value Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)

--bootnodesv4 value Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)

--bootnodesv5 value Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)

--port value Network listening port (default: 30303)

--maxpeers value Maximum number of network peers (network disabled if set to 0) (default: 25)

--maxpendpeers value Maximum number of pending connection attempts (defaults used if set to 0) (default: 0)

--nat value NAT port mapping mechanism (any|none|upnp|pmp|extip:) (default: "any")

--nodiscover Disables the peer discovery mechanism (manual peer addition)

--v5disc Enables the experimental RLPx V5 (Topic Discovery) mechanism

--netrestrict value Restricts network communication to the given IP networks (CIDR masks)

--nodekey value P2P node key file

--nodekeyhex value P2P node key as hex (for testing)

MINER OPTIONS:

--mine Enable mining

--minerthreads value Number of CPU threads to use for mining (default: 8)

--etherbase value Public address for block mining rewards (default = first account created) (default: "0")

--targetgaslimit value Target gas limit sets the artificial target gas floor for the blocks to mine (default: 4712388)

--gasprice "18000000000" Minimal gas price to accept for mining a transactions

--extradata value Block extra data set by the miner (default = client version)

GAS PRICE ORACLE OPTIONS:

--gpoblocks value Number of recent blocks to check for gas prices (default: 10)

--gpopercentile value Suggested gas price is the given percentile of a set of recent transaction gas prices (default: 50)

VIRTUAL MACHINE OPTIONS:

--vmdebug Record information useful for VM and contract debugging

LOGGING AND DEBUGGING OPTIONS:

--metrics Enable metrics collection and reporting

--fakepow Disables proof-of-work verification

--nocompaction Disables db compaction after import

--verbosity value Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 3)

--vmodule value Per-module verbosity: comma-separated list of = (e.g. eth/*=5,p2p=4)

--backtrace value Request a stack trace at a specific logging statement (e.g. "block.go:271")

--debug Prepends log messages with call-site location (file and line number)

--pprof Enable the pprof HTTP server

--pprofaddr value pprof HTTP server listening interface (default: "127.0.0.1")

--pprofport value pprof HTTP server listening port (default: 6060)

--memprofilerate value Turn on memory profiling with the given rate (default: 524288)

--blockprofilerate value Turn on block profiling with the given rate (default: 0)

--cpuprofile value Write CPU profile to the given file

--trace value Write execution trace to the given file

WHISPER (EXPERIMENTAL) OPTIONS:

--shh Enable Whisper

--shh.maxmessagesize value Max message size accepted (default: 1048576)

--shh.pow value Minimum POW accepted (default: 0.2)

DEPRECATED OPTIONS:

--fast Enable fast syncing through state downloads

--light Enable light client mode

MISC OPTIONS:

--help, -h show help

COPYRIGHT:

Copyright 2013-2017 The go-ethereum Authors 帮助文档:WIKE帮助文档区块链开发(三)以太坊客户端命令行选项汇总区块链开发(二)以太坊客户端基本操作命令更多交流,欢迎WX:zhengpeng0725编辑于 2017-12-23 20:14区块链(Blockchain)​赞同 1​​添加评论​分享​喜欢​收藏​申请

工作量证明 (PoW) | ethereum.org

明 (PoW) | ethereum.org跳转至主要内容学习用法构建参与研究搜索​​​​语言 ZH帮助更新此页面本页面有新版本,但现在只有英文版。请帮助我们翻译最新版本。翻译页面没有错误!此页面未翻译,因此特意以英文显示。不再显示Change page概述基础主题以太坊简介以太币简介去中心化应用程序简介Web2 与 Web3 的对比帐户交易区块以太坊虚拟机 (EVM)操作码Gas费用节点和客户端运行节点客户端多样性节点即服务节点架构轻客户端归档节点引导节点网络共识机制工作量证明矿工挖矿算法Dagger-HashimotoEthash权益证明Gasper弱主观性认证权益证明机制的奖励和惩罚权益证明攻击与防御密钥权益证明与工作量证明提出区块权益正明常见问题以太坊堆栈堆栈简介智能合约智能合约语言智能合约结构智能合约库测试用智能合约编译智能合约部署智能合约验证智能合约升级智能合约智能合约安全性智能合约形式化验证可组合性开发网络开发框架以太坊客户端APIJavaScript API后端APIJSON-RPC数据和分析区块浏览器存储集成开发环境 (IDE)编程语言DartDelphi.NETGolangJavaJavaScriptPythonRubyRust语言高级链桥标准令牌标准ERC-20:同质化代币ERC-721:非同质化代币 (NFT)ERC-777ERC-1155ERC-4626最大可提取价值 (MEV)预言机缩放乐观卷叠零知识卷叠状态通道侧链以太坊 Plasma 扩容解决方案Validium数据可用性网络层网络地址门户网络数据结构与编码默克尔前缀树递归长度前缀编码 (RLP)简单序列化 (SSZ)Web3 密钥存储定义设计基础设计和用户体验简介工作量证明 (PoW)x上次修改时间: @xiaomage(opens in a new tab), Invalid DateTime查看贡献者在本页面前提条件什么是工作量证明 (POW)工作量证明和挖矿以太坊的工作量证明机制如何运作?工作量证明机制工作量证明和安全性工作量证明的经济模型最终确定性工作量证明能源消耗优点和缺点与权益证明对比更愿意通过视频学习?延伸阅读视频相关主题以太坊网络最初采用一种称为工作量证明 (PoW) 的共识机制。 这种机制允许以太坊网络的节点就以太坊区块链上记录的所有信息的状态达成共识,并防止某些产生经济影响的攻击。 然而,以太坊在 2022 年终结了工作量证明并开始采用权益证明。工作量证明现已弃用。 以太坊不再使用工作量证明作为其部分共识机制。 它改用权益证明。 阅读有关权益证明和质押的更多信息。前提条件为了更好地理解此页面,建议提前阅读交易、区块和共识机制。什么是工作量证明 (POW)中本聪共识采用工作量证明,一度允许去中心化的以太坊网络对帐户余额和交易顺序等达成共识(即所有节点都同意)。 这种机制防止用户“重复支付”他们的货币,同时确保极难攻击或操作以太坊区块链。 这些安全特性现在由权益证明提供,后者采用称为 Gasper 的共识机制。工作量证明和挖矿工作量证明是一种基础性算法,它为矿工在工作量证明区块链上进行的工作设置难度和规则。 挖矿就是“工作”本身。 挖矿是向区块链中添加有效区块。 这很重要,因为链的长度有助于网络跟随区块链的正确分叉。 “工作”完成得越多,链越长,区块编号就越大,就更能确定网络达到最新状态。有关挖矿的更多信息以太坊的工作量证明机制如何运作?以太坊交易处理到区块中。 在现已弃用的工作量证明以太坊中,每个区块包含:区块的难度,例如:3,324,092,183,262,715混合哈希(mixHash),例如:0x44bca881b07a6a09f83b130798072441705d9a665c5ac8bdf2f39a3cdf3bee29nonce--例如:0xd3ee432b4fb3d26b这些区块数据与工作量证明直接相关。工作量证明机制工作量证明协议 Ethash 要求矿工经过激烈的试错竞赛,找到一个区块的随机数。 只有具备有效随机数的区块才能加入区块链中。当矿工们争相创建区块时,他们会反复通过一个数学函数放置一个数据集,此数据集只能通过下载和运行整条区块链获得(矿工们都是这样做的)。 该数据集用来产生一个低于目标随机数的混合哈希,而此目标随机数由区块难度决定。 做到这些最好的方式是试错。难度决定了哈希的目标值。 目标值越小,有效哈希的集合就越小。 一旦生成哈希,其他矿工和客户端就很容易验证哈希。 即使一条交易记录出现改变,整个哈希就会变得完全不同,表示出现欺诈。哈希使得欺诈更容易被发现。 此外,工作量证明作为一个流程,同样有效威慑了对区块链的攻击。工作量证明和安全性激励矿工在以太坊主链上挖矿。 对于一小部分矿工而言,没有任何激励措施让他们去开辟一条自己的新链 - 因为这破坏了体系。 区块链依赖于唯一状态来判断真实性。工作量证明的目标是延长链。 最长的链是最可信的有效链,因为需要完成最多的计算工作来生成它。 在以太坊的工作量证明体系中,几乎不可能创建新的区块来清除交易、创建虚假交易或维护第二条链。 那是因为恶意矿工总是需要比其他人更快地解出区块随机数。要持续创建恶意但有效的区块,恶意矿工将需要超过 51% 的网络挖矿算力才能击败其他人。 这种海量的“工作”需要大量昂贵的算力,而且消耗的能源甚至可能超过攻击所得的收益。工作量证明的经济模型工作量证明还负责向系统中发行新货币并激励矿工完成工作。自君士坦丁堡升级以来,成功创建区块的矿工将获得两个新铸造的以太币及部分交易费作为奖励。 叔块也会获得 1.75 个以太币的补偿。 叔块是由一个矿工创建的有效区块,几乎与此同时另一个矿工创建了规范区块。要确定规范区块,最终取决于哪条链构建于第一个区块之上。 叔块通常是由于网络延迟而出现。最终确定性如果交易属于一个无法更改的区块时,它就在以太坊上具有“最终确定性”。由于矿工以去中心化的方式工作,有可能同时开采出两个有效区块。 这就产生了一个临时分叉。 最后,在后续区块被开采出并添加到其中一条链使其更长时,这条链就会成为被接受的链。但更复杂的是,在临时分叉上被拒绝的交易可能没有包含在被接受的主链上。 这意味着区块是可逆的。 因此,最终确定性是指你在认为交易不可逆之前需要等待的一段时间。 在以前的工作量证明以太坊中,一个特定区块 N 之后开采出的区块越多,就更加确信区块 N 内的交易是成功的且不可回滚。 现在,基于权益证明机制,最终确定是区块的明确属性,而不再是概率性的。工作量证明能源消耗对工作量证明提出的一项主要批评是保证网络安全所需的能源消耗。 为了维持安全和去中心化,采用工作量证明的以太坊每年消耗大量能源。 在即将过渡到权益证明之际,以太坊矿工的总能源消耗大约为 70 亿千瓦时/年(大约与捷克共和国相当 - 数据来自 2022 年 7 月 18 日 digiconomist(opens in a new tab))。优点和缺点优点缺点工作量证明并无对错。 你不需要以太币来启动,出块奖励允许你从 0 ETH 获得正的收益。 而在权益证明中,你需要以太币来启动获取收益的过程。工作量证明消耗了大量能源,对环境不利。工作量证明是一个经过考验和测试的共识机制,多年来一直保持了比特币和以太坊的安全性和去中心化。如果你想要挖矿,需要花大量的启动资金去购买专业设备。与权益证明方式相比,工作量证明是比较容易实施的。因为算力的不断增加,矿池可能会主导挖矿过程,导致中心化和安全风险。与权益证明对比从更高层面上看,权益证明和工作量证明的最终目标相同,即帮助去中心化网络安全地达成共识。 但它们在实现方式和人员上有些不同:权益证明 (PoS) 让质押 ETH 不再需要算力。权益证明 (PoS) 将矿工替换为验证者。 验证者通过质押他们的 ETH 来创建新的区块。验证者不会竞争创建区块,而是由算法随机选择。终局性是很清晰的:在特定的检查节点,如果 2/3 验证者确定了区块,这个区块将被视为最终状态。 验证者必须在区块压上自己全部质押,因此如果他们试图串通更改区块链,他们就会失去他们的全部质押。有关权益证明的更多信息更愿意通过视频学习?延伸阅读多数攻击(opens in a new tab)关于结算终局性(opens in a new tab)视频对工作量证明协议的技术说明(opens in a new tab)相关主题矿工权益证明back-to-top ↑本文对你有帮助吗?是否前一页共识机制下一页矿工编辑页面(opens in a new tab)在本页面前提条件什么是工作量证明 (POW)工作量证明和挖矿以太坊的工作量证明机制如何运作?工作量证明机制工作量证明和安全性工作量证明的经济模型最终确定性工作量证明能源消耗优点和缺点与权益证明对比更愿意通过视频学习?延伸阅读视频相关主题网站最后更新: 2024年3月13日(opens in a new tab)(opens in a new tab)(opens in a new tab)学习学习中心什么是以太坊?什么是以太币 (ETH)?以太坊钱包什么是 Web3?智能合约Gas fees运行节点以太坊安全和预防欺诈措施测试中心以太坊词汇表用法指南选择钱包获取以太币Dapps - 去中心化应用稳定币NFT - 非同质化代币DeFi - 去中心化金融DAO - 去中心化自治组织去中心化身份质押ETH二层网络构建构建者首页教程相关文档通过编码来学习设置本地环境资助基础主题用户体验/用户界面设计基础Enterprise - Mainnet EthereumEnterprise - Private Ethereum参与社区中心在线社区以太坊活动为 ethereum.org 做贡献翻译计划以太坊漏洞悬赏计划以太坊基金会以太坊基金会的博客(opens in a new tab)生态系统支持方案(opens in a new tab)Devcon(opens in a new tab)研究以太坊白皮书以太坊路线图安全性增强以太坊技术史开放研究以太坊改进提案 (Eip)以太坊治理关于我们以太坊品牌资产Code of conduct工作机会隐私政策使用条款缓存政策联系我们(opens in a new tab)本页面对你有帮

挖矿 | ethereum.org

ethereum.org跳转至主要内容学习用法构建参与研究搜索​​​​语言 ZH帮助更新此页面本页面有新版本,但现在只有英文版。请帮助我们翻译最新版本。翻译页面没有错误!此页面未翻译,因此特意以英文显示。不再显示Change page概述基础主题以太坊简介以太币简介去中心化应用程序简介Web2 与 Web3 的对比帐户交易区块以太坊虚拟机 (EVM)操作码Gas费用节点和客户端运行节点客户端多样性节点即服务节点架构轻客户端归档节点引导节点网络共识机制工作量证明矿工挖矿算法Dagger-HashimotoEthash权益证明Gasper弱主观性认证权益证明机制的奖励和惩罚权益证明攻击与防御密钥权益证明与工作量证明提出区块权益正明常见问题以太坊堆栈堆栈简介智能合约智能合约语言智能合约结构智能合约库测试用智能合约编译智能合约部署智能合约验证智能合约升级智能合约智能合约安全性智能合约形式化验证可组合性开发网络开发框架以太坊客户端APIJavaScript API后端APIJSON-RPC数据和分析区块浏览器存储集成开发环境 (IDE)编程语言DartDelphi.NETGolangJavaJavaScriptPythonRubyRust语言高级链桥标准令牌标准ERC-20:同质化代币ERC-721:非同质化代币 (NFT)ERC-777ERC-1155ERC-4626最大可提取价值 (MEV)预言机缩放乐观卷叠零知识卷叠状态通道侧链以太坊 Plasma 扩容解决方案Validium数据可用性网络层网络地址门户网络数据结构与编码默克尔前缀树递归长度前缀编码 (RLP)简单序列化 (SSZ)Web3 密钥存储定义设计基础设计和用户体验简介挖矿x上次修改时间: @xiaomage(opens in a new tab), Invalid DateTime查看贡献者在本页面前提条件以太坊挖矿是什么?为什么存在矿工?挖矿成本如何挖掘以太坊交易叔块直观演示挖矿算法相关主题工作量证明不再是以太坊共识机制的基础,这意味着挖矿已终结。 取而代之的是,以太坊将由质押了以太币的验证者保护。 你可以立即开始质押以太币。 阅读更多关于合并、权益证明和质押的信息。 此页面仅展示历史内容。前提条件为了更好地了解此页面,推荐先阅读交易、区块和工作量证明。以太坊挖矿是什么?挖矿是指创建要添加到以太坊区块链的交易块的过程,在以太坊现已弃用的工作量证明架构中进行。挖矿一词源于将加密货币比作黄金的比喻。 黄金或贵金属很稀缺,数字代币也很稀缺,在工作量证明体系中,只能通过挖矿增加总量。 在工作量证明以太坊中,只能通过挖矿进行发行。 然而,与黄金或贵金属不同,以太坊挖矿也是一种通过在区块链中创建、验证、发布和传播区块来保护网络的方式。以太币挖矿 = 保护网络安全挖矿是任何工作量证明区块链的命脉。 在过渡到权益证明之前,以太坊矿工,即运行软件的计算机,利用它的时间和算力处理交易并产生区块。为什么存在矿工?在以太坊这样的去中心化系统中,需要确保每个人都同意交易的顺序。 矿工通过解决计算难题来产生区块并保护网络免受攻击,从而帮助实现这一目标。关于工作量证明的更多信息以前任何人都能使用他们的计算机在以太坊网络上挖矿。 然而,并非每个人都可以通过挖矿实现以太币 (ETH) 获利。 在大多数情况下,矿工必须购买专用计算机硬件,并且能够获得廉价能源。 普通计算机不太可能获得足够的区块奖励来支付相关的挖矿成本。挖矿成本建造和维护矿机所需硬件的潜在成本矿机的电力成本如果你在矿池中挖矿,这些矿池通常对矿池生成的每个区块收取固定百分比的费用支持矿机的潜在成本(通风、能源监测、电线等)要进一步探索挖矿收益,请使用挖矿收益计算器,例如 Etherscan(opens in a new tab) 提供的挖矿收益计算器。如何挖掘以太坊交易以下内容将简要介绍如何在以太坊工作量证明中挖掘交易。 在这里可以找到对以太坊权益证明中该过程的类比介绍。用户编写和通过一些帐户私钥来签署交易请求。用户通过一些节点将自己的交易请求广播到整个以太坊网络。在听到新的转账请求时,每个以太坊网络节点会添加这笔交易到本地的内存池,这些内存池包括他们收到的没有被添加到区块链以承认的所有转账请求。在这个时候,一个挖矿节点将几十或上百个交易请求汇总到潜在区块中,从而尽量多收取交易手续费,同时保证不超出区块燃料限制。 采矿节点将:验证每个交易请求的有效性(例如没有人试图将以太币从他们没有签名的帐户中转移出来,请求是否有格式错误等),然后执行请求的本地代码,改变本地副本 EVM 的状态。 矿工获得每个交易请求的转账的手续费到他们的帐户。一旦在本地 EVM 副本上验证并执行了块中的所有转账请求,就开始为潜在块生成工作证明“合法性证书”。最终,矿工将完成为包含我们特定交易请求的区块生成的证书。 然后,矿工广播完成的区块,其中包括证书和校验新 EVM 状态。其他节点将收到新的区块。 他们将验证证书,执行区块上所有的转账(包括最初由用户广播的交易),然后校验新 EVM 状态,之后执行所有满足 EVM 校验和的转账。 只有这样,这些节点才会将该块附加到区块链的尾部,并接受新的 EVM 状态作为新的规范状态。每个节点将从其未完成的本地内存池的转账请求中删除新区块中已经存在的转账请求。加入网络的新节点将按顺序下载所有块,包括未被打包的交易块。 初始化本地 EVM 副本(作为空白状态的 EVM 开始),在本地 EVM 副本上执行每个块中的每个转账,校验各块的校验和。每个交易都只会被挖掘(首次包含在新区块中并传播)一次,但在推进规范以太坊虚拟机状态的过程中,每个参与者都会执行和验证交易。 这凸显出区块链的核心准则之一:不信任,就验证。叔块基于工作量证明的区块挖掘是概率性的,这意味着有时由于网络延迟而同时公布了两个有效的区块。 在这种情况下,协议必须确定最长链(因此大多数即是最“有效的”),同时针对已提交但未被包含的有效区块,给予矿工部分奖励以确保公平。 这促使网络进一步去中心化,因为小矿工群体可能面临更大的延迟,但仍然可以通过叔块Ommer (uncle) blockWhen a proof-of-work miner finds a valid block, another miner may have published a competing block which is added to the tip of the blockchain first. This valid, but stale, block can be included by newer blocks as ommers and receive a partial block reward. The term "ommer" is the preferred gender-neutral term for the sibling of a parent block, but this is also sometimes referred to as an "uncle". This was relevant for Ethereum when it was a proof-of-work network, but ommers are not a feature of proof-of-stake Ethereum because precisely one block proposer is selected in each slot.奖励获得收益。对于父区块的同级区块来说,“ommer”一词不分性别,因而为首选,但有时也被称为“uncle”(叔)。 因为以太坊切换到权益证明机制后,叔块就不会被挖掘了,因为每个时隙中只选择了一名提议者。 通过查看被挖掘叔块的历史图表(opens in a new tab),你可以看到这种变化。直观演示跟随 Austin 了解挖矿和工作量证明区块链。挖矿算法以太坊主网只使用过一种挖矿算法 -“Ethash”。 Ethhash 是一种初始研发挖矿算法“Dagger-Hashimoto”的后续版本。有关挖矿算法的更多信息。相关主题燃料以太坊虚拟机工作量证明back-to-top ↑本文对你有帮助吗?是否前一页工作量证明下一页挖矿算法编辑页面(opens in a new tab)在本页面前提条件以太坊挖矿是什么?为什么存在矿工?挖矿成本如何挖掘以太坊交易叔块直观演示挖矿算法相关主题网站最后更新: 2024年3月13日(opens in a new tab)(opens in a new tab)(opens in a new tab)学习学习中心什么是以太坊?什么是以太币 (ETH)?以太坊钱包什么是 Web3?智能合约Gas fees运行节点以太坊安全和预防欺诈措施测试中心以太坊词汇表用法指南选择钱包获取以太币Dapps - 去中心化应用稳定币NFT - 非同质化代币DeFi - 去中心化金融DAO - 去中心化自治组织去中心化身份质押ETH二层网络构建构建者首页教程相关文档通过编码来学习设置本地环境资助基础主题用户体验/用户界面设计基础Enterprise - Mainnet EthereumEnterprise - Private Ethereum参与社区中心在线社区以太坊活动为 ethereum.org 做贡献翻译计划以太坊漏洞悬赏计划以太坊基金会以太坊基金会的博客(opens in a new tab)生态系统支持方案(opens in a new tab)Devcon(opens in a new tab)研究以太坊白皮书以太坊路线图安全性增强以太坊技术史开放研究以太坊改进提案 (Eip)以太坊治理关于我们以太坊品牌资产Code of conduct工作机会隐私政策使用条款缓存政策联系我们(opens in a new tab)本页面对你有帮

ETHASH 挖矿算法 — 以太坊的指南针 1.0.0 documentation

ETHASH 挖矿算法 — 以太坊的指南针 1.0.0 documentation

以太坊的指南针

目录

如何学习这本书

第 1 章 以太坊:一台全球计算机

简史

发展阶段

以太坊的特色

第 2 章 账户是什么

小白基础知识问答

我的以太币记录在哪里?

我的以太币余额如何变化?

什么是区块?

区块和状态的关系

“巨大的账本”

我如何参与以太坊?

我如何与其他人同步账本?

账户探秘

账户与账户状态

账户状态的内涵

已执行交易总数

持币数量

存储区的哈希值

代码区的哈希值

没有钱包App, 如何生成账户?

智能合约地址的生成

扩展阅读

资料篇:Keystore 与私钥保存

资料篇:常用钱包 App

资料篇:EIP-55 格式的账户地址

第 3 章 交易是驱动力

交易的发送

交易与消息的区别

交易的特性是什么?

交易的样子

交易的生命周期

扩展阅读

资料篇:共识与工作量证明

比特币的PoW机制(简单版)

比特币算力的中心化问题

以太坊的Pow/Pos机制

资料篇:矿工与挖矿奖励

第 4 章 数据结构

Radix树

Merkle树和 Merkle证明

Merkle Patricia树

RLP编码

RLP字符/字符串编码

RLP字符/字符串解码

RLP数组编码

RLP数组解码

扩展阅读

资料篇:状态树 (以及存储树)

资料篇:交易树

资料篇:收据树

资料篇:区块

第 5 章 构建一条以太坊私链

安装

Geth客户端的结构

启动一条以太坊私链

接收挖矿奖励

转账与收款

第 6 章 手把手教你部署智能合约

什么是智能合约?

安装编译器

Solc编译智能合约

智能合约发布准备

部署智能合约

调用智能合约

第 7 章 以太坊虚拟机探秘

虚拟机的执行结果

虚拟机的执行资源

合约调用合约?

虚拟机的输入输出

Gas 花费与退回

虚拟机指令集

第 8 章 Solidity语法练习

基础概念

没有浮点数运算

合约基础

变量类型

运算符号

结构体 Struct

数组array

函数申明

类型转换与内置函数

合约与事件

语法进阶

数据结构:map

环境变量:msg.sender

require还是assert?

继承和引入

省钱妙招:内存变量

接口与合约调用

多返回值

高级语法和概念

Contract 构造函数

Ownable控制

Pausable控制

省钱妙招:struct 结构体

时间单位表达

带参数的函数修饰符

for 循环

合约收款:payable修饰符

支付费用:transfer方法

小结

第 9 章 Truffle合约开发实战

编译、测试工具安装

Truffle的安装

Ganache的安装

Truffle启动样例项目

下载样例

编译项目

部署项目到 Ganache

测试项目

上手实践:ERC20合约

新建项目目录

ERC20 Basic合约接口

ERC20 合约接口

SafeMath基础数学库

猫币:CAT数字资产合约

上手实践:ERC20合约测试

准备工作

测试辅助函数与库

测试代码分析

测试运行与结果

附录 有意思的冷知识

短地址攻击

比特币的区块

以太坊与比特币账户的区别

隐私与安全性的比较

数据体积与并发能力

发送交易时对双花的处理

“不可能的三角”问题

ETHASH 挖矿算法

ETHASH和比特币PoW的异同

ETHASH的设计目标

ETHASH的挖矿运行总流程

ETHASH算法源代码解读

以太坊的指南针

»

附录 有意思的冷知识 »

ETHASH 挖矿算法

Edit on GitHub

ETHASH 挖矿算法¶

把最好的东西留到最后品尝,本书将以太坊的PoW(Proof of work)挖矿算法核心ETHASH算法作为最好的礼物留到最后讲解。掌握了ETHASH算法我们就有能力进行新的、独立的公链开发。这个知识也是最难消化的,需要读者有许多相应的数学知识背景。请让我们一步一步来对照着源代码讲解这部分知识。

ETHASH和比特币PoW的异同¶

ETHASH这个算法是消耗资源的PoW模式,同比特币共识算法一样,它需要消耗大量的计算资源得出最终的“结论”。但是这个结论的得出和执行交易的顺序无关。也就是说一般情况下并非需要调整“交易的排列组合”来影响最终的哈希计算值结果符合“阈值”的标准。这点和比特币是完全不一样的。在交易序列唯一确定后,以太坊共识算法通过调整8字节(64bit)的nonce值来让计算最终结果符合“阈值”的要求。

ETHASH的算法更加依赖于CPU+内存的双料资源组合,比特币的SHA256算法仅仅依赖于CPU的资源,两者在挖矿公平性上也是不同的,这点在后文会有讲解。

ETHASH的设计目标¶

在比特币诞生之后经历了很长一段时间,开源社区发现仅依赖于CPU的计算的算法造成挖矿成功率向算力高的一方倾斜,并诞生出了诸如矿机这种专门的设备用于挖矿。矿机并不是一台完整的计算机,而是利用如ASIC集成电路、GPU、FPGA等专用电路进行并发操作。获得更高的多挖矿效率。这个趋势渐渐将普通人的电脑淘汰出挖矿的队伍,让话语权集中于数个矿场主手中。有违背于区块链公链“人人参与,去中心化”的精神,对区块链的分布式安全也是严重的威胁。在后世的算法设计中,就将装备了“慢CPU”的设备也能参与进挖矿定为一个重要的设计目标。PoW挖矿算法更多地让整台计算机资源都充分被利用,例如GPU、内存等设备,将单纯提高CPU的优势抹平。

ETHASH并非一日铸成,前身经历了两次演进/组合,前身称之为Dagger-Hashimoto算法。Dagger与Hashimoto是两个不同的算法,它们共同组合起来形成了一套“Memory Hard Function”也就是对内存要求较高的计算/验证算法。它的核心点就是要找到一个8字节(64bit)的nonce值。而这个随机数的产生,没有比枚举更好的策略,这样对于每个挖矿者而言,找到随机数的概率是公平的。而这个随机数的找到的概率,取决于预先设置的挖矿难度。难度越高,找到随机数的概率越小,则同样的挖矿者需要更长时间来搜寻。这让以太坊有通过设置挖矿难度动态调整出块时间的可能。我们现在习惯的15秒出一个以太坊的块,就是动态难度调整和世界千万挖矿者算力博弈的最终动态平衡。

ETHASH的挖矿运行总流程¶

ETHASH改良了Dagger-Hashimoto,正确的说已经脱胎换骨,和原来的算法已经面目全非。它的总算法分为DAG的生成和DAG的使用(挖矿)两个部分。它有效地解决了单纯内存依赖的算法诸如Scrypt算法加密难与解密同样难的困境,也突破Dagger算法不抵抗内存共享硬件加速的困境,从全区块链数据的生成改为固定的1GB的数据的生成,支持了客户端预生成数据,保障挖矿难度的平滑过度。

总的工作量/工作量证明总体流程如下。

计算一个种子(Seed),该种子的计算依赖于当本块及本块之前的所有块。

从种子中计算得出一个缓存(Cache),该缓存仅仅由种子得出,是一个16MB大小的数据集。轻客户端应存储下该缓存用于日后验证。

从缓存中生成一个1GB大小的数据集(DataSet),这个数据集通常称为DAG。完整客户端或者挖矿客户端需要保存该1GB大小的数据,该数据随时间线性增长。

挖矿过程即为哈希过程。哈希的输入是取得1GB数据集的数个子部分,并将它们放在一起执行哈希。验证过程是可以在轻客户端通过Cache缓存生成被挖矿制定的数据碎片并执行哈希验证。故而轻客户端并不需要时刻保存1GB的DAG。

每当30000个以太坊区块被发掘后,1GB的数据集将被更新一次,所以矿工的主要精力放在读取这个数据集上,而非产生数据集。为了平滑过度30000个时间点上的DAG产生带来的延迟,可以预先生成DAG数据。

ETHASH算法源代码解读¶

我们之前探讨的算法都是纸上谈兵。接下去我们将分段用Go语言源码 方式来查看一下究竟ETHASH的挖矿和验证过程是如何进行的。探讨挖矿过程就如同探索爱丽丝仙境中的兔子洞,必须层层向下探索,它的最终解答的问题是:如何才能用ETHASH算法找到一个合法的nonce,进而形成一个块?

整个打包块的过程源于sealer(封装)函数,它需要负责封装一个合法的块,这个块的获得将是一个mine(挖矿)过程,我们来查看一下它们的函数签名。

/consensus/ethash/sealer.go¶

func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {

Seal函数总目标是找到一个nonce,让其符合块难度设定,这样块就能成为合法的块而被其他节点所接受。接受多个参数输入,并返回一个Ethash的指针。输入参数中包含了ChainReader,可料想到对于区块链前置的数据是有扫描的;Block可见最终也会修改块的部分数据,例如头部数据。我们来查看一下Ethash数据结构是怎样的:

/consensus/ethash/ethash.go¶

type Ethash struct {

config Config

caches *lru // LRU类型的Cache缓存避免大量反复查询

datasets *lru // LRU类型的 DataSet数据集,防止反复生成

// 挖矿相关

rand *rand.Rand // 产生nonce的随机数

threads int // 挖矿需要的线程数量

update chan struct{}

hashrate metrics.Meter // 跟踪当下hash rate挖矿效率的参数

// 远程打包者所关注的参数

workCh chan *sealTask // 通知渠道,通知远程打包者打包数据

fetchWorkCh chan *sealWork // 获取渠道, 远程打包者获取元数据

submitWorkCh chan *mineResult // 提交渠道,远程打包者提交打包结果

fetchRateCh chan chan uint64 // 获取渠道,获取远程打包者提交挖矿效率参数值

submitRateCh chan *hashrate // 提交渠道,远程大包着提交挖矿效率参数值

// 用于测试的钩子

shared *Ethash

fakeFail uint64

fakeDelay time.Duration

lock sync.Mutex

closeOnce sync.Once

exitCh chan chan error

}

我们看到了熟悉的三个元素,caches、datasets、rand,这三个参数在之前的算法粗略讲解里面已经提到,是ETHASH的所使用到参数的基石,我们看下这个具体的封装区块的过程。

/consensus/ethash/sealer.go¶

// Seal函数主要功能是触发miner函数进行挖矿操作

func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {

// 为了简洁,我们删去了测试代码

// 为了简洁,我们删去了共享挖矿的代码

// 取消挖矿信号量

abort := make(chan struct{})

ethash.lock.Lock()

threads := ethash.threads

if ethash.rand == nil { // 产生一个可靠的随机数

seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))

if err != nil {

ethash.lock.Unlock()

return err

}

ethash.rand = rand.New(rand.NewSource(seed.Int64()))

}

ethash.lock.Unlock()

if threads == 0 {

threads = runtime.NumCPU()// 决定多少并发挖矿线程

}

if threads < 0 {

threads = 0 // 取消本地挖矿功能

}

// 将挖矿过程推送给远程挖矿者

if ethash.workCh != nil {

ethash.workCh <- &sealTask{block: block, results: results}

}

var (

pend sync.WaitGroup

locals = make(chan *types.Block)

)

for i := 0; i < threads; i++ {

pend.Add(1)

go func(id int, nonce uint64) { // 最重要的函数,etash.mine为挖矿函数

defer pend.Done()

ethash.mine(block, id, nonce, abort, locals)

}(i, uint64(ethash.rand.Int63()))

}

// 开启多线程,直到挖矿成功或者取消挖矿

go func() {

var result *types.Block

select {

case <-stop:

// 外部取消信号捕捉,直接关闭挖矿线程

close(abort)

case result = <-locals:

// 某一线程找到了合法块,通知其他挖矿线程关闭

select {

case results <- result:

default:

log.Warn("Sealing result is not read by miner", "mode", "local", "sealhash", ethash.SealHash(block.Header()))

}

close(abort)

case <-ethash.update:

// 重启所有挖矿线程

close(abort)

if err := ethash.Seal(chain, block, results, stop); err != nil {

log.Error("Failed to restart sealing after update", "err", err)

}

}

// Wait for all miners to terminate and return the block

pend.Wait()

}()

return nil

}

我们看到上文中大部分代码都在处理多线程关系,还有挖矿的开启和停止,用到了Go语言的核心功能–多线程并发。挖矿的代码就一行,是一个调用,调用了ethash.mine(block, id, nonce) 这个子函数进行真的苦力活PoW算法,下面我们查看一下这个具体挖矿的实现代码。

/consensus/ethash/sealer.go¶

// 通过PoW挖矿行为找到最终符合条件的nonce值

func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block) {

// 从区块头部获取必要的信息

var (

header = block.Header()

hash = ethash.SealHash(header).Bytes()

target = new(big.Int).Div(two256, header.Difficulty)

number = header.Number.Uint64()

dataset = ethash.dataset(number, false)

)

// 开启反复试算nonce值,直到算出,或者取消。

var (

attempts = int64(0)

nonce = seed

)

logger := log.New("miner", id)

logger.Trace("Started ethash search for new nonces", "seed", seed)

search:

for { // 死循环开始

select {

case <-abort:

// 如果我们取消了,停止

logger.Trace("Ethash nonce search aborted", "attempts", nonce-seed)

ethash.hashrate.Mark(attempts)

break search

default:

// 记录尝试次数

attempts++

if (attempts % (1 << 15)) == 0 {

ethash.hashrate.Mark(attempts)

attempts = 0

}

// 重要! 试算PoW算式下的nonce值

digest, result := hashimotoFull(dataset.dataset, hash, nonce)

// 重要! 成功找到nonce值的判定标准!

if new(big.Int).SetBytes(result).Cmp(target) <= 0 {

// 更新header,试算结束!

header = types.CopyHeader(header)

header.Nonce = types.EncodeNonce(nonce)

header.MixDigest = common.BytesToHash(digest)

// 成功找到块打包结束

select {

case found <- block.WithSeal(header):

logger.Trace("Ethash nonce found and reported", "attempts", nonce-seed, "nonce", nonce)

case <-abort:

logger.Trace("Ethash nonce found but discarded", "attempts", nonce-seed, "nonce", nonce)

}

break search

}

nonce++

}

}

runtime.KeepAlive(dataset)

}

在上方的代码中,总逻辑是一个死循环,循环内部反复试算nonce值直到符合难度规定,那么判断的条件就是一个依据,如下面这行代码所示。

if new(big.Int).SetBytes(result).Cmp(target) <= 0 {

这句话至关重要,如果试算出来的结果result小于target,则试算成功。那么又是如何试算的呢?我们仔细看可以看到这么一个试算函数。

digest, result := hashimotoFull(dataset.dataset, hash, nonce)

/consensus/ethash/algorithm.go¶

func hashimotoFull(dataset []uint32, hash []byte, nonce uint64) ([]byte, []byte) {

lookup := func(index uint32) []uint32 {

offset := index * hashWords

return dataset[offset : offset+hashWords]

}

// 将具体的hashimoto算法触发,获得最终的结果

return hashimoto(hash, nonce, uint64(len(dataset))*4, lookup)

}

上文可以看到hashimotoFull函数将计算的过程完全代理给了hashimoto函数,本身并没有过多的数据计算和操作,我们再深入到最深的兔子洞—hashitmoto()函数来看一下。

// 针对某个header和nonce,hashimoto函数采撷DataSet中部分数据来进行哈希

func hashimoto(hash []byte, nonce uint64, size uint64, lookup func(index uint32) []uint32) ([]byte, []byte) {

// 计算理论上用的到的“行”

rows := uint32(size / mixBytes)

// 组合header+nonce 形成 64 byte 的seed

seed := make([]byte, 40)

copy(seed, hash)

binary.LittleEndian.PutUint64(seed[32:], nonce)

seed = crypto.Keccak512(seed)

seedHead := binary.LittleEndian.Uint32(seed)

// 用seed开始“混合”操作

mix := make([]uint32, mixBytes/4)

for i := 0; i < len(mix); i++ {

mix[i] = binary.LittleEndian.Uint32(seed[i%16*4:])

}

// 混合入数据集DataSet中的数据

temp := make([]uint32, len(mix))

for i := 0; i < loopAccesses; i++ {

parent := fnv(uint32(i)^seedHead, mix[i%len(mix)]) % rows

for j := uint32(0); j < mixBytes/hashBytes; j++ {

copy(temp[j*hashWords:], lookup(2*parent+j))

}

fnvHash(mix, temp)

}

// 压缩混合

for i := 0; i < len(mix); i += 4 {

mix[i/4] = fnv(fnv(fnv(mix[i], mix[i+1]), mix[i+2]), mix[i+3])

}

mix = mix[:len(mix)/4]

digest := make([]byte, common.HashLength)

for i, val := range mix {

binary.LittleEndian.PutUint32(digest[i*4:], val)

}

// 返回混合的哈希值,输出

return digest, crypto.Keccak256(append(seed, digest...))

}

至此我们已经清晰地分析了整个试算nonce值的过程,整个过程犹如爱丽丝漫游仙境,需要层层向下探索兔子洞,按照“Seal -> mine -> hashimotoFull -> hashimoto”的顺序一层层往下解读源代码,找到试算nonce的过程,一旦找到合法的nonce立即停止多线程的mine挖矿过程,返回最终结果给Seal函数,形成合法的区块头。

Previous

© Copyright 2019, laalaguer.

Built with Sphinx using a

theme

provided by Read the Docs.

启动自己的以太坊节点 | ethereum.org

的以太坊节点 | ethereum.org跳转至主要内容学习用法构建参与研究搜索​​​​语言 ZH帮助更新此页面本页面有新版本,但现在只有英文版。请帮助我们翻译最新版本。翻译页面没有错误!此页面未翻译,因此特意以英文显示。不再显示Change page概述基础主题以太坊简介以太币简介去中心化应用程序简介Web2 与 Web3 的对比帐户交易区块以太坊虚拟机 (EVM)操作码Gas费用节点和客户端运行节点客户端多样性节点即服务节点架构轻客户端归档节点引导节点网络共识机制工作量证明矿工挖矿算法Dagger-HashimotoEthash权益证明Gasper弱主观性认证权益证明机制的奖励和惩罚权益证明攻击与防御密钥权益证明与工作量证明提出区块权益正明常见问题以太坊堆栈堆栈简介智能合约智能合约语言智能合约结构智能合约库测试用智能合约编译智能合约部署智能合约验证智能合约升级智能合约智能合约安全性智能合约形式化验证可组合性开发网络开发框架以太坊客户端APIJavaScript API后端APIJSON-RPC数据和分析区块浏览器存储集成开发环境 (IDE)编程语言DartDelphi.NETGolangJavaJavaScriptPythonRubyRust语言高级链桥标准令牌标准ERC-20:同质化代币ERC-721:非同质化代币 (NFT)ERC-777ERC-1155ERC-4626最大可提取价值 (MEV)预言机缩放乐观卷叠零知识卷叠状态通道侧链以太坊 Plasma 扩容解决方案Validium数据可用性网络层网络地址门户网络数据结构与编码默克尔前缀树递归长度前缀编码 (RLP)简单序列化 (SSZ)Web3 密钥存储定义设计基础设计和用户体验简介启动自己的以太坊节点上次修改时间: , 2023年12月8日查看贡献者在本页面前提条件选择一种方式运行环境和硬件设施本地或云端硬件要求即插即用解决方案在单板计算机上运行以太坊启动节点引导式设置手动客户端设置获取客户端软件客户端设置启动执行客户端运行执行客户端启动共识客户端运行共识客户端添加验证者使用节点访问远程过程调用运行节点保持节点在线创建客户端服务更新客户端运行额外服务监测节点延伸阅读相关主题运行你自己的节点为你提供各种好处,打开新的可能性,并为支持生态系统提供帮助。 这个页面将引导你启动自己的节点,并参与验证以太坊交易。注意,在合并之后,运行以太坊节点需要两种客户端,即执行层 (EL) 客户端和共识层 (CL) 客户端。 本页面将展示如何安装、配置和连接这两种客户端以运行以太坊节点。前提条件你应该明白什么是以太坊节点,以及你可能想要运行客户端的原因。 节点和客户端涵盖了这一主题。如果你不熟悉运行节点这一主题,或者正在寻找技术含量较低的方式,建议你先参阅我们为了便于用户理解而编撰的运行以太坊节点简介。选择一种方式要启动自己的以太坊节点,第一步是选择你的运行方式。 根据要求和各种可能性,你必须选择客户端实现(执行客户端和共识客户端)、环境(硬件、系统)和客户端设置参数。本页面将指导你做出这些决定,并帮助你找到运行以太坊实例的最合适方式。要选择客户端实现,请查看所有可用的主网就绪执行客户端和共识客户端,并了解客户端多样性。决定是在自己的硬件还是云端运行软件,同时考虑客户端的要求。准备好环境后,使用带有高级选项的终端,通过初学者友好界面或手动安装所选客户端。在节点运行和同步后,你便随时可以使用该节点,但请务必留意节点的维护。运行环境和硬件设施本地或云端以太坊客户端能够在消费级电脑上运行,并且不需要任何专用硬件,例如矿机。 因此,你可以根据需要选择多种节点部署方案。 简而言之,我们考虑在本地物理计算机和云端服务器上运行节点:云端服务商提供了高可用的服务器以及静态公共 IP 地址获得专用或虚拟服务器比自己搭建更加方便取舍是:是否需要信赖云服务商三方由于全节点所需的存储大小,租用服务器的价格可能会很高自有硬件更去信任并且更有主动权只需一次性投入可以购买预先配置好的机器你必须亲自准备并维护机器和网络,并有可能亲自对机器和网络进行故障排除上面两种方案各有优点,总结如上。 如果你正在寻找云端解决方案,除了许多传统云计算服务商外,还有一些专注于部署以太坊节点的服务商, 查看节点即服务,了解有关托管节点的更多选项。硬件不过,一个抗审查的去中心化网络不应该依赖于云服务提供商。 而且,在自己的本地硬件上运行节点对该生态系统来说更健康。 从估算数据(opens in a new tab)来看,在云端运行大部分节点可能引发单点故障。以太坊客户端可以在你的计算机、笔记本电脑、服务器甚至单板计算机上运行。 虽然可以在你的个人计算机上运行客户端,但为你的节点配备一台专用机器可以显著提高其性能和安全性,同时最大限度地减少对你的主计算机的影响。使用自己的硬件非常容易。 一般人可以选择一些简单的选项,技术水平较高的人士则可以在高级设置当中进行抉择。 接下来,我们了解一下在你的机器上运行以太坊客户端的要求和方法。要求硬件要求因客户端不同而异,但通常不是很高,因为节点只需保持同步即可。 不要将其与需要更多算力的挖矿混淆。 不过,功能更强大的硬件的确可以优化同步时间和性能。在安装任何客户端之前,请确保计算机有足够的资源运行它。 你可以在下面找到最低要求和推荐要求。硬件的瓶颈通常是磁盘空间。 同步以太坊区块链是一种高强度的输入/输出密集型操作,并且需要大量空间。 最好使用在同步完成后还有数百 GB 可用空间的固态硬盘 (SSD)。数据库的大小和初始同步速度取决于所选客户端、其配置和同步策略。你还要确保网络连接没有带宽限制(opens in a new tab)。 我们建议你使用不计流量的网络连接,因为初始同步和广播到网络的数据可能超过你的限额。操作系统所有客户端都支持主流操作系统——Linux、MacOS、Windows。 这意味着你可以在普通台式机或服务器上运行节点,并在这些设备上安装最适合你的操作系统 (OS)。 为了避免出现潜在的问题和安全漏洞,请确保你的操作系统为最新。最低要求2 核以上 CPU8 GB 内存2 TB 固态硬盘10 MB/秒以上带宽推荐的规格要求4 核以上高速 CPU16GB 以上内存2TB 以上高速固态硬盘25 MB/秒以上带宽你选择的同步模式和客户端将影响磁盘空间要求,但我们估计了下面每种客户端需要的磁盘空间。客户端磁盘大小(快照同步)磁盘大小(完整归档)Geth500GB+12TB 以上Nethermind500GB+12TB 以上Besu800GB 以上12TB 以上Erigon未提供2.5TB 以上注意:Erigon 未提供快照同步,但可以进行完全修剪 (~500GB)对于共识客户端,空间要求也取决于客户端实现和启用的功能(例如验证者、罚没者),但通常需要另外 200GB 磁盘空间存储信标数据。 由于验证者数量巨大,带宽负载也会增加。 你可以在此分析中找到关于共识客户端要求的详细信息(opens in a new tab)。即插即用解决方案即插即用解决方案是使用自身硬件运行节点的最简单方式。 来自供应商的预配置机器提供最简洁的体验:订购、连接、运行。 一切都已预配置好并自动运行,你可以通过直观的指南和仪表板监测和控制软件。DappNode(opens in a new tab)Avado(opens in a new tab)在单板计算机上运行以太坊运行以太坊节点的一种经济简便的方法是使用单板计算机,甚至可以使用 ARM 架构的单板机,如树莓派。 ARM 上的以太坊(opens in a new tab)为树莓派和其他 ARM 单板机提供便于运行的多种执行客户端和共识客户端映像。这类小型、实惠且高效的设备非常适合在家中运行节点,但请记住它们的性能有限。启动节点实际的客户端设置可以使用自动启动器完成,或者通过直接设置客户端软件手动完成。对于初级用户,推荐的方法是使用启动器,这种软件可以指导你完成安装并自动执行客户端设置过程。 但是,如果你有一些终端使用经验,手动设置步骤应该很容易完成。引导式设置一些用户友好的项目旨在改善客户端设置体验。 这些启动器提供自动客户端安装和配置,有些甚至提供图形界面用于引导式设置和监测客户端。以下是一些可以帮助你安装和控制客户端的项目,只需单击几下即可:DappNode(opens in a new tab) - DappNode 不仅仅可以在供应商提供的机器上安装。 该软件、实际的节点启动器和具有许多功能的控制中心可以在任意硬件上使用。eth-docker(opens in a new tab) - 使用 Docker 进行的自动化设置专注于简便和安全的质押,它需要用户具备基本的终端和 Docker 知识。我们推荐进阶用户可以选择此项目。Stereum(opens in a new tab) - 通过 SSH 连接在远程服务器上安装客户端的启动器,配备 GUI 设置指南、控制中心和许多其他功能。NiceNode(opens in a new tab) - 提供简便用户体验的启动器,可在你的计算机上运行节点。 只需选择客户端并单击几下即可启动它们。 仍在开发中。Sedge(opens in a new tab) - 节点设置工具,使用 CLI 向导自动生成 Docker 配置。 由 Nethermind 使用 Go 编写。手动客户端设置另一种选择是手动下载、验证和配置客户端软件。 即使一些客户端提供图形界面,手动设置仍然需要一些基本的终端使用技能,但它可以提供更多功能。如上所述,设置自己的以太坊节点需要运行一对共识客户端和执行客户端。 一些客户端可能包括另一类型的轻客户端,并且无需任何其他软件即可同步。 但是,完全去信任验证需要同时实现这两种客户端。获取客户端软件首先,你需要获取自己喜欢的执行客户端和共识客户端软件。你可以仅下载适合你的操作系统和架构的可执行应用或安装包。 始终验证下载安装包的签名和校验和。 一些客户端还提供存储库或 Docker 映像,以简化安装和更新。 所有客户端都是开源的,因此你也可以使用源代码构建它们。 这是一种更高阶的方法,但在某些情况下,你可能需要这么做。上述客户端列表中的链接文档提供各个客户端的安装说明。以下是客户端的发布页面,你可以在其中找到它们的预构建二进制文件或安装说明:执行客户端Besu(opens in a new tab)Erigon(opens in a new tab)(不提供预构建的二进制文件,必须编译)Geth(opens in a new tab)Nethermind(opens in a new tab)另外值得注意的是,客户端多样性有关执行层的问题之一。 我们建议读者考虑运行非主流执行客户端。共识客户端Lighthouse(opens in a new tab)Lodestar(opens in a new tab)(不提供预构建的二进制文件,仅提供 Docker 映像或使用源代码进行构建)Nimbus(opens in a new tab)Prysm(opens in a new tab)Teku(opens in a new tab)客户端多样性对于运行验证者的共识节点来说至关重要。 如果大多数验证者都在运行单一客户端实现,那么网络安全就会面临风险。 因此,我们建议考虑选择非主流客户端。查看最新的网络客户端使用情况(opens in a new tab),并了解关于客户端多样性的更多信息。验证软件从互联网下载软件时,建议验证其完整性。 此步骤是可选的,但特别是对于像以太坊客户端这样的关键基础设施,务必要了解潜在的攻击向量并避免它们。 如果下载了预构建的二进制文件,则需要信任它,并冒着攻击者将可执行文件替换为恶意文件的风险。开发者使用他们的 PGP 密钥签署已发布的二进制文件,这样你就可以通过加密方式验证你正在运行他们创建的软件。 你只需要获取开发者使用的公钥,公钥可以在客户端发布页面或文档中找到。 下载客户端版本及其签名后,你可以使用 PGP 实现(例如 GnuPG(opens in a new tab))轻松验证它们。 查看有关在 Linux(opens in a new tab) 或 Windows/MacOS(opens in a new tab) 上使用 gpg 验证开源软件的教程。另一种验证方式是确保所下载软件的哈希(一种唯一的加密指纹)与开发者提供的哈希相符。 这种方式甚至比使用 PGP 更容易,并且一些客户端仅提供此选项。 只需在下载的软件上运行哈希函数并将其与发布页面中的哈希进行比较。 例如:1sha256sum teku-22.6.1.tar.gz239b2f8c1f8d4dab0404ce70ea314ff4b3c77e9d27aff9d1e4c1933a5439767dde客户端设置安装、下载或编译客户端软件后,你就可以运行它了。 这仅意味着必须使用正确的配置执行客户端。 客户端提供丰富的配置选项,你可以通过它们启用各种功能。我们从可以显著影响客户端性能和数据使用的选项开始介绍。 同步模式是指下载和验证区块链数据的不同方法。 在启动节点前,你应该决定使用哪种网络和同步模式。 最重要的考虑因素是客户端需要的磁盘空间和同步时间。 关注客户端文档以便确定默认的同步模式。 如果默认的同步模式不适合你,请根据安全级别、可用数据和成本选择另一种同步模式。 除了同步算法之外,你还可以设置修剪不同类型的旧数据。 修剪可以删除过时的数据,例如删除最近区块上无法访问的状态树节点。其他基本配置选项包括:选择网络(主网或测试网)、为远程过程调用或 WebSocket 启用超文本传输协议端点等。 你可以在客户端相关文档中找到所有功能和选项。 你可以通过使用对应的标记在 CLI 或配置文件中直接执行客户端,以便设置不同的客户端配置。 每种客户端都有一点差异;有关配置选项的详细信息,请始终参阅其官方文档或帮助页面。进行测试时,你可能更愿意在其中一个测试网上运行客户端。 参阅受支持网络概览。要了解如何运行具有基本配置的执行客户端,请见下一节中的示例。启动执行客户端启动以太坊客户端软件之前,请最后检查环境是否已就绪。 例如,请确保:针对所选的网络和同步模式,磁盘空间足够。内存和 CPU 未被其他程序停止。操作系统已更新至最新版本。系统有正确的时间和日期。路由器和防火墙接受监听端口上的连接。 默认情况下,以太坊客户端使用监听 (TCP) 端口和发现端口 (UDP),两者默认均在 30303 上。首先在测试网上运行客户端,这有助于确保一切都正常运行。你需要在一开始就声明所有非默认的客户端配置。 你可以使用标记或配置文件来声明你的首选配置。 每种客户端的功能集和配置语法都不同。 请查看你的客户端相关文档,了解具体细节。执行客户端和共识客户端通过引擎应用程序接口(opens in a new tab)中指定的经过身份验证的端点进行通信。 为了连接到共识客户端,执行客户端必须在已知路径上生成 jwtsecret(opens in a new tab)。 出于安全和稳定性的原因,客户端应该在同一台机器上运行,并且两种客户端都必须知道该路径,因为该路径用于验证它们之间的本地远程过程调用连接。 执行客户端还必须为经过身份验证的应用程序接口定义一个监听端口。此令牌由客户端软件自动生成,但在某些情况下,你可能需要自己生成它。 你可以使用 OpenSSL(opens in a new tab) 生成该令牌:1openssl rand -hex 32 > jwtsecret运行执行客户端本节将指导你启动执行客户端。 它仅提供基本配置示例,该示例将使用以下设置启动客户端:指定要连接的网络,在我们的示例中为主网你也可以选择任一测试网络,用于设置的初步测试定义数据目录,包括区块链在内的所有数据都将存储在其中确保用真实路径代替该路径,例如指向外置驱动器的路径启用与客户端通信的接口包括用于与共识客户端通信的 JSON 远程过程调用和引擎应用程序接口为经过身份验证的应用程序接口定义 jwtsecret 的路径确保将示例路径替换为客户端可以访问的真实路径,例如 /tmp/jwtsecret请记住,这只是一个基本示例,所有其他设置都将设置为默认值。 请关注每种客户端的相关文档以了解默认的值、设置和功能。 有关更多功能的信息,例如运行验证者、监测等,请参考具体客户端的相关文档。请注意,示例中的反斜杠 \ 仅用于设置格式;配置标记可以在一行中定义。运行 Besu此示例在主网上启动 Besu,将区块链数据以默认格式存储在 /data/ethereum 下,启用 JSON 远程过程调用和引擎应用程序接口以连接共识客户端。 使用令牌 jwtsecret 对引擎应用程序接口进行身份验证,并且只允许来自 localhost 的调用。1besu --network=mainnet \2 --data-path=/data/ethereum \3 --rpc-http-enabled=true \4 --engine-rpc-enabled=true \5 --engine-host-allowlist="*" \6 --engine-jwt-enabled=true \7 --engine-jwt-secret=/path/to/jwtsecretBesu 还带有一个启动器选项,它会询问一系列问题并生成配置文件。 使用以下命令运行交互式启动器:1besu --XlauncherBesu 相关文档(opens in a new tab)包含更多选项和配置详细信息。运行 Erigon此示例在主网上启动 Erigon,将区块链数据存储在 /data/ethereum 下,启用 JSON 远程过程调用,定义允许的命名空间,并启用身份验证以连接由 jwtsecret 路径定义的共识客户端。1erigon --chain mainnet \2 --datadir /data/ethereum \3 --http --http.api=engine,eth,web3,net \4 --authrpc.jwtsecret=/path/to/jwtsecret默认情况下,Erigon 使用 8GB 机械硬盘执行完全同步,这将产生超过 2TB 的归档数据。 确保 datadir 指向有足够可用空间的磁盘,或者考虑使用可以修剪不同类型数据的 --prune 标记。 查看 Erigon 的 --help 了解更多信息。运行 Geth此示例在主网上启动 Geth,将区块链数据存储在 /data/ethereum 下,启用 JSON 远程过程调用并定义允许的命名空间。 它还会启用身份验证(以便连接需要使用 jwtsecret 路径的共识客户端)以及定义允许哪些连接的选项,在我们的示例中仅允许来自 localhost 的连接。1geth --mainnet \2 --datadir "/data/ethereum" \3 --http --authrpc.addr localhost \4 --authrpc.vhosts="localhost" \5 --authrpc.port 85516 --authrpc.jwtsecret=/path/to/jwtsecret查看相关文档中的所有配置选项(opens in a new tab),并了解关于运行 Geth 和共识客户端(opens in a new tab)的更多信息。运行 NethermindNethermind 提供各种安装选项(opens in a new tab)。 该软件包附带各种二进制文件,包括一个带有引导式设置的启动器,它将帮助你以交互方式创建配置。 或者,你会找到可执行文件 Runner,并且可以使用配置标记运行它。 默认情况下启用 JSON 远程过程调用。1Nethermind.Runner --config mainnet \2 --datadir /data/ethereum \3 --JsonRpc.JwtSecretFile=/path/to/jwtsecretNethermind 相关文档提供了有关运行 Nethermind 和共识客户端的完整指南(opens in a new tab)。执行客户端将启动其核心功能及所选端点,并开始寻找对等节点。 成功发现对等节点后,该客户端开始同步。 执行客户端将等待来自共识客户端的连接。 当客户端成功同步到最新状态时,最新的区块链数据将可用。启动共识客户端共识客户端必须以正确的端口配置启动,才能与执行客户端建立本地远程过程调用连接。 它在运行时必须使用公开的执行客户端端口作为配置参数。共识客户端还需要执行客户端的 jwt-secret 的路径,以便对它们之间的远程过程调用连接进行身份验证。 与上面的执行示例类似,每种共识客户端都有一个配置标记,该标记使用 jwt 令牌文件的路径作为参数。 此路径必须与提供给执行客户端的 jwt-secret 路径一致。如果你打算运行验证者,确保添加一个配置标记以指定接收费用的以太坊地址。 这是为你的验证者积攒以太币奖励的地址。 每种共识客户端都有一个将以太坊地址作为参数的选项,例如 --suggested-fee-recipient=0xabcd1。在测试网上启动信标节点时,可以使用公共端点进行检查点同步(opens in a new tab),从而大大节省同步时间。运行共识客户端运行 Lighthouse在运行 Lighthouse 之前,请在 Lighthouse 手册(opens in a new tab)中详细了解如何安装和配置它。1lighthouse beacon_node \2 --network mainnet \3 --datadir /data/ethereum \4 --http \5 --execution-endpoint http://127.0.0.1:8551 \6 --execution-jwt /path/to/jwtsecret运行 Lodestar通过编译或下载 Docker 映像来安装 Lodestar 软件。 在相关文档(opens in a new tab)和更全面的设置指南(opens in a new tab)中了解更多信息。1lodestar beacon \2 --rootDir="/data/ethereum" \3 --network=mainnet \4 --eth1.enabled=true \5 --execution.urls="http://127.0.0.1:8551" \6 --jwt-secret="/path/to/jwtsecret"运行 NimbusNimbus 包括共识客户端和执行客户端。 它也可以在各种设备上运行,甚至可以在算力很一般的设备上运行。 安装依赖项和 Nimbus(opens in a new tab)后,你可以运行它的共识客户端:1nimbus_beacon_node \2 --network=mainnet \3 --web3-url=http://127.0.0.1:8551 \4 --rest \5 --jwt-secret="/path/to/jwtsecret"运行 PrysmPrysm 带有脚本,可实现轻松自动安装。 详细信息可以在 Prysm 相关文档(opens in a new tab)中找到。1./prysm.sh beacon-chain \2 --mainnet \3 --datadir /data/ethereum \4 --execution-endpoint=http://localhost:8551 \5 --jwt-secret=/path/to/jwtsecret运行 Teku1teku --network mainnet \2 --data-path "/data/ethereum" \3 --ee-endpoint http://localhost:8551 \4 --ee-jwt-secret-file "/path/to/jwtsecret"当共识客户端连接到执行客户端读取存款合约并识别验证者时,它也连接到其他对等信标节点并开始从创世块同步共识时隙。 信标节点达到当前时段后,信标应用程序接口将可供验证者使用。 了解关于信标节点应用程序接口(opens in a new tab)的更多信息。添加验证者共识客户端充当验证者要连接的信标节点。 每种共识客户端都有自己的验证者软件,后者在各自的相关文档中都有详细描述。运行自己的验证者便可以进行单独质押,这是支持以太坊网络的最有影响的去信任方法。 然而,单独质押需要存入 32 个以太币。 若想在自己的节点上运行验证者并质押较少数量的以太币,你可能会对由无需许可的节点运营商组成的去中心化池感兴趣,例如 Rocket Pool(opens in a new tab)。开始质押和生成验证者密钥的最简单方法是使用 Goerli 测试网质押启动板(opens in a new tab),它允许你通过在 Goerli 上运行节点(opens in a new tab)来测试你的设置。 当准备好使用主网时,你可以使用主网质押启动板(opens in a new tab)重复这些步骤。研读质押页面以了解质押选项概述。使用节点执行客户端提供远程过程调用应用程序接口端点;在以太坊网络上,你可以通过多种方式使用这些端点提交交易、与智能合约交互或部署智能合约:使用合适的协议(例如,curl)手动调用端点附加提供的控制台(例如 geth attach)使用 Web3 库在应用中实现端点,例如 web3.py(opens in a new tab) 和 ethers(opens in a new tab)不同的客户端有不同的远程过程调用端点实现。 不过,你可以选择一种标准 JSON-RPC 与每种客户端搭配使用。 想要了解概况,请阅读 JSON-RPC 文档。 需要从以太坊网络中获取信息的应用,可以使用此远程过程调用。 例如,受欢迎的钱包 MetaMask 可让你连接到自己的远程过程调用端点(opens in a new tab),该端点具有卓越的隐私和安全优势。共识客户端都公开一个信标应用程序接口(opens in a new tab),可用于检查共识客户端的状态,或者通过使用 Curl(opens in a new tab) 等工具发送请求来下载区块和共识数据。 更多相关信息可在每种共识客户端的相关文档中找到。访问远程过程调用执行客户端 JSON-RPC 的默认端口是 8545,但可以在配置中修改本地端点的端口。 默认情况下,远程过程调用接口只能在计算机的本地主机上访问。 为了让该端口可被远程访问,你可以通过将地址改为 0.0.0.0 公开它。 这样就可以通过本地网络或公共互联网协议地址访问该端口。 大多数情况下,你还需要在路由器上设置端口转发。在互联网上公开端口时应保持谨慎,因为这会让互联网上的任何人都可以控制你的节点。 恶意行为者可以通过访问你的节点让你的系统下线,或者如果你将客户端用作钱包,他们会窃取你的资金。解决该问题的办法是,禁止修改可能有危害的远程过程调用方法。 例如,对于 Geth,你可以使用标记 —http.api web3,eth,txpool 声明可修改的方法。开发边缘层应用程序接口或 Web 服务器应用(如 Nginx)并将它们连接到客户端的本地地址和端口,这样做可扩展对远程过程调用接口的访问。 利用中间层还让开发者能够设置远程过程调用接口的安全 https 连接证书。设置 Web 服务器、代理或面向外部的表现层状态转换应用程序接口,并不是访问节点的远程过程调用端点的唯一方法。 另一种设置可公开访问端点且保护隐私的方法是,将节点托管在自己的 Tor(opens in a new tab) 洋葱服务上。 这将让你在本地网络外部无需静态公共互联网协议地址或开放的端口也能访问此远程过程调用端口。 然而,使用此配置可能只允许通过 Tor 网络访问远程过程调用端点,但并非所有应用程序都支持 Tor 网络,从而可能导致发生连接问题。为此,你必须创建自己的洋葱服务(opens in a new tab)。 查看有关洋葱服务设置的相关文档(opens in a new tab)以托管你自己的节点。 你可以将其指向具有远程过程调用端口代理的 Web 服务器,或者直接指向远程过程调用。最后,访问内部网络最流行的方式之一是通过虚拟专用网连接。 根据你的用例和需要访问节点的用户数,也许可以选择安全的虚拟专用网连接。 OpenVPN(opens in a new tab) 是一种功能完善的安全套接层虚拟专用网,它使用行业标准安全套接字层/传输层安全协议实现了开放式系统互联二层或三层安全网络扩展,支持基于证书、智能卡和/或用户名/密码凭据的灵活客户端身份验证方法,并允许用户或群组特定的访问控制策略(使用应用于虚拟专用网虚拟接口的防火墙规则)。运行节点你应该定期监控你的节点,确保它正常运行。 你可能还需要偶尔对它进行维护。保持节点在线你的节点不必一直在线,但你应该尽可能让节点保持在线,使其与网络保持同步。 你可以将其关闭以重新启动,但请记住:如果正在向磁盘写入最近的网络状态,关闭节点可能需要花费几分钟。强制关闭会破坏数据库,这可能需要你重新同步整个节点。客户端将无法与网络同步,重启后,客户端需要重新同步。 虽然节点可以从它最近一次关闭的位置开始同步,但此过程需要的时间取决于它离线的时间。但是,共识层的验证者节点就需要一直在线。验证者节点离线将影响所有依赖它的服务。 如果你是为了质押而运行节点,应该尽可能地减少停机时间。创建客户端服务考虑创建一个在启动时自动运行客户端的服务。 例如,在 Linux 服务器上,最佳做法是创建一种服务,例如使用 systemd,为有限权限的用户执行配置正确的客户端并自动重启。更新客户端你应该通过安装最新的安全补丁、功能和以太坊改进提案,让客户端软件更新到最新版本。 特别是在硬分叉之前,确保运行正确的客户端版本。在重要的网络更新之前,以太坊基金会在其博客(opens in a new tab)上发布相关文章。 你可以订阅这些公告(opens in a new tab),以便在你的节点需要更新时收到邮件通知。更新客户端非常简单。 每种客户端在其相关文档中都有具体说明,但通常更新过程仅包括下载最新版本并使用正确的可执行文件重启而已。 客户端应该会从上一次中断的位置继续,但请应用所有更新。每种客户端实现都有一个人类可读的版本字符串,该字符串在点对点协议中使用但也可以从命令行访问。 该版本字符串让用户可以检查他们运行的客户端版本是否正确,并支持区块浏览器和用来量化网络上特定客户端分布的其他分析工具。 有关版本字符串的更多信息,请参阅各客户端相关文档。运行额外服务运行自己的节点,可以让你使用需要直接访问以太坊客户端远程过程调用的服务。 这些服务构建在以太坊上,如二层网络解决方案、钱包后端、区块浏览器、开发者工具和其他以太坊基础设施。监测节点为了正确监测节点,请考虑收集指标。 客户端提供了指标端点,因此你可以获得有关节点的全面数据。 使用 InfluxDB(opens in a new tab) 或 Prometheus(opens in a new tab) 等工具创建数据库,并且可以在 Grafana(opens in a new tab) 等软件中将其可视化并转换成图表。 在可视化节点和整个网络时,Grafana 有许多设置和各种仪表版可供使用。 例如,查看有关监测 Geth 的教程。在监测过程中,请务必密切关注机器的性能。 在节点初始同步期间,客户端软件可能会占用大量 CPU 和内存资源。 除了 Grafana,你也可以使用操作系统自带的 htop 或 uptime 等工具来监测节点。延伸阅读以太坊质押指南(opens in a new tab) – Somer Esat,定期更新指南 | 如何在主网上为以太坊质押设置验证者(opens in a new tab) – CoinCashew,定期更新有关在测试网上运行验证者的 ETHStaker 指南(opens in a new tab) – ETHStaker,定期更新面向节点运营商的合并常见问题解答(opens in a new tab) - 2022 年 7 月分析成为已验证以太坊全节点的硬件要求(opens in a new tab) - Albert Palau,2018 年 9 月 24 日运行以太坊全节点:勉励者指南(opens in a new tab) – Justin Leroux,2019 年 11 月 7 日在以太坊主网上运行 Hyperledger Besu 节点:优点、要求和设置(opens in a new tab) – Felipe Faraggi,2020 年 5 月 7 日部署具有监测堆栈的 Nethermind 以太坊客户端(opens in a new tab) – Nethermind.eth,2020 年 7 月 8 日相关主题节点和客户端区块网络back-to-top ↑本文对你有帮助吗?是否前一页节点和客户端下一页客户端多样性编辑页面(opens in a new tab)在本页面前提条件选择一种方式运行环境和硬件设施本地或云端硬件要求即插即用解决方案在单板计算机上运行以太坊启动节点引导式设置手动客户端设置获取客户端软件客户端设置启动执行客户端运行执行客户端启动共识客户端运行共识客户端添加验证者使用节点访问远程过程调用运行节点保持节点在线创建客户端服务更新客户端运行额外服务监测节点延伸阅读相关主题网站最后更新: 2024年3月13日(opens in a new tab)(opens in a new tab)(opens in a new tab)学习学习中心什么是以太坊?什么是以太币 (ETH)?以太坊钱包什么是 Web3?智能合约Gas fees运行节点以太坊安全和预防欺诈措施测试中心以太坊词汇表用法指南选择钱包获取以太币Dapps - 去中心化应用稳定币NFT - 非同质化代币DeFi - 去中心化金融DAO - 去中心化自治组织去中心化身份质押ETH二层网络构建构建者首页教程相关文档通过编码来学习设置本地环境资助基础主题用户体验/用户界面设计基础Enterprise - Mainnet EthereumEnterprise - Private Ethereum参与社区中心在线社区以太坊活动为 ethereum.org 做贡献翻译计划以太坊漏洞悬赏计划以太坊基金会以太坊基金会的博客(opens in a new tab)生态系统支持方案(opens in a new tab)Devcon(opens in a new tab)研究以太坊白皮书以太坊路线图安全性增强以太坊技术史开放研究以太坊改进提案 (Eip)以太坊治理关于我们以太坊品牌资产Code of conduct工作机会隐私政策使用条款缓存政策联系我们(opens in a new tab)本页面对你有帮

以太坊1.9挖矿启动过程源码阅读 | 曹欢的博客

以太坊1.9挖矿启动过程源码阅读 | 曹欢的博客

caohuan

全部文章(75)

以太坊(9)

defi(4)

fabric(14)

区块链(18)

golang(12)

java(2)

linux(13)

数据库(3)

友情链接

叶落阁

全部文章

大纲

零知识证明

路印协议

区块链

以太坊

beego

defi

fabric

java

ipfs私网搭建

2022/06/15

安装leveldb

2022/06/14

陆羽协议5-使用docker配置fabric同构跨链

2022/03/01

陆羽协议4-异构跨链

2022/02/21

陆羽协议3-同构跨链

2022/02/13

陆羽协议2-同构多链互相访问

2022/02/11

k8s常用命令记录

2022/01/13

Dockerfile

2021/12/26

docker命令

2021/12/25

陆羽协议1-单链调用

2021/12/21

陆羽协议

2021/12/12

k8s

2021/11/14

Mac下的npm、nrm、nvm

2021/10/28

使用公钥方式登录服务器

2021/10/27

使用go调用智能合约

2021/09/06

创建自己的以太坊生态(2)

2021/08/21

创建自己的以太坊生态(1)

2021/08/14

uniswapV2(4)-周边源码解析

2021/07/24

uniswapV2(3)-源码解析

2021/07/20

uniswapV2(2)-运行逻辑

2021/07/19

uniswapV2(1)-白皮书

2021/07/18

各种环境下各种包的安装

2021/06/11

filecoin环境搭建

2021/05/26

以太坊1.9区块同步源码解析

2021/04/15

以太坊1.9consensus包解析

2021/03/18

以太坊1.9挖矿启动过程源码阅读

2021/03/11

git常用命令记录

2021/02/25

fabric常用命令

2021/02/13

gin入门

2020/12/20

go build的ldflage参数

2020/11/13

使用gdb调试golang程序

2020/11/12

make及makefile

2020/10/27

利用reflect包把struct转[]string

2020/08/24

fabric-go-sdk的使用

2020/07/18

fabric学习(11)——fabric-ca的使用

2020/07/18

查看机器配置

2020/07/13

beego中设置路由的几种方式

2020/06/25

修改亚马逊登录方式为密码登录

2020/06/11

fabric学习(10)——在3个组织基础上新建一个channel

2020/05/31

fabric学习(9)——使用CouchDB及索引的操作

2020/05/25

fabric学习(8)——chaincode

2020/05/22

fabric学习(7)——更新channel配置

2020/03/09

fabric学习(6)——添加组织机构(2)

2020/03/03

fabric学习(5)——添加组织机构(1)

2020/02/26

fabric学习(4)——在新创建的联盟中创建channel

2020/02/23

fabric学习(3)——创建联盟

2020/02/22

fabric学习(2)——不使用byfn搭建fabric网络(2)

2020/02/19

fabric学习(1)——不使用byfn搭建fabric网络(1)

2020/02/18

gomod、govendor的使用

2019/12/10

修改以太坊的地址思路

2019/11/30

零知识证明

2019/11/11

路印协议

2019/10/28

tendermint提供的RPC接口(三)自定义DeliverTx的响应

2019/09/10

tendermint提供的RPC接口(二)

2019/09/09

tendermint提供的RPC接口(一)

2019/09/08

windows环境使用tendermint

2019/09/06

sync.Mutex互斥锁的用法

2019/08/28

defer的执行顺序

2019/08/24

Go语言命令行库urfave/cli简介

2019/07/12

以太坊阻止日蚀攻击

2019/07/12

golang时间戳转换

2019/05/23

Go规范

2019/02/28

fmt格式占位符

2019/01/11

solidity知识点总结

2018/09/14

PBFT每个步骤的详细消息要素和签名内容

2018/07/11

比特币以太坊eos地址生成

2018/05/21

fabric检查点(checkpoint)分析

2018/04/03

各种主流链的HASH算法、PKI及秘钥长度

2018/03/28

比特币、以太坊、比特股时间误差处理

2018/03/22

linux常用命令记录

2017/07/11

orcale删除当前用户下所有的表

2017/05/23

oracle控制台常用命令

2017/04/19

sqlserver解决锁表

2016/10/25

eclipse操作

2016/10/20

keytool生成证书请求文件(.csr)

2016/08/25

<

>

以太坊1.9挖矿启动过程源码阅读

以太坊

发布时间 : 2021-03-11 10:57

字数:3k

1,makeFullNode1.1 newWorker1.1.1 mainLoop()监听的channelnewWorkChchainSideChtxsChexitChtxsSub.Err()chainHeadSub.Err()chainSideSub.Err()1.1.2 newWorkLoop()监听的channelstartCh & chainHeadChtimer.CresubmitIntervalChresubmitAdjustChexitCh1.1.3 resultLoop()监听的channelresultChexitCh1.1.4 taskLoop()监听的channeltaskChexitCh1.2 miner.update()2,startNode

之前阅读过以太坊1.7.x版本的源码,现在升级到了1.9.25,很多源码都做了很大的改动,网上还没有相关的源码阅读,因此决定自己分享一下。

本文介绍挖矿相关的源码,其余部分不做赘述。

geth启动时,进入的是cmd/geth/main.go中的main方法,执行main方法之前会先执行init方法,init方法中加载了很多命令行参数,关于命令行参数的介绍:Go语言命令行库urfave/cli简介 。

启动geth时,如果没有加console参数,会执行main.go中的geth方法:

func geth(ctx *cli.Context) error {

if args := ctx.Args(); len(args) > 0 {

return fmt.Errorf("invalid command: %q", args[0])

}

prepare(ctx)//检查运行环境及机器配置等

stack, backend := makeFullNode(ctx)//stack就是node实例,backend是service

defer stack.Close()

startNode(ctx, stack, backend)

stack.Wait()

return nil

}

如果加了console参数,会执行

cmd/geth/consolecmd.go中的localConsole方法:

func localConsole(ctx *cli.Context) error {

// Create and start the node based on the CLI flags

prepare(ctx)//检查运行环境及机器配置等

stack, backend := makeFullNode(ctx)

startNode(ctx, stack, backend)

defer stack.Close()

.....

}

两处地方都是先执行makeFullNode方法,再执行startNode方法。

1,makeFullNodefunc makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {

stack, cfg := makeConfigNode(ctx)//配置节点,配置级别:启动参数>配置文件>默认配置

backend := utils.RegisterEthService(stack, &cfg.Eth)//注册ethService

...

}

重点关注一下RegisterEthService方法中的New方法,位于eth/backend.go:

func RegisterEthService(stack *node.Node, cfg *eth.Config) ethapi.Backend {

...

backend, err := eth.New(stack, cfg)

...

return backend.APIBackend

}

func New(stack *node.Node, config *Config) (*Ethereum, error) {

// 设置轻节点及同步模式

// 设置gasPrice

// 设置快照缓存

// 设置创世块SetupGenesisBlock

// 初始化Ethereum对象等等

...

// 创建矿工,创建完成后等待启动停止信号

eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock)

eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData))

...

}

进入miner.New方法

func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(block *types.Block) bool) *Miner {

miner := &Miner{

eth: eth,

mux: mux,

engine: engine,

exitCh: make(chan struct{}),

startCh: make(chan common.Address),

stopCh: make(chan struct{}),

worker: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock, true),

}

go miner.update()

return miner

}

1.1 newWorker位于miner/worker.go

func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool, init bool) *worker {

//初始化worker对象

worker := &worker{

config: config,

chainConfig: chainConfig,

engine: engine,

eth: eth,

mux: mux,

chain: eth.BlockChain(),

isLocalBlock: isLocalBlock,

localUncles: make(map[common.Hash]*types.Block),

remoteUncles: make(map[common.Hash]*types.Block),

unconfirmed: newUnconfirmedBlocks(eth.BlockChain(), miningLogAtDepth),

pendingTasks: make(map[common.Hash]*task),

txsCh: make(chan core.NewTxsEvent, txChanSize),

chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),

chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize),

newWorkCh: make(chan *newWorkReq),

taskCh: make(chan *task),

resultCh: make(chan *types.Block, resultQueueSize),

exitCh: make(chan struct{}),

startCh: make(chan struct{}, 1),

resubmitIntervalCh: make(chan time.Duration),

resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize),

}

...

//重点关注这几个loop

go worker.mainLoop()

go worker.newWorkLoop(recommit)

go worker.resultLoop()

go worker.taskLoop()

// 提交一个初始化的pending状态

if init {

worker.startCh <- struct{}{}

}

return worker

}

四个loop都是开启无限循环等待指示,接收到不同channel发送过来的命令会执行不同的操作

这些channel都定义在miner/worker.go中的type worker struct {}中

1.1.1 mainLoop()监听的channelnewWorkCh

chainSideCh

txsCh

exitCh

txsSub.Err()

chainHeadSub.Err()

chainSideSub.Err()

newWorkCh

case req := <-w.newWorkCh:

w.commitNewWork(req.interrupt, req.noempty, req.timestamp)

执行commitNewWork方法

func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) {

...

//检查系统时间和当前区块时间差异

//新建一个区块头,填入父区块号,区块高度,gasLimit,时间戳等

//检查coinbase是否存在

//Prepare方法是consenus包下面定义的Engine的接口,由consenus/ethash和clique包分别实现其所有方法,包含Prepare方法

//ethash实现的是pos算法,clique实现的是poa算法,poa算法主要运行在测试网上,之所以不在测试网也使用pos是因为测试网算力不足,pos会遭到攻击

//本文主要分析ethash算法的挖矿过程,除了特别说明,下文所有介绍的Engine接口的实现算法都是ethash算法

//Prepare方法是计算当前区块所需要的难度值,即header.Difficulty,方便后续计算hash的时候做比较(pos算法精髓)

if err := w.engine.Prepare(w.chain, header); err != nil {

log.Error("Failed to prepare header for mining", "err", err)

return

}

//检查是否有DAO硬分叉

//组装叔块,叔块不能距离当前块的高度超过7

//组装交易池中的交易

//组装成区块并提交新交易

w.commit(uncles, w.fullTaskHook, true, tstart)

}

commit方法

func (w *worker) commit(uncles []*types.Header, interval func(), update bool, start time.Time) error {

...

//FinalizeAndAssemble也是ethash包中的方法,根据传入参数组装成区块

block, err := w.engine.FinalizeAndAssemble(w.chain, w.current.header, s, w.current.txs, uncles, receipts)

...

//将组装好的区块和数据发送给taskCh这个channel,该channel是在taskLoop中监听的channel,详见下文

case w.taskCh <- &task{receipts: receipts, state: s, block: block, createdAt: time.Now()}:

w.unconfirmed.Shift(block.NumberU64() - 1)

log.Info("Commit new mining work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()),

"uncles", len(uncles), "txs", w.current.tcount,

"gas", block.GasUsed(), "fees", totalFees(block, receipts),

"elapsed", common.PrettyDuration(time.Since(start)))

...

}

chainSideCh这个channel仅是用于测试环境,不再分析

txsCh接收交易的channel,接收到交易后,如果共识引擎没有工作,就把交易提交到交易池中。如果共识引擎没在工作,但当前是dev环境或者poa共识,那么也会调用commitNewWork方法参与出块

exitCh接收到退出信号,停止mainLoop循环

txsSub.Err()订阅交易错误,停止mainLoop循环

chainHeadSub.Err()订阅区块头错误,停止mainLoop循环

chainSideSub.Err()订阅ChainSide错误,停止mainLoop循环

1.1.2 newWorkLoop()监听的channelstartCh

chainHeadCh

timer.C

resubmitIntervalCh

resubmitAdjustCh

exitCh

先看看commit和clearPending两个方法:

//中止正在执行的事务,然后重新提交一个新的任务,向newWorkCh通道发消息,mainLoop接收到消息开始工作

commit := func(noempty bool, s int32) {

if interrupt != nil {

atomic.StoreInt32(interrupt, s)

}

interrupt = new(int32)//0

w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty, timestamp: timestamp}

timer.Reset(recommit)

atomic.StoreInt32(&w.newTxs, 0)

}

// 清除旧的pending状态的任务,pendingTask是做什么用的会在taskLoop中说到

clearPending := func(number uint64) {

w.pendingMu.Lock()

for h, t := range w.pendingTasks {

if t.block.NumberU64()+staleThreshold <= number {

delete(w.pendingTasks, h)

}

}

w.pendingMu.Unlock()

}

startCh & chainHeadCh都是先执行clearPending再执行commit,向mainLoop传递newWork消息

timer.C每隔一段时间T(不能低于1秒),检查是否有新交易,如果有新交易,就把新交易也重新统计,方便找到更高手续费的交易,调用commit方法。如果没有新交易,则继续循环

resubmitIntervalCh用于设置T的大小,即间隔多久会检查新交易,最小不能低于1秒,是通过api中的miner.SetRecommitInterval调用的

resubmitAdjustCh用于增加或者减少矿工重新提交的时间间隔

exitCh退出Loop

1.1.3 resultLoop()监听的channelresultCh

exitCh

resultChcase block := <-w.resultCh:

// Short circuit when receiving empty result.

if block == nil {

continue

}

// Short circuit when receiving duplicate result caused by resubmitting.

if w.chain.HasBlock(block.Hash(), block.NumberU64()) {

continue

}

var (

sealhash = w.engine.SealHash(block.Header())

hash = block.Hash()

)

w.pendingMu.RLock()

task, exist := w.pendingTasks[sealhash]

w.pendingMu.RUnlock()

if !exist {

log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", hash)

continue

}

// Different block could share same sealhash, deep copy here to prevent write-write conflict.

var (

receipts = make([]*types.Receipt, len(task.receipts))

logs []*types.Log

)

for i, receipt := range task.receipts {

// add block location fields

receipt.BlockHash = hash

receipt.BlockNumber = block.Number()

receipt.TransactionIndex = uint(i)

receipts[i] = new(types.Receipt)

*receipts[i] = *receipt

// Update the block hash in all logs since it is now available and not when the

// receipt/log of individual transactions were created.

for _, log := range receipt.Logs {

log.BlockHash = hash

}

logs = append(logs, receipt.Logs...)

}

// Commit block and state to database.

_, err := w.chain.WriteBlockWithState(block, receipts, logs, task.state, true)

if err != nil {

log.Error("Failed writing block to chain", "err", err)

continue

}

log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash,

"elapsed", common.PrettyDuration(time.Since(task.createdAt)))

// Broadcast the block and announce chain insertion event

w.mux.Post(core.NewMinedBlockEvent{Block: block})

// Insert the block into the set of pending ones to resultLoop for confirmations

w.unconfirmed.Insert(block.NumberU64(), block.Hash())

主要做了4件事:

1,校验收到区块的hash是否在pendingTask内

2,尝试写入本地账本、更改世界状态

3,广播出去

4,把该块加入待确认的块中,等待确认

exitCh退出Loop

1.1.4 taskLoop()监听的channeltaskCh

exitCh

taskChtaskCh接收到的消息,即为后续需要执行的task

case task := <-w.taskCh:

if w.newTaskHook != nil {

w.newTaskHook(task)

}

// 先调用SealHash方法,返回一个区块hash

sealHash := w.engine.SealHash(task.block.Header())

if sealHash == prev {

continue

}

// Interrupt previous sealing operation

interrupt()

stopCh, prev = make(chan struct{}), sealHash

if w.skipSealHook != nil && w.skipSealHook(task) {

continue

}

w.pendingMu.Lock()

//把该task加入pendingTasks,前文提到过,pending太久的任务会被删除

w.pendingTasks[sealHash] = task

w.pendingMu.Unlock()

//调用Seal方法开始挖矿,使用不同的nonce去计算,直到找到难度满足的nonce,找到区块后,发送到resultCh这个channel中,resultCh接收到的消息是在上文

//介绍的resultLoop中进行处理的

if err := w.engine.Seal(w.chain, task.block, w.resultCh, stopCh); err != nil {

log.Warn("Block sealing failed", "err", err)

}

exitCh

退出Loop

整理如下图:

1.2 miner.update()这个方法比较好理解

func (miner *Miner) update() {

//订阅downloader相关频道

events := miner.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{})

defer func() {

if !events.Closed() {

events.Unsubscribe()

}

}()

shouldStart := false

canStart := true

dlEventCh := events.Chan()

for {

select {

//接收到downloader频道的消息

case ev := <-dlEventCh:

if ev == nil {

// Unsubscription done, stop listening

dlEventCh = nil

continue

}

switch ev.Data.(type) {

//如果是开始下载的信号,就先同步再挖矿

case downloader.StartEvent:

wasMining := miner.Mining()

miner.worker.stop()

canStart = false

if wasMining {

// Resume mining after sync was finished

shouldStart = true

log.Info("Mining aborted due to sync")

}

//如果是下载失败的信号,就直接开始挖矿

case downloader.FailedEvent:

canStart = true

if shouldStart {

miner.SetEtherbase(miner.coinbase)

miner.worker.start()

}

//如果是下载完成的信号,也直接开始挖矿

case downloader.DoneEvent:

canStart = true

if shouldStart {

miner.SetEtherbase(miner.coinbase)

miner.worker.start()

}

// Stop reacting to downloader events

events.Unsubscribe()

}

//如果是miner.startCh传来了信号,则是开始挖矿的信号,检查条件满足后,调用miner.worker.start()方法

case addr := <-miner.startCh:

miner.SetEtherbase(addr)

if canStart {

miner.worker.start()

}

shouldStart = true

case <-miner.stopCh:

shouldStart = false

miner.worker.stop()

case <-miner.exitCh:

miner.worker.close()

return

}

}

}

miner.worker.start()方法向newWorkLoop中的startCh传递了消息,矿工开始工作

func (w *worker) start() {

atomic.StoreInt32(&w.running, 1)

w.startCh <- struct{}{}

}

2,startNodefunc startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) {

...

utils.StartNode(stack)

...

//账户相关操作

}

func StartNode(stack *node.Node) {

...

//如果启动参数上面带有--mine或者是--dev(开发测试模式)的话

if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {

//

...

//调用eth/api_backend.go中的startMining方法

if err := ethBackend.StartMining(threads); err != nil {

utils.Fatalf("Failed to start mining: %v", err)

}

}

}

StartMining则会调用eth/backend.go中的StartMining方法

func (b *EthAPIBackend) StartMining(threads int) error {

return b.eth.StartMining(threads)

}

同样的,在控制台内调用miner.start()方法的时候,也会调用该方法

func (api *PrivateMinerAPI) Start(threads *int) error {

if threads == nil {

return api.e.StartMining(runtime.NumCPU())

}

return api.e.StartMining(*threads)

}

下面看看StartMining方法:

func (s *Ethereum) StartMining(threads int) error {

//设置挖矿线程数量

//设置gasPrice

//设置etherbase

//检查是否是poa

//最后开启新的协程去挖矿

go s.miner.Start(eb)

}

return nil

}

最后start方法很简单,就是把coinbase传递到startCh这个channel中去,还记得这个channel吗?在newWorkLoop中

func (miner *Miner) Start(coinbase common.Address) {

miner.startCh <- coinbase

}

至此以太坊挖矿启动的过程就分析完了,还有一个疑问,在启动了四个loop之后,为什么要调用下面的代码发送消息

if init {

worker.startCh <- struct{}{}

}

debug之后发现,这其实是为了提交一个初始化的pending状态,并且在后续的代码中还会检查work对象中running字段的状态及coinbase是否设置,如果没有设置,是不会启动挖矿的

转载请注明来源

©2017 caohuan

Built with Hexo and 3-hexo theme

×

喜欢就点赞,疼爱就打赏

支付宝微信