Move Language Advanced
Global Storage Operations

Global Storage Operations

  • Các chương trình Move có thể create, delete, và update resources trong global storage bằng cách sử dụng năm lệnh sau:
OperationDescriptionAborts?
move_to<T>(&signer, T)Publish T under signer.addressIf signer.address already holds a T
move_from<T>(address): TRemove T from address and return itIf address does not hold a T
borrow_global_mut<T>(address): &TReturn a mutable reference to the T stored under addressIf address does not hold a T
borrow_global<T>(address): &TReturn an immutable reference to the T stored under addressIf address does not hold a T
exists<T>(address): boolReturn true if T is stored under addressNever
  • Mỗi lệnh trong số này được tham số hóa bởi một loại T với key ability. Tuy nhiên, mỗi loại T phải được khai báo trong module hiện tại. Điều này đảm bảo rằng một tài nguyên chỉ có thể được thao tác thông qua API được module định nghĩa. Các lệnh cũng yêu cầu một địa chỉ &signer đại diện cho địa chỉ tài khoản nơi tài nguyên loại T được lưu trữ
module my_addrx::counter {
    use std::signer;
    use std::account;
 
    /// Resource that wraps an integer counter
    struct Counter has key { i: u64 }
 
    /// Publish a `Counter` resource with value `i` under the given `account`
    public fun publish(account: &signer, i: u64) {
      // "Pack" (create) a Counter resource. This is a privileged operation that
      // can only be done inside the module that declares the `Counter` resource
      move_to(account, Counter { i })
    }
 
    /// Read the value in the `Counter` resource stored at `addr`
    public fun get_count(addr: address): u64 acquires Counter {
        borrow_global<Counter>(addr).i
    }
 
    /// Increment the value of `addr`'s `Counter` resource
    public fun increment(addr: address) acquires Counter {
        let c_ref = &mut borrow_global_mut<Counter>(addr).i;
        *c_ref = *c_ref + 1
    }
 
    /// Reset the value of `account`'s `Counter` to 0
    public fun reset(account: &signer) acquires Counter {
        let c_ref = &mut borrow_global_mut<Counter>(signer::address_of(account)).i;
        *c_ref = 0
    }
 
    /// Delete the `Counter` resource under `account` and return its value
    public fun delete(account: &signer): u64 acquires Counter {
        // remove the Counter resource
        let c = move_from<Counter>(signer::address_of(account));
        // "Unpack" the `Counter` resource into its fields. This is a
        // privileged operation that can only be done inside the module
        // that declares the `Counter` resource
        let Counter { i } = c;
        i
    }
 
    /// Return `true` if `addr` contains a `Counter` resource
    public fun resource_exists(addr: address): bool {
        exists<Counter>(addr)
    }
 
    #[test(admin = @0x123)]
    public entry fun test_flow(admin: signer) acquires Counter
    {
        account::create_account_for_test(signer::address_of(&admin));
 
        publish(&admin,5);
        assert!(get_count(signer::address_of(&admin))==5,1);
        increment(signer::address_of(&admin));
        assert!(get_count(signer::address_of(&admin))==6,1);
        reset(&admin);
        assert!(get_count(signer::address_of(&admin))==0,1);
        delete(&admin);
        assert!(resource_exists(signer::address_of(&admin))==false,1);
    }
}

Trong ví dụ về counter, bạn có thể đã nhận thấy rằng các hàm get_count, increment, reset, và delete được chú thích với acquires Counter. Một hàm Move m::f phải được chú thích với acquires T nếu và chỉ nếu:

  • body function m::f chứa một lệnh move_from<T>, borrow_global_mut<T>, hoặc borrow_global<T>, hoặc
  • body function m::f gọi một hàm m::g được khai báo trong cùng một module và được chú thích với acquires.