Smart Contracts

Welcome to the Tutorials section of Real’s documentation! Here, you’ll find practical guides to help you build on the Real blockchain, a decentralized Layer 1 (L1) network built with the Cosmos SDK. This tutorial focuses on writing smart contracts, empowering developers to create decentralized applications (dApps) and tokenized real-world assets (RWAs) on Real.


Writing Smart Contracts on Real

The Real blockchain, as an L1 built with the Cosmos SDK, supports smart contracts through CosmWasm, a secure and efficient framework for writing smart contracts in Rust. This tutorial will guide you through the process of writing, compiling, and deploying a simple smart contract on Real.

Prerequisites

Before you begin, ensure you have the following:

  • Rust: Install Rust and Cargo (Rust’s package manager) by following the official Rust installation guide.

  • CosmWasm Tools: Install the cosmwasm tools for compiling and optimizing smart contracts. Run:

cargo install cosmwasm-check
  • Real Node Setup: Set up a local Real node or connect to the Real Testnet. Follow our Node Setup Guide for instructions.

  • Real CLI: Install the Real CLI (reald) to interact with the blockchain. Download it from our Downloads page.

  • Wallet: Set up a Real wallet with some testnet REAL tokens. Request tokens from the Real Testnet Faucet.

Step 1: Set Up Your Development Environment

  1. Create a New Project: Start by creating a new Rust project for your smart contract.

    cargo new --lib real-first-contract
    cd real-first-contract
  2. Update Cargo.toml:

Add the necessary dependencies for CosmWasm. Edit your Cargo.toml to include:

[package]
name = "real-first-contract"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
cosmwasm-std = "1.5.0"
cosmwasm-schema = "1.5.0"
serde = { version = "1.0", features = ["derive"] }
  1. Initialize Your Contract Structure:

CosmWasm contracts typically have three main entry points: instantiate, execute, and query. Create the basic structure in src/lib.rs.

Step 2: Write a Simple Smart Contract

Let’s write a basic smart contract that stores a counter value and allows users to increment it. This example demonstrates the core concepts of CosmWasm on Real.

Replace the contents of src/lib.rs with the following code:

use cosmwasm_std::{
    entry_point, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult,
};
use cosmwasm_schema::{cw_serde, QueryResponses};

#[cw_serde]
pub struct InstantiateMsg {
    pub count: i32,
}

#[cw_serde]
pub enum ExecuteMsg {
    Increment {},
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
    #[returns(GetCountResponse)]
    GetCount {},
}

#[cw_serde]
pub struct GetCountResponse {
    pub count: i32,
}

// State storage
#[cw_serde]
pub struct State {
    pub count: i32,
}

const CONTRACT_STATE: cosmwasm_std::Item<State> = cosmwasm_std::Item::new("state");

#[entry_point]
pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    msg: InstantiateMsg,
) -> StdResult<Response> {
    let state = State { count: msg.count };
    CONTRACT_STATE.save(deps.storage, &state)?;
    Ok(Response::new().add_attribute("method", "instantiate"))
}

#[entry_point]
pub fn execute(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    msg: ExecuteMsg,
) -> StdResult<Response> {
    match msg {
        ExecuteMsg::Increment {} => {
            let mut state = CONTRACT_STATE.load(deps.storage)?;
            state.count += 1;
            CONTRACT_STATE.save(deps.storage, &state)?;
            Ok(Response::new().add_attribute("method", "increment"))
        }
    }
}

#[entry_point]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
    match msg {
        QueryMsg::GetCount {} => {
            let state = CONTRACT_STATE.load(deps.storage)?;
            to_binary(&GetCountResponse { count: state.count })
        }
    }
}

What This Contract Does:

  • Instantiate: Initializes the contract with a starting count value.

  • Execute: Allows users to increment the counter with the Increment message.

  • Query: Lets users query the current count value with the GetCount message.

Step 3: Compile and Optimize Your Contract

  1. Compile the Contract:

Build the contract to ensure there are no errors:

cargo build --release --target wasm32-unknown-unknown
  1. Optimize the Wasm File:

Use the CosmWasm optimizer to reduce the contract size for deployment:

cosmwasm-check target/wasm32-unknown-unknown/release/real_first_contract.wasm

If successful, the optimized .wasm file will be ready in the target directory.

Step 4: Deploy the Smart Contract on Real

  1. Store the Contract Code:

Use the Real CLI to upload the compiled contract to the blockchain. Replace <YOUR_WALLET>with your wallet name:

reald tx wasm store target/wasm32-unknown-unknown/release/real_first_contract.wasm --from <YOUR_WALLET> --chain-id real-testnet-1 --gas auto --fees 5000ureal

Note the code_id returned by this command (e.g., 1).

  1. Instantiate the Contract:

Deploy an instance of the contract with an initial count of 0:

reald tx wasm instantiate 1 '{"count": 0}' --from <YOUR_WALLET> --chain-id real-testnet-1 --label "Real First Contract" --gas auto --fees 5000ureal

Note the contract_address returned (e.g., real1...).

Interact with the Contract:

  • Increment the Counter:

    reald tx wasm execute <CONTRACT_ADDRESS> '{"increment": {}}' --from <YOUR_WALLET> --chain-id real-testnet-1 --gas auto --fees 5000ureal
  • Query the Counter:

    reald query wasm contract-state smart <CONTRACT_ADDRESS> '{"get_count": {}}' --chain-id real-testnet-1

    This should return the current count (e.g., {"count": 1} after one increment).

Step 5: Test and Debug

  • Run Unit Tests: Add unit tests in src/lib.rs to verify your contract’s functionality. Use the cosmwasm_std::testing module for mock dependencies.

  • Check Logs: Use the Real Block Explorer explorer.realfin.io to view transaction logs and ensure your contract behaves as expected.

  • Iterate: Debug any issues by checking error messages in the CLI output or explorer.

Next Steps

  • Explore Advanced Features: Learn how to integrate RWA tokenization logic into your smart contracts with our Tokenization Guide.

  • Use Real’s SDK: Leverage the Cosmos SDK’s modules (e.g., x/bank, x/staking) to add more functionality to your dApps. See our SDK Documentation.

  • Join the Community: Share your contract and get feedback on our X Channel (Twitter) or Telegram.

Additional Resources


Need Help?

If you have questions or need assistance, reach out to our team:

Happy coding on Real – let’s build the future of decentralized finance together!

Last updated