How Sharedrop Works: A Complete EOSIO Token Distribution Guide
Sharedrop, a term often used within the EOSIO ecosystem, describes a method of distributing tokens to a large number of accounts in a decentralized and efficient manner. It’s a powerful tool for projects launching on EOSIO-based blockchains (like EOS, Telos, WAX, and others) to achieve initial token distribution, bootstrap community engagement, and improve decentralization. This guide details the entire process, from conception to execution, and provides best practices for a successful Sharedrop.
I. What is a Sharedrop?
A Sharedrop is not an airdrop in the traditional sense, though the terms are sometimes used interchangeably. Here’s the crucial difference:
- Airdrop: Typically involves sending tokens directly to user accounts, often requiring those accounts to hold a specific asset (e.g., holding EOS to receive an airdrop of a new token). Airdrops can be resource-intensive on blockchains with RAM costs (like EOSIO).
- Sharedrop: Users claim tokens themselves from a smart contract. The contract holds the tokens, and users must actively participate by interacting with the contract (paying for the RAM to store their allocation) to receive their share. This shifts the resource burden to the users, making it far more scalable for distributing to a vast number of accounts.
Key Benefits of a Sharedrop:
- Scalability: Allows for distribution to millions of accounts, overcoming the limitations of traditional airdrops on RAM-limited blockchains.
- Decentralization: Promotes wider token distribution, avoiding concentration in a few hands.
- Community Building: Encourages active participation and engagement as users must claim their tokens.
- Cost-Effectiveness (for the project): The project doesn’t pay for the RAM costs associated with storing each user’s token allocation. This is a significant advantage over airdrops.
- Fairness (potentially): Can be designed with rules to ensure equitable distribution (e.g., based on Genesis snapshot, activity levels, or other criteria).
- Filtering out inactive accounts: Because users need to claim their tokens actively, sharedrops tend to exclude abandoned or inactive accounts, resulting in a more engaged token holder base.
II. Planning Your Sharedrop: The Design Phase
Before writing any code, careful planning is essential. This stage defines the rules, eligibility criteria, and overall strategy of your Sharedrop.
-
Define Your Goals:
- What are you trying to achieve with the Sharedrop? (e.g., wide distribution, rewarding early adopters, incentivizing specific actions).
- What metrics will you use to measure success? (e.g., number of claims, token holder distribution, social media engagement).
-
Tokenomics:
- Total Supply: How many tokens will be allocated to the Sharedrop? This should be a clearly defined portion of your total token supply.
- Claim Period: How long will users have to claim their tokens? (e.g., 6 months, 1 year, indefinitely). A limited claim period creates urgency but might exclude some users. An indefinite claim period allows maximum participation but might result in unclaimed tokens.
- Claim Decay (Optional): Will the amount of claimable tokens decrease over time? This can incentivize early claiming. For example, the claimable amount could decrease linearly or exponentially over the claim period.
- Vesting (Optional): Will the claimed tokens be immediately available, or will they be subject to a vesting schedule? Vesting can prevent immediate dumping and encourage long-term holding.
-
Eligibility Criteria:
- Snapshot-Based: The most common method. A snapshot of the blockchain is taken at a specific block height. Accounts that meet certain criteria at the time of the snapshot are eligible. Common criteria include:
- Holding a specific token: (e.g., holding EOS at the snapshot). This is the classic “Genesis snapshot” approach.
- Staking a specific token: (e.g., staking EOS to the REX).
- Account Age: (e.g., accounts created before a certain date).
- Participation in a specific event: (e.g., voting for Block Producers).
- Multiple Criteria: A combination of the above.
- Activity-Based: Eligibility is based on user activity on the blockchain or within a specific dApp. This is more complex to implement but can reward active users.
- KYC/AML (Optional): In some cases, projects may require Know Your Customer (KYC) and Anti-Money Laundering (AML) verification for eligibility. This adds complexity but may be necessary for regulatory compliance.
- Whitelist/Blacklist: You might want to explicitly include or exclude certain accounts.
- Snapshot-Based: The most common method. A snapshot of the blockchain is taken at a specific block height. Accounts that meet certain criteria at the time of the snapshot are eligible. Common criteria include:
-
Claiming Mechanism:
- Single Claim: Users can claim their entire allocation in a single transaction.
- Multiple Claims: Users can claim portions of their allocation over time, possibly with limitations on the frequency or amount.
- Claim Fee (Optional): A small fee (in EOS or another token) can be charged to cover transaction costs or deter Sybil attacks.
-
Technical Considerations:
- RAM Cost: The primary resource consideration on EOSIO. The Sharedrop contract will need enough RAM to store the state of the Sharedrop (e.g., the list of eligible accounts and their claimable amounts). However, users pay for the RAM to store their individual token balances after they claim.
- CPU/NET: While less of a concern than RAM, ensure the contract is optimized to minimize CPU and NET usage.
- Security Audits: Crucially important. The Sharedrop contract should be thoroughly audited by a reputable security firm to identify and fix any vulnerabilities before deployment.
III. Development: Building the Sharedrop Smart Contract
This section outlines the core components of a typical EOSIO Sharedrop smart contract. This is a simplified example and would need to be adapted based on your specific design choices. We’ll use EOSIO.CDT (Contract Development Toolkit) for writing the contract in C++.
“`c++
include
include
include
include
using namespace eosio;
class [[eosio::contract(“sharedrop”)]] sharedrop : public contract {
public:
using contract::contract;
// Structure to hold claim data for each user
struct [[eosio::table]] claim_info {
name account; // Account name
asset claimed; // Amount already claimed
asset claimable; // Total claimable amount
uint64_t primary_key() const { return account.value; }
};
// Multi-index table to store claim information
typedef multi_index<“claims”_n, claim_info> claims_table;
// Action to allow users to claim tokens
[[eosio::action]]
void claim(name account) {
require_auth(account); // Only the account can claim for itself
claims_table claims(get_self(), get_self().value);
auto itr = claims.find(account.value);
//Check that there is claim information
check(itr != claims.end(), "No claim found for this account.");
//Check that they haven't already claimed
check(itr->claimable.amount > itr->claimed.amount, "Tokens already fully claimed.");
//Calculate how much they can claim
asset amount_to_claim = itr->claimable - itr->claimed;
// Inline action to transfer tokens to the user
action(
permission_level{get_self(), "active"_n},
"eosio.token"_n, // Replace with your token contract
"transfer"_n,
std::make_tuple(get_self(), account, amount_to_claim, std::string("Sharedrop claim"))
).send();
// Update the claim information
claims.modify(itr, account, [&](auto& row) {
row.claimed += amount_to_claim;
});
}
// Action to initialize the Sharedrop (called only once by the contract owner)
[[eosio::action]]
void init(std::vector
require_auth(get_self()); // Only the contract owner can initialize
claims_table claims(get_self(), get_self().value);
// Populate the claims table with the initial allocations
for (const auto& allocation : allocations) {
claims.emplace(get_self(), [&](auto& row) {
row.account = allocation.first;
row.claimable = allocation.second;
row.claimed = asset(0, allocation.second.symbol); // Initialize claimed to 0
});
}
}
// You could add a function to allow the contract owner to update allocations
// before the Sharedrop opens for claims, if needed.
[[eosio::action]]
void updatealloc(name account, asset new_allocation) {
require_auth(get_self());
claims_table claims(_self, _self.value);
auto itr = claims.find(account.value);
check(itr != claims.end(), "Account not found in allocations.");
claims.modify(itr, get_self(), [&](auto& row) {
row.claimable = new_allocation;
});
}
};
“`
Explanation:
claim_info
struct: Stores the account name, the amount already claimed, and the total claimable amount.claims_table
: A multi-index table that stores theclaim_info
for each eligible account. The primary key is the account name.claim
action:require_auth(account)
: Ensures that only the account itself can claim its tokens.- Finds the account’s claim information in the
claims_table
. - Checks if the account is eligible and has unclaimed tokens.
- Calculates
amount_to_claim
- Uses an inline action to transfer the tokens from the contract’s account to the user’s account using the
eosio.token
contract (you’ll need to replace"eosio.token"_n
with your actual token contract). - Updates the
claimed
amount in theclaims_table
.
init
action:require_auth(get_self())
: Only the contract owner (initially, the account that deployed the contract) can call this action.- Iterates through the
allocations
vector (which would be populated from your snapshot data) and adds a record to theclaims_table
for each eligible account.
updatealloc
action (Optional): Allows the contract owner to modify the allocation for a specific account. This is useful for correcting errors or making adjustments before the claim period begins.
IV. Data Preparation: Generating the Allocation List
The allocations
vector in the init
action needs to be populated with data derived from your eligibility criteria (e.g., the blockchain snapshot). This typically involves:
- Taking a Snapshot: Use a tool like
cleos
(the EOSIO command-line interface) or a custom script to capture the state of the blockchain at a specific block height. You’ll need to query the relevant tables (e.g.,accounts
table ineosio.token
contract for token balances,rex
table for staked EOS). -
Processing the Snapshot: Write a script (e.g., in Python, JavaScript) to:
- Read the snapshot data.
- Apply your eligibility criteria (e.g., filter accounts based on token balance, staking, etc.).
- Calculate the allocation for each eligible account based on your chosen formula.
- Generate a data structure (e.g., a JSON file or a CSV file) that can be used to populate the
allocations
vector. The format should be a list of pairs:[ { "account": "accountname1", "amount": "100.0000 TOK" }, { "account": "accountname2", "amount": "50.0000 TOK" }, ... ]
-
Uploading Allocation data to contract:
The processed snapshot data needs to be passed to theinit
action of the contract. This needs to be done in chunks, as the transaction size is limited. A common approach is to write a script that reads the JSON/CSV file, splits it into smaller chunks, and sends multipleinit
transactions to the contract. Important: The sum ofamount
in all chunks must match the total token supply allocated to the Sharedrop.
V. Deployment and Execution
- Compile the Contract: Use the EOSIO.CDT to compile your C++ code into a WebAssembly (WASM) file and an Application Binary Interface (ABI) file.
- Deploy the Contract: Use
cleos
or a wallet with contract deployment capabilities to deploy the WASM and ABI files to your chosen EOSIO blockchain. You’ll need to create a new account for the contract and allocate sufficient RAM to store the contract’s code and initial state. - Issue your Token: If you haven’t already, you will need to create and issue your token using a token contract (such as a modified
eosio.token
contract). Ensure your sharedrop contract has enough tokens to cover the planned distribution. - Initialize the Sharedrop: Call the
init
action of your deployed contract, providing the prepared allocation data (as described in Section IV). This populates theclaims_table
with the eligible accounts and their claimable amounts. Remember to do this in chunks if your allocation list is large. - Announce the Sharedrop: Inform your community about the Sharedrop, providing clear instructions on how to claim their tokens. This includes:
- The address of the Sharedrop contract.
- The name of the
claim
action. - The claim period.
- Any other relevant details (e.g., claim fee, vesting schedule).
- Monitor and Support: Monitor the Sharedrop’s progress (e.g., number of claims, remaining unclaimed tokens). Provide support to users who encounter issues claiming their tokens.
VI. Best Practices and Considerations
- Security: Prioritize security above all else. Thoroughly test your contract, get it audited by a reputable firm, and follow secure coding practices.
- User Experience: Make the claiming process as simple and intuitive as possible. Provide clear instructions and helpful error messages.
- Communication: Keep your community informed throughout the entire process. Be transparent about the rules, eligibility criteria, and any changes.
- RAM Management: Carefully estimate the RAM required for the Sharedrop contract’s state. Consider using techniques like table compression to reduce RAM usage.
- Testing: Test thoroughly on a testnet (e.g., Jungle, Kylin) before deploying to the mainnet.
- Gas Optimization: Optimize your smart contract code to minimize CPU and NET usage.
- Community Feedback: Gather feedback from your community throughout the planning and execution phases.
- Legal Compliance: Ensure that your Sharedrop complies with all applicable laws and regulations.
VII. Conclusion
Sharedrops are a powerful mechanism for achieving wide and decentralized token distribution on EOSIO blockchains. By carefully planning, developing a secure and efficient smart contract, and providing a user-friendly claiming experience, projects can leverage Sharedrops to build strong communities, increase token holder engagement, and establish a solid foundation for their decentralized applications. This guide provides a comprehensive overview of the entire process, empowering developers and project teams to successfully implement their own Sharedrops. Remember to always prioritize security and user experience, and to adapt the process to your specific project needs and goals.