明天即将迎来以太坊的升级——君士坦丁堡升级,这里记录一下升级内容(要点)
1,“君士坦丁堡”是什么?
- 君士坦丁堡是以太坊四个发展阶段中的第三阶段中的第二个子阶段。以太坊四个阶段非别是:Frontier(前沿),Homestead(家园),Metropolis(大都会),Serenity(宁静)。其中第三阶段会引入许多重要特性,于是就将第三阶段分成两步走——拜占庭子阶段跟君士坦丁堡子阶段。在君士坦丁堡子阶段会引入POS机制,变成POW + POS混合的局面,为Serenity阶段的纯POS做铺垫。
- 君士坦丁堡升级是一次硬分叉,但这次硬分叉不会导致出现两个币——因为这是一次无争议的分叉——整个社区都赞同这次分叉,大家都升级了客户端,到了指定的块高度之后,一起实行新的共识。
2,君士坦丁堡升级了哪些内容?
本次升级围绕五个EIP,范围涉及挖矿奖励、合约效率、存储效率、链外扩容等方面。
- EIP1234 减少出块奖励。
- EIP145 增加移位操作符,减少执行合约的花费。
- EIP1052 提升验证外部合约的效率。
- EIP1014 状态通道。
- EIP1283 更加合理的存储花费。优化SSTORE操作码的计费逻辑。
接下来我们分别研究下以上五个EIP的具体内容
2.1 EIP1234 减少出块奖励、推迟难度炸弹
这应该是本次升级最显著的改动了——将挖矿奖励由3eth将为2eth——称之为“the thirdening”。EIP1234还做了一件事:推迟难度炸弹大约12个月。所谓的难度炸弹,就是调高POW挖矿的难度,逼迫矿工由POW挖矿转为POS挖矿。如果难度炸弹过于激进,可能导致POW的那部分矿工收益锐减,可能会直接退出挖矿——会威胁链的安全。
2.2 EIP145 增加移位操作符,减少执行合约的花费
在EVM中增加三个原生操作符:SHL(左移)、SHR(逻辑右移)、SAR(算数右移)
名称 | 操作码 | 字节码 | 等效表达式 | gas | 备注 |
---|---|---|---|---|---|
左移 | SHL | 0x1B | (arg2 * 2^arg1) mod 2^256 | 35 | |
逻辑右移 | SHR | 0x1C | floor(arg2 / 2^arg1) | 35 | arg2、arg1为uint256 |
算术右移 | SAR | 0x1D | floor(arg2 / 2^arg1) | 3 | arg2为int256,arg1为uint256 |
丰富EVM的指令集,有利于编译出更高效(花费gas更少)的代码,但是已发布的合约代码无法从本EIP中受惠。
2.3 EIP1052 提升验证外部合约的效率
在EVM中增加EXTCODEHASH 操作符,字节码0x3F。接受一个address做参数,计算该地址下的代码的hash,并返回。假如地址下并无代码(是一个外部账户),返回空数据的hash:c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470。本操作码耗400gas。
2.4 EIP1014 状态通道
V神提的EIP,不太好理解。表面上来看,就是在EVM中增加了一个操作符CREATE2,字节码0xF5。
实际上是为以后的链外扩容做基础。
2.5 EIP1283 更加合理的存储花费
本EIP针对SSTORE操作码的计费提出了一个优化方案。之前SSTORE操作码的计费逻辑是这样的:
- 将Storage slot由0变为非0值,花费20000gas
- 将Storage slot由非0更改为非0,花费5000gas。
- 将Storage slot由非0更改为0,花费5000gas但是会返还15000gas,净赚10000gas。返还的gas不会超过当前交易的gas的一半。
现将计费逻辑优化如下:
首先针对Storage slot定义三个名次
- 初始值(original value):本交易执行之前,Storage slot的值。
- 当前值(current value):本交易中,执行当前SSTORE之前的值。
- 新值(new value):本交易中,当前SSTORE之后的值。
对于一个特定的交易,一个Storage slot只有一个初始值,可能有多个当前值、多个新值。
优化后的计费逻辑如下:
function calcStoreGas(originalValue, currentValue, newValue){
if(currentValue == newValue)
return 200;
//currentValue != newValue
if(currentValue == originalValue){
//该slot尚未在本次交易中更新过
if(originalValue == 0)
return 20000;
if(newValue == 0)
refund(15000);
return 5000;
}else{
// 该slot已经在本次交易中被更新过了——slot已经脏了
if(originalValue != 0){
if(currentValue == 0)
removeRefund(15000);
if(newValue == 0)
refund(15000);
}
if(originalValue == newValue){
//该slot被重置到了上一个交易的状态
if(originalValue == 0)
refund(19800);
else
refund(4800)
}
return 200;
}
}
从上面的代码可以看出,EIP1283将大大减少合约运行时花费的gas。已发布的合约代码也可从本EIP中受惠。
总结
以上五个EIP便是本次君士坦丁堡升级的主要内容,除了EIP1234外,其他四个EIP皆是围绕着EVM进行升级:EIP145、EIP1052、EIP1014是新增操作码,EIP1283是优化已有的操作码的行为。
后记
EIP1283有bug,会引起重入攻击,已经从君士坦丁堡升级中移除,放进下一次的伊斯坦布尔升级中,并更名为EIP2200,消除了重入攻击,详情稍后奉上。