Skip to content

Instantly share code, notes, and snippets.

@tomw1808
Last active December 6, 2018 08:46
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tomw1808/3e4075cbc517ea16bf01474ddce91286 to your computer and use it in GitHub Desktop.
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/)
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);
}
}
@Ajit666
Copy link

Ajit666 commented Feb 25, 2018

Hey Tom,

Should not we should have some function to get or check the current balance of the account, so that we can check how much amount is remaining after the whole flow of deposit and withdraw.

@Crizzooo
Copy link

Crizzooo commented Mar 8, 2018

It would be great if you could explain the problems with the 'bad' functions for those who are learning the language!

@adrianhara
Copy link

+1 to explaining

@yyssjj33
Copy link

yyssjj33 commented Apr 4, 2018

always call address.send(), address.call.value()() and address.transfer() at the very end of the function, or you will experience re-entry attack

@arun-munagala
Copy link

@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