Merkle Air-Drops: Make Love, Not War


via Ricmoo

The idea of token Air Drops is interesting and a powerful way to quickly get tokens into the hands of a large customer base, but the current incarnations are more closely related to carpet bombing than to air-dropping.

Accounts are littered with fragments of token shrapnel whether they wanted them or not, and in many cases, whether the account can even spend them.

The state of the blockchain becomes permanently bloated with:

  • contract storage for token balances that cannot be used
  • oodles of transactions required to disseminate tokens

Not to mention the ether gobbled up in fees and lost utility due to network congestion from the seeding transactions.

So, I would like to suggest a friendlier way to scatter tokens with a wide distribution using redeem-based Merkle Air Drops.

  • Deploy of any number of tokens in a single, cheap fixed-cost transaction
  • The receiver pays the gas*; which provides a bound on spam and dust as most people won’t pay a 12 cent transaction fee for 10 cents worth of tokens
  • All token holders have access to claim and use their tokens immediately and do not need to wait for seed transactions
  • Lost private keys and contracts without approve proxy methods do not waste blockchain state size with un-spendable balances or seeding transactions and do not waste ether
  • Tokens are often only needed on-chain in specific circumstances, such as transferring; hodlers can keep them off-chain (or at the very least move them on-chain during dips in gas prices)
  • People aren’t spooked by mysterious tokens showing up in their accounts (although this is likely the PR play that tokens were actually going)
  • technically, anyone may pay the gas, likely this would be the recipient of the tokens, but this also opens interesting use cases to explore; perhaps priority members get their token allocation paid by the token issuer, for example

By constructing a merkle root of all accounts and their balances, a complex token allocation can be deployed in a single contract transaction. The entire allocation can be made public, allowing anyone to construct the merkle proof for their tokens and claim them against the contract.

function redeem(uint256 index, address recipient,
                uint256 amount, bytes32[] merkleProof) public {
    // Make sure this has not been redeemed
    uint256 redeemedBlock = _redeemed[index / 256];
    uint256 redeemedMask = (uint256(1) << uint256(index % 256));
    require((redeemedBlock & redeemedMask) == 0);
    // Mark it as redeemed (if we fail, we revert)
    _redeemed[index / 256] = redeemedBlock | redeemedMask;
    // Compute the merkle root from the merkle proof
    bytes32 node = keccak256(index, recipient, amount);
    uint256 path = index;
    for (uint16 i = 0; i < merkleProof.length; i++) {
        if ((path & 0x01) == 1) {
            node = keccak256(merkleProof[i], node);
        } else {
            node = keccak256(node, merkleProof[i]);
        }
        path /= 2;
    }
    
    // Check the resolved merkle proof matches our merkle root
    require(node == _rootHash);
    
    // Redeem!
    _balances[recipient] += amount;
    _totalSupply += amount;
    Transfer(0, recipient, amount);
}

I have put together a simple JavaScript CLI tool and library to deploy, lookup and redeem Merkle Air Drops to demonstrate this technique. All that is necessary is a balance allocation JSON file which maps each account address to its allocated balance.

Here is a quick demonstration which gave away over 2.5 million tokens to the most recent one million accounts to send a transaction with a nonce of 0 as of block 5251718, providing each account with a number of tokens equal to the value of their first transaction.

/home/ricmoo> ethers-airdrop deploy "Pi Day N00b Token" "PIE" 18
Deployed:
  Contract Address: 0x334eec1482109Bd802D9e72A447848de3bCc1063

In the traditional “spirit” of an ICO, you can also use the --premine option to allocate tokens to yourself at the time of deployment. The cost to deploy this Air-Drop was 90 cents and each account can claim their tokens for about 17 cents, when or if they wish to do so.

/home/ricmoo> ethers-airdrop redeem CONTRACT_ADDRESS MY_ADDRESS

This is just a toy example of a Merkle Air-Drop, and other than my testing, I doubt there will be much demand for these tokens, and so all those unclaimed tokens will have no additional impact on the network or my costs.

Of course, the source code can be easily modified to put additional constraints or effects in the redeem method, such as early bird specials, decaying rewards, required payments or any other interesting allocation gremlin.

To simplify claiming tokens, a small static website can be created which has access to the balance allocation JSON file, and computes the Merkle proof for each customer. For example, here is our website to claim the procedurally generated stickers against our Sticker Registry that we handed out during DevCon3 and ETHWaterloo. Each sticker is unique, no two are alike, and their provenance is tracked on the blockchain against a private key printed on the back of each sticker. Deploying 512 stickers cost 4 cents, about 150 of which were given away, and only 3 have been actually claimed on-chain.

One last use-case I’d like to mention is ERC-721 tokens, similar to Crypto Kitties. By changing the balance allocation JSON file, which maps account addresses to initial balances, to an owner allocation JSON file, which maps token IDs to an initial owner account instead, a large collection of NFTs (Non-Fungible Tokens) could be efficiently handed out to a large number of initial collectors or players.

As always, thanks for reading! Any suggestions or feedback is always welcome, and feel free to follow me on Twitter for other updates to the random things I work on.

1 Like

💰 YEN · YouTube ·️ YEN.CAMP 🧠