-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
601f135
commit 1bd6f02
Showing
16 changed files
with
777 additions
and
3 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
pages/move_language_advanced/global_storage_operations.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# 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: | ||
|
||
| Operation | Description | Aborts? | | ||
|-------------------------------------|-----------------------------------------------------------------|-----------------------------------------| | ||
| `move_to<T>(&signer, T)` | Publish `T` under `signer.address` | If `signer.address` already holds a `T` | | ||
| `move_from<T>(address): T` | Remove `T` from `address` and return it | If `address` does not hold a `T` | | ||
| `borrow_global_mut<T>(address): &T` | Return a mutable reference to the `T` stored under `address` | If `address` does not hold a `T` | | ||
| `borrow_global<T>(address): &T` | Return an immutable reference to the `T` stored under `address` | If `address` does not hold a `T` | | ||
| `exists<T>(address): bool` | Return `true` if `T` is stored under `address` | Never | | ||
|
||
- 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ữ | ||
|
||
```rust | ||
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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Global Storage Structure | ||
Trong Move, cấu trúc `global storage` là một khu vực lưu trữ lâu dài cho phép các nhà phát triển lưu trữ dữ liệu trên blockchain. | ||
|
||
Cấu trúc lưu trữ toàn cầu trong Move bao gồm một loại dữ liệu ánh xạ (mapping), tương tự như hash table hoặc dictionary trong các ngôn ngữ lập trình khác. Loại dữ liệu mapping này cho phép các nhà phát triển lưu trữ các cặp key-values, trong đó key là unique identifier và value là data cần được lưu trữ. | ||
|
||
Mục đích của các chương trình Move là `read from` và `write to` vào global storage lâu dài có cấu trúc tree-shaped. Các chương trình không thể truy cập vào filesystem, network, hoặc bất kỳ dữ liệu nào ngoài tree này. | ||
|
||
- Trong pseudocode, cấu trúc global storage trông giống như sau: | ||
|
||
```rust | ||
struct GlobalStorage { | ||
resources: Map<(address, ResourceType), ResourceValue> | ||
modules: Map<(address, ModuleName), ModuleBytecode> | ||
} | ||
``` | ||
|
||
- Về cấu trúc, global storage là một khu rừng gồm các cây có gốc tại một account address. Mỗi address có thể lưu trữ cả giá trị dữ liệu resources và code module. | ||
- Như pseudocode ở trên chỉ ra, mỗi address có thể lưu trữ tối đa một giá trị resources của một loại cụ thể và tối đa một module với một tên cụ thể. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Address | ||
|
||
- `address` là một kiểu dữ liệu tích hợp trong Move được sử dụng để đại diện cho các vị trí (đôi khi gọi là tài khoản `account`) trong global storage. Một giá trị address là một định danh 256-bit (32-byte). Tại một address nhất định, có thể lưu trữ hai thứ: Module và Resource. | ||
|
||
- Mặc dù address là một số nguyên `256-bit`, address Move được thiết kế để trở nên không rõ ràng (intentionally opaque), chúng không thể được tạo ra từ các số nguyên, không hỗ trợ các phép toán số học, và không thể bị thay đổi. Mặc dù có thể có các chương trình thú vị sử dụng tính năng như vậy (ví dụ, toán tử con trỏ trong C thực hiện một vai trò tương tự), Move không cho phép hành vi động này vì nó được thiết kế từ đầu để hỗ trợ kiểm tra tĩnh. | ||
- Bạn có thể sử dụng các giá trị address tại thời điểm chạy (các giá trị kiểu address) để truy cập resources tại address đó. Bạn không thể truy cập các module tại thời điểm chạy thông qua các giá trị address. | ||
|
||
- Address và syntax: | ||
- Address có hai dạng, `named` hoặc `numerical`. Syntax của address named theo cùng một quy tắc với bất kỳ định danh tên nào trong Move. Syntax của address numerical không bị hạn chế ở các giá trị mã hex, và bất kỳ giá trị số u256 hợp lệ nào đều có thể được sử dụng làm giá trị address, ví dụ: `42`, `0xCAFE`, và `2024` đều là các literals address số hợp lệ. | ||
- Để phân biệt khi nào một address đang được sử dụng trong ngữ cảnh biểu thức(expression) hoặc không, cú pháp khi sử dụng address khác nhau tùy thuộc vào ngữ cảnh nơi nó được sử dụng: | ||
- Khi một address được sử dụng như một biểu thức, address phải được tiền tố bởi ký tự @, ví dụ: `@<numerical_value>` hoặc `@<named_address_identifier>`. | ||
- Ngoài ngữ cảnh biểu thức, address có thể được viết mà không cần ký tự @ đứng trước, ví dụ: `<numerical_value>` hoặc `<named_address_identifier>`. | ||
|
||
Nói chung, bạn có thể coi @ như một toán tử chuyển một address từ mục không gian tên thành mục biểu thức. | ||
|
||
```rust | ||
let addrx1:address = @0x1; //numerical address example | ||
let addrx2:address = @my_addrx;//named address example | ||
``` | ||
# Global Storage Operations: | ||
|
||
- Mục đích chính của các `address` là để tương tác với các hoạt động global storage. | ||
|
||
- Các address values được sử dụng với các thao tác `exists`, `borrow_global`, `borrow_global_mut`, và `move_from`. | ||
|
||
- Hoạt động global storage duy nhất không sử dụng địa chỉ là move_to, mà sử dụng `signer`. | ||
|
||
## Quyền sở hữu: | ||
- Tương tự như các giá trị scalar khác được tích hợp vào ngôn ngữ, các giá trị địa chỉ có thể sao chép ngầm định, nghĩa là chúng có thể được sao chép mà không cần lệnh rõ ràng như `copy`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Constants | ||
|
||
- Constants là một cách để đặt tên cho các giá trị tĩnh, được chia sẻ bên trong một module hoặc script. Trong Move, constants được khai báo bằng từ khóa const. | ||
|
||
- Giá trị của constants phải được biết trước tại thời điểm biên dịch. Giá trị của constants được lưu trữ trong module hoặc script đã biên dịch. Mỗi lần constants được sử dụng, một bản sao mới của giá trị đó sẽ được tạo ra. | ||
|
||
## Syntax | ||
```rust | ||
const <NAME>: <TYPE> = <EXPRESSION>; | ||
``` | ||
|
||
```rust | ||
module my_addrx::Constants | ||
{ | ||
use std::debug::print; | ||
|
||
//Some Examples | ||
const X:u64=10; | ||
const Y:address=@my_addrx; | ||
const Z:bool=false; | ||
|
||
fun constants() | ||
{ | ||
print(&X); | ||
print(&Y); | ||
print(&Z); | ||
|
||
} | ||
|
||
#[test] | ||
fun testing() | ||
{ | ||
constants(); | ||
} | ||
} | ||
``` | ||
|
||
## Naming | ||
Constants must start with a capital letter A to Z. After the first letter, constant names can contain underscores _, letters a to z, letters A to Z, or digits 0 to 9. | ||
- Constants phải bắt đầu với một từ cái được viết hoa (A-Z). | ||
- Sau từ cái đầu tiên, constant name có thể chưa các dấu như: _, chữ cái (a-z), chữ cái hoa (A-Z), hoặc số. | ||
|
||
```rust | ||
//Valid | ||
const Foo:u64=123; | ||
const Flag:bool=true; | ||
const My_Addrx:address=@my_addrx; | ||
const EIndexOutOfBound = 0; // Recommend | ||
|
||
//Invalid; | ||
const x:u8=10; | ||
const flag:bool=false; | ||
const my_addrx:address=@my_addrx; | ||
``` | ||
|
||
## Một số điểm quan trọng khác: | ||
- Constants chỉ giới hạn trong các kiểu dữ liệu nguyên thủy như `bool`, `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, `address`, và `vector<u8>` | ||
- Tên của constants nên sử dụng kiểu Upper Camel Case và bắt đầu bằng chữ "E" nếu chúng đại diện cho mã lỗi (ví dụ: `EIndexOutOfBounds`) và kiểu Upper Snake Case nếu chúng đại diện cho giá trị không phải lỗi (ví dụ: `MIN_STAKE`). | ||
- Constants có phạm vi public hiện tại không được hỗ trợ. Các giá trị const chỉ có thể được sử dụng trong module khai báo. | ||
- Giá trị của constants không thể truy cập được từ bên ngoài phạm vi module hoặc script của nó. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Generics | ||
|
||
- Move hỗ trợ việc sử dụng generics, cho phép các developer viết code có thể sử dụng với các loại dữ liệu khác nhau mà không cần phải viết lại code cho từng loại cụ thể. | ||
|
||
- Generics trong Move tương tự như generics trong các ngôn ngữ lập trình khác như Java và C#. Chúng cho phép các nhà phát triển viết code tái sử dụng có thể làm việc với bất kỳ loại nào đáp ứng một tập hợp các yêu cầu cụ thể. | ||
- Điều này có thể giúp giảm sự trùng lặp code và cải thiện khả năng đọc và duy trì code. | ||
|
||
- Trong Move, chúng ta thường sử dụng thuật ngữ generics thay thế cho các tham số kiểu và đối số kiểu. | ||
|
||
- Declaring Type Parameters - Khai báo Tham số Kiểu | ||
- Cả function và struct đều có thể nhận một danh sách các tham số kiểu trong chữ ký của chúng, được bao bởi một cặp dấu ngoặc nhọn \<_>. | ||
|
||
- Generic Functions | ||
- Các tham số kiểu cho hàm được đặt sau tên hàm và trước danh sách các tham số (giá trị). Mã sau đây định nghĩa một hàm nhận dạng generic mà nhận một giá trị của bất kỳ loại nào và trả lại giá trị đó mà không thay đổi. | ||
- Khi đã được định nghĩa, tham số kiểu T có thể được sử dụng trong các kiểu tham số, kiểu trả về, và bên trong thân hàm. | ||
|
||
## Generic Function | ||
```rust | ||
module my_addrx::Generics | ||
{ | ||
//a generic identity function that takes a value of any type and returns that value unchanged | ||
fun example<T>(num: T): T { | ||
num | ||
} | ||
|
||
#[test] | ||
fun testing() | ||
{ | ||
let x:u64 = example<u64>(8); | ||
let y:bool = example<bool>(true); | ||
|
||
assert!(x==8,1); | ||
assert!(y==true,1); | ||
|
||
} | ||
|
||
} | ||
``` | ||
|
||
## Generics Structs | ||
- Các tham số kiểu cho các cấu trúc (structs) được đặt sau tên struct và có thể được sử dụng để đặt tên cho các kiểu của các trường. | ||
```rust | ||
struct Foo<T> has copy, drop { x: T } | ||
|
||
struct Bar<T1, T2> has copy, drop { | ||
x: T1, | ||
y: vector<T2>, | ||
} | ||
``` |
Oops, something went wrong.