Last active
December 6, 2018 08:46
-
-
Save tomw1808/3e4075cbc517ea16bf01474ddce91286 to your computer and use it in GitHub Desktop.
This is an example of the difference between "address.send()", "address.call.value()()" and "address.transfer()" in Solidity. If you like this example, then checkout my courses I do on Udemy (https://vomtom.at/tag/course/)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.13; | |
contract someContract { | |
mapping(address => uint) balances; | |
function deposit() payable { | |
balances[msg.sender] += msg.value; | |
} | |
function withdrawVeryBad1(uint amount) { | |
if(balances[msg.sender] >= amount) { | |
msg.sender.send(amount); | |
balances[msg.sender] -= amount; | |
} | |
} | |
function withdrawVeryVeryBad2(uint amount) { | |
if(balances[msg.sender] >= amount) { | |
msg.sender.call.gas(2500000).value(amount)(); | |
balances[msg.sender] -= amount; | |
} | |
} | |
function withdrawVeryVeryBad3(uint amount) { | |
if(balances[msg.sender] >= amount) { | |
if(msg.sender.call.gas(2500000).value(amount)()) { | |
balances[msg.sender] -= amount; | |
} | |
} | |
} | |
function withdrawBad1(uint amount) { | |
if(balances[msg.sender] >= amount) { | |
if(msg.sender.send(amount)) { | |
balances[msg.sender] -= amount; | |
} | |
} | |
} | |
function withdrawOkayish(uint amount) { | |
if(balances[msg.sender] >= amount) { | |
balances[msg.sender] -= amount; | |
if(!msg.sender.send(amount)) { | |
throw; | |
} | |
} | |
} | |
function withdrawBad2(uint amount) { | |
if(balances[msg.sender] >= amount) { | |
balances[msg.sender] -= amount; | |
if(!msg.sender.call.gas(2500000).value(amount)()) { | |
throw; | |
} | |
} | |
} | |
//OKAY FUNCTIONS | |
function withdrawOK(uint amount) { | |
if(balances[msg.sender] >= amount) { | |
balances[msg.sender] -= amount; | |
msg.sender.transfer(amount); | |
} | |
} | |
//New Exception handling | |
function withdrawGood(uint amount) { | |
require(balances[msg.sender] >= amount); | |
balances[msg.sender] -= amount; | |
msg.sender.transfer(amount); | |
} | |
} |
+1 to explaining
always call address.send()
, address.call.value()()
and address.transfer()
at the very end of the function, or you will experience re-entry attack
@yyssjj33 I dont think address.call.value()() is a safe against re-entry attack. The other 2 have a gas limit but not call.value(). Unless you specify gas limit using gas().
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It would be great if you could explain the problems with the 'bad' functions for those who are learning the language!