Chapter 2 - Create your tribe

In this chapter we will make it possible for others to join our DAO. For that, we will implement CRUD (Create, Read, Update, Delete) functionalities inside our canister.
Introduction
The key element of any DAO is its community. This community unites over shared interests, objectives, and often a vision for the future. Typically, in a DAO, members are active participants: they engage in decision-making, contribute to the DAO, and can even receive compensation for their contributions.
Today, we won't focus on building the community itself (this could take months). Instead, we'll concentrate on the technical side, setting up a system to enroll members into our application and keep track of some basic information about them.
Resources
To complete this Chapter, we suggest browsing the following resources:
- Lesson 6 - Data structures
- Lesson 7 - Non primitive types
- Lesson 8 - Advanced types
- Lesson 9 - Handling errors
- HashMap module
- Result module
- Iter module
Tasks
To complete this project - you need to make use of the
HashMap
andResult
library in Motoko. Make sure that you've read the corresponding chapter.
To help you get started, we've defined different types in main.mo:
- A new type
Member
to represent the members of your DAO.
type Member = {
name: Text;
age : Nat;
};
- A new type
Result
that we've imported from the Result library. This type will be used to return potential errors from your functions.
type Result<A,B> = Result.Result<A,B>;
- A type
HashMap
that we've imported from the HashMap library. This type will be used to store the members of your DAO.
type HashMap<K,V> = HashMap.HashMap<K,V>;
-
Define an immutable variable members of type
Hashmap<Principal,Member>
that will be used to store the members of your DAO.You might be wondering why we're using an immutable variable in this context, especially when we plan to add members to the data structure. The reason for this choice is that we are using a HashMap, and our intention is not to change the reference to the HashMap itself, but rather to modify the content within the HashMap.
-
Implement the
addMember
function, this function takes amember
of typeMember
as a parameter, adds a new member to themembers
HashMap. The function should check if the caller is already a member. If that's the case use aResult
type to return an error message. -
Implement the
getMember
query function, this function takes aprincipal
of typePrincipal
as a parameter and returns the corresponding member. You will use aResult
type for your return value. -
Implement the
updateMember
function, this function takes amember
of typeMember
as a parameter and updates the corresponding member associated with the caller. If the member doesn't exist, return an error message. You will use aResult
type for your return value. -
Implement the
getAllMembers
query function, this function takes no parameters and returns all the members of your DAO as an array of type[Member]
. -
Implement the
numberOfMembers
query function, this function takes no parameters and returns the number of members of your DAO as aNat
. -
Implement the
removeMember
function, this function takes no parameter and removes the member associated with the caller. If there is no member associated with the caller, return an error message. You will use aResult
type for your return value. -
Complete Chapter 2 by deploying your canister and submitting your ID on motokobootcamp.com.
To deploy your application run
dfx deploy --playground chapter_2
.
Video
⚠️ Please be aware: the repository displayed in the video may not match the one you're working with, due to recent updates we've made to the repository which have not been reflected in the video. However, the core code should remain similar.