这篇文章是建立在poa共识的基础上, pos和pow应该是同理
好多论坛关于这个问题都是让升级客户端版本, 说是缓存导致的, 但是大部分情况下还是本地数据或者程序逻辑除了问题,导致计算的结果不匹配
首先要解决这个问题, 首先我们要清楚什么是世界状态
世界状态是以太坊区块链中的数据存储状态的一种结果hash表现, 是由所有截至当前区块的所有账户(余额,nonce,code,storage,…)等账户合约的基本属性和值来决定的, 一旦出现了世界状态不匹配, 那么肯定是节点和同步节点的账户的基本属性值不统一了, 要解决这个问题, 就需要找到具体是那些数据不统一了, 找到这些数据,造成这些数据不统一的原因, 然后就可以解决这个问题.
现在的世界状态不一致,将会在这里抛出错误:
1 | if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root { |
首先通过报错原因, 我们可以知道具体的不一致区块(注意, 这里是全节点同步方式, sync=full):
1 | BAD Block |
那这个时候, 我们就需要查询这个区块和前一个区块的数据.
对比两个区块有那些账户变动,这将输出所有相关账户属性变动的账户和合约地址,包括矿工手续费账户,矿工验证账户,转账账户, 相关合约账户
1 | debug.getModifiedAccountsByNumber(110,111) |
查询这些账户是否符合预期(这里的预期值得是你清楚,大部分都是和链的共识相关)
我这里查询是因为我的链是poa,然后我设置的手续费账户和节点验证账户不一致,导致出现了这个问题, 具体可以看我前一章说的问题,这个主要还是以太坊poa共识的实现不是很完善, 才会出现这个问题.
具体解决办法, 就是将设置的coinbase加在获取手续费账户的那里
1 | func (beacon *Beacon) Author(header *types.Header) (common.Address, error) { |
到这里就结束了, 解决方式还是挺简单的, 主要难点在于你要熟悉节点的共识,以及他每一步会做那些事情, 这些逻辑要清楚.
这里我被这个问题困扰了一周, 如果你感觉这个对你有用的话, 不妨请我喝杯咖啡.

...
...
00:00
00:00