A Step-by-Step Guide to Writing Your First Move Smart Contract on Aptos

Muhdsodiq Bolarinwa - Jun 7 - - Dev Community

A Step-by-Step Guide to Writing Your First Move Smart Contract on Aptos

Aptos is one of the independent layer 1 laying focus on scalability, security, and reliability among other blockchain. It supports smart contracts which its smart contract is written in move programming. The blockchain network utilizes Proof of Stake as the consensus mechanism We will create a simple smart contract a waste management system for people in a community. Aptos blockchain has maintained high-level security features and reduced transaction costs. We should delve into how to build a smart with move building waste management system.

To delve into move smart contract, you can either use remix or your local code editor such as vs for the sake of this tutorial we will utilize remix

Open your Remix IDE

Move aptos write smart contract

Look at the left corner of your screen you see a plugin icon click

Learn how to deploy smart on APtos move smart contract

A sidebar will pop up find CODE BY WELLDONE STUDIO activates in the code studio

Image description

Select Aptos

You need to install a wallet to interact with your smart contract. Visit this link wallet connect Aptos learning move to download the wallet from chrome extension.

Move

Setup your wallet account to interact with your wallet

Image description

Click Aptos to create a wallet after creating you can visit claim fuacet Aptos to claim testnet or devnet copy your address.
After you finish setting up the account, copy your seed phrase somewhere save.

After successfully claim


Let move to our smart contract using waste manager as an example

In your remix IDE on your left sidebar, create a new create project input the name of your project

waste_manager aptos

Locate your Move.toml
paste this code

[package]
name = "Examples"
version = "0.0.0"

[addresses]
wastes_Insured_addr = "paste your account address"

[dependencies]
AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-framework/", rev = "aptos-node-v1.13.1"}
Enter fullscreen mode Exit fullscreen mode

To get the address generated for this account navigate to .aptos/config.yaml you will find the generated account with the public key and private key

profiles:
  default:
    private_key: "0xee8f387ef0b4bb0018c4b91d1c0f71776a9b85935b4c6ec2823d6c0022fbf5cb"
    public_key: "0xc6c07218d79a806380ca67761905063ec7a78d41f79619f4562462a0f8b6be11"
    account: cbddf398841353776903dbab2fdaefc54f181d07e114ae818b1a67af28d1b018
    rest_url: "https://api.devnet.aptoslabs.com"
    faucet_url: "https://faucet.devnet.aptoslabs.com"

Enter fullscreen mode Exit fullscreen mode

To get started with the smart contract, you need to define a module that is placed under the account address which

module <account-address>::<module-name> {

}
Enter fullscreen mode Exit fullscreen mode

We will define a module, this module will be the container for our entire smart contract

module wastes_Insured_addr::wastes-Insured {

}
Enter fullscreen mode Exit fullscreen mode

We import our library which we are going to use in this smart contract.

Event is for emitting any event that occurred in our smart contract when a function is triggered.
Table: we utilize table to define our table for the smart contract input data
Signer is who is calling the smart contract at a particular time.
An account is associated with our smart contract.

 use aptos_framework::event;

    use std::string::String;
    use aptos_std::table::{Self, Table};
    use aptos_framework::account;
    use std::signer;
Enter fullscreen mode Exit fullscreen mode

We will define a struct that will hold our typed fields, it has the capability to store, drop, and copy.

struct Waste has store, drop, copy, {
        wast_id: u64,
        wasteType:String,
        collectionLocation: String,
        weigth: u64,
        isRecorded: bool,
        isValidated: bool
    }
Enter fullscreen mode Exit fullscreen mode

We will define our WasteList which will take waste array, new events emit when waste is recorded, and counter which will serve as the length of the waste store.

struct WasteList has key {
        waste: Table<u64, Waste>,
        waste_count: u64
    }

Enter fullscreen mode Exit fullscreen mode

We initialized error const, error are represented in number inmove language

const E_NOT_INITIALIZED: u64 = 1;
    const EWASTE_DOESNT_EXIST: u64 = 2;
    const EWASTE_IS_VALIDATED: u64 = 3; 
Enter fullscreen mode Exit fullscreen mode

Next, we create a list function which is the first an account must have, it's essential for submitting transactions which we will associate with a signer

public entry fun create_list(account: &signer) {
        let waste_holder = WasteList {
            waste: table::new(),
            set_waste_event: account::new_event_handle<Waste>(account),
            waste_count: 0
        };
        move_to(account, waste_holder);
    }
Enter fullscreen mode Exit fullscreen mode

We create a waste add function that submits the new waste transaction to the blockchain. We need to know the user submitting the transaction to the chain. it will accept all the fields typed in our struct which looks like this

public entry fun register_waste(account: &signer, wasteType: String, collectionLocation: String,
    weight: u64, wasteAmount: u64, hospitalAddress: address) acquires WasteList {
// we are getting the signer address
        let signer_address = signer::address_of(account);
// we check if the signer has been initialized or not
        assert!(exists<WasteList>(signer_address), E_NOT_INITIALIZED);
//We are getting waste list resources
        let waste_list = borrow_global_mut<WasteList>(signer_address);
// we increament the count of waste recorded
        let counter = waste_list.waste_count + 1;
// record a new waste
        let new_record_waste = Waste {
            wast_id: counter,
            wasteType:String,
        collectionLocation: String,
        weigth: u64,
        isRecorded: bool,
        isValidated: 
        };
// insert new waste recorded in to the waste table
        table::upsert(&mut waste_list.waste, counter, new_record_waste);
// set the waste count 
        waste_list.waste_count = counter;
// emit the waste event
       event::emit(new_record_waste);

    }
Enter fullscreen mode Exit fullscreen mode

We will have to validate waste when collect brings it to the company which each collected will have to be verified.

public entry fun validate_waste(account: &signer, waste_id: u64) acquires WasteList {
// initialized signer_address to get the signer address
        let signer_address = signer::address_of(account);
        assert!(exists<WasteList>(signer_address), E_NOT_INITIALIZED);
// we get the waste resources 
        let waste_list = borrow_global_mut<WasteList>(signer_address);
// we check if waste exist using assert 
        assert!(table::contains(&waste_list.waste, waste_id), EWASTE_DOESNT_EXIST);
        // get the waste that match the waste id 
        let waste_track = table::borrow_mut(&mut waste_list.waste, waste_id);
        // check if the waste is not validated yet 
        assert!(waste_track.isValidated == false, EWASTE_IS_VALIDATED);

        // validate the waste
        waste_track.isValidated = true;
    }
Enter fullscreen mode Exit fullscreen mode

Here is how to get started with Move programming language.

Next, click the compile button which appears inside the sidebar

You should have results similar to this


INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING Examples
{
  "Result": [
    "92c945f0ec6423e8ec1414a597f1d6fbc954c309f5846cbc73a43b62bfc37eba::waste_insure"
  ]
} 


Enter fullscreen mode Exit fullscreen mode

To deploy, hit the deploy button, to deploy.

Coming next how can we pay the waste collector using a
move smart contract?

. . . . . . . .
Terabox Video Player