Introduction
As a newly appointed Solidity Engineer at Polymath, I'm excited to share this step-by-step guide on automating token distributions via Ethereum smart contracts. This tutorial will walk you through creating a Node.js script that handles bulk ERC20 token transfers—specifically for airdropping 250 POLY tokens each to 40,000 verified subscribers.
Key Components
1. Token Contracts Overview
- PolyToken.sol: A standard ERC20 contract with fixed supply.
- PolyDistribution.sol: Handles initial token allocation via the
airdropTokens()function.
Critical Function: airdropTokens()
function airdropTokens(address[] _recipient) public onlyOwnerOrAdmin {
require(now >= startTime);
uint airdropped;
for(uint i = 0; i< _recipient.length; i++) {
if (!airdrops[_recipient[i]]) {
airdrops[_recipient[i]] = true;
require(POLY.transfer(_recipient[i], 250 * decimalFactor));
airdropped = airdropped.add(250 * decimalFactor);
}
}
AVAILABLE_AIRDROP_SUPPLY = AVAILABLE_AIRDROP_SUPPLY.sub(airdropped);
AVAILABLE_TOTAL_SUPPLY = AVAILABLE_TOTAL_SUPPLY.sub(airdropped);
grandTotalClaimed = grandTotalClaimed.add(airdropped);
}This function distributes tokens to addresses in batches of 80 (optimized for gas efficiency).
Step-by-Step Implementation
2. Project Setup
Install dependencies:
mkdir distributionTutorial
npm init
truffle init
npm install web3 fast-csv truffle-contract ethereumjs-testrpc --save3. Deploying Contracts
Configure truffle.js for Ropsten and deploy using:
module.exports = {
networks: {
ropsten: {
host: 'localhost',
port: 8545,
network_id: '3',
gas: 3500000,
gasPrice: 50000000000
}
}
};Run:
truffle migrate --network ropstenAutomating the Airdrop Process
4. Processing Subscriber Data
Read CSV File (
airdrop.csv):- Validate Ethereum addresses using
web3.utils.isAddress(). - Batch addresses into groups of 80.
- Validate Ethereum addresses using
Execute Airdrop:
async function setAllocation() { let polyDistribution = await PolyDistribution.at(polyDistributionAddress); for (let batch of distribData) { try { await polyDistribution.airdropTokens(batch, { from: accounts[0], gas: 4500000, gasPrice: 50000000000 }); console.log(`Batch processed: ${batch.length} addresses`); } catch (err) { console.error("Error:", err); } } }
5. Verification
Retrieve transfer logs to confirm successful distributions:
let events = await polyToken.Transfer({
from: polyDistribution.address
}, {
fromBlock: 0,
toBlock: 'latest'
});
events.get((error, logs) => {
logs.forEach(log => {
console.log(`Transferred ${log.args.value} to ${log.args.to}`);
});
});Optimizing Gas Costs
- Batch Size: 80 addresses per transaction balances gas limits and efficiency.
- Gas Price: Set dynamically based on network conditions.
👉 Learn more about optimizing Ethereum transactions
FAQs
Q1: Why batch 80 addresses per transaction?
A1: This number optimizes gas usage—large enough to minimize transactions but small enough to avoid out-of-gas errors.
Q2: How do I handle failed transactions?
A2: The script includes error logging to retry failed batches manually.
Q3: Can I customize token amounts per address?
A3: Yes! Modify the CSV to include a second column with amounts and update the contract’s airdropTokens() function.
Conclusion
This automated approach ensures efficient, scalable token distribution while maintaining transparency through on-chain verification. For the complete code, visit the Polymath GitHub repository.