前言撰写本文,初衷是围绕代币流动性落地需求,结合实操经历生出的一些实战思考。此前我拆解分析过大量具备宏大叙事的Meme币项目,也深入研究过Web3各大细分赛道的头部优质项目,更是复刻过诸多项目的核心智能合约。深耕许久后才幡然醒悟,行业发展终究要回归实际落地。不少从业者既看中Meme
撰写本文,初衷是围绕代币流动性落地需求,结合实操经历生出的一些实战思考。
此前我拆解分析过大量具备宏大叙事的 Meme 币项目,也深入研究过 Web3 各大细分赛道的头部优质项目,更是复刻过诸多项目的核心智能合约。深耕许久后才幡然醒悟,行业发展终究要回归实际落地。
不少从业者既看中 Meme 币发射平台一键发币的便捷性,又不愿被平台规则与权限束缚,更倾向于自主发币、独立运营项目。其实单纯部署发行代币门槛并不高,但绝大多数人都卡在了发币之后的流动性搭建环节。
哪怕是圈内资深玩家,也容易陷入认知误区:长期习惯了发射平台一键发币、自动形成交易流动的便捷模式,便误以为仅部署一份基础代币合约,代币就能自然实现流通交易。
基于这类普遍存在的认知偏差,本文将全面汇总主流自主发币玩法,同时重点详解当下实用性最强、优势最突出的代币内置交易合约搭建模式,理清自主发币与流动性搭建的完整逻辑。
撸热度、做土狗 Meme、快速开盘蹭行情
普通最简代币,无任何内置功能
正规项目、社群积分、纯流通代币
就是你上面那份带买币、自带兑换、交易税、销毁、持币分红合约
sell函数实现代币换回主币做资金盘模式、分红模式、静态兑换模式、独立生态币
主流 CEX、链游平台、社群专属币
内部积分、平台专属通证,不适合公开二级市场
| 发币方式 | 需建流动池 | 需发射平台 | 自带买卖 | 可自定义税制分红 | 难度 |
|---|---|---|---|---|---|
| 一键发射平台 | 后期自动建 | 必须用 | 仅限站内 | 不能自定义 | 极低 |
| 标准 ERC20 发币 | 必须手动建 | 不用 | 不能 | 不能 | 低 |
| 内置交易合约发币 | 完全不用建 | 完全不用 | 自带直兑买卖 | 全部自定义 | 中高 |
| 中心化后台发币 | 不需要 | 平台内 | 平台内交易 | 平台设定 | 极低 |
核心业务逻辑设计
买入阶段:散户打入 ETH,合约按比例发放代币(此时不收税,鼓励买入)。
转账/卖出抽税(税点) :只要用户把代币转给别人(或未来去 DEX 交易),合约自动扣除 5% 的交易税。
税款去向分流(分红与消耗) :
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title TaxAndDividendToken
* @dev 【天平版】完美修复旁观者散户债务剪刀差漏洞,采用工业级水位线红利算法(ETH原生版)
*/
contract TaxAndDividendToken is ERC20, ReentrancyGuard, Ownable {
// 【注意】1 ETH 兑换 1,000,000 代币。以太坊上 ETH 价格较高,你可以根据需要调整此汇率
uint256 public constant TOKENS_PER_ETH = 1000000;
uint256 public constant TAX_BURN = 200; // 2% 销毁
uint256 public constant TAX_DIVIDEND = 300; // 3% 分红
uint256 public constant TAX_DENOMINATOR = 10000;
uint256 public accEthPerShare; // 每股累计分配的 ETH 水位线
uint256 private constant SHARE_MULTIPLIER = 1e18; // 1e18 高精度放大器
uint256 public totalDividendPool; // 账面分红池 ETH 总额
bool private _inSwap;
// 记录用户钱包内累计尚未提取的 ETH 现金收益
mapping(address => uint256) public unclaimedRewards;
// 记录用户上一次同步分红时的全局每股收益水位线
mapping(address => uint256) public userLastAccPerShare;
// 免税白名单
mapping(address => bool) public isExcludedFromTax;
event TokenBought(
address indexed buyer,
uint256 ethSpent,
uint256 tokenReceived
);
event EthDistributed(uint256 ethAmount);
event DividendClaimed(address indexed user, uint256 ethAmount);
constructor(
string memory name,
string memory symbol,
address initialOwner
) ERC20(name, symbol) Ownable(initialOwner) {
isExcludedFromTax[address(this)] = true;
isExcludedFromTax[initialOwner] = true;
// 初始铸造 10 亿枚代币锁在合约中用于销售
_mint(address(this), 1000000000 * 10 ** decimals());
}
/**
* @dev 直投买入:散户发送 ETH 换取代币
*/
function buy() public payable nonReentrant {
require(msg.value > 0, "Must send ETH");
uint256 tokenAmount = msg.value * TOKENS_PER_ETH;
require(
balanceOf(address(this)) >= tokenAmount,
"Insufficient contract inventory"
);
// 在更新持仓前,先固化用户的历史收益
_savePendingRewards(msg.sender);
_transfer(address(this), msg.sender, tokenAmount);
emit TokenBought(msg.sender, msg.value, tokenAmount);
}
/**
* @dev 核心账本拦截器:处理转账扣税与分红水位线演进
*/
function _update(
address from,
address to,
uint256 value
) internal override(ERC20) {
// 白名单、铸造、销毁、或内部互换直接放行
if (
_inSwap ||
from == address(0) ||
to == address(0) ||
isExcludedFromTax[from] ||
isExcludedFromTax[to]
) {
super._update(from, to, value);
return;
}
// 1. 【时序修复】:在改变任何人持仓前,必须先归档双方的动态历史收益
_savePendingRewards(from);
_savePendingRewards(to);
uint256 burnAmount = (value * TAX_BURN) / TAX_DENOMINATOR;
uint256 dividendTokenAmount = (value * TAX_DIVIDEND) / TAX_DENOMINATOR;
uint256 finalToForward = value - burnAmount - dividendTokenAmount;
// 获取扣税前全网真正的有效散户外部总流通量
uint256 validSupply = totalSupply() - balanceOf(address(this));
// 2. 执行通缩销毁
if (burnAmount > 0) {
super._update(from, address(0), burnAmount);
}
// 3. 执行分红注入与水位线升级
if (dividendTokenAmount > 0 && validSupply > 0) {
_inSwap = true;
super._update(from, address(this), dividendTokenAmount);
_inSwap = false;
// 【核心修正】:dividendTokenAmount 本身带有 18 位 decimals
// 直接除以汇率即可得到正确的以太坊 wei 单位,不再乘以 1 ether 导致精度爆炸
uint256 virtualEthValue = dividendTokenAmount / TOKENS_PER_ETH;
totalDividendPool += virtualEthValue;
// 分红水位线滚动上涨(这里使用 SHARE_MULTIPLIER 放大是正确的,用于防止除法精度丢失)
accEthPerShare += (virtualEthValue * SHARE_MULTIPLIER) / validSupply;
emit EthDistributed(virtualEthValue);
}
// 4. 转账双方由于参与了此区块的交易,立刻将个人水位线对齐至全网最新
userLastAccPerShare[from] = accEthPerShare;
userLastAccPerShare[to] = accEthPerShare;
// 5. 送达净代币
super._update(from, to, finalToForward);
}
/**
* @dev 一键提现应得的 ETH 现金红利
*/
function claimDividend() external nonReentrant {
_savePendingRewards(msg.sender);
uint256 pending = unclaimedRewards[msg.sender];
require(pending > 0, "No dividend available");
require(address(this).balance >= pending, "Contract liquidity short");
require(totalDividendPool >= pending, "Dividend pool drained");
unclaimedRewards[msg.sender] = 0;
totalDividendPool -= pending;
// 将 ETH 安全转给用户
payable(msg.sender).transfer(pending);
emit DividendClaimed(msg.sender, pending);
}
/**
* @dev 查看当前属于用户的未领分红总额 (已归档 + 尚未归档的动态水位差收益)
*/
function pendingRewards(address user) public view returns (uint256) {
uint256 shareDiff = accEthPerShare - userLastAccPerShare[user];
uint256 newRewards = (balanceOf(user) * shareDiff) / SHARE_MULTIPLIER;
return unclaimedRewards[user] + newRewards;
}
/**
* @dev 内部归档工具:把用户的动态水位红利,固化进入其余额累加账本
*/
function _savePendingRewards(address user) internal {
if (balanceOf(user) > 0) {
uint256 shareDiff = accEthPerShare - userLastAccPerShare[user];
if (shareDiff > 0) {
unclaimedRewards[user] += (balanceOf(user) * shareDiff) / SHARE_MULTIPLIER;
}
}
// 同步个人的水位线至全网最新
userLastAccPerShare[user] = accEthPerShare;
}
function setExcludeFromTax(
address account,
bool excluded
) external onlyOwner {
isExcludedFromTax[account] = excluded;
}
/**
* @dev 提取项目方的管理资金(扣除分红池后剩余的 ETH)
*/
function withdrawProjectEth(
uint256 amount
) external onlyOwner nonReentrant {
require(
address(this).balance - totalDividendPool >= amount,
"Exceeds administrative funds"
);
payable(owner()).transfer(amount);
}
receive() external payable {
buy();
}
}
TaxAndDividendToken ETH 版全流程集成测试
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { parseEther } from "viem";
import { network } from "hardhat";
describe("TaxAndDividendToken ETH 版全流程集成测试", function () {
// 统一的契约部署与初始化脚手架
async function deployFixture() {
const { viem } = await (network as any).connect();
const [admin, alice, bob, charlie] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
// 部署分红税点代币合约
const token = await viem.deployContract("TaxAndDividendToken", [
"Tax & Dividend Token",
"TDT",
admin.account.address
]);
return {
admin, alice, bob, charlie,
token,
publicClient
};
}
it("【初始化状态】合约应当锁死初始代币库存,管理员默认免税", async function () {
const { token, admin } = await deployFixture();
const contractBalance = await token.read.balanceOf([token.address]);
const expectedSupply = parseEther("1000000000"); // 10 亿枚
assert.equal(contractBalance, expectedSupply, "初始 10 亿供应量未全额锁在合约库存中");
const isAdminExcluded = await token.read.isExcludedFromTax([admin.account.address]);
assert.equal(isAdminExcluded, true, "管理员应当默认进入免税白名单");
});
it("【直投买入】散户发送 ETH 换取代币,且买入行为不应当被抽税", async function () {
const { token, alice } = await deployFixture();
const buyAmountEth = parseEther("0.1"); // 0.1 ETH
await alice.sendTransaction({
to: token.address,
value: buyAmountEth
});
const aliceBalance = await token.read.balanceOf([alice.account.address]);
const expectedTokens = parseEther("100000"); // 0.1 * 1,000,000 = 100,000 TDT
assert.equal(aliceBalance, expectedTokens, "Alice 获得的代币数量与汇率不符,或买入时被错误扣税");
});
it("【抽税与通缩】非白名单转账扣除 5%(2% 销毁,3% 分红)", async function () {
const { token, alice, bob } = await deployFixture();
// Alice 买入 200,000 TDT
await alice.sendTransaction({ to: token.address, value: parseEther("0.2") });
const supplyBefore = await token.read.totalSupply();
// Alice 向 Bob 转账 100,000 TDT
const transferAmount = parseEther("100000");
await token.write.transfer([bob.account.address, transferAmount], { account: alice.account });
// Bob 应当收到 95% = 95,000 TDT
const bobBalance = await token.read.balanceOf([bob.account.address]);
const expectedBobNet = parseEther("95000");
assert.equal(bobBalance, expectedBobNet, "Bob 收到的代币净额不正确,税点计算有误");
// 全网总供应量应当减少 2% = 2,000 TDT
const supplyAfter = await token.read.totalSupply();
const supplyDiff = supplyBefore - supplyAfter;
assert.equal(supplyDiff, parseEther("2000"), "全网总供应量未按 2% 的比例执行黑洞通缩销毁");
});
it("【分红与提取】修正水位线时序后,持币散户应能按比例瓜分并成功提现 ETH 红利", async function () {
const { token, alice, bob, charlie, publicClient } = await deployFixture();
// 1. 准备阶段:Alice 和 Bob 各买入 0.1 ETH 的代币,此时两人持仓 1:1 (各 100,000 TDT)
// 全网有效散户流通量 validSupply = 200,000 TDT
await alice.sendTransaction({ to: token.address, value: parseEther("0.1") });
await bob.sendTransaction({ to: token.address, value: parseEther("0.1") });
// 2. 模拟资金池:由于合约的分红依靠 virtualEthValue 账面记录,
// 转账 100,000 TDT 产生的 3% 税款为 3,000 TDT,按汇率折算为 0.003 ETH。
// 为了让底层 claimDividend 能够成功转账,我们通过 hardhat_setBalance 为合约补充对应的真实 ETH 余额
const currentContractBalance = await publicClient.getBalance({ address: token.address });
const injectAmount = parseEther("0.003");
const targetBalanceHex = "0x" + (currentContractBalance + injectAmount).toString(16);
await publicClient.transport.request({
method: "hardhat_setBalance",
params: [token.address, targetBalanceHex],
});
// 3. 产生分红行为:Alice 向 Charlie(零持仓新户)转账 100,000 枚代币
// 此时触发 _update,计算分红并推高全局水位线 accEthPerShare
await token.write.transfer([charlie.account.address, parseEther("100000")], { account: alice.account });
// 4. 水位线验证:Bob 期间未进行任何操作,他的动态 pending 收益应当占分红池的 50%(因为占总有效流通量的 1/2)
// 0.003 ETH * 50% = 0.0015 ETH
const bobPending = await token.read.pendingRewards([bob.account.address]);
assert.equal(bobPending, parseEther("0.0015"), "Bob 自动分得的 ETH 红利数额不符合持仓比例");
// 5. 提现提取验证
const contractEthBefore = await publicClient.getBalance({ address: token.address });
await token.write.claimDividend({ account: bob.account });
const contractEthAfter = await publicClient.getBalance({ address: token.address });
// 合约真实减少的 ETH 应当等于 Bob 提走的红利
const contractEthDiff = contractEthBefore - contractEthAfter;
assert.equal(contractEthDiff, parseEther("0.0015"), "从分红合约中拨出的真实 ETH 资金量不正确");
// 6. 清账验证:提现后其 pending 账单应当自动归零清空
const bobPendingAfter = await token.read.pendingRewards([bob.account.address]);
assert.equal(bobPendingAfter, 0n, "提取红利后,Bob 的未领收益账单未能成功清零");
});
});
// scripts/deploy.js
import { network, artifacts } from "hardhat";
import { parseUnits } from "viem";
async function main() {
// 连接网络
const { viem } = await network.connect({ network: network.name });//指定网络进行链接
// 获取客户端
const [deployer, investor] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
const deployerAddress = deployer.account.address;
//部署usdt
const TaxAndDividendTokenArtifact = await artifacts.readArtifact("TaxAndDividendToken");
const TaxAndDividendTokenHash = await deployer.deployContract({
abi: TaxAndDividendTokenArtifact.abi,
bytecode: TaxAndDividendTokenArtifact.bytecode,
args: ["Tax & Dividend Token", "TDT", deployerAddress],
});
const TaxAndDividendTokenHashReceipt = await publicClient.waitForTransactionReceipt({
hash: TaxAndDividendTokenHash
});
console.log("TaxAndDividendToken合约地址:", TaxAndDividendTokenHashReceipt.contractAddress);
}
main().catch(console.error);
至此,市面上主流代币发行方式的优劣对比已全部梳理完毕,本文重点讲解的第三种一站式落地发币方案也讲解完结。理清各类发币模式利弊,吃透内置交易合约实操逻辑,便能摆脱平台束缚,独立完成代币发行与流动性搭建全流程,实现自主发币完整落地。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
作者暂未设置收款二维码