🟢
Aptos RU WiKi
  • Aptos Developer Network
  • Основы
    • Учётные записи (аккаунты)
    • События (events)
    • Полные ноды
    • Газ и комиссия за транзакции
    • Подтверждение
    • Топология сети
    • Транзакции и состояния
    • Валидирующие ноды
  • Гайды
    • Начало работы
    • Жизнь транзакции
    • Move в сети Aptos
    • Взаимодействие с блокчейном Aptos
  • Руководства по применению
    • Ваша первая транзакция
    • Ваш первый Move модуль
    • Ваш первый Dapp
    • Ваша первая монета
    • Ваш первый NFT
    • Расширение Wallet
  • Руководства по нодам
    • Запуск локального тестнета
    • Запуск полной ноды
      • Запуск полной ноды
      • Обновление полной ноды на новый релиз
      • Идентификация для полной ноды
      • Устранение неполадок при настройке полной ноды
  • Документы по вознаграждаемому тестнету
    • Введение
    • Запуск валидатора используя GCP
    • Запуск валидатора используя AWS
    • Запуск валидатора используя Azure
    • Запуск валидатора используя Docker
    • Запуск валидатора используя исходные файлы
    • Подключение к вознаграждаемому тестнету Aptos
  • Критерии работоспособности ноды
  • Телеметрия
  • Глоссарий
Powered by GitBook
On this page
  • Шаг 1) Напишите и протестируйте Move Module
  • Шаг 2) Публикация и взаимодействие с Move Module
  1. Руководства по применению

Ваш первый Move модуль

PreviousВаша первая транзакцияNextВаш первый Dapp

Last updated 2 years ago

В этом руководстве подробно рассказывается, как писать, компилировать, тестировать, публиковать и взаимодействовать с модулями Move в Aptos Blockchain. Мы рассмотрим следующие шаги:

  1. Напишите, скомпилируйте и протестируйте модуль Move.

  2. Опубликуйте модуль Move в Aptos Blockchain.

  3. Запустите и взаимодействуйте с ресурсами 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-core:

git clone https://github.com/aptos-labs/aptos-core.git
cd aptos-core
./scripts/dev_setup.sh
source ~/.cargo/env
git checkout origin/devnet

Установите Aptos Commandline tool. Узнайте больше по ссылке .

cargo install --git https://github.com/aptos-labs/aptos-core.git aptos

Шаг 1.2) Просмотрите модуль

В этом терминале измените каталоги на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.

const ENO_MESSAGE: u64 = 0;

    public fun get_message(addr: address): ASCII::String acquires MessageHolder {
        assert!(exists<MessageHolder>(addr), Errors::not_published(ENO_MESSAGE));
        *&borrow_global<MessageHolder>(addr).message
    }

    #[test(account = @0x1)]
    public(script) fun sender_can_set_message(account: signer) acquires MessageHolder {
        let addr = Signer::address_of(&account);
        set_message(account,  b"Hello, Blockchain");

        assert!(
          get_message(addr) == ASCII::string(b"Hello, Blockchain"),
          0
        );
    }

Шаг 2) Публикация и взаимодействие с Move Module

Теперь вернемся к нашему приложению для развертывания и взаимодействия с модулем в блокчейне 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 будет таким же, как у учетной записи, которая его публикует.

  def get_message(self, contract_address: str, account_address: str) -> Optional[str]:
        """ Retrieve the resource Message::MessageHolder::message """
        return self.account_resource(account_address, f"0x{contract_address}::Message::MessageHolder")
    /// Retrieve the resource Message::MessageHolder::message
    pub fn get_message(&self, contract_address: &str, account_address: &str) -> Option<String> {
        let module_type = format!("0x{}::Message::MessageHolder", contract_address);
        self.rest_client
            .account_resource(account_address, &module_type)
            .map(|value| value["data"]["message"].as_str().unwrap().to_string())
    }

    
  /** Retrieve the resource Message::MessageHolder::message */
  async getMessage(contractAddress: string, accountAddress: string): Promise<string> {
    const resource = await this.accountResource(accountAddress, `0x${contractAddress}::Message::MessageHolder`);
    if (resource == null) {
      return null;
    } else {
      return resource["data"]["message"];
    }
  }
  

Шаг 2.3) Изменение ресурса

Модули 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)
    }
    
  /**  Potentially initialize and set the resource Message::MessageHolder::message */
  async setMessage(contractAddress: string, accountFrom: Account, message: string): Promise<string> {
    let payload: { function: string; arguments: string[]; type: string; type_arguments: any[] };
    payload = {
      type: "script_function_payload",
      function: `0x${contractAddress}::Message::set_message`,
      type_arguments: [],
      arguments: [Buffer.from(message, "utf-8").toString("hex")],
    };

    const txnRequest = await this.generateTransaction(accountFrom.address(), payload);
    const signedTxn = await this.signTransaction(accountFrom, txnRequest);
    const res = await this.submitTransaction(signedTxn);
    return res["hash"];
  }
}

Шаг 3) Запуск и взаимодействие с Move module

Для Python3:

  • Откройте свой любимый терминал и перейдите туда, куда вы загрузили приведенный выше 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, либо :

Загрузите .

Загрузите .

Загрузите .

Учетная запись Алисы через

Учетная запись Боба на

Ваша первая транзакция
здесь
здесь
здесь
Move
Aptos command line tool
example project
example project
example project
REST interface
explorer