Smart contract security | Ethereum Foundation Blog

Published:

Solidity It In gegründet in October 2014, when neither Ethereum The The proof of the network and virtual machine was not real-world. Gas Prices were also very different back then. It was also the location of some of the most important design decisions. Serpent. During In In the last months, some patterns and examples that were once considered best practices were exposed to reality and found to be unpatterns. Because We Some of the following pages were recently updated Documentation On IntegrityHoweverThe majority of people don’t know how to use github’s commit flow. I’d Here are some of my findings.

The Minor problems are not my concern. Please refer the Documentation.

Shipping By ether

Sending Ether It This is one of the most essential things in life. SolidityIt turns out that there are subtleties that most people don’t know.

It It It is important that the recipient of theether initiates payment. The The The following is a EVIL An Example of an Auction Contract:

// THIS IS A NEGATIVE POOTO! Do Not to be used!
contract auction {
 Address highestBidDer;
 uint greatestBid;
  Function Bid() {
    If (msg.value < highestBid) Throw;
    If (highestBidDer != 0)
      highestBidder.send(highestBid); // Refund The previous bidder
    highestBidDer = msg.sender;
    highestBid = msg.value;
  }
}

Due The Maximum stack depth is 1024 HoweverBefore calling, the new bidder may increase the stack size by up to 1023 Bidding() Which This will allow you to Submit (highest offer) Call To fail silently (i.e. The Refunds will not be granted to the previous bidder. However, the highest bidder still wins. One Check If you’re able. Send The To prove it is worth the return value, you must succeed.

/// THIS IS STILL A NEGATIVE PHOTO! Do Not to be used!
If (highestBidDer != 0)
  If (!highestBidder.send(highestBid))
 Throw;

The

Throw

The The current call must be reversed. This This It is not a good idea as the recipient may implement the fallback function.

Function() { Throw; }

You You Can always do the Ether Transfer Failure would be an indication that you can't be outbid.

The Both You can avoid situations by changing the send pattern to a withdrawal pattern and giving control to the recipient of the transfer.

/// THIS IS STILL A NEGATIVE PHOTO! Do Not to be used!
contract auction {
 Address highestBidDer;
 uint greatestBid;
 Map(Address => Uint) Refunds;
  Function Bid() {
    If (msg.value < highestBid) Throw;
    If (highestBidDer != 0)
 Refunds[highestBidder] += highestBid;
    highestBidDer = msg.sender;
    highestBid = msg.value;
  }
  Function Refund() {
    If (msg.sender.send(Refunds[msg.sender]))
 Refunds[msg.sender] = 0;
  }
}
 

Why Is Is it still true? “negative example” Above The contract? Due To The gas mechanics: It is a good contract, but it is still not a great example. The The The reason is that code execution can’t be stopped by the recipient during shipment. This This This means that while the send function is still in progress, the recipient can call back to pick up the package. Refund. At At At that point, the amount to be refunded would not change. They The amount would be returned, and so on. In This The recipient does not receive the gas stipend (2100 Gas) and there is no way for another shipment to be made using such a large quantity of gas. HoweverThis Attacks are possible on the code below msg.sender.call.value(refunds[msg.sender])().

With With Despite all this, it should be accepted (though it isn’t an exact example of an acceptable code). Auction Contract).

contract auction {
 Address highestBidDer;
 uint greatestBid;
 Map(Address => Uint) Refunds;
  Function Bid() {
    If (msg.value < highestBid) Throw;
    If (highestBidDer != 0)
 Refunds[highestBidder] += highestBid;
    highestBidDer = msg.sender;
    highestBid = msg.value;
  }
  Function Refund() {
 Refund Uint = Refunds[msg.sender];
 Refunds[msg.sender] = 0;
    If (!msg.sender.send(Refund))
 Refunds[msg.sender] = Refund;
  }
}

Note We Throw can be used to fail a sent, but we can reverse state changes manually and throw has far less side effects.

Throw

The Throw Statement can be used depending on the function to reverse any state changes during a call. HoweverIt All gas can be wasted, which is why it’s so expensive. This Could potentially cause the death of current function calls. ThereforeI would highly recommend it. Only In The following scenarios are possible:

1. Revert The Ether Transfer Refer to the current function

If Functions are not meant to be accepted Ether Throw To reject any argument which isn’t in current state. Ether. Using Throwing It is the only way to send reliable messages Ether Gas Issues in stack depth and fuel consumption: Recipients might have an issue with the fallback function. This causes them to not be able to receive and consumes too many gasoline. Ether Or It is possible that the function was maliciously called. context that is too deep (or earlier than the calling function).

Note This It is what accidentally sends Ether Contracts are not always UX problems. It’s It is impossible to predict which order or when transactions will be added to each block. If The The contract must be written so that it only accepts the first transaction. Ether Included Other transactions cannot be accepted.

2. Reverse The Functions can have a variety of effects.

If You If you don’t know their names, you won’t be able to know how they are implemented. This This These calls are unpredictable and throwing them is the only way for them to be reversed. Of While It is crucial to not call these functions within your contract. However, it is also important that you do so if you know you will need to reverse them. But There are situations where you might only discover the truth after the fact.

Loops Block gas limit

There There There is a limit on the amount of gas you can burn per block. This Although Limit can be adjusted but it is hard to raise. This It Each feature must use a minimum amount of gas at all times. The Here’s A bad example of a vote agreement:

/// THIS IS STILL A NEGATIVE PHOTO! Do Not to be used!
Contract Voting {
 Map(Address => Uint) voteWeight;
 Address[] YesVotes;
 Weigh;
  address beneficiary;
 Uint Sum;
  Function VoteYes() { yesVotes.push(msg.sender); }
  Function tallyVotes() {
 uint YouVotes;
    For (Uint = 0; i < yesVotes.length; ++i)
 YesVotes += voteWeight[yesVotes[i]];
    If (YesVotes > Minimum Weight)
      beneficiary.send(Sum);
  }
}

The Contracts You can have many problems, but the most important problem is one. I’d The Loop problem is what I’d Like to stress? Assume The vote weights could also be transferred and divided in token-like fashion (as an example, DAO coins). This You It is possible to create unlimited numbers of clones. Creating These Clones can increase gas consumption and lengthen the time they are in use by increasing the size or loop of the TallyVotes function.

This All Loops in contracts are valid even if they are not explicitly visible. This is againIt’s It is okay to have loops with an arbitrary length, provided that the caller has control over the length of the loop. For example, when it iterates on an array passed in a function argument. But Never This It would lead to a situation in the which one party controls the length of a cycle and is not the first to fail.

As As This is also why we have the DAO contract concept for locked accounts. The weight of the vote is counted at its point of casting. This It is to stop the loop from becoming stuck. You If your vote weight is not set before the end, you can still vote by simply transferring tokens.

Ether Receive Backup function

If You Want your contract to be accepted? Ether Send Regular mail() You You should not be charged for the fallback function. You You You can only use 2300 petrol, so storage writes and function call cannot be sent. Ether. BasicallyAll To log an event, external processes will need to know what to do in the fallback function. Of Any Contract feature can be granted ether but is not tied to gas restriction. Functions You Rejecting is not an option. Ether They You can choose to not receive any. We They are exploring the possibility of a reversal in coming years.

Related articles

Recent articles