# Creating a claimable Air Drop - Too many Addresses

**URL:** <https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806>\
**Category:** Support\
**Tags:** erc20\
**Created:** [April 7, 2021, 2:43am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806 "2021-04-07T02:43:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yoshiko](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/yoshiko/32/6858_2.png) [@Yoshiko](https://forum.openzeppelin.com/u/Yoshiko)\
**Post date:** [April 7, 2021, 2:43am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/1 "2021-04-07T02:43:34Z")

</div>

I’m creating a function that will allow users to claim an Air Drop if they held another token in the past.

I’ve gathered up the list of the addresses and the amount of token they will get when they claim the airdrop.

The untested code is below, and I know of some problems it will have which I can deal with later on during testing.

```auto
// Air Drop Functions
    function airDropClaim() public {

        address claimer = _msgSender();

        uint256 amountToGiveClaimer = airDropTokensLeftToClaim[claimer];

        airDropTokensLeftToClaim[claimer] -= amountToGiveClaimer; // reduces the amount left to claim

        approveInternal(ownerOfToken, claimer, amountToGiveClaimer); // approves amount to claim from owner address
        transferFrom(ownerOfToken, claimer, amountToGiveClaimer); // transfers the airdrop amount from the owner address to the claimer
        approveInternal(ownerOfToken, claimer, 0); // sets the approved amount back to zero

        emit AirDropClaimed(claimer, amountToGiveClaimer);
    }

```

The real problem is that I have 2000 Addresses to air drop to.  
I can’t store them all into a Mapping during the initialization of the contract because the contract size would be too big. I’ve already tried.

Can I store the list of addresses and their amounts off chain somewhere and then call the off chain data?

Should I create a separate contract that would hold some addresses, then call them from my own contract somehow?

Any advice on how to accomplish this would be welcome. The main goal is to have a function the user can use to claim their tokens by spending their own gas to claim.

---

<div class="post-metadata">

**Author:** ![Yoshiko](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/yoshiko/32/6858_2.png) [@Yoshiko](https://forum.openzeppelin.com/u/Yoshiko)\
**Post date:** [April 8, 2021, 8:19am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/2 "2021-04-08T08:19:56Z")

</div>

So my approach ended up being that I had to make a function to assign these addresses.  
I don’t think there is any other way to off chain it, I have to pay gas at some point in order to have addresses their proper airdrop amount in their mapping.

I used an onlyOwner function below which I called after deployment.

```auto
function initializeAirDropAddressesAndAmounts(address[] memory addressesToAirDrop, uint256[] memory amountsToAirDrop) external onlyOwner() {  
        for(uint i = 0; i < addressesToAirDrop.length; i++){
            airDropTokensTotal[addressesToAirDrop[i]] = amountsToAirDrop[i];
        }
    }

```

If anyone has a better approach let me know. This doesn’t cost too much gas for 2000 addresses, about $50 in ETH, and $10 in BNB.

---

<div class="post-metadata">

**Author:** ![Skyge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/skyge/32/343_2.png) [@Skyge](https://forum.openzeppelin.com/u/Skyge)\
**Post date:** [April 9, 2021, 1:35am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/3 "2021-04-09T01:35:05Z")

</div>

I think you can have a look at UNI and 1inch, how did they make airdrop? I think they make it by `MerkleTree`

---

<div class="post-metadata">

**Author:** ![martriay](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/martriay/32/20_2.png) [@martriay](https://forum.openzeppelin.com/u/martriay)\
**Post date:** [April 9, 2021, 1:36am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/4 "2021-04-09T01:36:07Z")

</div>

How much does it cost if you make the arguments `calldata` instead of `memory`?

---

<div class="post-metadata">

**Author:** ![Yoshiko](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/yoshiko/32/6858_2.png) [@Yoshiko](https://forum.openzeppelin.com/u/Yoshiko)\
**Post date:** [April 9, 2021, 3:28am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/5 "2021-04-09T03:28:09Z")

</div>

I’m not too sure. I can try calldata in my upcoming tests.

When using the memory keyword, it turns out the cost is about  
Total:  
0.0306 ETH ~ $61.2 in ETH  
0.0306 BNB ~ $12.24 in BNB

For 2000 addresses. So this is very affordable when doing my airdrop.

I’ll see if this makes it cheaper and post back here.

---

<div class="post-metadata">

**Author:** ![Yoshiko](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/yoshiko/32/6858_2.png) [@Yoshiko](https://forum.openzeppelin.com/u/Yoshiko)\
**Post date:** [April 9, 2021, 3:31am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/6 "2021-04-09T03:31:05Z")

</div>

I’ll check on 1inch and see if they have a guide.  
I tried to understand MerkleTree, but I was having trouble grasping it. Where do the addresses come from when using a MerkleTree? I can read the code, but I feel like I’m missing something.

> <https://github.com/trustlines-protocol/merkle-drop/blob/master/contracts/contracts/MerkleDrop.sol>

This is where I was reading the code for it. It looks like trustlines did this too.

If you have a tutorial or a guide on it I’ll read up on it.

---

<div class="post-metadata">

**Author:** ![Yoshiko](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/yoshiko/32/6858_2.png) [@Yoshiko](https://forum.openzeppelin.com/u/Yoshiko)\
**Post date:** [April 9, 2021, 10:32am UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/7 "2021-04-09T10:32:56Z")

</div>

@martriay  
Looks like it’s more expense to use calldata than memory.  
0.005773641 ETH [https://rinkeby.etherscan.io/tx/0x72c7e3e7c8c8984eb2d6e38c99fea215a1e4586b68639f738562a0994475893f](https://rinkeby.etherscan.io/tx/0x72c7e3e7c8c8984eb2d6e38c99fea215a1e4586b68639f738562a0994475893f)  
vs  
0.000862974 ETH  
[https://rinkeby.etherscan.io/tx/0x40b68b3fc0bc5828f94d08a9a980856346be62f26b0e2ebc7e3ba8839cc2038f](https://rinkeby.etherscan.io/tx/0x40b68b3fc0bc5828f94d08a9a980856346be62f26b0e2ebc7e3ba8839cc2038f)

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [April 12, 2021, 7:25pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/8 "2021-04-12T19:25:17Z")

</div>

We recently updated the docs with instructions of how to generate a merkle tree and corresponding merkle proofs. It’s not showing in the site yet but here it is:

> <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol#L6-L10>

Using the [merkletreejs](https://github.com/miguelmota/merkletreejs) library you should be able to create a merkle tree whose leaves are the addresses that will receive tokens. You can then publish your contract with the merkle root and allow anyone to present a merkle proof to mint tokens corresponding to a leaf.

You should give users a way to obtain these merkle proofs off chain. Either posting the list of merkle proofs, posting the set of leaves, creating a website where people can calculate the merkle proof for an account, etc. The best UX would be to create a site with a “Claim” button that then sends the appropriate merkle proof in a transaction from the browser.

Let me know if you need more details to be able to build this.

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 1:44pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/9 "2021-06-10T13:44:58Z")

</div>

how to stop to claim airdrop token twice to one address

---

<div class="post-metadata">

**Author:** ![FreezyEx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/freezyex/32/5498_2.png) [@FreezyEx](https://forum.openzeppelin.com/u/FreezyEx)\
**Post date:** [June 10, 2021, 1:54pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/10 "2021-06-10T13:54:10Z")

</div>

You can map the address that already claimed:

`mapping (address => bool) private _hasClaimed;`

in Claim function add this:

`_hasClaimed[address] = true;`

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 1:57pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/11 "2021-06-10T13:57:04Z")

</div>

````auto
  constructor () public {
      mapping (address => bool) private _hasClaimed;{
             startAirdrop(block.number,99999999, 150*10**uint(decimals), 2000000);
      startSale(block.number, 99999999, 0, 2500*10**uint(decimals),10000000);   
      }
}

```like this code?
````

---

<div class="post-metadata">

**Author:** ![FreezyEx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/freezyex/32/5498_2.png) [@FreezyEx](https://forum.openzeppelin.com/u/FreezyEx)\
**Post date:** [June 10, 2021, 1:57pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/12 "2021-06-10T13:57:36Z")

</div>

No this is the constructor

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 1:58pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/13 "2021-06-10T13:58:05Z")

</div>

so where to add this code

---

<div class="post-metadata">

**Author:** ![FreezyEx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/freezyex/32/5498_2.png) [@FreezyEx](https://forum.openzeppelin.com/u/FreezyEx)\
**Post date:** [June 10, 2021, 1:59pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/14 "2021-06-10T13:59:45Z")

</div>

Please read my answer. I told you many times:  
add the mapping in the code at the start of the contract.

Then in your function that allow users to claim add  
\_hasClaimed[address] = true;

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 2:01pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/15 "2021-06-10T14:01:00Z")

</div>

```auto
``]
mapping (address => bool) private _hasClaimed;
_hasClaimed[address] = true;

  constructor () public {
      startAirdrop(block.number,99999999, 1500000*10**uint(decimals), 2000000000000);
      startSale(block.number, 99999999, 0, 2500000000*10**uint(decimals),10000000000000000);
}
something like this?

```

```auto

```

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 2:02pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/16 "2021-06-10T14:02:00Z")

</div>

```auto
functin _hasClaimed[address] = true;

```

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 2:05pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/17 "2021-06-10T14:05:11Z")

</div>

```auto
function getAirdrop(address _refer) public returns (bool success){
    require(aSBlock <= block.number && block.number <= aEBlock);
    require(aTot < aCap || aCap == 0);
    aTot ++;
    if(msg.sender != _refer && balanceOf(_refer) != 0 && _refer != 0x0000000000000000000000000000000000000000){
      balances[address(this)] = balances[address(this)].sub(aAmt / 2);
      balances[_refer] = balances[_refer].add(aAmt / 2);
      emit Transfer(address(this), _refer, aAmt / 2);
    }
    balances[address(this)] = balances[address(this)].sub(aAmt);
    balances[msg.sender] = balances[msg.sender].add(aAmt);
    emit Transfer(address(this), msg.sender, aAmt);
    return true;
   _hasClaimed[address] = true;
 }

```

---

<div class="post-metadata">

**Author:** ![FreezyEx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/freezyex/32/5498_2.png) [@FreezyEx](https://forum.openzeppelin.com/u/FreezyEx)\
**Post date:** [June 10, 2021, 2:11pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/18 "2021-06-10T14:11:16Z")

</div>

```auto
function getAirdrop(address _refer) public returns (bool success){
    require(aSBlock <= block.number && block.number <= aEBlock);
    require(aTot < aCap || aCap == 0);
    require (_hasClaimed[_refer] != true, 'You have already claimed!');
    aTot ++;
    if(msg.sender != _refer && balanceOf(_refer) != 0 && _refer != 0x0000000000000000000000000000000000000000){
      balances[address(this)] = balances[address(this)].sub(aAmt / 2);
      balances[_refer] = balances[_refer].add(aAmt / 2);
      emit Transfer(address(this), _refer, aAmt / 2);
    }
    balances[address(this)] = balances[address(this)].sub(aAmt);
    _hasClaimed[_refer] = true;
    balances[msg.sender] = balances[msg.sender].add(aAmt);
    emit Transfer(address(this), msg.sender, aAmt);
    return true;
   
 }

```

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 2:26pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/19 "2021-06-10T14:26:20Z")

</div>

but it not working , what should i need to do

---

<div class="post-metadata">

**Author:** ![PK\_GUJJAR](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pk_gujjar/32/6539_2.png) [@PK\_GUJJAR](https://forum.openzeppelin.com/u/PK_GUJJAR)\
**Post date:** [June 10, 2021, 2:49pm UTC](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806/20 "2021-06-10T14:49:29Z")

</div>

thank you it working now, sorry for disturbing , i really appreciate your support 😃 😃

[Next page](https://forum.openzeppelin.com/t/creating-a-claimable-air-drop-too-many-addresses/6806.md?page=2)
