目录
以太坊经典(Ethereum Classic)
以太坊经典的难度计算
实例
为什么要延迟难度炸弹
以太坊经典(Ethereum Classic)
以太坊经典(Ethereum Classic)是由以太坊(Ethereum)分叉而来的另一种区块链系统。
分叉的起因是2016年6月发生的轰动事件:The DAO攻击,黑客盗取了The DAO众筹合约中的以太币。关于如何应对这个事件,社区内有两种观点:
这两个观点各自都有支持者,支持观点1的人决定通过硬分叉的方式将以太币追回,并归还给原来的众筹参与者(这个分支也就是现在的以太坊)。支持观点2的人决定继续在原来的链上挖矿(这个分支就是现在的以太坊经典)。 最后,大约在北京时间2016年7月20日晚9点20分左右,区块高度1,920,000,以太坊正式进行硬分叉,产生了两条链。 |
以太坊1,920,000区块 |
以太坊经典1,920,000区块 |
可以看到,在同样的高度1,920,000,出现了两个Hash不同的区块,分叉正式完成。从此以太坊和以太坊经典走上了各自的发展道路,天各一方,不相往来。 以太坊和以太坊经典自分叉后就是两个区块链系统,其上的电子币虽然都叫以太币,但是互不通用。为了区分,一般把以太坊中的以太币简称ETH,把以太坊经典中的以太币简称ETC。 |
注意:千万不要把以太坊和以太坊经典的地址弄混,一旦把ETH发到ETC地址,或者ETC发到ETH地址,将会导致以太币丢失。 |
以太坊经典的难度计算
以太坊经典的代码同样是开源的,区块链也完全公开,没什么问题是读一遍代码弄不明白的,如果有,就再读一遍。 |
func CalcDifficulty(config *ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {num := new(big.Int).Add(parentNumber, common.Big1) // increment block number to currentf, fork, configured := config.GetFeature(num, "difficulty")if !configured {return calcDifficultyFrontier(time, parentTime, parentNumber, parentDiff)}name, ok := f.GetString("type")if !ok { name = "" } // will fall to default panicswitch name {case "ecip1010":if length, ok := f.GetBigInt("length"); ok {explosionBlock := big.NewInt(0).Add(fork.Block, length)if num.Cmp(explosionBlock) < 0 {return calcDifficultyDiehard(time, parentTime, parentDiff,fork.Block)} else {return calcDifficultyExplosion(time, parentTime, parentNumber, parentDiff,fork.Block, explosionBlock)}} else {panic(fmt.Sprintf("Length is not set for diehard difficulty at %v", num))}case "homestead":return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)case "frontier":return calcDifficultyFrontier(time, parentTime, parentNumber, parentDiff)default:panic(fmt.Sprintf("Unsupported difficulty '%v' for block: %v", name, num))}}
可以发现,以太坊经典对难度计算做了些小手脚,增加了两个新的算法calcDifficultyDiehard和calcDifficultyExplosion。感兴趣的小伙伴可以在这里找到和难度计算相关的全部代码:core/block_validator.go,代码中使用的配置参数在这里core/data_chainconfig.go |
相比以太坊,以太坊经典修改了难度炸弹部分。
|
这个对难度炸弹的修改在以太坊经典的开发社区中被称为“难度炸弹延迟”。与比特币的BIP类似,以太坊经典也把共识规则的更新用文档记录下来,称为以太坊经典改进提议(Ethereum Classic Improvement Proposal),简称ECIP。这次难度炸弹延迟被记录于ECIP1010。 难度计算公式的其余两项:父区块难度和难度调整,以太坊经典依然沿用了以太坊的计算方法。 |
实例
以太坊经典的用户较少,我只找到了两个区块链浏览器:
遗憾的是,他们都不能精确显示难度。不过没关系,可以在自己的机器上运行一个Geth,同步完成后就可以查看所有区块的信息了。由于Geth是命令行工具,没有漂亮的界面。如果有谁知道更好的以太坊经典区块浏览器,请留言告知我,我会及时更新。 还是随意挑一个区块,比如4,421,544,让我们来计算一下它的难度。 |
想计算区块的难度,需要知道这些信息:
|
在Geth的Javascript控制台中可以使用debug.printBlock(blockNumber)函数查看区块的详细信息,首先我们查一下父区块4,421,543: |
$echo -e `geth --exec "debug.printBlock(4421543)" attach`Block(#4421543): Size: 837.00 B {MinerHash: f4d068b903a67890cac5ddaff94a66d99a0464dfeef1c0bab3c7b3a7bf2965e4Header(2762936eb0879e86c2b0309a69fdfa3566bb3101e3cf344acf54d2534f2f3498):[ParentHash: 40f5cd2ec0be0e819c8689307c24d38edb75450358922286ec2c48e532bca427UncleHash: 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347Coinbase: df7d7e053933b5cc24372f878c90e62dadad5d42Root: de7c6ce1ea8c74644eba0579d42163c969e2c6b04cd57c1059470ca124b618baTxSha 497f1a6fd4d13db0f2eb4d90c11670485e5305a39a6782ec68417a9b060ae5f2ReceiptSha: 57bd177107249827f9a85e2d2b28d53180be4e4fb5069d0a1fd90f3822aa0097Bloom: 00000000000000000000000000000000000000000400000000000000000000000000000000000000000000000080000008000000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000800000000000000000100000000000400000000000000000400000000000000000000000Difficulty: 132145956937056Number: 4421543GasLimit: 4700036GasUsed: 58209Time: 1504744551Extra: ETC ethermine - EU2MixDigest: 7f09929b10732bb47d2473adaf172d5dfc146d560a10a6ab98c80538135ad351Nonce: 6960c3d00b731872]
从父区块中,我们知道了: parent_timestamp = 1504744551 parent_diff = 132145956937056 |
再来查一下4,421,544区块: |
$echo -e `geth --exec "debug.printBlock(4421544)" attach`Block(#4421544): Size: 1.55 kB {MinerHash: 89a0ecdc93471ef468f96dcb97c757b744a4a93b1fe142bed6f416552c2fd818Header(601d2019900d12781fbc0788ca3b55535b4ba6ee5337e5d7dce822860e3f9699):[ParentHash: 2762936eb0879e86c2b0309a69fdfa3566bb3101e3cf344acf54d2534f2f3498UncleHash: 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347Coinbase: 9eab4b0fc468a7f5d46228bf5a76cb52370d068dRoot: 1c59d3ab4e415e217f7544b38bd73bcdda21d56865315af8fafcf7bb8726c9a9TxSha 0ff3a73cedb8687b652df84baa46a98f6cdc24d5fa6a5e4e8335839ba7938304ReceiptSha: 2d45de0f095c9655204fca5c1e93db9f203b284c1e7b981a30693a9971dc3f3cBloom: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000080000000000000000020000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008000000000000000Difficulty: 132081700979477Number: 4421544GasLimit: 4704624GasUsed: 254912Time: 1504744574Extra: nanopool.orgMixDigest: 278b40bb8843841d6d5fcf843beeb0aeb2948b953696d884c367d5716685946eNonce: 2850d644089a46c5]
从区块中,我们知道了: block_timestamp = 1504744574 block_number = 4421544 |
难度公式: block_diff = parent_diff + 难度调整 + 难度炸弹 |
难度调整 = parent_diff // 2048 * MAX(1 – (block_timestamp – parent_timestamp) // 10, -99) = 132145956937056 // 2048 * MAX(1 – (1504744551 – 1504744574) // 10, -99) = 132145956937056 // 2048 * MAX(1 – 23 // 10, -99) = 132145956937056 //2048 * MAX(1 – 2, -99) = 132145956937056 //2048 * MAX(-1, -99) = 132145956937056 //2048 * (-1) = -64524393035 因为4,421,544区块在3,000,000到5,000,000之间,难度炸弹固定在3,000,000区块处。 |
难度炸弹 = INT(2**((3000000// 100000) – 2)) = INT(2**(30 – 2)) = 2**28 = 268435456 所以, block_diff = 132145956937056 – 64524393035 + 268435456 = 132081700979477 与前面查到的4,421,544区块的难度一致。 |
为什么要延迟难度炸弹
官方说法是,对共识和协议的更新需要足够的时间进行论证、开发和测试,完成这些需要足够的时间。如果难度炸弹在这些工作完成之前爆炸,会导致以太坊经典的网络不可用。而鲁莽的赶在难度炸弹产生影响之前抢先部署未经充分论证和测试的软件,可能会造成更大的风险。因此需要进行一次更新,在2,000,000个区块,也就是大约一年的时间内,暂时停止难度炸弹的增长。 网上的一些文章把这次“难度炸弹延迟”称为“拆弹”是不准确的,难度炸弹依然存在,没有被去掉,只是引爆时间延后了。只要还需要挖矿,难度炸弹就会一直保留,以防止矿工掌握过大的话语权,这也是设置难度炸弹的目的。 |