В этом руководстве подробно рассказывается, как писать, компилировать, тестировать, публиковать и взаимодействовать с модулями Move в Aptos Blockchain. Мы рассмотрим следующие шаги:
Напишите, скомпилируйте и протестируйте модуль Move.
Опубликуйте модуль Move в Aptos Blockchain.
Запустите и взаимодействуйте с ресурсами Move Module.
Это руководство основано на разделе в качестве библиотеки для этого примера. Данное руководство содержит пример кода, который можно полностью загрузить:
В этом руководстве основное внимание будет уделено hello_blockchain.py и повторному использованию библиотеки first_transaction.py из предыдущего руководства.
Вы найдете python project .
В этом руководстве основное внимание будет уделено hello_blockchain.rs и повторному использованию библиотеки first_transaction.rs из предыдущего руководства.
Вы найдете rust project .
В этом руководстве основное внимание будет уделено hello_blockchain.ts и повторному использованию библиотеки first_transaction.ts из предыдущего руководства.
Вы найдете typescript project .
Шаг 1) Напишите и протестируйте Move Module
Шаг 1.1) Загрузите Aptos-core
Для простоты выполнения этой задачи в Aptos-core имеется каталог move-examples , который позволяет легко создавать и тестировать модули Move без загрузки дополнительных ресурсов. Со временем мы расширим этот раздел, чтобы описать, как использовать для разработки инструменты .
В этом терминале измените каталоги наaptos-move/move-examples/hello_blockchain. Сохраните окно терминала до конца данного руководства — далее мы будем называть его "Move Window". В оставшейся части этого раздела будет рассмотрен файл sources/HelloBlockchain.move.
Этот модуль позволяет пользователям создать и установить ресурс String под своей учетной записью. Пользователи могут устанавливать только свой ресурс и не могут устанавливать ресурсы других.
module HelloBlockchain::Message {
use Std::ASCII;
use Std::Errors;
use Std::Signer;
struct MessageHolder has key {
message: ASCII::String,
}
public(script) fun set_message(account: signer, message_bytes: vector<u8>)
acquires MessageHolder {
let message = ASCII::string(message_bytes);
let account_addr = Signer::address_of(&account);
if (!exists<MessageHolder>(account_addr)) {
move_to(&account, MessageHolder {
message,
})
} else {
let old_message_holder = borrow_global_mut<MessageHolder>(account_addr);
old_message_holder.message = message;
}
}
}
В приведенном выше коде два важных раздела — это структура MessageHolder и функция set_message. set_message — это функция сценария script , позволяющая вызывать ее непосредственно транзакциями. После ее вызова функция определит, есть ли у текущей учетной записи ресурс MessageHolder , а также создаст и сохранит сообщение message , если оно не существует. Если ресурс существует, сообщение message в MessageHolder перезаписывается.
Шаг 1.3) Тестирование модуля
Move позволяет выполнять встроенные тесты, поэтому мы добавляем get_message ,чтобы сделать извлечение сообщения message удобным и тестовую функцию sender_can_set_message для проверки сквозного потока. Это можно проверить, запустив cargo test. Есть еще один тест sources/HelloBlockchainTest.move , демонстрирующий другой метод написания тестов.
Это можно проверить, введя на терминале cargo test test_hello_blockchain -p move-examples -- --exact .
Примечание: sender_can_set_message - это функция script для вызова функции script - set_message.
Теперь вернемся к нашему приложению для развертывания и взаимодействия с модулем в блокчейне Atpos. Как упоминалось ранее, это руководство основано на предыдущем руководстве и использует общий код. Соответственно, в этом руководстве обсуждаются только новые функции данной библиотеки, включая возможность публикации, отправки транзакцииset_message и чтения MessageHolder::message. Единственное отличие от публикации модуля и отправки транзакции — это тип полезной нагрузки. См. следующее:
Шаг 2.1) Публикация Move Module
class HelloBlockchainClient(RestClient):
def publish_module(self, account_from: Account, module_hex: str) -> str:
"""Publish a new module to the blockchain within the specified account"""
payload = {
"type": "module_bundle_payload",
"modules": [
{"bytecode": f"0x{module_hex}"},
],
}
txn_request = self.generate_transaction(account_from.address(), payload)
signed_txn = self.sign_transaction(account_from, txn_request)
res = self.submit_transaction(signed_txn)
return str(res["hash"])
pub struct HelloBlockchainClient {
pub rest_client: RestClient,
}
impl HelloBlockchainClient {
/// Represents an account as well as the private, public key-pair for the Aptos blockchain.
pub fn new(url: String) -> Self {
Self {
rest_client: RestClient::new(url),
}
}
/// Publish a new module to the blockchain within the specified account
pub fn publish_module(&self, account_from: &mut Account, module_hex: &str) -> String {
let payload = serde_json::json!({
"type": "module_bundle_payload",
"modules": [{"bytecode": format!("0x{}", module_hex)}],
});
self.rest_client.execution_transaction_with_payload(account_from, payload)
}
export class HelloBlockchainClient extends RestClient {
/** Publish a new module to the blockchain within the specified account */
async publishModule(accountFrom: Account, moduleHex: string): Promise<string> {
const payload = {
type: "module_bundle_payload",
modules: [{ bytecode: `0x${moduleHex}` }],
};
const txnRequest = await this.generateTransaction(accountFrom.address(), payload);
const signedTxn = await this.signTransaction(accountFrom, txnRequest);
const res = await this.submitTransaction(signedTxn);
return res["hash"];
}
Шаг 2.2) Чтение ресурса
Модуль публикуется по адресу. Ниже приведен адрес contract_address . Это похоже на предыдущий пример, где монетаCoin находится по адресу 0x1. contract_address будет таким же, как у учетной записи, которая его публикует.
Модули Move должны раскрывать функции script для запуска и управления ресурсами. Затем script можно вызвать из транзакции.
Примечание: хотя интерфейс REST и может отображать строки, но из-за ограничений JSON и Move он не может определить, является ли аргумент строкой или строкой в шестнадцатеричном коде. Таким образом, аргументы транзакции всегда предполагают последнее. Следовательно, в этом примере сообщение закодировано как шестнадцатеричная строка.
def set_message(self, contract_address: str, account_from: Account, message: str) -> str:
""" Potentially initialize and set the resource Message::MessageHolder::message """
payload = {
"type": "script_function_payload",
"function": f"0x{contract_address}::Message::set_message",
"type_arguments": [],
"arguments": [
message.encode("utf-8").hex(),
]
}
res = self.execute_transaction_with_payload(account_from, payload)
return str(res["hash"])
/// Potentially initialize and set the resource Message::MessageHolder::message
pub fn set_message(
&self,
contract_address: &str,
account_from: &mut Account,
message: &str,
) -> String {
let message_hex = hex::encode(message.as_bytes());
let payload = serde_json::json!({
"type": "script_function_payload",
"function": format!("0x{}::Message::set_message", contract_address),
"type_arguments": [],
"arguments": [message_hex]
});
self.rest_client.execution_transaction_with_payload(account_from, payload)
}
Откройте свой любимый терминал и перейдите туда, куда вы загрузили приведенный выше example project.
Установите необходимые библиотеки: pip3 install -r requirements.txt.
Выполните: python3 hello_blockchain.py Message.mv
Для Rust:
Откройте свой любимый терминал и перейдите туда, куда вы загрузили приведенный выше example project.
Выполните: cargo run --bin hello-blockchain -- Message.mv
Для Typescript:
Откройте свой любимый терминал и перейдите туда, куда вы загрузили приведенный выше example project.
Установите необходимые библиотеки: yarn install
Выполните: yarn hello_blockchain Message.mv
Через некоторое время появится сообщение: "Обновите модуль с адресом Алисы, создайте, скопируйте по указанному пути и нажмите Enter."
В терминале "Move Window" и для файла Move, который мы ранее рассматривали:
Скопируйте адрес Алисы
Скомпилируйте модули с адресом Алисы с помощью aptos move compile --package-dir . --named-addresses HelloBlockchain=0x{alice_address_here}. Здесь бы заменяем общий адрес HelloBlockChain='_' в hello_blockchain/move.toml на адрес Алисы
Скопируйте build/Examples/bytecode_modules/Message.mv в ту же папку, что и код этого руководства
Вернитесь в другое окно терминала и нажмите "enter" в командной строке, чтобы продолжить выполнение остальной части кода
Результат должен выглядеть следующим образом:
=== Addresses ===
Alice: 11c32982d04fbcc79b694647edff88c5b5d5b1a99c9d2854039175facbeefb40
Bob: 7ec8f962139943bc41c17a72e782b7729b1625cf65ed7812152a5677364a4f88
=== Initial Balances ===
Alice: 10000000
Bob: 10000000
Update the module with Alice's address, build, copy to the provided path, and press enter.
=== Testing Alice ===
Publishing...
Initial value: None
Setting the message to "Hello, Blockchain"
New value: Hello, Blockchain
=== Testing Bob ===
Initial value: None
Setting the message to "Hello, Blockchain"
New value: Hello, Blockchain
Результат показывает, что Алиса и Боб перешли от отсутствия ресурсов к одному с message "Hello, Blockchain".
Данные можно проверить, посетив либо интерфейс REST, либо :