You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

智能合约众筹ICO分阶段预售实现方案咨询

Great question! Let's break down both approaches and help you pick the best fit for your ICO, plus walk through the key details to ensure all 300,000 tokens end up in investors' hands.

This is the cleaner, more user-friendly approach for your multi-stage presale. Here's why it works:

Pros

  • Unified management: All stage rules (dates, token caps, discounts) live in one contract. Investors only need to remember one address, and you can easily track total tokens sold across all stages without juggling multiple contracts.
  • Automatic stage transitions: The contract can automatically detect which phase we're in based on the current block timestamp—no need to manually deploy new contracts or notify investors of address changes at each stage cutoff.
  • Guaranteed token accuracy: You predefine the total 300k token split across stages, so there's no risk of overissuing tokens or miscalculating totals across separate contracts.

Cons

  • Slightly more complex code: You'll need to write logic to handle stage checks, calculate discounted prices, and enforce per-stage token caps. But this is manageable with careful testing.

Core Implementation Tips

Here’s a simplified outline of how to structure the contract:

  1. Define a Stage struct: Store each phase's start/end timestamps, max tokens, and discount rate (use integers for Solidity, e.g., 50 for 50% off).
  2. Initialize stages in the constructor: Hardcode your 3 phases (double-check timestamps—use a tool to convert dates to Unix time in seconds).
  3. Add a stage detection function: A getCurrentStage() method that checks block.timestamp to return the active phase.
  4. Build the purchase logic: In your buyTokens() function:
    • Verify the ICO has started and the current stage has tokens left.
    • Calculate the token amount based on the investor's ETH payment and the stage's discount.
    • Transfer tokens to the investor and update the total sold count.
  5. Add safety guards: Restrict ETH withdrawals to an owner address, prevent purchases before the ICO starts, and block buys once a stage's token cap is hit.

Example code snippet for stage handling:

pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract MultiStageICOSale {
    IERC20 public immutable token;
    uint256 public immutable basePrice; // Wei per token (e.g., 1e15 = 0.001 ETH per token at full price)
    
    struct Stage {
        uint256 startTime;
        uint256 endTime;
        uint256 maxTokens;
        uint256 discountPercent; // 50 = 50% off, 100 = full price
    }

    Stage[3] public stages;
    uint256 public totalTokensSold;

    constructor(IERC20 _token) {
        token = _token;
        basePrice = 1e15;
        
        // Initialize stages (Unix timestamps for 2018 dates)
        stages[0] = Stage(
            1527811200, // 2018-06-01 UTC
            1528675200, // 2018-06-10 UTC
            100000 * 10**18,
            50
        );
        stages[1] = Stage(
            1528675200,
            1529539200, // 2018-06-20 UTC
            100000 * 10**18,
            75
        );
        stages[2] = Stage(
            1529539200,
            type(uint256).max, // No end date until tokens sell out
            100000 * 10**18,
            100
        );
    }

    function getCurrentStage() public view returns(Stage memory) {
        uint256 now = block.timestamp;
        if (now >= stages[0].startTime && now < stages[0].endTime) return stages[0];
        if (now >= stages[1].startTime && now < stages[1].endTime) return stages[1];
        if (now >= stages[2].startTime) return stages[2];
        revert("ICO has not started yet");
    }

    function buyTokens() external payable {
        Stage memory currentStage = getCurrentStage();
        
        // Calculate remaining tokens in current stage
        uint256 stageSold = totalTokensSold;
        if (currentStage == stages[1]) stageSold -= stages[0].maxTokens;
        if (currentStage == stages[2]) stageSold -= stages[0].maxTokens + stages[1].maxTokens;
        uint256 remainingTokens = currentStage.maxTokens - stageSold;
        require(remainingTokens > 0, "Stage tokens sold out");

        // Calculate token amount (adjust for discount)
        uint256 tokenAmount = (msg.value * 100) / (currentStage.discountPercent * basePrice);
        require(tokenAmount <= remainingTokens, "Insufficient tokens left for this purchase");

        // Transfer tokens to investor
        require(token.transfer(msg.sender, tokenAmount), "Token transfer failed");
        totalTokensSold += tokenAmount;
    }

    // Owner-only function to withdraw raised ETH
    function withdrawETH() external {
        payable(msg.sender).transfer(address(this).balance);
    }
}

Option 2: Three Separate Contracts

This approach involves deploying a unique contract for each presale stage.

Pros

  • Simpler code per contract: Each contract only handles one stage's logic, making testing and auditing faster.
  • Risk isolation: A bug in one stage's contract won't directly affect the others (though this is less of an issue with modern Solidity practices).

Cons

  • Investor confusion: You'll need to communicate three different contract addresses to investors at each stage, increasing the risk of users sending ETH to the wrong address.
  • Manual management: You'll have to deploy each new contract when a stage ends, pause the old one, and coordinate announcements—this adds operational friction and room for error.
  • Token cap risk: You'll need to ensure each contract is only allocated its 100k token quota via your main ERC20 contract's approve() function. A misconfiguration could lead to overissuing tokens.

Final Recommendation

Go with the single contract approach. It’s more efficient for you and your investors, reduces operational risk, and ensures full control over the total token supply. Just make sure to:

  • Double-check all timestamps and token caps before deployment.
  • Test edge cases (e.g., purchases exactly at stage cutoff times, max token buys per stage).
  • Get the contract audited by a professional firm—ICO contracts handle real funds, so security is non-negotiable.

内容的提问来源于stack exchange,提问作者Jacktur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:33:27