# Your First Coin

This tutorial introduces how you can compile, deploy, and mint your own coin, named MoonCoin.

### Step 1: Pick an SDK[​](https://aptos.dev/tutorials/your-first-coin#step-1-pick-an-sdk) <a href="#step-1-pick-an-sdk" id="step-1-pick-an-sdk"></a>

Install your preferred SDK from the below list:

* [TypeScript SDK](https://aptos.dev/sdks/ts-sdk/index)
* [Python SDK](https://aptos.dev/sdks/python-sdk)
* [Rust SDK](https://aptos.dev/sdks/rust-sdk)

***

### Step 2: Install the CLI[​](https://aptos.dev/tutorials/your-first-coin#step-2-install-the-cli) <a href="#step-2-install-the-cli" id="step-2-install-the-cli"></a>

[Install the precompiled binary for the Aptos CLI](https://aptos.dev/cli-tools/aptos-cli-tool/install-aptos-cli).

***

### Step 3: Run the example[​](https://aptos.dev/tutorials/your-first-coin#step-3-run-the-example) <a href="#step-3-run-the-example" id="step-3-run-the-example"></a>

Clone the `aptos-core` repo:

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

* Typescript
* Python
* Rust

Navigate to the TypeScript SDK directory:

```
cd ~/aptos-core/ecosystem/typescript/sdk
```

Install the necessary dependencies:

```
yarn
```

Run the TypeScript [`your_coin`](https://github.com/aptos-labs/aptos-core/blob/main/ecosystem/typescript/sdk/examples/typescript/your_coin.ts) example:

```
yarn your_coin ~/aptos-core/aptos-move/move-examples/moon_coin
```

***

#### Step 3.1: Build the package[​](https://aptos.dev/tutorials/your-first-coin#step-31-build-the-package) <a href="#step-31-build-the-package" id="step-31-build-the-package"></a>

The example run will pause with the following output:

```
=== Addresses ===Alice: 0x5e603a89cf690d7134cf2f24fdb16ba90c4f5686333721c12e835fb6c76bc7baBob: 0xc8421fa4a99153f955e50f1de2a6acff2f3fd0bb33aa17ba1f5b32b699f6c825Update the package with Alice's address, compile, and press enter.
```

At this point, open another terminal and change directories to the MoonCoin package's directory:

```
cd ~/aptos-core/aptos-move/move-examples/moon_coin
```

Next, build the package using the CLI:

```
aptos move compile --named-addresses MoonCoin=0x5e603a89cf690d7134cf2f24fdb16ba90c4f5686333721c12e835fb6c76bc7ba --save-metadata
```

The `--named-addresses` is a list of address mappings that must be translated in order for the package to be compiled to be stored in Alice's account. Notice how `MoonCoin` is set to Alice's address printed above. Also `--save-metadata` is required to publish the package.

***

#### Step 3.2: Completing the example[​](https://aptos.dev/tutorials/your-first-coin#step-32-completing-the-example) <a href="#step-32-completing-the-example" id="step-32-completing-the-example"></a>

Returning to the previous prompt, press ENTER as the package is now ready to be published.

The application will complete, printing:

```
Publishing MoonCoin package.Bob registers the newly created coin so he can receive it from Alice.Bob's initial MoonCoin balance: 0.Alice mints Bob some of the new coin.Bob's updated MoonCoin balance: 100.
```

***

### Step 4: MoonCoin in depth[​](https://aptos.dev/tutorials/your-first-coin#step-4-mooncoin-in-depth) <a href="#step-4-mooncoin-in-depth" id="step-4-mooncoin-in-depth"></a>

#### Step 4.1: Building and publishing the MoonCoin package[​](https://aptos.dev/tutorials/your-first-coin#step-41-building-and-publishing-the-mooncoin-package) <a href="#step-41-building-and-publishing-the-mooncoin-package" id="step-41-building-and-publishing-the-mooncoin-package"></a>

Move contracts are effectively a set of Move modules known as a package. When deploying or upgrading a new package, the compiler must be invoked with `--save-metadata` to publish the package. In the case of MoonCoin, the following output files are critical:

* `build/Examples/package-metadata.bcs`: Contains the metadata associated with the package.
* `build/Examples/bytecode_modules/moon_coin.mv`: Contains the bytecode for the `moon_coin.move` module.

These are read by the example and published to the Aptos blockchain:

* Typescript
* Python
* Rust

```
const modulePath = process.argv[2];const packageMetadata = fs.readFileSync(path.join(modulePath, "build", "Examples", "package-metadata.bcs"));const moduleData = fs.readFileSync(path.join(modulePath, "build", "Examples", "bytecode_modules", "moon_coin.mv"));console.log("Publishing MoonCoin package.");let txnHash = await client.publishPackage(alice, new HexString(packageMetadata.toString("hex")).toUint8Array(), [  new TxnBuilderTypes.Module(new HexString(moduleData.toString("hex")).toUint8Array()),]);await client.waitForTransaction(txnHash, { checkSuccess: true }); 
```

***

#### Step 4.2: Understanding the MoonCoin module[​](https://aptos.dev/tutorials/your-first-coin#step-42-understanding-the-mooncoin-module) <a href="#step-42-understanding-the-mooncoin-module" id="step-42-understanding-the-mooncoin-module"></a>

The MoonCoin module defines the `MoonCoin` struct, or the distinct type of coin type. In addition, it contains a function called `init_module`. The `init_module` function is called when the module is published. In this case, MoonCoin initializes the `MoonCoin` coin type as a `ManagedCoin`, which is maintained by the owner of the account.

MANAGEDCOIN FRAMEWORK

[`ManagedCoin`](https://github.com/aptos-labs/aptos-core/blob/f81ccb01f00227f9c0f36856fead4879f185a9f6/aptos-move/framework/aptos-framework/sources/managed_coin.move#L1) is a simple coin management framework for coins directly managed by users. It provides convenience wrappers around `mint` and `burn`.

```
module MoonCoin::moon_coin {    struct MoonCoin {}    fun init_module(sender: &signer) {        aptos_framework::managed_coin::initialize<MoonCoin>(            sender,            b"Moon Coin",            b"MOON",            6,            false,        );    }}
```

***

#### Step 4.3: Understanding coins[​](https://aptos.dev/tutorials/your-first-coin#step-43-understanding-coins) <a href="#step-43-understanding-coins" id="step-43-understanding-coins"></a>

Coins have several primitives:

* **Minting**: Creating new coins.
* **Burning**: Deleting coins.
* **Freezing**: Preventing an account from storing coins in `CoinStore`.
* **Registering**: Creating a `CoinStore` resource on an account for storing coins.
* **Transferring**: Withdrawing and depositing coins into `CoinStore`.

TIP

The entity that creates a new coin gains the capabilities for minting, burning, and freezing.

In order to transfer, withdraw, or deposit coins, you must have a `CoinStore` registered for the specific coin. In this tutorial, this is `CoinStore<MoonCoin>`.

***

**Step 4.3.1: Initializing a coin**[**​**](https://aptos.dev/tutorials/your-first-coin#step-431-initializing-a-coin)

Once a coin type has been published to the Aptos blockchain, the entity that published that coin type can initialize it:

```
public fun initialize<CoinType>(    account: &signer,    name: string::String,    symbol: string::String,    decimals: u8,    monitor_supply: bool,): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) {    let account_addr = signer::address_of(account);    assert!(        coin_address<CoinType>() == account_addr,        error::invalid_argument(ECOIN_INFO_ADDRESS_MISMATCH),    );    assert!(        !exists<CoinInfo<CoinType>>(account_addr),        error::already_exists(ECOIN_INFO_ALREADY_PUBLISHED),    );    let coin_info = CoinInfo<CoinType> {        name,        symbol,        decimals,        supply: if (monitor_supply) { option::some(optional_aggregator::new(MAX_U128, false)) } else { option::none() },    };    move_to(account, coin_info);    (BurnCapability<CoinType>{ }, FreezeCapability<CoinType>{ }, MintCapability<CoinType>{ })}
```

This ensures that this coin type has never been initialized before. Notice the check on lines 10 and 15 to ensure that the caller to `initialize` is the same one that actually published this module, and that there is no `CoinInfo` stored on their account. If both those conditions check, then a `CoinInfo` is stored and the caller obtains capabilities for burning, freezing, and minting.

TIP

MoonCoin calls this `initialize` function automatically upon package publishing.

***

**Step 4.3.2: Registering a coin**[**​**](https://aptos.dev/tutorials/your-first-coin#step-432-registering-a-coin)

To use a coin, an entity must register a `CoinStore` for it on their account:

```
public fun register<CoinType>(account: &signer) {    let account_addr = signer::address_of(account);    assert!(        !is_account_registered<CoinType>(account_addr),        error::already_exists(ECOIN_STORE_ALREADY_PUBLISHED),    );    account::register_coin<CoinType>(account_addr);    let coin_store = CoinStore<CoinType> {        coin: Coin { value: 0 },        frozen: false,        deposit_events: account::new_event_handle<DepositEvent>(account),        withdraw_events: account::new_event_handle<WithdrawEvent>(account),    };    move_to(account, coin_store);}
```

As this is a `public fun` and not a `public entry fun`, coins will need to provide their own means for registering or users can construct Move `scripts` to call the function.

MoonCoin uses `ManagedCoin` that provides an entry function wrapper: `managed_coin::register`.

***

**Step 4.3.3: Minting a coin**[**​**](https://aptos.dev/tutorials/your-first-coin#step-433-minting-a-coin)

Minting coins requires the mint capability that was produced during initialization. the function `mint` (see below) takes in that capability and an amount, and returns back a `Coin<T>` struct containing that amount of coins. If the coin tracks supply, it will be updated.

```
public fun mint<CoinType>(    amount: u64,    _cap: &MintCapability<CoinType>,): Coin<CoinType> acquires CoinInfo {    if (amount == 0) {        return zero<CoinType>()    };    let maybe_supply = &mut borrow_global_mut<CoinInfo<CoinType>>(coin_address<CoinType>()).supply;    if (option::is_some(maybe_supply)) {        let supply = option::borrow_mut(maybe_supply);        optional_aggregator::add(supply, (amount as u128));    };    Coin<CoinType> { value: amount }}
```

`ManagedCoin` makes this easier by providing a entry function `managed_coin::mint`.

***

**Step 4.3.4: Transferring a coin**[**​**](https://aptos.dev/tutorials/your-first-coin#step-434-transferring-a-coin)

Aptos provides several building blocks to support coin transfers:

* `coin::deposit<CoinType>`: Allows any entity to deposit a coin into an account that has already called `coin::register<CoinType>`.
* `coin::withdraw<CoinType>`: Allows any entity to extract a coin amount from their account.
* `coin::transfer<CoinType>`: Leverages withdraw and deposit to perform an end-to-end transfer.

IMPORTANT

Aptos does not emit transfer events, but instead it leverages withdraw and deposit events.

* [Aptos CLI](https://aptos.dev/cli-tools/aptos-cli-tool/use-aptos-cli)
* [TypeScript SDK](https://aptos.dev/sdks/ts-sdk/index)
* [Python SDK](https://aptos.dev/sdks/python-sdk)
* [Rust SDK](https://aptos.dev/sdks/rust-sdk)
* [REST API specification](https://fullnode.devnet.aptoslabs.com/v1/spec#/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jin-network.gitbook.io/jin-network/developer-tutorials/your-first-coin.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
