# Ваша первая монета

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

1. Разверните модуль MoonCoin. Будем называть его MoonCoin.
2. Инициализируйте MoonCoin через стандартный модуль фреймворка Coin.
3. Зарегистрируйте учетную запись получателя, чтобы получить MoonCoin.
4. Создайте MoonCoin получателю как владелец MoonCoin.

Это руководство основано на секции [Ваша первая транзакция](https://cr-nepos.gitbook.io/aptos-ru/rukovodstva-po-primeneniyu/vasha-pervaya-tranzakciya) в качестве библиотеки для этого примера. Данное руководство содержит пример кода, который можно загрузить ниже:

{% tabs %}
{% tab title="Python" %}
В этом руководстве основное внимание будет уделено `first_coin.py` и повторному использованию библиотеки`first_transaction.py` из предыдущего руководства.

Вы найдете python project [здесь](https://github.com/aptos-labs/aptos-core/tree/main/developer-docs-site/static/examples/python)
{% endtab %}

{% tab title="Rust" %}
В этом руководстве основное внимание будет уделено `first_coin.rs` и повторному использованию библиотеки `first_transaction.rs` из предыдущего руководства.

Вы найдете rust project [здесь](https://github.com/aptos-labs/aptos-core/tree/main/developer-docs-site/static/examples/rust)
{% endtab %}

{% tab title="Typescript" %}
В этом руководстве основное внимание будет уделено  `first_coin.ts` и повторному использованию библиотеки `first_transaction.ts` из предыдущего руководства.

Вы найдете typescript project [здесь](https://github.com/aptos-labs/aptos-core/tree/main/developer-docs-site/static/examples/typescript)
{% endtab %}
{% endtabs %}

### Шаг 1) Разверните модуль MoonCoin <a href="#step-1-deploy-mooncoin-module" id="step-1-deploy-mooncoin-module"></a>

#### Шаг 1.1) Загрузите Aptos-core <a href="#step-11-download-aptos-core" id="step-11-download-aptos-core"></a>

Для простоты выполнения этой задачи у Aptos-core имеется `move-examples` каталог, который позволяет легко создавать и тестировать модули Move без загрузки дополнительных ресурсов. Со временем мы расширим этот раздел и опишем, как использовать инструменты [Move](https://github.com/move-language/move/tree/main/language/documentation/tutorial) для разработки.

А сейчас загрузите и подготовьте 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. См. подробнее [Aptos command line tool](https://github.com/aptos-labs/aptos-core/tree/main/crates/aptos)

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

#### Шаг 1.2) Просмотрите модуль <a href="#step-12-review-the-module" id="step-12-review-the-module"></a>

В этом терминале измените каталоги на `aptos-move/move-examples/moon_coin`. Сохраните это окно терминала до конца руководства - в дальнейшем мы будем называть его «Move Window». В оставшейся части этого раздела будет рассмотрен файл `sources/MoonCoinType.move`.

Этот модуль позволяет пользователям создать новый MoonCoinType::MoonCoin::MoonCoin, который можно использовать для регистрации в платформенном модуле Coin (0x1::Coin) для создания стандартной монеты Coin. Разработчики могут написать свои собственные функции в модуле MoonCoin, если они хотят сделать больше, чем то, что предоставляется в стандартном режиме 0x1::Coin или 0x1::ManagedCoin (добавляет функции создания/сжигания монет).

```
module MoonCoinType::MoonCoin {
    struct MoonCoin {}
}
```

Код очень прост, так как мы не добавляем в MoonCoin больше функций, чем стандартные, предоставляемые фреймворком Coin (перевод, депозит, вывод, создание, сжигание). Наиболее важной частью является структура MoonCoin, определяющая новый тип монеты, которую можно зарегистрировать с помощью 0x1::Coin.

#### Шаг 1.3) Развертывание модуля Move, содержащего тип MoonCoin <a href="#step-13-deploying-the-move-module-containing-mooncoin-type" id="step-13-deploying-the-move-module-containing-mooncoin-type"></a>

{% tabs %}
{% tab title="Python" %}
Для Python3:

* Загрузите [example project](https://github.com/aptos-labs/aptos-core/tree/main/developer-docs-site/static/examples/python)
* Откройте свой любимый терминал и перейдите туда, куда вы загрузили приведенный выше пример проекта.
* Установите необходимые библиотеки: `pip3 install -r requirements.txt`.
* Выполните пример: `python3 first_coin.py MoonCoin.mv`
  {% endtab %}

{% tab title="Rust" %}
Для Rust:

* Загрузите [example project](https://github.com/aptos-labs/aptos-core/tree/main/developer-docs-site/static/examples/rust)
* Откройте свой любимый терминал и перейдите туда, куда вы загрузили приведенный выше пример проекта.
* Выполните пример: `cargo run --bin first_coin -- MoonCoin.mv`
  {% endtab %}

{% tab title="Typescript" %}
Для Typescript:

* Загрузите [example project](https://github.com/aptos-labs/aptos-core/tree/main/developer-docs-site/static/examples/typescript)
* Откройте свой любимый терминал и перейдите туда, куда вы загрузили приведенный выше пример проекта.
* Установите необходимые библиотеки: `yarn install`
* Выполните пример: `yarn first_coin MoonCoin.mv`
  {% endtab %}
  {% endtabs %}

#### Шаг 1.4) Проверка результата выполнения <a href="#step-14-verify-output" id="step-14-verify-output"></a>

* Через несколько секунд вы увидите сообщение «Обновите модуль с адресом Алисы, создайте, скопируйте указанный путь и нажмите enter».
* В терминале «Move Window» и для файла Move, который мы ранее рассматривали:
  * Скопируйте адрес Алисы
  * Скомпилируйте модули с адресом Алисы с помощью `aptos move compile --package-dir . --named-addresses MoonCoinType=0x{alice_address_here}`. Здесь мы заменяем общий адрес `MoonCoinType='_'` в `moon_coin/move.toml` на адрес Алисы
  * Скопируйте `build/Examples/bytecode_modules/MoonCoin.mv` в ту же папку, что и код этого руководства
* Вернитесь в другое окно терминала и нажмите "enter" в командной строке, чтобы продолжить выполнение остальной части кода

Результат должен выглядеть следующим образом:

```
=== Addresses ===
Alice: 11c32982d04fbcc79b694647edff88c5b5d5b1a99c9d2854039175facbeefb40
Bob: 7ec8f962139943bc41c17a72e782b7729b1625cf65ed7812152a5677364a4f88

Update the module with Alice's address, build, copy to the provided path, and press enter.
```

### Шаг 2) Инициализируйте MoonCoin <a href="#step-2-initialize-mooncoin" id="step-2-initialize-mooncoin"></a>

Модуль MoonCoin уже развернут. Следующим шагом будет инициализация MoonCoin. В этом примере мы будем использовать 0x1::ManagedCoin::initialize, так как нам нужна возможность создавать/сжигать наш новый MoonCoin. Это добавит в MoonCoin стандартные функции, такие как перевод, создание, сжигание и стандартные события (регистрация, депозит, вывод).

{% tabs %}
{% tab title="Python" %}

```
    def initialize_coin(self, account_from: Account) -> Optional[str]:
        """ Initialize a new coin with the given coin type. """
        payload = {
            "type": "script_function_payload",
            "function": "0x1::ManagedCoin::initialize",
            "type_arguments": [f"0x{account_from.address()}::MoonCoin::MoonCoin"],
            "arguments": [
                "Moon Coin".encode("utf-8").hex(),
                "MOON".encode("utf-8").hex(),
                "6",
                False
            ]
        }
        res = self.execute_transaction_with_payload(account_from, payload)
        return str(res["hash"])
```

{% endtab %}

{% tab title="Rust" %}

```
    /// Initializes the new coin.
    pub fn initialize_coin(&self, account_from: &mut Account) -> String {
        let payload = serde_json::json!({
            "type": "script_function_payload",
            "function": "0x1::ManagedCoin::initialize",
            "type_arguments": [format!("0x{}::MoonCoin::MoonCoin", account_from.address())],
            "arguments": [
                hex::encode("Moon Coin".as_bytes()),
                hex::encode("MOON".as_bytes()),
                "6",
                false,
            ]
        });
        self.rest_client.execution_transaction_with_payload(account_from, payload)
    }
    
```

{% endtab %}

{% tab title="Typescript" %}

```
  /** Initializes the new coin */
  async initializeCoin(accountFrom: Account, coinTypeAddress: string): Promise<string> {
    let payload: { function: string; arguments: any[]; type: string; type_arguments: any[] } = {
      type: "script_function_payload",
      function: `0x1::ManagedCoin::initialize`,
      type_arguments: [`0x${coinTypeAddress}::MoonCoin::MoonCoin`],
      arguments: [
        Buffer.from("Moon Coin", "utf-8").toString("hex"),
        Buffer.from("MOON", "utf-8").toString("hex"),
        "6",
        false,
      ],
    };
    return await this.executeTransactionWithPayload(accountFrom, payload);
  }
  
```

{% endtab %}
{% endtabs %}

### Шаг 3) Зарегистрируйте учетную запись получателя для получения MoonCoin <a href="#step-3-register-a-recipient-account-to-receive-mooncoin" id="step-3-register-a-recipient-account-to-receive-mooncoin"></a>

В других сетях, поскольку токены/монеты — это просто номера баланса в контракте, любой может «отправить» кому угодно случайную монету, даже если получатель этого не хочет. В Aptos пользователь должен зарегистрироваться для получения `Coin<RandomCoin>` , прежде чем ее можно будет ему отправить.

Чтобы зарегистрироваться, получателю достаточно запустить `0x1::Coin::register<CoinType>`:

{% tabs %}
{% tab title="Python" %}

```
    def register_coin(self, account_receiver: Account, coin_type_address: str) -> str:
        """ Register the receiver account to receive transfers for the new coin. """

        payload = {
            "type": "script_function_payload",
            "function": "0x1::Coin::register",
            "type_arguments": [f"0x{coin_type_address}::MoonCoin::MoonCoin"],
            "arguments": []
        }
        res = self.execute_transaction_with_payload(account_receiver, payload)
        return str(res["hash"])
```

{% endtab %}

{% tab title="Rust" %}

```
    /// Receiver needs to register the coin before they can receive it.
    pub fn register_coin(
        &self,
        account_receiver: &mut Account,
        coin_type_address: &str,
    ) -> String {
        let payload = serde_json::json!({
            "type": "script_function_payload",
            "function": "0x1::Coin::register",
            "type_arguments": [format!("0x{}::MoonCoin::MoonCoin", coin_type_address)],
            "arguments": []
        });
        self.rest_client.execution_transaction_with_payload(account_receiver, payload)
    }
    
```

{% endtab %}

{% tab title="Typescript" %}

```
  /** Receiver needs to register the coin before they can receive it */
  async registerCoin(coinReceiver: Account, coinTypeAddress: string): Promise<string> {
    let payload: { function: string; arguments: string[]; type: string; type_arguments: any[] };
    payload = {
      type: "script_function_payload",
      function: `0x1::Coin::register`,
      type_arguments: [`0x${coinTypeAddress}::MoonCoin::MoonCoin`],
      arguments: [],
    };
    return await this.executeTransactionWithPayload(coinReceiver, payload);
  }
  
```

{% endtab %}
{% endtabs %}

### Шаг 4) Отправьте MoonCoin получателю как владельцу MoonCoin <a href="#step-4-mint-mooncoin-to-the-recipient-as-the-owner-of-the-mooncoin" id="step-4-mint-mooncoin-to-the-recipient-as-the-owner-of-the-mooncoin"></a>

При инициализации новой монеты (Шаг 2) учетная запись владельца получает возможность создавать/сжигать новую монету. Учетная запись владельца может создать MoonCoin, активировав 0x1::ManagedCoin::mint.

{% tabs %}
{% tab title="Python" %}

```
    def mint_coin(
        self,
        account_coin_owner: Account,
        receiver_address: str,
        amount: int
    ) -> str:
        """ Register the receiver account to receive transfers for the new coin. """

        payload = {
            "type": "script_function_payload",
            "function": "0x1::ManagedCoin::mint",
            "type_arguments": [f"0x{account_coin_owner.address()}::MoonCoin::MoonCoin"],
            "arguments": [
                receiver_address,
                f"{amount}"
            ]
        }
        res = self.execute_transaction_with_payload(account_coin_owner, payload)
        return str(res["hash"])
```

{% endtab %}

{% tab title="Rust" %}

```
    /// Receiver needs to register the coin before they can receive it.
    pub fn mint_coin(
        &self,
        account_owner: &mut Account,
        receiver_address: &str,
        amount: u64,
    ) -> String {
        let payload = serde_json::json!({
            "type": "script_function_payload",
            "function": "0x1::ManagedCoin::mint",
            "type_arguments": [format!("0x{}::MoonCoin::MoonCoin", account_owner.address())],
            "arguments": [
                receiver_address,
                amount.to_string(),
            ]
        });
        self.rest_client.execution_transaction_with_payload(account_owner, payload)
    }
    
```

{% endtab %}

{% tab title="Typescript" %}

```
  /** Mints the newly created coin to a specified receiver address */
  async mintCoin(
    coinOwner: Account,
    coinTypeAddress: string,
    receiverAddress: string,
    amount: number,
  ): Promise<string> {
    let payload: { function: string; arguments: string[]; type: string; type_arguments: any[] };
    payload = {
      type: "script_function_payload",
      function: `0x1::ManagedCoin::mint`,
      type_arguments: [`0x${coinTypeAddress}::MoonCoin::MoonCoin`],
      arguments: [receiverAddress, amount.toString()],
    };
    return await this.executeTransactionWithPayload(coinOwner, payload);
  }
  
```

{% endtab %}
{% endtabs %}

### Шаг 5) Проверьте баланс MoonCoin Боба <a href="#step-5-check-bobs-balance-of-mooncoin" id="step-5-check-bobs-balance-of-mooncoin"></a>

{% tabs %}
{% tab title="Python" %}

```
    def get_balance(
        self,
        account_address: str,
        coin_type_address: str,
    ) -> str:
        """ Returns the coin balance of the given account """

        return self.account_resource(account_address, f"0x1::Coin::CoinStore<0x{coin_type_address}::MoonCoin::MoonCoin>")
```

{% endtab %}

{% tab title=" Rust" %}

```
    /// Receiver needs to register the coin before they can receive it.
    pub fn get_balance(
        &self,
        account_address: &str,
        coin_type_address: &str,
    ) -> u64 {
        let module_type = format!(
            "0x1::Coin::CoinStore<0x{}::MoonCoin::MoonCoin>",
            coin_type_address,
        );
        self.rest_client
            .account_resource(account_address, &module_type)
            .map(|value| value["data"]["coin"]["value"].as_str().unwrap().to_string().parse::<u64>().unwrap())
            .unwrap()
    }
    
```

{% endtab %}

{% tab title="Typescript" %}

```
  /** Return the balance of the newly created coin */
  async getBalance(accountAddress: string, coinTypeAddress: string): Promise<string> {
    const resource = await this.accountResource(
      accountAddress,
      `0x1::Coin::CoinStore<0x${coinTypeAddress}::MoonCoin::MoonCoin>`,
    );
    if (resource == null) {
      return null;
    } else {
      return resource["data"]["coin"]["value"];
    }
  }
  
```

{% endtab %}
{% endtabs %}

Данные можно проверить, посетив либо интерфейс REST, либо explorer:

* Учетная запись Алисы через [REST interface](https://fullnode.devnet.aptoslabs.com/accounts/a52671f10dc3479b09d0a11ce47694c0/)
* Учетная запись Боба через [explorer](https://explorer.devnet.aptos.dev/account/ec6ec14e4abe10aaa6ad53b0b63a1806)
