Loading...
Loading...
Compare original and translation side by side
&mut Resource[addr]#[randomness]borrow_global_mut<Resource>(addr)&mut Resource[addr]#[randomness]borrow_global_mut<Resource>(addr)https://mainnet.movementnetwork.xyz/v1https://explorer.movementnetwork.xyz/?network=mainnethttps://testnet.movementnetwork.xyz/v1https://faucet.movementnetwork.xyz/https://explorer.movementnetwork.xyz/?network=bardock+testnethttps://mainnet.movementnetwork.xyz/v1https://explorer.movementnetwork.xyz/?network=mainnethttps://testnet.movementnetwork.xyz/v1https://faucet.movementnetwork.xyz/https://explorer.movementnetwork.xyz/?network=bardock+testnetmodule my_addr::my_module {
use std::signer;
use aptos_framework::object;
// Error codes (const)
const E_NOT_OWNER: u64 = 1;
// Resources (structs with abilities)
struct MyResource has key, store {
value: u64,
}
// Init function (called on publish)
fun init_module(sender: &signer) {
// Setup code
}
// Entry functions (callable from transactions)
public entry fun do_something(sender: &signer) {
// Implementation
}
// View functions (read-only, no gas)
#[view]
public fun get_value(addr: address): u64 acquires MyResource {
borrow_global<MyResource>(addr).value
}
}module my_addr::my_module {
use std::signer;
use aptos_framework::object;
// 错误码(常量)
const E_NOT_OWNER: u64 = 1;
// 资源(带能力的结构体)
struct MyResource has key, store {
value: u64,
}
// 初始化函数(发布时调用)
fun init_module(sender: &signer) {
// 初始化代码
}
// 入口函数(可通过交易调用)
public entry fun do_something(sender: &signer) {
// 实现逻辑
}
// 视图函数(只读,无需Gas)
#[view]
public fun get_value(addr: address): u64 acquires MyResource {
borrow_global<MyResource>(addr).value
}
}| Ability | Meaning |
|---|---|
| Can be stored as top-level resource |
| Can be stored inside other structs |
| Can be copied (duplicated) |
| Can be discarded/destroyed |
has keyhas key, storehas store, drop, copyhas drop| Ability | 含义 |
|---|---|
| 可作为顶级资源存储 |
| 可嵌套存储于其他结构体中 |
| 可被复制(生成副本) |
| 可被丢弃/销毁 |
has keyhas key, storehas store, drop, copyhas drop// Store resource at signer's address
move_to(signer, resource);
// Check if resource exists
exists<MyResource>(addr);
// Borrow immutable reference
let ref = borrow_global<MyResource>(addr);
// Borrow mutable reference
let ref = borrow_global_mut<MyResource>(addr);
// Remove and return resource
let resource = move_from<MyResource>(addr);// 将资源存储到签名者地址下
move_to(signer, resource);
// 检查资源是否存在
exists<MyResource>(addr);
// 借用不可变引用
let ref = borrow_global<MyResource>(addr);
// 借用可变引用
let ref = borrow_global_mut<MyResource>(addr);
// 移除并返回资源
let resource = move_from<MyResource>(addr);use std::signer;
// Get address from signer
let addr = signer::address_of(signer);
// Signer is proof of account ownership
// Cannot be forged or transferreduse std::signer;
// 从签名者获取地址
let addr = signer::address_of(signer);
// 签名者是账户所有权的证明
// 不可伪造或转移use aptos_framework::object::{Self, Object, ConstructorRef};
// Create a named object (deterministic address)
let constructor_ref = object::create_named_object(
creator,
b"my_seed"
);
// Create a random object (unique address)
let constructor_ref = object::create_object(creator_addr);
// Create sticky object (non-deletable, at module address)
let constructor_ref = object::create_sticky_object(@my_addr);
// Get the object signer to store resources
let obj_signer = object::generate_signer(&constructor_ref);
// Store resource at object address
move_to(&obj_signer, MyData { value: 100 });
// Get object from constructor
let obj: Object<MyData> = object::object_from_constructor_ref(&constructor_ref);use aptos_framework::object::{Self, Object, ConstructorRef};
// 创建命名对象(确定性地址)
let constructor_ref = object::create_named_object(
creator,
b"my_seed"
);
// 创建随机对象(唯一地址)
let constructor_ref = object::create_object(creator_addr);
// 创建粘性对象(不可删除,位于模块地址下)
let constructor_ref = object::create_sticky_object(@my_addr);
// 获取对象签名者以存储资源
let obj_signer = object::generate_signer(&constructor_ref);
// 将资源存储到对象地址下
move_to(&obj_signer, MyData { value: 100 });
// 从构造器引用中获取对象
let obj: Object<MyData> = object::object_from_constructor_ref(&constructor_ref);// Generate refs from constructor (must be done at creation time)
let extend_ref = object::generate_extend_ref(&constructor_ref);
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let delete_ref = object::generate_delete_ref(&constructor_ref);
// Store refs for later use
struct MyController has key {
extend_ref: ExtendRef,
transfer_ref: TransferRef,
}// 在创建时生成引用(后续无法生成)
let extend_ref = object::generate_extend_ref(&constructor_ref);
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let delete_ref = object::generate_delete_ref(&constructor_ref);
// 存储引用供后续使用
struct MyController has key {
extend_ref: ExtendRef,
transfer_ref: TransferRef,
}// Get object address
let obj_addr = object::object_address(&obj);
// Check ownership
let is_owner = object::is_owner(obj, addr);
let owner = object::owner(obj);
// Transfer object
object::transfer(owner_signer, obj, recipient);
// Calculate deterministic address
let obj_addr = object::create_object_address(&creator, seed);// 获取对象地址
let obj_addr = object::object_address(&obj);
// 检查所有权
let is_owner = object::is_owner(obj, addr);
let owner = object::owner(obj);
// 转移对象
object::transfer(owner_signer, obj, recipient);
// 计算确定性地址
let obj_addr = object::create_object_address(&creator, seed);use aptos_framework::fungible_asset::{Self, MintRef, BurnRef, TransferRef, Metadata};
use aptos_framework::primary_fungible_store;
use aptos_framework::object;
struct FAController has key {
mint_ref: MintRef,
burn_ref: BurnRef,
transfer_ref: TransferRef,
}
fun create_fa(creator: &signer) {
// Create object to hold FA metadata
let constructor_ref = object::create_sticky_object(@my_addr);
// Initialize as fungible asset with primary store
primary_fungible_store::create_primary_store_enabled_fungible_asset(
&constructor_ref,
option::some(1000000000), // max_supply (optional)
string::utf8(b"My Token"),
string::utf8(b"MTK"),
8, // decimals
string::utf8(b"https://example.com/icon.png"),
string::utf8(b"https://example.com"),
);
// Generate refs for mint/burn/transfer control
let mint_ref = fungible_asset::generate_mint_ref(&constructor_ref);
let burn_ref = fungible_asset::generate_burn_ref(&constructor_ref);
let transfer_ref = fungible_asset::generate_transfer_ref(&constructor_ref);
// Store refs
let obj_signer = object::generate_signer(&constructor_ref);
move_to(&obj_signer, FAController { mint_ref, burn_ref, transfer_ref });
}use aptos_framework::fungible_asset::{Self, MintRef, BurnRef, TransferRef, Metadata};
use aptos_framework::primary_fungible_store;
use aptos_framework::object;
struct FAController has key {
mint_ref: MintRef,
burn_ref: BurnRef,
transfer_ref: TransferRef,
}
fun create_fa(creator: &signer) {
// 创建存储FA元数据的对象
let constructor_ref = object::create_sticky_object(@my_addr);
// 初始化带主存储的可替代资产
primary_fungible_store::create_primary_store_enabled_fungible_asset(
&constructor_ref,
option::some(1000000000), // 最大供应量(可选)
string::utf8(b"My Token"),
string::utf8(b"MTK"),
8, // 小数位数
string::utf8(b"https://example.com/icon.png"),
string::utf8(b"https://example.com"),
);
// 生成铸币/销毁/转移控制引用
let mint_ref = fungible_asset::generate_mint_ref(&constructor_ref);
let burn_ref = fungible_asset::generate_burn_ref(&constructor_ref);
let transfer_ref = fungible_asset::generate_transfer_ref(&constructor_ref);
// 存储引用
let obj_signer = object::generate_signer(&constructor_ref);
move_to(&obj_signer, FAController { mint_ref, burn_ref, transfer_ref });
}fun mint(recipient: address, amount: u64) acquires FAController {
let controller = borrow_global<FAController>(@my_addr);
let fa = fungible_asset::mint(&controller.mint_ref, amount);
primary_fungible_store::deposit(recipient, fa);
}fun mint(recipient: address, amount: u64) acquires FAController {
let controller = borrow_global<FAController>(@my_addr);
let fa = fungible_asset::mint(&controller.mint_ref, amount);
primary_fungible_store::deposit(recipient, fa);
}fun burn(from: address, amount: u64) acquires FAController {
let controller = borrow_global<FAController>(@my_addr);
let fa = primary_fungible_store::withdraw(from_signer, metadata, amount);
fungible_asset::burn(&controller.burn_ref, fa);
}fun burn(from: address, amount: u64) acquires FAController {
let controller = borrow_global<FAController>(@my_addr);
let fa = primary_fungible_store::withdraw(from_signer, metadata, amount);
fungible_asset::burn(&controller.burn_ref, fa);
}#[view]
public fun balance(owner: address, metadata: Object<Metadata>): u64 {
primary_fungible_store::balance(owner, metadata)
}#[view]
public fun balance(owner: address, metadata: Object<Metadata>): u64 {
primary_fungible_store::balance(owner, metadata)
}// User-initiated transfer
public entry fun transfer(
sender: &signer,
metadata: Object<Metadata>,
recipient: address,
amount: u64
) {
primary_fungible_store::transfer(sender, metadata, recipient, amount);
}
// Admin transfer (using transfer_ref)
fun admin_transfer(
from: address,
to: address,
amount: u64
) acquires FAController {
let controller = borrow_global<FAController>(@my_addr);
let from_store = primary_fungible_store::ensure_primary_store_exists(from, metadata);
let to_store = primary_fungible_store::ensure_primary_store_exists(to, metadata);
fungible_asset::transfer_with_ref(
&controller.transfer_ref,
from_store,
to_store,
amount
);
}// 用户发起的转移
public entry fun transfer(
sender: &signer,
metadata: Object<Metadata>,
recipient: address,
amount: u64
) {
primary_fungible_store::transfer(sender, metadata, recipient, amount);
}
// 管理员转移(使用transfer_ref)
fun admin_transfer(
from: address,
to: address,
amount: u64
) acquires FAController {
let controller = borrow_global<FAController>(@my_addr);
let from_store = primary_fungible_store::ensure_primary_store_exists(from, metadata);
let to_store = primary_fungible_store::ensure_primary_store_exists(to, metadata);
fungible_asset::transfer_with_ref(
&controller.transfer_ref,
from_store,
to_store,
amount
);
}use aptos_token_objects::collection;
use aptos_token_objects::token;
fun create_collection(creator: &signer) {
collection::create_unlimited_collection(
creator,
string::utf8(b"My Collection Description"),
string::utf8(b"My Collection"),
option::none(), // royalty
string::utf8(b"https://example.com/collection"),
);
}
// Or with fixed supply
fun create_fixed_collection(creator: &signer) {
collection::create_fixed_collection(
creator,
string::utf8(b"Description"),
1000, // max_supply
string::utf8(b"Collection Name"),
option::none(),
string::utf8(b"https://example.com"),
);
}use aptos_token_objects::collection;
use aptos_token_objects::token;
fun create_collection(creator: &signer) {
collection::create_unlimited_collection(
creator,
string::utf8(b"My Collection Description"),
string::utf8(b"My Collection"),
option::none(), // 版税
string::utf8(b"https://example.com/collection"),
);
}
// 或固定供应量的集合
fun create_fixed_collection(creator: &signer) {
collection::create_fixed_collection(
creator,
string::utf8(b"Description"),
1000, // 最大供应量
string::utf8(b"Collection Name"),
option::none(),
string::utf8(b"https://example.com"),
);
}fun mint_nft(creator: &signer, recipient: address) {
let constructor_ref = token::create_named_token(
creator,
string::utf8(b"Collection Name"),
string::utf8(b"Token description"),
string::utf8(b"Token #1"),
option::none(), // royalty
string::utf8(b"https://example.com/token/1"),
);
// Transfer to recipient
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let token_obj = object::object_from_constructor_ref(&constructor_ref);
object::transfer_with_ref(
object::generate_linear_transfer_ref(&transfer_ref),
recipient
);
}fun mint_nft(creator: &signer, recipient: address) {
let constructor_ref = token::create_named_token(
creator,
string::utf8(b"Collection Name"),
string::utf8(b"Token description"),
string::utf8(b"Token #1"),
option::none(), // 版税
string::utf8(b"https://example.com/token/1"),
);
// 转移给接收者
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let token_obj = object::object_from_constructor_ref(&constructor_ref);
object::transfer_with_ref(
object::generate_linear_transfer_ref(&transfer_ref),
recipient
);
}struct MyTokenData has key {
power: u64,
rarity: String,
}
fun mint_with_data(creator: &signer) {
let constructor_ref = token::create(
creator,
string::utf8(b"Collection"),
string::utf8(b"Description"),
string::utf8(b"Token Name"),
option::none(),
string::utf8(b"https://example.com/token"),
);
let token_signer = object::generate_signer(&constructor_ref);
move_to(&token_signer, MyTokenData {
power: 100,
rarity: string::utf8(b"Legendary"),
});
}struct MyTokenData has key {
power: u64,
rarity: String,
}
fun mint_with_data(creator: &signer) {
let constructor_ref = token::create(
creator,
string::utf8(b"Collection"),
string::utf8(b"Description"),
string::utf8(b"Token Name"),
option::none(),
string::utf8(b"https://example.com/token"),
);
let token_signer = object::generate_signer(&constructor_ref);
move_to(&token_signer, MyTokenData {
power: 100,
rarity: string::utf8(b"Legendary"),
});
}use aptos_framework::event;
#[event]
struct TransferEvent has drop, store {
from: address,
to: address,
amount: u64,
}
fun emit_transfer(from: address, to: address, amount: u64) {
event::emit(TransferEvent { from, to, amount });
}use aptos_framework::event;
#[event]
struct TransferEvent has drop, store {
from: address,
to: address,
amount: u64,
}
fun emit_transfer(from: address, to: address, amount: u64) {
event::emit(TransferEvent { from, to, amount });
}const E_NOT_ADMIN: u64 = 1;
struct AdminConfig has key {
admin: address,
}
fun only_admin(sender: &signer) acquires AdminConfig {
let config = borrow_global<AdminConfig>(@my_addr);
assert!(
signer::address_of(sender) == config.admin,
E_NOT_ADMIN
);
}const E_NOT_ADMIN: u64 = 1;
struct AdminConfig has key {
admin: address,
}
fun only_admin(sender: &signer) acquires AdminConfig {
let config = borrow_global<AdminConfig>(@my_addr);
assert!(
signer::address_of(sender) == config.admin,
E_NOT_ADMIN
);
}const E_PAUSED: u64 = 2;
struct PauseState has key {
paused: bool,
}
fun when_not_paused() acquires PauseState {
let state = borrow_global<PauseState>(@my_addr);
assert!(!state.paused, E_PAUSED);
}const E_PAUSED: u64 = 2;
struct PauseState has key {
paused: bool,
}
fun when_not_paused() acquires PauseState {
let state = borrow_global<PauseState>(@my_addr);
assert!(!state.paused, E_PAUSED);
}struct Counter has key {
value: u64,
}
fun increment() acquires Counter {
let counter = borrow_global_mut<Counter>(@my_addr);
counter.value = counter.value + 1;
}struct Counter has key {
value: u64,
}
fun increment() acquires Counter {
let counter = borrow_global_mut<Counter>(@my_addr);
counter.value = counter.value + 1;
}[package]
name = "my_project"
version = "1.0.0"
authors = []
[addresses]
my_addr = "_"
[dependencies.AptosFramework]
git = "https://github.com/movementlabsxyz/aptos-core.git"
rev = "m1"
subdir = "aptos-move/framework/aptos-framework"
[dependencies.AptosStdlib]
git = "https://github.com/movementlabsxyz/aptos-core.git"
rev = "m1"
subdir = "aptos-move/framework/aptos-stdlib"
[dependencies.AptosTokenObjects]
git = "https://github.com/movementlabsxyz/aptos-core.git"
rev = "m1"
subdir = "aptos-move/framework/aptos-token-objects"[package]
name = "my_project"
version = "1.0.0"
authors = []
[addresses]
my_addr = "_"
[dependencies.AptosFramework]
git = "https://github.com/movementlabsxyz/aptos-core.git"
rev = "m1"
subdir = "aptos-move/framework/aptos-framework"
[dependencies.AptosStdlib]
git = "https://github.com/movementlabsxyz/aptos-core.git"
rev = "m1"
subdir = "aptos-move/framework/aptos-stdlib"
[dependencies.AptosTokenObjects]
git = "https://github.com/movementlabsxyz/aptos-core.git"
rev = "m1"
subdir = "aptos-move/framework/aptos-token-objects"Error: "type does not have the 'key' ability"
Fix: Add `has key` to struct definitionError: "cannot copy value"
Fix: Add `has copy` or use reference `&`Error: "cannot drop value"
Fix: Add `has drop` or explicitly handle the valueError: "type does not have the 'key' ability"
Fix: 为结构体定义添加`has key`Error: "cannot copy value"
Fix: 添加`has copy`或使用引用`&`Error: "cannot drop value"
Fix: 添加`has drop`或显式处理该值Error: "cannot borrow global mutably"
Fix: Use `borrow_global_mut` and add `acquires` annotationError: "value still borrowed"
Fix: Ensure previous borrow ends before new borrowError: "cannot borrow global mutably"
Fix: 使用`borrow_global_mut`并添加`acquires`注解Error: "value still borrowed"
Fix: 确保新借用前已结束之前的借用Error: "expected type X, found Y"
Fix: Check function signatures, ensure types matchError: "missing acquires annotation"
Fix: Add `acquires ResourceName` to function signatureError: "expected type X, found Y"
Fix: 检查函数签名,确保类型匹配Error: "missing acquires annotation"
Fix: 为函数签名添加`acquires ResourceName`Error: "function is not public"
Fix: Add `public` or `public entry` to functionError: "module not found"
Fix: Check Move.toml dependencies, ensure correct import pathError: "function is not public"
Fix: 为函数添加`public`或`public entry`修饰符Error: "module not found"
Fix: 检查Move.toml依赖,确保导入路径正确brew install movementlabsxyz/tap/movement
movement --versionbrew install aptos
aptos --version # must be exactly 7.4.0setup_clibrew install movementlabsxyz/tap/movement
movement --versionbrew install aptos
aptos --version # 必须为7.4.0版本setup_cliundefinedundefined
---
---existsborrow_globalmovement move testborrow_globalexistsmovement move test