Local MCP Server
在Termux中运行本地MCP服务器,支持Ollama模型的文件读取与命令执行。
下载 312
基于Aptos Move V2标准生成安全的智能合约,支持NFT、DAO及去中心化应用。
openclaw skills install @iskysun96/write-contracts命令、参数、文件名以原文为准
aptos_token_objects::collection 和 aptos_token_objects::token 模块Object<AptosToken> 来引用 NFT(不要使用通用的 Object<T>)aptos_token::token 模块../../../patterns/move/DIGITAL_ASSETS.md 获取完整的 NFT 设计模式Object<T> 来表示所有对象引用(绝不要使用原始地址)Object<T>(绝不要返回 ConstructorRef)object::owner(obj) == signer::address_of(user)object::generate_signer(&constructor_ref) 来获取对象签名者object::create_named_object(creator, seed) assert!(signer::address_of(user) == expected, E_UNAUTHORIZED)
&mut 引用给公共函数obj.is_owner(user)(将第一个参数定义为 self)vector[index] 而不是 vector::borrow()@marketplace_addr(不要使用辅助函数)#[view] 注解**标记只读访问器函数(seller, price, timestamp)#[view] 放在文档注释之前**——若 /// comment 写在 #[view] 前面,会导致编译警告。应先写 #[view],再写 ///security-audit 技能进行审查struct MyObject has key {
name: String,
transfer_ref: object::TransferRef,
delete_ref: object::DeleteRef,
}
// 错误常量
const E_NOT_OWNER: u64 = 1;
const E_EMPTY_STRING: u64 = 2;
const E_NAME_TOO_LONG: u64 = 3;
// 配置常量
const MAX_NAME_LENGTH: u64 = 100;
/// 使用正确模式创建对象
public fun create_my_object(creator: &signer, name: String): Object<MyObject> {
// 1. 创建对象
let constructor_ref = object::create_object(signer::address_of(creator));
// 2. 在构造函数销毁前生成所有需要的引用
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let delete_ref = object::generate_delete_ref(&constructor_ref);
// 3. 获取对象签名者
let object_signer = object::generate_signer(&constructor_ref);
// 4. 将数据存入对象
move_to(&object_signer, MyObject {
name,
transfer_ref,
delete_ref,
});
// 5. 返回类型化的对象引用(ConstructorRef 自动销毁)
object::object_from_constructor_ref<MyObject>(&constructor_ref)
}
/// 更新操作,包含所有权验证
public entry fun update_object(
owner: &signer,
obj: Object<MyObject>,
new_name: String
) acquires MyObject {
// ✅ 始终:验证所有权
assert!(object::owner(obj) == signer::address_of(owner), E_NOT_OWNER);
// ✅ 始终:验证输入
assert!(string::length(&new_name) > 0, E_EMPTY_STRING);
assert!(string::length(&new_name) <= MAX_NAME_LENGTH, E_NAME_TOO_LONG);
// 安全继续
let obj_data = borrow_global_mut<MyObject>(object::object_address(&obj));
obj_data.name = new_name;
}struct ListingInfo has store, drop, copy {
seller: address,
price: u64,
listed_at: u64,
}
/// 访问器函数 - 测试无法直接访问结构体字段
/// 多字段访问使用元组返回
#[view]
public fun get_listing_details(nft_addr: address): (address, u64, u64) acquires Listings {
let listings = borrow_global<Listings>(get_marketplace_address());
assert!(table::contains(&listings.items, nft_addr), E_NOT_LISTED);
let listing = table::borrow(&listings.items, nft_addr);
(listing.seller, listing.price, listing.listed_at)
}
/// 单字段访问器,仅需一个值时使用
#[view]
public fun get_staked_amount(user_addr: address): u64 acquires Stakes {
let stakes = borrow_global<Stakes>(get_vault_address());
if (table_with_length::contains(&stakes.items, user_addr)) {
table_with_length::borrow(&stakes.items, user_addr).amount
} else {
0
}
}module my_addr::my_module {
// ============ Imports ============
use std::signer;
use std::string::String;
use aptos_framework::object::{Self, Object};
use aptos_framework::event;
// ============ Events ============
#[event]
struct ItemCreated has drop, store {
item: address,
creator: address,
}
// ============ Structs ============
// 定义你的数据结构
// ============ Constants ============
const E_NOT_OWNER: u64 = 1;
const E_UNAUTHORIZED: u64 = 2;
// ============ Init Module ============
fun init_module(deployer: &signer) {
// 初始化全局状态、注册表等
}
// ============ Public Entry Functions ============
// 用户可见的函数
// ============ Public Functions ============
// 可组合的函数
// ============ Private Functions ============
// 内部辅助函数
}⚠️ 当用户提到存储相关需求(“store”、“track”、“registry”、“mapping”、“list”、“collection”):
references/storage-decision-tree.md).length()?**(条件性判断)references/storage-patterns.md)| 模式 | 推荐的存储类型 |
|---|---|
| 用户注册表 | Table<address, UserInfo> |
| 质押记录 | Table<address, StakeInfo> |
| 排行榜 | BigOrderedMap<u64, address> |
| 交易日志 | SmartVector<TxRecord> 或 Vector |
| 白名单(少于100) | Vector<address> |
| 投票记录 | TableWithLength<address, bool> |
| 配置项(少于50) | OrderedMap<String, Value> |
| DAO提案 | BigOrderedMap<u64, Proposal> |
| 资产集合 | Vector<Object<T>> 或 SmartVector |
示例推荐:
Table<address, StakeInfo>,因为用户数量可能无上限且存在并发操作(独立槽位支持并行访问)”BigOrderedMap<u64, address>,因为需要有序遍历(时间复杂度 O(log n),生产环境请使用 allocate_spare_slots)”⚠️ 禁止使用 SmartTable(已弃用,应使用 BigOrderedMap)
详细信息: 参见 references/ 目录中的决策树、类型对比及Gas优化指南。
aptos_token::token@my_addr 命名地址和 "0x..." 占位符.env 或 ~/.aptos/config.yaml** —— 这些文件包含私钥| 场景 | 检查条件 | 错误码 |
|---|---|---|
| 零金额 | assert!(amount > 0, E_ZERO_AMOUNT) | E_ZERO_AMOUNT |
| 金额过大 | assert!(amount <= MAX, E_AMOUNT_TOO_HIGH) | E_AMOUNT_TOO_HIGH |
| 空向量 | assert!(vector::length(&v) > 0, E_EMPTY_VECTOR) | E_EMPTY_VECTOR |
| 空字符串 | assert!(string::length(&s) > 0, E_EMPTY_STRING) | E_EMPTY_STRING |
| 字符串过长 | assert!(string::length(&s) <= MAX, E_STRING_TOO_LONG) | E_STRING_TOO_LONG |
| 零地址 | assert!(addr != @0x0, E_ZERO_ADDRESS) | E_ZERO_ADDRESS |
| 溢出 | assert!(a <= MAX_U64 - b, E_OVERFLOW) | E_OVERFLOW |
| 下溢 | assert!(a >= b, E_UNDERFLOW) | E_UNDERFLOW |
| 除零 | assert!(divisor > 0, E_DIVISION_BY_ZERO) | E_DIVISION_BY_ZERO |
| 未经授权访问 | assert!(signer == expected, E_UNAUTHORIZED) | E_UNAUTHORIZED |
| 非所有者操作 | assert!(object::owner(obj) == user, E_NOT_OWNER) | E_NOT_OWNER |
详细模式说明(references/ 文件夹):
references/storage-decision-tree.md - ⭐ 存储类型选择框架(当提及存储时使用)references/storage-patterns.md - ⭐ 使用场景模式与智能默认值references/storage-types.md - 所有6种存储类型的详细对比references/storage-gas-optimization.md - 存储相关的Gas优化策略references/object-patterns.md - 命名对象、集合、嵌套对象模式references/access-control.md - RBAC 和权限控制系统references/safe-arithmetic.md - 溢出/下溢防护references/initialization.md - init_module 模式与注册表创建references/events.md - 事件发出的最佳实践references/v2-syntax.md - Move V2 的现代特性(方法调用、索引、匿名函数)references/complete-example.md - 完整注释的NFT集合合约示例模式文档(patterns/ 文件夹):
../../../patterns/move/DIGITAL_ASSETS.md - 数字资产(NFT)标准 —— 对 NFT 至关重要../../../patterns/move/OBJECTS.md - 完整的对象模型指南../../../patterns/move/SECURITY.md - 安全检查清单与设计模式../../../patterns/move/MOVE_V2_SYNTAX.md - 现代语法示例官方文档:
相关技能:
search-aptos-examples - 在 aptos-core 中查找类似示例(可选)generate-tests - 为合约编写测试(在编写合约后使用)security-audit - 部署前对合约进行安全审计已收录 1 个 Skill