• Discover
  • Partner with us
  • Chapters
  • Blog

Build on Internet Computer with ICP Rust CDK

Course Introduction

Introduction
Overview of the IC ecosystem and core differences
Introduction to the Internet Computer (IC) ecosystem
Overview of the IC architecture and its components
Setting up the development environment for IC

Introduction
Creating Smart Contract
State Management 1
State Management 2
Update and Query Functions
Updating the Candid File
Testing the Contract

Creating Smart Contract for Final Project
Creating Functions 1
Creating Functions 2
Creating Functions 3
Creating Candid File
Testing and Deploying Smart Contract
Overview of the Frontend for Final Project
Explaining Frontend Code

Final Project

Managing Memory and State in the Internet Computer Smart Contract

In the previous lesson, we created a struct for our Exam smart contract and implemented the necessary traits to support serialization and deserialization for stable memory on the Internet Computer. In this lesson, we’ll expand on that by setting up thread-local variables and managing stable memory using RefCell and a memory manager.

Recap: Struct and Traits

Previously, we:

  • Defined the Exam struct with fields: out_of, course_name, and curve.
  • Applied the following macros:
  • #[derive(CandidType, Serialize, Deserialize)] for Candid compatibility.
  • Implemented two traits:
  • Storable: for converting data to and from bytes.
  • BoundedStorable: to set memory size constraints (max_size = 100, is_fixed_size = false).

This setup enables the contract to persist data across deployments using stable memory.

What Are Thread-Local Variables?

In Rust, thread-local variables allow the creation of thread-specific storage. Since the Internet Computer is single-threaded, using thread_local! ensures safe and isolated storage that we can still mutate using RefCell.

Why Use RefCell?

Rust enforces immutability, but with RefCell, we can mutably borrow data even from a shared, seemingly immutable structure—perfect for our use case in canister smart contracts.

Defining the Memory Manager

We define a memory_manager inside a thread_local! block. This manager allows us to simulate multiple memory slots within a single stable memory instance by virtually splitting it into 256 slots.

thread_local! {
    static MEMORY_MANAGER: RefCell<MemoryManager<DefaultMemoryImpl>> = RefCell::new(
        MemoryManager::init(DefaultMemoryImpl::default())
    );
}

Why We Need a Memory Manager

ICP allows only one data storage structure per stable memory. To store multiple structures—like Exam data and participation percentages—we must partition the memory. This is where the memory manager comes into play, managing multiple virtual memory segments from a single physical location.

Creating the Exam Map

Next, we define the Exam Map to store all exam records using StableBTreeMap. This acts like a dictionary with keys and values:

thread_local! {
    static EXAM_MAP: RefCell<StableBTreeMap<u64, Exam, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get_memory_id(0))
        )
    );
}
  • u64 serves as the unique identifier (e.g., 0, 1, 2) for each exam.
  • Exam is the value structure.
  • This setup allows you to store, retrieve, and update exam data reliably across canister upgrades.

Creating the Participation Percentage Map

We define a second map for participation percentages, using the same memory manager but a different virtual memory ID:

thread_local! {
    static PARTICIPATION_PERCENTAGE_MAP: RefCell<StableBTreeMap<u64, u64, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get_memory_id(1))
        )
    );
}

This map links each exam ID (u64) to a participation percentage value (u64), e.g., 65%.

Recap of What We’ve Done

  1. Created the Exam struct with serialization traits.
  2. Defined thread_local! memory storage using RefCell to allow internal mutation.
  3. Initialized a memory manager to simulate multiple memory regions within a single stable memory.
  4. Defined two stable maps:
  • EXAM_MAP for exam records.
  • PARTICIPATION_PERCENTAGE_MAP for attendance metrics.

This setup is reusable and forms the backbone for most ICP-based smart contract projects.

Previous
Next

Lesson discussion

Swap insights and ask questions about “Build on Internet Computer with ICP Rust CDK”.

Enroll to participate
Start the course to unlock the discussion. Enrolling helps us keep conversations relevant to learners.
WebsiteDiscoverPartner with UsBlogEvents
Discover
CoursesCircleRustSoliditySolanaWeb3 FundamentalsBlockchain Basics
CompanyAbout UsBrand GuidelineFAQsTerms of UsePrivacy PolicyGDPR NoticeCookies
Don't miss any update!

Disclaimer: The information, programs, and events provided on https://risein.com is strictly for upskilling and networking purposes related to the technical infrastructure of blockchain platforms. We do not provide financial or investment advice, nor do we make any representations regarding the value, profitability, or future price of any blockchain or cryptocurrency. Users are encouraged to conduct their own research and consult with licensed financial professionals before engaging in any investment activities. https://risein.com disclaims any responsibility for financial decisions made by users based on the information provided here.

© 2026 Rise In, All rights reserved