mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Cleanup to make the docs more consistent.
This commit is contained in:
		
							parent
							
								
									2b4b86aa7f
								
							
						
					
					
						commit
						7e838fd4a8
					
				| @ -52,17 +52,12 @@ become the new richest. | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         function withdraw() returns (bool) { | ||||
|         function withdraw() { | ||||
|             uint amount = pendingWithdrawals[msg.sender]; | ||||
|             // Remember to zero the pending refund before | ||||
|             // sending to prevent re-entrancy attacks | ||||
|             pendingWithdrawals[msg.sender] = 0; | ||||
|             if (msg.sender.send(amount)) { | ||||
|                 return true; | ||||
|             } else { | ||||
|                 pendingWithdrawals[msg.sender] = amount; | ||||
|                 return false; | ||||
|             } | ||||
|             msg.sender.transfer(amount); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -83,9 +78,7 @@ This is as opposed to the more intuitive sending pattern: | ||||
| 
 | ||||
|         function becomeRichest() payable returns (bool) { | ||||
|             if (msg.value > mostSent) { | ||||
|                 // Check if call succeeds to prevent an attacker | ||||
|                 // from trapping the previous person's funds in | ||||
|                 // this contract through a callstack attack | ||||
|                 // This line can cause problems (explained below). | ||||
|                 richest.transfer(msg.value); | ||||
|                 richest = msg.sender; | ||||
|                 mostSent = msg.value; | ||||
| @ -99,11 +92,15 @@ This is as opposed to the more intuitive sending pattern: | ||||
| Notice that, in this example, an attacker could trap the | ||||
| contract into an unusable state by causing ``richest`` to be | ||||
| the address of a contract that has a fallback function | ||||
| which consumes more than the 2300 gas stipend.  That way, | ||||
| whenever ``send`` is called to deliver funds to the | ||||
| "poisoned" contract, it will cause execution to always fail | ||||
| because there will not be enough gas to finish the execution | ||||
| of the fallback function. | ||||
| which fails (e.g. by using ``revert()`` or by just | ||||
| conssuming more than the 2300 gas stipend). That way, | ||||
| whenever ``transfer`` is called to deliver funds to the | ||||
| "poisoned" contract, it will fail and thus also ``becomeRichest`` | ||||
| will fail, with the contract being stuck forever. | ||||
| 
 | ||||
| In contrast, if you use the "withdraw" pattern from the first example, | ||||
| the attacker can only cause his or her own withdraw to fail and not the | ||||
| rest of the contract's workings. | ||||
| 
 | ||||
| .. index:: access;restricting | ||||
| 
 | ||||
|  | ||||
| @ -1034,7 +1034,7 @@ more advanced example to implement a set). | ||||
|             // The library functions can be called without a | ||||
|             // specific instance of the library, since the | ||||
|             // "instance" will be the current contract. | ||||
|             assert(Set.insert(knownValues, value)); | ||||
|             require(Set.insert(knownValues, value)); | ||||
|         } | ||||
|         // In this contract, we can also directly access knownValues.flags, if we want. | ||||
|     } | ||||
|  | ||||
| @ -88,7 +88,7 @@ outlined further below: | ||||
|       function withdraw() { | ||||
|           var share = shares[msg.sender]; | ||||
|           shares[msg.sender] = 0; | ||||
|           require(msg.sender.send(share)); | ||||
|           msg.sender.transfer(share); | ||||
|       } | ||||
|   } | ||||
| 
 | ||||
| @ -123,22 +123,23 @@ Sending and Receiving Ether | ||||
|   (for example in the "details" section in Remix). | ||||
| 
 | ||||
| - There is a way to forward more gas to the receiving contract using | ||||
|   ``addr.call.value(x)()``. This is essentially the same as ``addr.send(x)``, | ||||
|   ``addr.call.value(x)()``. This is essentially the same as ``addr.transfer(x)``, | ||||
|   only that it forwards all remaining gas and opens up the ability for the | ||||
|   recipient to perform more expensive actions. This might include calling back | ||||
|   recipient to perform more expensive actions (and it only returns a failure code | ||||
|   and does not automatically propagate the error). This might include calling back | ||||
|   into the sending contract or other state changes you might not have thought of. | ||||
|   So it allows for great flexibility for honest users but also for malicious actors. | ||||
| 
 | ||||
| - If you want to send Ether using ``address.send``, there are certain details to be aware of: | ||||
| - If you want to send Ether using ``address.transfer``, there are certain details to be aware of: | ||||
| 
 | ||||
|   1. If the recipient is a contract, it causes its fallback function to be executed which can, in turn, call back the sending contract. | ||||
|   2. Sending Ether can fail due to the call depth going above 1024. Since the caller is in total control of the call | ||||
|      depth, they can force the transfer to fail; make sure to always check the return value of ``send``. Better yet, | ||||
|      depth, they can force the transfer to fail; take this possibility into account or use ``send`` and make sure to always check its return value. Better yet, | ||||
|      write your contract using a pattern where the recipient can withdraw Ether instead. | ||||
|   3. Sending Ether can also fail because the execution of the recipient contract | ||||
|      requires more than the allotted amount of gas (explicitly by using ``throw`` or | ||||
|      requires more than the allotted amount of gas (explicitly by using ``revert`` or | ||||
|      because the operation is just too expensive) - it "runs out of gas" (OOG). | ||||
|      If the return value of ``send`` is checked, this might provide a | ||||
|      If you use ``transfer`` or ``send`` with a return value check, this might provide a | ||||
|      means for the recipient to block progress in the sending contract. Again, the best practice here is to use | ||||
|      a :ref:`"withdraw" pattern instead of a "send" pattern <withdrawal_pattern>`. | ||||
| 
 | ||||
| @ -171,9 +172,9 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like | ||||
|             owner = msg.sender; | ||||
|         } | ||||
| 
 | ||||
|         function transfer(address dest, uint amount) { | ||||
|         function transferTo(address dest, uint amount) { | ||||
|             require(tx.origin == owner); | ||||
|             require(dest.call.value(amount)()); | ||||
|             dest.transfer(amount); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -191,7 +192,7 @@ Now someone tricks you into sending ether to the address of this attack wallet: | ||||
|         } | ||||
| 
 | ||||
|         function() { | ||||
|             TxUserWallet(msg.sender).transfer(owner, msg.sender.balance); | ||||
|             TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -87,11 +87,13 @@ of votes. | ||||
|         // Give `voter` the right to vote on this ballot. | ||||
|         // May only be called by `chairperson`. | ||||
|         function giveRightToVote(address voter) { | ||||
|             // `throw` terminates and reverts all changes to | ||||
|             // If the argument of `require` evaluates to `false`, | ||||
|             // it terminates and reverts all changes to | ||||
|             // the state and to Ether balances. It is often | ||||
|             // a good idea to use this if functions are | ||||
|             // called incorrectly. But watch out, this | ||||
|             // will also consume all provided gas. | ||||
|             // will currently also consume all provided gas | ||||
|             // (this is planned to change in the future). | ||||
|             require(msg.sender == chairperson || !voters[voter].voted); | ||||
|             voters[voter].weight = 1; | ||||
|         } | ||||
| @ -268,7 +270,6 @@ activate themselves. | ||||
|             // period is over. | ||||
|             require(now < auctionStart + biddingTime); | ||||
| 
 | ||||
| 
 | ||||
|             // If the bid is not higher, send the | ||||
|             // money back. | ||||
|             require(msg.value <= highestBid); | ||||
| @ -329,7 +330,7 @@ activate themselves. | ||||
|             AuctionEnded(highestBidder, highestBid); | ||||
| 
 | ||||
|             // 3. Interaction | ||||
|             require(beneficiary.transfer(highestBid)); | ||||
|             beneficiary.transfer(highestBid); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -400,8 +401,8 @@ high or low invalid bids. | ||||
|         /// functions. `onlyBefore` is applied to `bid` below: | ||||
|         /// The new function body is the modifier's body where | ||||
|         /// `_` is replaced by the old function body. | ||||
|         modifier onlyBefore(uint _time) { require(!now >= _time); _; } | ||||
|         modifier onlyAfter(uint _time) { require(!now <= _time); _; } | ||||
|         modifier onlyBefore(uint _time) { require(now < _time); _; } | ||||
|         modifier onlyAfter(uint _time) { require(now > _time); _; } | ||||
| 
 | ||||
|         function BlindAuction( | ||||
|             uint _biddingTime, | ||||
| @ -446,8 +447,8 @@ high or low invalid bids. | ||||
|         { | ||||
|             uint length = bids[msg.sender].length; | ||||
|             require( | ||||
|                 _values.length == length || | ||||
|                 _fake.length == length || | ||||
|                 _values.length == length && | ||||
|                 _fake.length == length && | ||||
|                 _secret.length == length | ||||
|             ); | ||||
| 
 | ||||
| @ -544,10 +545,10 @@ Safe Remote Purchase | ||||
|         function Purchase() payable { | ||||
|             seller = msg.sender; | ||||
|             value = msg.value / 2; | ||||
|             require(!2 * value != msg.value); | ||||
|             require(2 * value == msg.value); | ||||
|         } | ||||
| 
 | ||||
|         modifier require(bool _condition) { | ||||
|         modifier condition(bool _condition) { | ||||
|             require(_condition); | ||||
|             _; | ||||
|         } | ||||
| @ -589,7 +590,7 @@ Safe Remote Purchase | ||||
|         /// is called. | ||||
|         function confirmPurchase() | ||||
|             inState(State.Created) | ||||
|             require(msg.value == 2 * value) | ||||
|             condition(msg.value == 2 * value) | ||||
|             payable | ||||
|         { | ||||
|             purchaseConfirmed(); | ||||
| @ -609,8 +610,9 @@ Safe Remote Purchase | ||||
|             // can call in again here. | ||||
|             state = State.Inactive; | ||||
|             // This actually allows both the buyer and the seller to | ||||
|             // block the refund. | ||||
|             require(buyer.transfer(value) || seller.transfer(this.balance)); | ||||
|             // block the refund - the withdraw pattern should be used. | ||||
|             buyer.transfer(value); | ||||
|             seller.transfer(this.balance)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user