1

I'm trying to figure out a way to transfer some tokens from my address to multiple other addresses which all must receive a specific value associated with the specific address, how would I go about this instead of transferring one by one?

6
  • It occurred to me after thinking more about your question to ask if you we're trying to do this in a development contract or not. How were you hoping to do this? – Thom Ives Nov 25 '17 at 2:27
  • 1
    Is it possible to add multiple 'setHolder' at once? or only manually one by one and then call the releaseHolderShares. – NowsyMe Nov 25 '17 at 15:45
  • @Ismael in your reference it's the same amount to many addresses. I want different amounts based on the address – NowsyMe Nov 25 '17 at 18:05
  • 2
    @NowsyMe The code accepts an array of addresses and an array of values, each address can receive a different value. – Ismael Nov 25 '17 at 18:34
  • 2
    Check their repository github.com/omisego/airdrop for further instruction. – Ismael Nov 25 '17 at 20:33
1

I had the same question, and I figured it out using some good examples from courses out on the web.

Use the contract below in Remix. It will compile with 12 warnings. Use the Javascript VM in the Run tab (upper right). Make sure the first address of the 5 addresses is chosen.

Use something like these, using the 5th, and 4th accounts given by the Javascript VM, to set share holders using the setHolder function in Remix - lower right:

  1. "0xdd870fa1b7c4700f2bd7f44238821c26f7392148", 100000, "Billy", "Bob"
  2. "0x583031d1113ad414f02576bd6afabfb302140225", 100000, "John", "Smith"

I set a modifier that prevents the shares being released for 5 minutes. Check that it won't transfer before the 5 minutes when you use the releaseHolderShares function - lower right.

Then, after 5 minutes, try again and check the balances. Voila, you transferred to the list of share holders you created.

Sorry for the length, but I wanted to do this in the spirit of an ERC20 compliant contract. Also, you could hard code the addresses you want to send to in the contract, but given immutability after creation, I think that's a bad idea.

pragma solidity ^0.4.18;

contract ReleaseShares {
    string public constant symbol = "Test";
    string public constant name = "Test Release";
    uint8 public constant decimals = 18;
    uint256 public totalSupply = 10000000;
    address public owner;
    uint public creationTime;

    // Constructor
    function ReleaseShares() public {
        owner = msg.sender;
        balances[owner] = totalSupply;
        creationTime = now;
    }

    modifier releaseOfSharesOK() {
        require(now >= (creationTime + 300));
        _;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    // Balances and allowances for each account
    mapping(address => uint256) balances;
    mapping(address => mapping (address => uint256)) allowed;

    function balanceOf(address _owner) constant public returns (uint256 balance) {
        return balances[_owner];
    }

    // Transfer the balance from owner's account to another account
    function transfer(address _to, uint256 _amount) public returns (bool success) {
        if (balances[msg.sender] >= _amount 
            && _amount > 0
            && balances[_to] + _amount > balances[_to]) {
            balances[msg.sender] -= _amount;
            balances[_to] += _amount;
            return true;
        } else {
            return false;
        }
    }

    function transferFrom(
        address _from,
        address _to,
        uint256 _amount
    ) public returns (bool success) {
        if (balances[_from] >= _amount
            && allowed[_from][msg.sender] >= _amount
            && _amount > 0
            && balances[_to] + _amount > balances[_to]) {
            balances[_from] -= _amount;
            allowed[_from][msg.sender] -= _amount;
            balances[_to] += _amount;
            return true;
        } else {
            return false;
        }
    }

    // Allow _spender to withdraw from your account, multiple times, up to the _value amount.
    // If this function is called again it overwrites the current allowance with _value.
    function approve(address _spender, uint256 _amount) public returns (bool success) {
        allowed[msg.sender][_spender] = _amount;
        return true;
    }

    function allowance(address _owner, address _spender) constant public returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }

    function() public payable { }

    ////////////////////////////////////////////////////////////////////////////
    // Share release operations
    ////////////////////////////////////////////////////////////////////////////
    struct Holder {
        uint amount;
        string fName;
        string lName;
    }

    mapping (address => Holder) holders;
    address[] public holderAccts;

    function setHolder(
        address _address, 
        uint _amount, 
        string _fName, 
        string _lName
        ) onlyOwner public {
            var holder = holders[_address];

            holder.amount = _amount;
            holder.fName = _fName;
            holder.lName = _lName;

            holderAccts.push(_address) -1;
    }

    function getHolders() view public returns(address[]) {
        return holderAccts;
    }

    function getHolder(address _address) view public returns (uint, string, string) {
        return (holders[_address].amount, holders[_address].fName, holders[_address].lName);
    }

    function countHolders() view public returns (uint) {
        return holderAccts.length;
    }

    function releaseHolderShares() releaseOfSharesOK onlyOwner public {
        uint256 numberOfAccts = holderAccts.length;
        for (uint i = 0; i < numberOfAccts; i ++) {
            transfer(holderAccts[i], holders[holderAccts[i]].amount);
        }
    }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.