Close Menu
    Trending
    • Dogecoin Rally On Thin Ice: Analyst Predicts Sudden Shakeout
    • Ethereum validators back raising gas limit to 45 million for improved network capacity
    • Bitcoin Tests $120K as Bulls Target $130K Breakout
    • These Meme Coins Explode as Bitcoin Price Eyes $120K Again: Market Watch
    • XRP Targets $6–$10 If Bitcoin Hits $144,000, Analyst Predicts
    • Ethereum ATH Above $4,800? Here’s How High It Will Go If 2021 Repeats
    • Little Pepe Presale Hits $8.8M as Meme Coin Mania Returns
    • Ripple (XRP) Rally Cools After Hitting $3.65—What’s Next?
    Simon Crypto
    • Home
    • Crypto Market Trends
    • Bitcoin News
    • Crypto Mining
    • Cryptocurrency
    • Blockchain
    • More
      • Altcoins
      • Ethereum
    Simon Crypto
    Home»Ethereum»Smart Contract Security | Ethereum Foundation Blog
    Ethereum

    Smart Contract Security | Ethereum Foundation Blog

    Team_SimonCryptoBy Team_SimonCryptoFebruary 8, 2025No Comments8 Mins Read
    Share
    Facebook Twitter LinkedIn Pinterest Email


    Solidity was began in October 2014 when neither the Ethereum community nor the digital machine had any real-world testing, the gasoline prices at the moment had been even drastically totally different from what they’re now. Moreover, a few of the early design selections had been taken over from Serpent. Over the last couple of months, examples and patterns that had been initially thought of best-practice had been uncovered to actuality and a few of them really turned out to be anti-patterns. As a consequence of that, we lately up to date a few of the Solidity documentation, however as most individuals in all probability don’t observe the stream of github commits to that repository, I want to spotlight a few of the findings right here.

    I cannot discuss in regards to the minor points right here, please learn up on them within the documentation.

    Sending Ether

    Sending Ether is meant to be one of many easiest issues in Solidity, but it surely seems to have some subtleties most individuals don’t realise.

    It will be important that at greatest, the recipient of the ether initiates the payout. The next is a BAD instance of an public sale contract:

    // THIS IS A NEGATIVE EXAMPLE! DO NOT USE!
    contract public sale {
      deal with highestBidder;
      uint highestBid;
      perform bid() {
        if (msg.worth < highestBid) throw;
        if (highestBidder != 0)
          highestBidder.ship(highestBid); // refund earlier bidder
        highestBidder = msg.sender;
        highestBid = msg.worth;
      }
    }

    Due to the maximal stack depth of 1024 the brand new bidder can all the time improve the stack dimension to 1023 after which name bid() which can trigger the ship(highestBid) name to silently fail (i.e. the earlier bidder won’t obtain the refund), however the brand new bidder will nonetheless be highest bidder. One option to verify whether or not ship was profitable is to verify its return worth:

    /// THIS IS STILL A NEGATIVE EXAMPLE! DO NOT USE!
    if (highestBidder != 0)
      if (!highestBidder.ship(highestBid))
        throw;

    The

    throw

    assertion causes the present name to be reverted. It is a unhealthy concept, as a result of the recipient, e.g. by implementing the fallback perform as

    perform() { throw; }

    can all the time power the Ether switch to fail and this may have the impact that no person can overbid her.

    The one option to stop each conditions is to transform the sending sample right into a withdrawing sample by giving the recipient management over the switch:

    /// THIS IS STILL A NEGATIVE EXAMPLE! DO NOT USE!
    contract public sale {
      deal with highestBidder;
      uint highestBid;
      mapping(deal with => uint) refunds;
      perform bid() {
        if (msg.worth < highestBid) throw;
        if (highestBidder != 0)
          refunds[highestBidder] += highestBid;
        highestBidder = msg.sender;
        highestBid = msg.worth;
      }
      perform withdrawRefund() {
        if (msg.sender.ship(refunds[msg.sender]))
          refunds[msg.sender] = 0;
      }
    }
     

    Why does it nonetheless say “destructive instance” above the contract? Due to gasoline mechanics, the contract is definitely high quality, however it’s nonetheless not a great instance. The reason being that it’s unattainable to forestall code execution on the recipient as a part of a ship. Which means that whereas the ship perform continues to be in progress, the recipient can name again into withdrawRefund. At that time, the refund quantity continues to be the identical and thus they’d get the quantity once more and so forth. On this particular instance, it doesn’t work, as a result of the recipient solely will get the gasoline stipend (2100 gasoline) and it’s unattainable to carry out one other ship with this quantity of gasoline. The next code, although, is susceptible to this assault: msg.sender.name.worth(refunds[msg.sender])().

    Having thought of all this, the next code must be high quality (after all it’s nonetheless not a whole instance of an public sale contract):

    contract public sale {
      deal with highestBidder;
      uint highestBid;
      mapping(deal with => uint) refunds;
      perform bid() {
        if (msg.worth < highestBid) throw;
        if (highestBidder != 0)
          refunds[highestBidder] += highestBid;
        highestBidder = msg.sender;
        highestBid = msg.worth;
      }
      perform withdrawRefund() {
        uint refund = refunds[msg.sender];
        refunds[msg.sender] = 0;
        if (!msg.sender.ship(refund))
         refunds[msg.sender] = refund;
      }
    }

    Word that we didn’t use throw on a failed ship as a result of we’re in a position to revert all state modifications manually and never utilizing throw has so much much less side-effects.

    Utilizing Throw

    The throw assertion is usually fairly handy to revert any modifications made to the state as a part of the decision (or complete transaction relying on how the perform known as). It’s important to remember, although, that it additionally causes all gasoline to be spent and is thus costly and can doubtlessly stall calls into the present perform. Due to that, I want to advocate to make use of it solely within the following conditions:

    1. Revert Ether switch to the present perform

    If a perform just isn’t meant to obtain Ether or not within the present state or with the present arguments, it’s best to use throw to reject the Ether. Utilizing throw is the one option to reliably ship again Ether due to gasoline and stack depth points: The recipient may need an error within the fallback perform that takes an excessive amount of gasoline and thus can not obtain the Ether or the perform may need been known as in a malicious context with too excessive stack depth (maybe even previous the calling perform).

    Word that by accident sending Ether to a contract just isn’t all the time a UX failure: You possibly can by no means predict by which order or at which era transactions are added to a block. If the contract is written to solely settle for the primary transaction, the Ether included within the different transactions needs to be rejected.

    2. Revert results of known as capabilities

    For those who name capabilities on different contracts, you possibly can by no means understand how they’re applied. Which means that the consequences of those calls are additionally not know and thus the one option to revert these results is to make use of throw. After all it’s best to all the time write your contract to not name these capabilities within the first place, if you understand you’ll have to revert the consequences, however there are some use-cases the place you solely know that after the very fact.

    Loops and the Block Gasoline Restrict

    There’s a restrict of how a lot gasoline could be spent in a single block. This restrict is versatile, however it’s fairly onerous to extend it. Which means that each single perform in your contract ought to keep beneath a certain quantity of gasoline in all (cheap) conditions. The next is a BAD instance of a voting contract:

    /// THIS IS STILL A NEGATIVE EXAMPLE! DO NOT USE!
    contract Voting {
      mapping(deal with => uint) voteWeight;
      deal with[] yesVotes;
      uint requiredWeight;
      deal with beneficiary;
      uint quantity;
      perform voteYes() { yesVotes.push(msg.sender); }
      perform tallyVotes() {
        uint yesVotes;
        for (uint i = 0; i < yesVotes.size; ++i)
          yesVotes += voteWeight[yesVotes[i]];
        if (yesVotes > requiredWeight)
          beneficiary.ship(quantity);
      }
    }

    The contract really has a number of points, however the one I want to spotlight right here is the issue of the loop: Assume that vote weights are transferrable and splittable like tokens (consider the DAO tokens for example). This implies you can create an arbitrary variety of clones of your self. Creating such clones will improve the size of the loop within the tallyVotes perform till it takes extra gasoline than is on the market inside a single block.

    This is applicable to something that makes use of loops, additionally the place loops will not be explicitly seen within the contract, for instance whenever you copy arrays or strings inside storage. Once more, it’s high quality to have arbitrary-length loops if the size of the loop is managed by the caller, for instance in case you iterate over an array that was handed as a perform argument. However by no means create a state of affairs the place the loop size is managed by a celebration that may not be the one one affected by its failure.

    As a aspect word, this was one cause why we now have the idea of blocked accounts contained in the DAO contract: Vote weight is counted on the level the place the vote is solid, to forestall the truth that the loop will get caught, and if the vote weight wouldn’t be mounted till the tip of the voting interval, you possibly can solid a second vote by simply transferring your tokens after which voting once more.

    Receiving Ether / the fallback perform

    If you would like your contract to obtain Ether through the common ship() name, you must make its fallback perform low-cost. It will probably solely use 2300, gasoline which neither permits any storage write nor perform calls that ship alongside Ether. Mainly the one factor it’s best to do contained in the fallback perform is log an occasion in order that exterior processes can react on the very fact. After all any perform of a contract can obtain ether and isn’t tied to that gasoline restriction. Features really must reject Ether despatched to them if they don’t need to obtain any, however we’re interested by doubtlessly inverting this behaviour in some future launch.



    Source link

    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email

    Related Posts

    Ethereum validators back raising gas limit to 45 million for improved network capacity

    July 21, 2025

    Ethereum ATH Above $4,800? Here’s How High It Will Go If 2021 Repeats

    July 21, 2025

    Traders are bullish on ETH as price begins to catch up with the tech

    July 19, 2025

    Volume 50% Higher Than BTC’s

    July 19, 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Categories
    • Altcoins
    • Bitcoin News
    • Blockchain
    • Crypto Market Trends
    • Crypto Mining
    • Cryptocurrency
    • Ethereum
    Archives
    • July 2025
    • June 2025
    • May 2025
    • April 2025
    • March 2025
    • February 2025
    • January 2025
    • December 2024
    • November 2024
    Archives
    • July 2025
    • June 2025
    • May 2025
    • April 2025
    • March 2025
    • February 2025
    • January 2025
    • December 2024
    • November 2024
    Top Posts

    HOME Lifts Off After World’s Largest Crypto Exchange by Trading Volume Adds Support for Defi App

    June 13, 2025

    ad

    About us

    Welcome to SimonCrypto.in, your ultimate destination for everything crypto! Whether you’re a seasoned investor, a blockchain enthusiast, or just beginning your journey into the fascinating world of cryptocurrencies, we’re here to guide you every step of the way.

    At SimonCrypto.in, we are passionate about demystifying the complex world of digital currencies and blockchain technology. Our mission is to provide insightful, accurate, and up-to-date information to empower our readers to make informed decisions in the ever-evolving crypto space.

    Top Insights

    Goerli Dencun Announcement | Ethereum Foundation Blog

    December 8, 2024

    XRP Price Holds Above $2.47, But Bulls Struggle to Gain Control

    February 24, 2025

    VanEck Predicts $4,000,000,000,000 Explosion in DeFi Volumes for 2025 – Here’s Why

    December 15, 2024
    Categories
    • Altcoins
    • Bitcoin News
    • Blockchain
    • Crypto Market Trends
    • Crypto Mining
    • Cryptocurrency
    • Ethereum
    • Privacy Policy
    • Disclaimer
    • Terms and Conditions
    • About us
    • Contact us
    Copyright © 2024 SimonCrypto All Rights Reserved.

    Type above and press Enter to search. Press Esc to cancel.