Solidity 合约开发规范
本技能为 Web3 Agent Marketplace 项目的智能合约开发提供标准化指导,确保代码安全、高效且可扩展。
项目核心合约架构
合约系统分为以下四大核心模块:
- •AgentRegistry.sol:管理 Agent 的链上身份、元数据(IPFS 链接)及开发者权益。
- •TaskEscrow.sol:核心业务逻辑,处理任务创建、资金托管、确认交付及自动结算。
- •DAOGovernance.sol:处理用户与 Agent 之间的纠纷仲裁,支持 DAO 成员投票裁决。
- •AaveIntegration.sol(可选):实现托管资金在等待结算期间存入 Aave 赚取收益的逻辑。
开发环境规范
- •工具链:推荐使用 Foundry 进行开发、测试和脚本部署。
- •编译器版本:固定使用
0.8.20或更高版本,确保使用最新的安全特性。 - •依赖库:优先使用 OpenZeppelin Contracts 实现访问控制(Ownable/AccessControl)和溢出保护。
代码设计规范
1. 状态与类型定义
solidity
// 使用结构体归一化任务属性
struct Task {
uint256 id;
address employer;
address agent;
uint256 budget;
TaskStatus status;
uint256 createdAt;
}
enum TaskStatus { OPEN, IN_PROGRESS, COMPLETED, DISPUTED, CANCELLED }
2. 核心业务逻辑实现 (TaskEscrow 示例)
solidity
contract TaskEscrow is ReentrancyGuard, Ownable {
// 强制使用 Checks-Effects-Interactions 模式
function completeTask(uint256 taskId) external nonReentrant {
Task storage task = tasks[taskId];
require(msg.sender == task.employer, "Only employer can confirm");
require(task.status == TaskStatus.IN_PROGRESS, "Invalid status");
task.status = TaskStatus.COMPLETED; // Effects
uint256 commission = (task.budget * commissionRate) / 10000;
uint256 payment = task.budget - commission;
(bool success, ) = payable(task.agent).call{value: payment}(""); // Interactions
require(success, "Payment failed");
emit TaskSettled(taskId, task.agent, payment);
}
}
安全生产准则
资金安全
- •防止重入:所有涉及转账的函数必须添加
nonReentrant修饰符。 - •拉取支付 (Pull over Push):在处理大规模奖励分发时,优先让用户自行
claim,而非合约主动transfer。 - •溢出检查:Solidity 0.8+ 默认处理,但在进行复杂比例计算(如
budget * rate / 10000)时,确保先乘后除以保留精度。
访问控制
- •关键参数修改(如费率、仲裁员名单)必须限制在
onlyOwner或onlyRole(ADMIN_ROLE)。 - •采用紧急开关机制(
Pausable),在发现重大漏洞时能即时停止核心功能。
仲裁逻辑 (DAO)
- •仲裁期锁定资金:一旦任务进入
DISPUTED状态,资金应由合约锁定,直到满足投票阈值。 - •投票快照:使用区块高度或时间戳作为投票权重的快照依据,防止双花投票。
Gas 优化指南
- •数据类型:尽可能使用
uint256以匹配 EVM 字长。 - •存储访问:减少对
storage变量的读写。如果多次调用,先将其缓存到memory。 - •错误处理:使用
error InsufficientBalance()替代require(condition, "Very long error message")以节省 Gas。 - •事件记录:对不参与链上逻辑计算的数据(如任务标题、描述),仅通过
emit Event记录到日志。
测试要求 (Foundry)
- •单元测试:覆盖所有
require断言的各种边界情况。 - •Fuzz Testing:对转账金额、佣金比例等数值进行随机输入测试。
- •集成测试:模拟
Marketplace -> TaskEscrow -> Aave的完整资金流向。
solidity
function testFuzz_Settlement(uint256 budget) public {
vm.assume(budget > 0.01 ether && budget < 100 ether);
// ... 模拟结算逻辑
}