Перейти к содержимому

Ваш Первый Модуль Move

Блокчейн Aptos позволяет разработчикам писать полные по Тьюрингу смарт-контракты (называемые “модули”) с помощью безопасного по дизайну языка Move. Смарт-контракты позволяют пользователям отправлять деньги через блокчейн, а также писать произвольный код, даже игры! Все начинается с того, что Aptos CLI создает аккаунт, который будет хранить развернутый (“опубликованный”) модуль Move.

Этот учебник поможет вам понять модули Move, проведя через настройку минимальной среды Aptos, а затем как компилировать, тестировать, публиковать и взаимодействовать с модулями Move в блокчейне Aptos. Вы узнаете как:

  1. Настроить среду, установить CLI
  2. Создать аккаунт devnet и профинансировать его
  3. Компилировать и тестировать модуль Move
  4. Публиковать (или “разворачивать”) модуль Move в блокчейне Aptos
  5. Взаимодействовать с модулем
  6. Продолжить создание с Aptos (следующие шаги)

Изменения в блокчейне называются “транзакциями”, и они требуют аккаунт для оплаты сетевой комиссии (“комиссия за газ”). Нам нужно будет создать аккаунт с некоторым количеством APT для оплаты этой комиссии и владения опубликованным контрактом. Для этого нам понадобится использовать Aptos CLI.

  1. Установить Aptos CLI

    Установите Aptos CLI (если еще не установили).

  2. Открыть новый терминал

    Откройте новое окно терминала или вкладку.

  3. Проверить установку

    Запустите aptos --version для проверки установки.

    Окно терминала
    aptos --version

    Вы должны увидеть ответ типа aptos 4.6.1.

  4. Создать папку проекта

    Создайте новую папку для этого учебника, запустив:

    Окно терминала
    mkdir my-first-module
  5. Перейти в папку проекта

    Запустите cd my-first-module для перехода в вашу новую папку.

  6. Инициализировать ваш аккаунт

    Запустите aptos init и нажимайте ‘enter’ для каждого шага настройки, чтобы создать тестовый аккаунт в devnet.

    Вы должны увидеть сообщение об успехе, подобное этому:

    Окно терминала
    ---
    Aptos CLI is now set up for account 0x9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba as profile default!
    {
    "Result": "Success"
    }
  7. Фондировать ваш аккаунт

    Запустите aptos account fund-with-faucet --account default для добавления APT на ваш аккаунт:

    Окно терминала
    aptos account fund-with-faucet --account default

    Вы должны увидеть сообщение об успехе:

    Окно терминала
    {
    "Result": "Added 100000000 Octas to account 9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba"
    }
  8. Проверить баланс аккаунта

    Запустите aptos account balance для проверки баланса вашего аккаунта:

    Окно терминала
    aptos account balance

    Вы должны увидеть что-то вроде:

    Окно терминала
    {
    "Result": "100000000"
    }

    Это означает, что у вас есть 1 APT (помните, 1 APT = 100,000,000 Octas).

Теперь создадим простой модуль Move. Модуль похож на библиотеку или пакет в других языках программирования - он содержит функции и структуры данных.

  1. Инициализировать проект Move

    Запустите aptos move init --name hello_blockchain для создания новой структуры проекта Move:

    Окно терминала
    aptos move init --name hello_blockchain

    Это создаст следующую структуру папок:

    my-first-module/
    ├── Move.toml # Конфигурация проекта
    └── sources/ # Ваши исходные файлы Move
  2. Создать исходный файл

    Создайте новый файл sources/hello_blockchain.move:

    Окно терминала
    touch sources/hello_blockchain.move
  3. Добавить код модуля

    Откройте sources/hello_blockchain.move в вашем редакторе и добавьте следующий код:

    module hello_blockchain::message {
    use std::error;
    use std::signer;
    use std::string;
    use aptos_framework::event;
    //:!:>resource
    struct MessageHolder has key {
    message: string::String,
    }
    //<:!:resource
    #[event]
    struct MessageChange has drop, store {
    account: address,
    from_message: string::String,
    to_message: string::String,
    }
    /// Не существует MessageHolder ресурса под адресом аккаунта
    const E_NO_MESSAGE: u64 = 0;
    #[view]
    public fun get_message(addr: address): string::String acquires MessageHolder {
    assert!(exists<MessageHolder>(addr), error::not_found(E_NO_MESSAGE));
    borrow_global<MessageHolder>(addr).message
    }
    public entry fun set_message(account: signer, message: string::String)
    acquires MessageHolder {
    let account_addr = signer::address_of(&account);
    if (!exists<MessageHolder>(account_addr)) {
    move_to(&account, MessageHolder {
    message,
    })
    } else {
    let old_message = borrow_global_mut<MessageHolder>(account_addr);
    let from_message = old_message.message;
    event::emit(MessageChange {
    account: account_addr,
    from_message,
    to_message: copy message,
    });
    old_message.message = message;
    }
    }
    #[test(admin = @0x123)]
    public entry fun sender_can_set_message(admin: signer) acquires MessageHolder {
    let addr = signer::address_of(&admin);
    aptos_framework::account::create_account_for_test(addr);
    set_message(admin, string::utf8(b"Hello, Blockchain"));
    assert!(
    get_message(addr) == string::utf8(b"Hello, Blockchain"),
    E_NO_MESSAGE
    );
    }
    }

    Этот модуль:

    • Определяет ресурс MessageHolder для хранения строки сообщения
    • Имеет функцию set_message для установки сообщения аккаунта
    • Имеет функцию get_message для чтения сообщения аккаунта
    • Включает базовый тест
  1. Компилировать модуль

    Запустите aptos move compile для компиляции вашего модуля:

    Окно терминала
    aptos move compile

    Если все пройдет хорошо, вы увидите:

    Окно терминала
    Compiling, may take a little while to download git dependencies...
    UPDATING GIT DEPENDENCY https://github.com/aptos-labs/aptos-core.git
    INCLUDING DEPENDENCY AptosFramework
    INCLUDING DEPENDENCY AptosStdlib
    INCLUDING DEPENDENCY MoveStdlib
    BUILDING hello_blockchain
    {
    "Result": "Success"
    }
  2. Запустить тесты

    Запустите aptos move test для выполнения тестов:

    Окно терминала
    aptos move test

    Вы должны увидеть:

    Окно терминала
    Compiling, may take a little while to download git dependencies...
    BUILDING hello_blockchain
    Running Move unit tests
    [ PASS ] 0xf8f6f2::message::sender_can_set_message
    Test result: OK. Total tests: 1; passed: 1; failed: 0
    {
    "Result": "Success"
    }
  3. Исправить любые ошибки

    Если у вас есть ошибки компиляции или тестов, внимательно прочитайте сообщения об ошибках и исправьте код.

Теперь опубликуем наш модуль в блокчейне!

  1. Опубликовать модуль

    Запустите aptos move publish для развертывания вашего модуля:

    Окно терминала
    aptos move publish

    Вы увидите информацию о транзакции и будет предложено подтвердить:

    Окно терминала
    Compiling, may take a little while to download git dependencies...
    BUILDING hello_blockchain
    package size 1755 bytes
    Do you want to submit a transaction for a range of [194800 - 292200] Octas at a gas unit price of 100 Octas? [yes/no]

    Введите yes и нажмите Enter.

  2. Подтвердить публикацию

    После успешной публикации вы увидите что-то вроде:

    Окно терминала
    {
    "Result": {
    "transaction_hash": "0x45c0f6f1b208e2f....",
    "gas_used": 1947,
    "gas_unit_price": 100,
    "sender": "9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba",
    "sequence_number": 0,
    "success": true,
    "timestamp_us": 1685077849297587,
    "version": 528422121,
    "vm_status": "Executed successfully"
    }
    }

    Поздравляем! Ваш модуль теперь в блокчейне.

Теперь давайте взаимодействовать с нашим опубликованным модулем.

  1. Установить сообщение

    Вызовите функцию set_message для установки сообщения:

    Окно терминала
    aptos move run \
    --function-id 'default::message::set_message' \
    --args 'string:Hello, Aptos!'

    Вы увидите результат транзакции:

    Окно терминала
    {
    "Result": {
    "transaction_hash": "0x1d644eba8187fa8475...",
    "gas_used": 736,
    "gas_unit_price": 100,
    "sender": "9ec1cfa30b885a5c9d595f32f3381ec16d208734913b587be9e210f60be9f9ba",
    "sequence_number": 1,
    "success": true,
    "timestamp_us": 1685077973499641,
    "version": 528422122,
    "vm_status": "Executed successfully"
    }
    }
  2. Прочитать сообщение

    Вызовите функцию get_message для чтения сообщения:

    Окно терминала
    aptos move view \
    --function-id 'default::message::get_message' \
    --args 'address:default'

    Вы должны увидеть ваше сохраненное сообщение:

    Окно терминала
    {
    "Result": [
    "Hello, Aptos!"
    ]
    }
  3. Обновить сообщение

    Давайте изменим сообщение:

    Окно терминала
    aptos move run \
    --function-id 'default::message::set_message' \
    --args 'string:Hello, Move!'

    Прочитайте его снова, чтобы подтвердить изменение:

    Окно терминала
    aptos move view \
    --function-id 'default::message::get_message' \
    --args 'address:default'

    Результат:

    Окно терминала
    {
    "Result": [
    "Hello, Move!"
    ]
    }

Вы также можете видеть ваш модуль и транзакции в Aptos Explorer:

  1. Перейти в Aptos Explorer

    Откройте Aptos Explorer в вашем браузере.

  2. Переключиться на Devnet

    В правом верхнем углу убедитесь, что выбрана сеть “Devnet”.

  3. Найти ваш аккаунт

    Скопируйте адрес вашего аккаунта из вывода CLI и вставьте его в поисковую строку.

  4. Изучить ваш аккаунт

    Вы увидите:

    • Баланс аккаунта
    • Опубликованные модули
    • Историю транзакций
    • Ресурсы (включая ваш MessageHolder)

Давайте глубже рассмотрим ключевые концепции Move:

struct MessageHolder has key {
message: string::String,
}
  • Ресурсы - это структуры данных, которые могут быть сохранены в глобальном хранилище
  • has key означает, что эта структура может быть сохранена под адресом аккаунта
  • Ресурсы уникальны - они не могут быть скопированы или случайно удалены
public entry fun set_message(account: signer, message: string::String)
  • public entry функции могут быть вызваны извне (из транзакций)
  • signer представляет аккаунт, подписывающий транзакцию
  • Эти функции могут изменять состояние блокчейна
#[view]
public fun get_message(addr: address): string::String
  • #[view] функции только читают данные
  • Они не могут изменять состояние
  • Они могут быть вызваны без отправки транзакции
// Проверить, существует ли ресурс
exists<MessageHolder>(addr)
// Переместить ресурс в хранилище
move_to(&account, MessageHolder { message })
// Заимствовать ресурс
borrow_global<MessageHolder>(addr)
// Изменяемо заимствовать ресурс
borrow_global_mut<MessageHolder>(addr)
/// Коды ошибок
const E_NO_MESSAGE: u64 = 0;
const E_INVALID_MESSAGE: u64 = 1;
public fun get_message(addr: address): string::String acquires MessageHolder {
assert!(exists<MessageHolder>(addr), error::not_found(E_NO_MESSAGE));
borrow_global<MessageHolder>(addr).message
}
#[event]
struct MessageChange has drop, store {
account: address,
from_message: string::String,
to_message: string::String,
}
// Эмитировать событие
event::emit(MessageChange {
account: account_addr,
from_message,
to_message: copy message,
});
#[test(admin = @0x123)]
public entry fun test_set_message(admin: signer) acquires MessageHolder {
let addr = signer::address_of(&admin);
aptos_framework::account::create_account_for_test(addr);
set_message(admin, string::utf8(b"Test Message"));
assert!(
get_message(addr) == string::utf8(b"Test Message"),
E_NO_MESSAGE
);
}

Поздравляем! Вы успешно создали, развернули и взаимодействовали с вашим первым модулем Move. Вот некоторые следующие шаги для продолжения обучения:

Ошибка компиляции: “could not find package”

error: could not find package `hello_blockchain` in ...
  • Убедитесь, что Move.toml существует и правильно настроен
  • Проверьте название пакета в Move.toml

Ошибка публикации: “INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEE”

error: INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEE
  • Профинансируйте ваш аккаунт: aptos account fund-with-faucet --account default

Ошибка выполнения: “FUNCTION_NOT_FOUND”

error: FUNCTION_NOT_FOUND
  • Проверьте правильность ID функции
  • Убедитесь, что модуль опубликован

Ошибка ресурса: “RESOURCE_NOT_FOUND”

error: RESOURCE_NOT_FOUND
  • Убедитесь, что ресурс был создан раньше
  • Проверьте адрес аккаунта

Добро пожаловать в экосистему Aptos! Продолжайте изучать и создавать удивительные dApps. 🚀