Title: How to Write and Deploy Your First Aptos Smart Contract Introduction In this hands-on tutorial, you'll build and deploy a minimal “Hello, Aptos!” smart contract on the Aptos blockchain using the Move language and the Aptos CLI. By the end, you'll have: • Written a Move module that stores a greeting on-chain • Compiled and published your module to Aptos DevNet • Invoked your contract to initialize and update the greeting • Retrieved on-chain data to verify your changes Let’s dive in. Prerequisites Before you begin, make sure you have: 1. Node.js (v16+) installed 2. Rust & Move installed (via Aptos CLI) 3. Aptos CLI (v0.5+) installed and in your PATH (see Source: first-move-module.mdx) 4. A funded DevNet account (we'll use the CLI faucet) 5. Git (optional, for cloning templates) 6. A terminal/command prompt Step-by-Step Guide Step 1: Configure Your Aptos CLI & Account First, verify your CLI installation: ```bash aptos --version ``` Initialize your local Aptos configuration and create a new account: ```bash aptos init --profile default ``` This command prompts you for a profile name (we'll use default) and generates a key pair plus a local config file (~/.aptos/config.yaml). Next, fund your account on DevNet: ```bash aptos account fund-with-faucet --profile default --amount 1 ``` This gives you 1 APT to pay for gas when publishing and transacting (Source: first-move-module.mdx). Step 2: Create and Initialize a Move Package Create a new directory for your contract and initialize a Move package: ```bash mkdir hello_world cd hello_world aptos move init --name hello_world ``` This generates: • Move.toml — your package manifest • A `sources/` folder for your modules • A `Move.toml` pointing at `sources/` by default (Source: smart-contracts.mdx) Step 3: Write Your Move Module Open `sources/hello_world.move` and replace its contents with the following: ```move address 0x1 { module hello_world { use std::signer; use std::vector; /// A resource that holds our on-chain greeting. resource struct Greeting { value: vector<u8> } /// Entry function to store a default greeting. public entry fun init(account: &signer) { // Move the Greeting resource under the caller’s address. move_to<Greeting>(account, Greeting { value: b"Hello, Aptos!" }); } /// Entry function to update the existing greeting. public entry fun update(account: &signer, new_value: vector<u8>) { let addr = signer::address_of(account); // Borrow the resource and mutate its `value` field. let greeting_ref = borrow_global_mut<Greeting>(addr); greeting_ref.value = new_value; } } } ``` Key points: - We declare a Greeting resource that wraps a `vector<u8>` (bytes) for text. - `init` publishes the Greeting under the signer’s address. - `update` mutates the stored resource. (Source: first-move-module.mdx) Step 4: Compile Your Module From the `hello_world` root directory, run: ```bash aptos move compile --package-dir . ``` If all goes well, you should see “Build finished with no errors.” This ensures your Move code is syntactically valid and type-safe. Step 5: Publish (Deploy) to DevNet Deploy your module to the chain: ```bash aptos move publish --package-dir . --profile default ``` You’ll see a transaction hash and confirmation once your module is live at your account address. Note the “Sender” address; that’s where our module now resides. Step 6: Initialize Your Greeting On-Chain Invoke your `init` entry function to create the resource: ```bash # Replace 0x1 with your sender address if you used a different one. MODULE_ADDR=$(aptos account list --profile default | grep Address | awk '{print $2}') aptos move run \ --function-id "${MODULE_ADDR}::hello_world::init" \ --profile default ``` This transaction stores the `Greeting` resource on-chain under your address. Step 7: Read Your On-Chain Greeting Use the CLI to fetch your resource and view the stored bytes: ```bash aptos account resource \ --account $MODULE_ADDR \ --resource-type "${MODULE_ADDR}::hello_world::Greeting" \ --profile default ``` You’ll see something like: ```json { "parsed": { "value": [72,101,108,108,111,44,32,65,112,116,111,115,33] }, ... } ``` Those numbers are ASCII codes for “Hello, Aptos!”. Step 8: Update Your Greeting Let’s change the greeting to “Aptos FTW!”. Note we need to pass the new string as a `vector<u8>` literal by encoding to hex or bytes. For simplicity, we’ll pass ASCII codes directly: ```bash aptos move run \ --function-id "${MODULE_ADDR}::hello_world::update" \ --args 65 112 116 111 115 32 70 84 87 33 \ --profile default ``` This updates the `Greeting` resource. Step 9: Verify the Updated Greeting Fetch the resource again: ```bash aptos account resource \ --account $MODULE_ADDR \ --resource-type "${MODULE_ADDR}::hello_world::Greeting" \ --profile default ``` Now you’ll see the ASCII codes for “Aptos FTW!”. The Full Code Below is the complete, copy-pasteable Move module for your `sources/hello_world.move`. Make sure your `Move.toml` name matches `hello_world`. ```move address 0x1 { module hello_world { use std::signer; use std::vector; /// A resource that holds our on-chain greeting. resource struct Greeting { value: vector<u8> } /// Entry function to store a default greeting. public entry fun init(account: &signer) { move_to<Greeting>(account, Greeting { value: b"Hello, Aptos!" }); } /// Entry function to update the existing greeting. public entry fun update(account: &signer, new_value: vector<u8>) { let addr = signer::address_of(account); let greeting_ref = borrow_global_mut<Greeting>(addr); greeting_ref.value = new_value; } } } ``` Move.toml (auto-generated by `aptos move init`): ```toml [package] name = "hello_world" version = "0.0.1" authors = ["Your Name <you@example.com>"] edition = "2022" [addresses] # Replace 0x1 with your actual deployer address after publishing. hello_world = "0x1" [dependencies] ``` Conclusion Congratulations! You’ve: • Written a Move module that manages on-chain data • Compiled and published it to Aptos DevNet • Interacted via CLI to initialize, update, and read the resource Next Steps • Integrate this module into a frontend using the Aptos TypeScript SDK (see multi-agent and sponsoring docs in the TS SDK guides) • Dive deeper into Move with the Move Book or Aptos Move examples (Source: smart-contracts.mdx) • Explore advanced patterns: capabilities, coin standards, and multi-signer transactions Head over to the Aptos Discord to show off your first smart contract and keep building!