Skip to content

Instantly share code, notes, and snippets.

@tjade273
Last active July 9, 2016 20:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjade273/faf307b35ac1d356e40abc64d6a1279a to your computer and use it in GitHub Desktop.
Save tjade273/faf307b35ac1d356e40abc64d6a1279a to your computer and use it in GitHub Desktop.
A contract that allows sending arbitrary amounts to a list of accounts in an atomic manner
//This version does not support sending to contracts with fallback functions. Funds that cannot be delivered are returned to the sender.
contract Multisend {
mapping(address => uint) public nonces;
function send(address[] addrs, uint[] amounts, uint nonce) {
if(addrs.length != amounts.length || nonce != nonces[msg.sender]) throw;
uint val = msg.value;
for(uint i = 0; i<addrs.length; i++){
if(val < amounts[i]) throw;
if(addrs[i].send(amounts[i])){
val -= amounts[i];
}
}
msg.sender.send(val);
nonces[msg.sender]++;
}
}
//This version puts the recipient in charge of withdrawing, avoiding gas cost issues. Recipients must call the "withdraw" function to claim their ETH
contract Multisend2 {
mapping(address => uint) public balances;
mapping(address => uint) public nonces;
function send(address[] addrs, uint[] amounts, unit nonce) {
if(addrs.length != amounts.length || nonce != nonces[msg.sender]) throw;
uint val = msg.value;
for(uint i = 0; i<addrs.length; i++){
if(val < amounts[i]) throw;
balances[addrs[i]] += amounts[i];
val -= amounts[i];
}
balances[msg.sender] += val;
nonces[msg.sender]++;
}
function withdraw(){
uint balance = balances[msg.sender];
balances[msg.sender] = 0;
if(!msg.sender.send(balance)) throw;
}
function(){
withdraw();
}
}
// This one tries sending, and falls back to the withdrawl method if the send fails
contract Multisend3 {
mapping(address => uint) public balances;
mapping(address => uint) public nonces;
function send(address[] addrs, uint[] amounts, uint nonce) {
if(addrs.length != amounts.length || nonce != nonces[msg.sender]) throw;
uint val = msg.value;
for(uint i = 0; i<addrs.length; i++){
if(val < amounts[i]) throw;
if(!addrs[i].send(amounts[i])){
balances[addrs[i]] += amounts[i];
}
val -= amounts[i];
}
if(!msg.sender.send(val)){
balances[msg.sender] += val;
}
nonces[msg.sender]++;
}
function withdraw(){
uint balance = balances[msg.sender];
balances[msg.sender] = 0;
if(!msg.sender.send(balance)) throw;
}
function(){
withdraw();
}
}
@veox
Copy link

veox commented Jul 9, 2016

Multisend2.sol has typo: unit instead of uint. I personally like this one best.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment