【免责声明】本文仅为区块链智能合约技术架构、工程案例科普,不构成任何投资、交易建议。文中描述的链上合约机制仅为代码实现方案,相关链上凭证不具备法定货币属性,不鼓励任何虚拟资产交易行为,请遵守各地监管法规。
引言
在 Web3 与 AI 深度融合的浪潮下,链上游戏和自主智能体(Autonomous Agents)正在成为新的流量入口。然而,传统的游戏代币发行普遍面临着“开盘即巅峰、缺乏持续赋能、抗 Rug(防跑路)能力弱、治理中心化”等核心痛点。
Akedo Protocol 应运而生。它是一套专为 AI 引擎与游戏创作者打造的一键去中心化发币与资产孵化生态系统。通过原生的 $AKE 代币刚性通缩模型、智能时间锁金库(Liquidity Locker)以及严密的权限和边界防护,Akedo 为链上游戏生态构筑了一道安全、可持续的经济闭环。
一、 Akedo 项目背景与核心愿景
1. 行业背景
当前,无论是通过 AI 一键生成游戏(GameFi 2.0),还是社区共创的独立游戏集合,都急需一个能够解决信任问题的基础设施:
- 信任危机:创作者或项目方往往手握大量初始代币,容易在开盘后瞬间抛售(Rug Pull)。
- 价值捕获缺失:生态代币无法将游戏发行与底层通缩绑定,导致代币沦为纯粹的投机工具。
- 开发门槛高:复杂的代币经济学设计与安全锁仓逻辑阻碍了优质AI游戏项目的快速冷启动。
2. Akedo 的解决方案
Akedo 采用模块化智能合约架构,将协议计费凭证 AKE、游戏资产工厂、资产时间锁深度绑定。AI 智能代理或人类创作者,可以低成本、在零信任合约约束下部署游戏链上资产,协议设计让所有生态参与方(协议贡献者、运维资金池、销毁池)共享协议生态发展带来的资源收益。
二、 核心架构与技术实现
整个 Akedo 协议由四个核心合约组成,形成了一套严密的防线:
1. AkedoCoreToken ($AKE 原生代币)
-
角色:整个生态的价值锚点与燃料。
-
三向分流机制 (
burnAndDistributeFees) :当创作者调用工厂发币时,系统会强制扣除固定数量的 $AKE 手续费,并基于 Solidity 0.8.28 的纯数学计算精度进行无精度丢失的三向分流:- 33% 刚性销毁(打入
0x...dEaD黑洞地址),实现长期通缩。 - 33% 注入质押池(Staking Pool),回馈长期支持生态的质押者。
- 34% 进入国库(Treasury),用于生态可持续运营。
- 33% 刚性销毁(打入
-
安全防御:内置零地址防御(
ZeroAddressDetected),杜绝运维配置失误导致资产永久卡死。
2. AkedoCollectionToken (独立游戏代币模型)
- 由发射台动态克隆部署的标准化 ERC20 游戏代币,用于承载具体的 AI 游戏生态资产。
3. AkedoLiquidityLocker (流动性与资产安全时间锁)
- 角色:防 Rug 的核心护城河。
- 核心机制:新生成的游戏代币并非全部直接交由创作者,而是强制将 80% 锁入时间锁金库,剩余 20% 释放给创作者用于初始流动性做市(LP)。
- 防御亮点:支持严格的时间锁校验(
LockDurationNotMet)、所有权验证(NotTheTokenCreator)以及状态清零防重入(lock.amount = 0),彻底杜绝双花与未到期提前提现尝试。
4. AkedoLaunchpadFactory (发射台工厂)
- 角色:AI 游戏与资产生成的“超级网关”。
- 用法:创作者只需传入游戏名称、符号、总供应量及锁定时长,工厂合约便会自动完成:扣除 AKE 手续费 触发分流 部署游戏代币 80% 强制锁仓 20% 释放做市 移交主权。
5. 核心合约实现
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
// ==========================================
// 1. $AKE 原生代币合约 (AkedoCoreToken)
// ==========================================
contract AkedoCoreToken is ERC20, Ownable {
using SafeERC20 for IERC20;
// Solidity 0.8.28 自定义错误 - 大幅节省 Gas 费
error ZeroAddressDetected();
error InvalidFeeConfiguration();
error InsufficientBalanceForDistribution();
// 手续费接收地址
address public stakingPool;
address public treasury;
// 刚性通缩死地址(黑洞)
address public constant BURN_ADDRESS = address(0x000000000000000000000000000000000000dEaD);
event FeesDistributed(uint256 burned, uint256 staked, uint256 treasuryAllocation);
event EcosystemAddressesUpdated(address indexed newStaking, address indexed newTreasury);
constructor(
uint256 initialSupply,
address _stakingPool,
address _treasury
) ERC20("Akedo Token", "AKE") Ownable(msg.sender) {
if (_stakingPool == address(0) || _treasury == address(0)) revert ZeroAddressDetected();
stakingPool = _stakingPool;
treasury = _treasury;
_mint(msg.sender, initialSupply);
}
/**
* @notice 修改生态系统分流接收地址
*/
function updateEcosystemAddresses(address _stakingPool, address _treasury) external onlyOwner {
if (_stakingPool == address(0) || _treasury == address(0)) revert ZeroAddressDetected();
stakingPool = _stakingPool;
treasury = _treasury;
emit EcosystemAddressesUpdated(_stakingPool, _treasury);
}
/**
* @notice 触发 33%销毁、33%质押、34%国库 的三向分流核心结算接口
*/
function burnAndDistributeFees(address feePayer, uint256 totalFee) external {
if (balanceOf(feePayer) < totalFee) revert InsufficientBalanceForDistribution();
// 依靠 0.8.28 纯数学计算精度进行精确切分
uint256 burnAmount = (totalFee * 33) / 100;
uint256 stakingAmount = (totalFee * 33) / 100;
uint256 treasuryAmount = totalFee - burnAmount - stakingAmount; // 确保不因精度丢失产生死账
// 链上底层执行划转与销毁
_transfer(feePayer, BURN_ADDRESS, burnAmount);
_transfer(feePayer, stakingPool, stakingAmount);
_transfer(feePayer, treasury, treasuryAmount);
emit FeesDistributed(burnAmount, stakingAmount, treasuryAmount);
}
}
// ==========================================
// 2. 独立游戏代币模型 (GameCollectionToken)
// ==========================================
contract GameCollectionToken is ERC20, Ownable {
constructor(
string memory name,
string memory symbol,
uint256 totalSupply,
address creator
) ERC20(name, symbol) Ownable(creator) {
_mint(creator, totalSupply);
}
}
// ==========================================
// 3. 安全时间锁合约 (AkedoLiquidityLocker)
// ==========================================
contract AkedoLiquidityLocker {
using SafeERC20 for IERC20;
error LockDurationNotMet();
error NotTheTokenCreator();
struct LockInfo {
uint256 amount;
uint256 unlockTime;
address creator;
}
mapping(address => LockInfo) public tokenLocks;
event AssetLocked(address indexed token, address indexed creator, uint256 amount, uint256 unlockTime);
event AssetReleased(address indexed token, address indexed creator, uint256 amount);
/**
* @notice 将派生的游戏资产锁入时间锁金库
*/
function lockToken(
address token,
address creator,
uint256 amount,
uint256 duration
) external {
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
tokenLocks[token] = LockInfo({
amount: amount,
unlockTime: block.timestamp + duration,
creator: creator
});
emit AssetLocked(token, creator, amount, block.timestamp + duration);
}
/**
* @notice 到期后由创作者提取
*/
function releaseToken(address token) external {
LockInfo storage lock = tokenLocks[token];
if (msg.sender != lock.creator) revert NotTheTokenCreator();
if (block.timestamp < lock.unlockTime) revert LockDurationNotMet();
uint256 amountToRelease = lock.amount;
lock.amount = 0; // 防范重入攻击
IERC20(token).safeTransfer(lock.creator, amountToRelease);
emit AssetReleased(token, lock.creator, amountToRelease);
}
}
// ==========================================
// 4. 发射台工厂合约 (AkedoLaunchpadFactory)
// ==========================================
contract AkedoLaunchpadFactory is Ownable {
error FeePaymentFailed();
error InvalidCreationParams();
AkedoCoreToken public immutable akedoToken;
AkedoLiquidityLocker public immutable liquidityLocker;
// AI 引擎发布游戏的刚性 AKE 代币手续费 (例如 100 $AKE)
uint256 public gameCreationFee = 100 * 10**18;
event GameTokenLaunched(
address indexed tokenAddress,
address indexed creator,
string name,
string symbol,
uint256 lockedAmount
);
event CreationFeeUpdated(uint256 newFee);
constructor(address _akedoToken, address _locker) Ownable(msg.sender) {
akedoToken = AkedoCoreToken(_akedoToken);
liquidityLocker = AkedoLiquidityLocker(_locker);
}
function setGameCreationFee(uint256 newFee) external onlyOwner {
gameCreationFee = newFee;
emit CreationFeeUpdated(newFee);
}
/**
* @notice AI引擎或创作者一键生成独立游戏代币的核心接口
* @param name 游戏代币名称
* @param symbol 游戏代币符号
* @param totalSupply 总发行量
* @param lockDuration 代币锁定时长(秒)
*/
function launchGameToken(
string calldata name,
string calldata symbol,
uint256 totalSupply,
uint256 lockDuration
) external returns (address) {
if (totalSupply == 0 || lockDuration == 0) revert InvalidCreationParams();
// 1. 强制扣除创作者的 AKE 币,并直接触发底层 AKE 代币的三向分流结算逻辑
akedoToken.burnAndDistributeFees(msg.sender, gameCreationFee);
// 2. 动态克隆/部署全新的独立游戏代币合约
GameCollectionToken newGameToken = new GameCollectionToken(
name,
symbol,
totalSupply,
address(this) // 先将所有权和初始代币给工厂以便直接划转入锁
);
// 3. 将 80% 的游戏初始代币强制注入时间锁,作为社区生态和防Rug基金
uint256 lockAmount = (totalSupply * 80) / 100;
uint256 creatorAmount = totalSupply - lockAmount;
// 授权并锁仓
IERC20(address(newGameToken)).approve(address(liquidityLocker), lockAmount);
liquidityLocker.lockToken(address(newGameToken), msg.sender, lockAmount, lockDuration);
// 4. 将剩余的 20% 分发给创作者进行初始流动性做市
IERC20(address(newGameToken)).transfer(msg.sender, creatorAmount);
// 5. 将新游戏代币的掌控权移交给创作者人类本身
newGameToken.transferOwnership(msg.sender);
emit GameTokenLaunched(address(newGameToken), msg.sender, name, symbol, lockAmount);
return address(newGameToken);
}
}
三、 典型应用场景与用法
场景一:AI 游戏引擎自动化发币
- 流程:AI 智能体自主开发了一款链上太空射击游戏。AI 代理通过调用
AkedoLaunchpadFactory.launchGameToken()接口,一键发布代币$CSAI。 - 保障:社区玩家由于知道 80% 的代币已被锁入
AkedoLiquidityLocker,且无法提前取出,因此对项目的信任度极高,愿意直接参与开盘交易。
场景二:生态通缩与价值捕获
- 流程:随着越来越多 AI 游戏通过 Akedo 发射台诞生,市场对 $AKE 代币的需求激增。
- 结果:源源不断的手续费被触发并执行 33% 销毁,使 $AKE 长期处于通缩状态,赋能质押者和长期持币者。
四、 严密的测试保障(基于 Hardhat & Foundry)
- 完备测试用例:AKEDO Protocol Full End-to-End Integration
- 基础通缩流:AKE 独立分流接口应实现无精度丢失的 33/33/34 分润
- 发射台闭环:创作者应能一键发币,且 80% 游戏代币被刚性扣留锁仓
- 时间锁安全拦截:未到期前拒绝提取,非所有者无法冒领,到期后顺利放行
- 边界与溢出拦截:拦截游戏发行总供应量为 0 或锁定时长为 0 的恶意篡改尝试
- 零地址灾难级防御:拦截初始化和运维配置中的 0x0 地址风险
- 资产安全释放防御:防止二次提取(双花尝试)和重入漏洞
- 生态分润动态升级验证:非管理员越权修改配置应被立即驳回
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { parseEther, getAddress, parseEventLogs } from "viem";
import { network } from "hardhat";
describe("AKEDO Protocol Full End-to-End Integration", function () {
// 定义全套合约部署固件 (Fixture)
async function deployAkedoFixture() {
const { viem } = await (network as any).getOrCreate();
const [owner, creator, stakingPool, treasury, maliciousActor] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
const testClient = await viem.getTestClient();
// 1. 部署 $AKE 原生代币 (初始铸造 10 亿枚 AKE)
const initialSupply = parseEther("1000000000");
const akedoToken = await viem.deployContract("AkedoCoreToken", [
initialSupply,
stakingPool.account.address,
treasury.account.address,
]);
// 2. 部署流动性安全时间锁合约
const liquidityLocker = await viem.deployContract("AkedoLiquidityLocker");
// 3. 部署一键发币发射台工厂合约
const launchpadFactory = await viem.deployContract("AkedoLaunchpadFactory", [
akedoToken.address,
liquidityLocker.address,
]);
// 4. 运营环境初始化:给创作者运送初始 AKE 代币用于发币测试
const fundingAmount = parseEther("10000");
await akedoToken.write.transfer([creator.account.address, fundingAmount], { account: owner.account });
return {
viem,
akedoToken,
liquidityLocker,
launchpadFactory,
owner,
creator,
stakingPool,
treasury,
maliciousActor,
publicClient,
testClient,
fundingAmount,
};
}
it("1. 基础通缩流:AKE 独立分流接口应实现无精度丢失的 33/33/34 分润", async function () {
const { akedoToken, creator, stakingPool, treasury } = await deployAkedoFixture();
const feeAmount = parseEther("100");
await akedoToken.write.approve([akedoToken.address, feeAmount], { account: creator.account });
await akedoToken.write.burnAndDistributeFees([creator.account.address, feeAmount], { account: creator.account });
const burnAddress = "0x000000000000000000000000000000000000dEaD";
assert.equal(await akedoToken.read.balanceOf([burnAddress]), parseEther("33"));
assert.equal(await akedoToken.read.balanceOf([stakingPool.account.address]), parseEther("33"));
assert.equal(await akedoToken.read.balanceOf([treasury.account.address]), parseEther("34"));
});
it("2. 发射台闭环:创作者应能一键发币,且 80% 游戏代币被刚性扣留锁仓", async function () {
const { viem, akedoToken, launchpadFactory, liquidityLocker, creator, publicClient } = await deployAkedoFixture();
const creationFee = await launchpadFactory.read.gameCreationFee();
await akedoToken.write.approve([launchpadFactory.address, creationFee], { account: creator.account });
const gameTokenName = "CyberSpace AI";
const gameTokenSymbol = "CSAI";
const totalGameSupply = parseEther("1000000");
const lockDuration = 86400n;
const txHash = await launchpadFactory.write.launchGameToken([
gameTokenName,
gameTokenSymbol,
totalGameSupply,
lockDuration
], { account: creator.account });
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
const logs = parseEventLogs({
abi: launchpadFactory.abi,
eventName: "GameTokenLaunched",
logs: receipt.logs,
});
const launchedTokenAddress = getAddress(logs[0].args.tokenAddress);
const gameToken = await viem.getContractAt("GameCollectionToken", launchedTokenAddress);
assert.equal(await gameToken.read.name(), gameTokenName);
assert.equal(await gameToken.read.symbol(), gameTokenSymbol);
assert.equal(await gameToken.read.balanceOf([creator.account.address]), (totalGameSupply * 20n) / 100n);
assert.equal(await gameToken.read.balanceOf([liquidityLocker.address]), (totalGameSupply * 80n) / 100n);
const lockInfo = await liquidityLocker.read.tokenLocks([launchedTokenAddress]);
assert.equal(lockInfo[0], (totalGameSupply * 80n) / 100n);
assert.equal(getAddress(lockInfo[2]), getAddress(creator.account.address));
});
it("3. 时间锁安全拦截:未到期前拒绝提取,非所有者无法冒领,到期后顺利放行", async function () {
const { viem, akedoToken, launchpadFactory, liquidityLocker, creator, maliciousActor, testClient, publicClient } = await deployAkedoFixture();
const creationFee = await launchpadFactory.read.gameCreationFee();
await akedoToken.write.approve([launchpadFactory.address, creationFee], { account: creator.account });
const totalGameSupply = parseEther("500000");
const lockDuration = 3600n;
const txHash = await launchpadFactory.write.launchGameToken([
"AI Quest", "AIQ", totalGameSupply, lockDuration
], { account: creator.account });
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
const logs = parseEventLogs({
abi: launchpadFactory.abi,
eventName: "GameTokenLaunched",
logs: receipt.logs,
});
const gameTokenAddress = getAddress(logs[0].args.tokenAddress);
// 【恶意冒领拦截测试】
await assert.rejects(
async () => {
await liquidityLocker.write.releaseToken([gameTokenAddress], { account: maliciousActor.account });
},
(err: any) => {
const msg = String(err.message || err);
return msg.includes("NotTheTokenCreator");
},
"安全拦截:不应允许非创作者提取锁定资产"
);
// 【未到期强制提取测试】
await assert.rejects(
async () => {
await liquidityLocker.write.releaseToken([gameTokenAddress], { account: creator.account });
},
(err: any) => {
const msg = String(err.message || err);
return msg.includes("LockDurationNotMet");
},
"安全拦截:未到期前合约应锁死提取路径"
);
await testClient.increaseTime({ seconds: 3601 });
await testClient.mine({ blocks: 1 });
await liquidityLocker.write.releaseToken([gameTokenAddress], { account: creator.account });
const finalBalance = await (await viem.getContractAt("GameCollectionToken", gameTokenAddress)).read.balanceOf([creator.account.address]);
assert.equal(finalBalance, totalGameSupply, "到期后创作者未能安全收回锁仓代币");
});
// ==========================================
// 4. 【边界与溢出拦截测试】
// ==========================================
it("4. 边界与溢出拦截:拦截游戏发行总供应量为 0 或锁定时长为 0 的恶意篡改尝试", async function () {
const { akedoToken, launchpadFactory, creator } = await deployAkedoFixture();
const creationFee = await launchpadFactory.read.gameCreationFee();
await akedoToken.write.approve([launchpadFactory.address, creationFee], { account: creator.account });
// 验证总供应量为 0 拦截
await assert.rejects(
async () => {
await launchpadFactory.write.launchGameToken(["Zero Supply", "ZS", 0n, 86400n], { account: creator.account });
},
(err: any) => String(err.message || err).includes("InvalidCreationParams"),
"应拦截供应量为 0 的异常创建"
);
// 验证锁定时长为 0 拦截
await assert.rejects(
async () => {
await launchpadFactory.write.launchGameToken(["Zero Duration", "ZD", parseEther("1000000"), 0n], { account: creator.account });
},
(err: any) => String(err.message || err).includes("InvalidCreationParams"),
"应拦截锁定时长为 0 的异常创建"
);
});
// ==========================================
// 5. 【零地址灾难级防御测试】
// ==========================================
it("5. 零地址灾难级防御:拦截初始化和运维配置中的 0x0 地址风险", async function () {
const { viem, treasury } = await deployAkedoFixture();
const initialSupply = parseEther("1000000000");
const zeroAddress = "0x0000000000000000000000000000000000000000";
// 构造函数传入零地址初始化
await assert.rejects(
async () => {
await viem.deployContract("AkedoCoreToken", [initialSupply, zeroAddress, treasury.account.address]);
},
(err: any) => String(err.message || err).includes("ZeroAddressDetected"),
"应拦截构造函数中的零地址"
);
// 动态更新生态接收地址时传入零地址
const { akedoToken, owner } = await deployAkedoFixture();
await assert.rejects(
async () => {
await akedoToken.write.updateEcosystemAddresses([zeroAddress, treasury.account.address], { account: owner.account });
},
(err: any) => String(err.message || err).includes("ZeroAddressDetected"),
"应拦截动态更新时的零地址"
);
});
// ==========================================
// 6. 【资产安全释放防御测试】
// ==========================================
it("6. 资产安全释放防御:防止二次提取(双花尝试)和重入漏洞", async function () {
const { viem, akedoToken, launchpadFactory, liquidityLocker, creator, publicClient, testClient } = await deployAkedoFixture();
const creationFee = await launchpadFactory.read.gameCreationFee();
await akedoToken.write.approve([launchpadFactory.address, creationFee], { account: creator.account });
const totalGameSupply = parseEther("1000000");
const txHash = await launchpadFactory.write.launchGameToken(["Game C", "GC", totalGameSupply, 3600n], { account: creator.account });
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
const logs = parseEventLogs({ abi: launchpadFactory.abi, eventName: "GameTokenLaunched", logs: receipt.logs });
const gameTokenAddress = getAddress(logs[0].args.tokenAddress);
await testClient.increaseTime({ seconds: 3601 });
await testClient.mine({ blocks: 1 });
// 第一次正常提取
await liquidityLocker.write.releaseToken([gameTokenAddress], { account: creator.account });
const gameToken = await viem.getContractAt("GameCollectionToken", gameTokenAddress);
const balanceAfterFirst = await gameToken.read.balanceOf([creator.account.address]);
// 第二次重复提取(由于锁仓额度被清零,合约内部不会重复转账,状态安全清零)
await liquidityLocker.write.releaseToken([gameTokenAddress], { account: creator.account });
const balanceAfterSecond = await gameToken.read.balanceOf([creator.account.address]);
assert.equal(balanceAfterFirst, balanceAfterSecond, "二次重复提取不应增加额外资产划转");
});
// ==========================================
// 7. 【生态分润动态升级验证测试】
// ==========================================
it("7. 生态分润动态升级验证:非管理员越权修改配置应被立即驳回", async function () {
const { akedoToken, launchpadFactory, maliciousActor } = await deployAkedoFixture();
const dummyAddress = "0x0000000000000000000000000000000000000123";
// 非管理员尝试修改生态接收地址
await assert.rejects(
async () => {
await akedoToken.write.updateEcosystemAddresses([dummyAddress, dummyAddress], { account: maliciousActor.account });
},
(err: any) => {
const msg = String(err.message || err);
return msg.includes("OwnableUnauthorizedAccount") || msg.includes("Ownable");
},
"非管理员修改生态地址应被拒绝"
);
// 非管理员尝试修改游戏发行费率
await assert.rejects(
async () => {
await launchpadFactory.write.setGameCreationFee([parseEther("50")], { account: maliciousActor.account });
},
(err: any) => {
const msg = String(err.message || err);
return msg.includes("OwnableUnauthorizedAccount") || msg.includes("Ownable");
},
"非管理员修改发行费率应被拒绝"
);
});
});
五、 总结
Akedo Protocol 通过精妙的代币经济学设计与坚固的智能合约安全防线,成功解决了传统 Launchpad 普遍存在的信任缺失与通缩无力问题。它不仅是 AI 游戏时代的一键发币利器,更通过代码级别的约束,为 Web3 创作者和投资者打造了一个透明、公平、可持续生长的去中心化生态。