Interacting with Celo's Stablecoin, Celo Dollars, using Python

Interacting with Celo's Stablecoin, Celo Dollars, using Python
none 0.0 0


With Celo, anyone with a mobile phone would have access to financial tools. It is a mobile-first, open-source blockchain platform. One of Celo’s distinguishing qualities is its stablecoin, Celo Dollars (cUSD). A digital asset called cUSD is linked to the US Dollar, ensuring price stability and lowering the likelihood of volatility. In this tutorial, we’ll demonstrate how to use Python and the framework to communicate with the Celo blockchain and Celo Dollars.


In order to fully understand this tutorial, you should have:

  • Fundamental knowledge of blockchain technology and smart contracts.
  • knowledge in Python programming.
  • Although not necessary, understanding the Celo environment is helpful.


You’ll need the following before you can begin this tutorial:

  • Python 3.6 and above.
  • Installed library for
  • A Testnet wallet for the cryptocurrency Celo (you can get them from the Celo Faucet).

Step 1: Setting up the environment

Setting up a development environment is necessary before we can start interacting with the Celo tokens using in Python.

On your terminal, use the following commands to create a new folder for your project:

mkdir celo-interaction-pythoncd celo-interaction-python

In your new directory, create a Python virtual environment and activate it with the following commands:

python3 -m venv envsource env/bin/activate

Next, Install the following libraries using pip, the Python package manager:

pip install web3 python-dotenv

Next, let’s import the installed libraries, and connect to the Celo Testnet network. Create a file called “” in the root directory of your project and paste the following code:

import os from web3 import Web3from dotenv import load_dotenvload_dotenv()# Celo network parametersCELO_ALFAJORES_RPC_URL = ""# Connect to the Celo Alfajores testnetw3 = Web3(Web3.HTTPProvider(CELO_ALFAJORES_RPC_URL))# Load private key and initialize accountprivate_key = os.environ.get("CELO_DEPLOYER_PRIVATE_KEY")deployer = w3.eth.account.from_key(private_key)ERC20_ABI = [    {        "constant": True,        "inputs": [],        "name": "totalSupply",        "outputs": [{"name": "", "type": "uint256"}],        "payable": False,        "stateMutability": "view",        "type": "function"    },    {        "constant": True,        "inputs": [{"name": "owner", "type": "address"}],        "name": "balanceOf",        "outputs": [{"name": "", "type": "uint256"}],        "payable": False,        "stateMutability": "view",        "type": "function"    },    {        "constant": False,        "inputs": [            {"name": "to", "type": "address"},            {"name": "value", "type": "uint256"}        ],        "name": "transfer",        "outputs": [{"name": "", "type": "bool"}],        "payable": False,        "stateMutability": "nonpayable",        "type": "function"    },    {        "constant": True,        "inputs": [            {"name": "owner", "type": "address"},            {"name": "spender", "type": "address"}        ],        "name": "allowance",        "outputs": [{"name": "", "type": "uint256"}],        "payable": False,        "stateMutability": "view",        "type": "function"    },    {        "constant": False,        "inputs": [            {"name": "spender", "type": "address"},            {"name": "value", "type": "uint256"}        ],        "name": "approve",        "outputs": [{"name": "", "type": "bool"}],        "payable": False,        "stateMutability": "nonpayable",        "type": "function"    },    {        "constant": False,        "inputs": [            {"name": "from", "type": "address"},            {"name": "to", "type": "address"},            {"name": "value", "type": "uint256"}        ],        "name": "transferFrom",        "outputs": [{"name": "", "type": "bool"}],        "payable": False,        "stateMutability": "nonpayable",        "type": "function"    }]

Your private key should be substituted for CELO_DEPLOYER_PRIVATE_KEY in the .env file and the deployer object which contains the contract address of a user is gotten from the private key. The ERC20_ABI is the ABI of the Celo network and can be used to interact with it.

Step 2: Checking the cUSD balance

You’ll need the cUSD token contract address to check your balance in cUSD. It’s located here. To achieve the balance, we shall develop a function.

# Get cUSD balancedef get_cusd_balance(account_address, contract_address):    # Get cUSD contract    cusd_contract = w3.eth.contract(address=contract_address, abi=ERC20_ABI)    # Get cUSD balance    balance = cusd_contract.functions.balanceOf(account_address).call()    balance = w3.from_wei(balance, "ether")    return balance

The balance of a Celo Dollar (cUSD) token for a particular account can be obtained using this function. The account address and the cUSD contract address are the two inputs it accepts.

By providing the contract address and its ABI to the w3.eth.contract() function, it first obtains the cUSD contract. Following that, it uses the contract’s balanceOf() function to retrieve the balance while giving the account address.

The sum is then returned after being divided by 1018 and converted from wei (the smallest unit of ether) to cUSD.

Step 3: Sending cUSD

Let’s now write a function to transfer cUSD between accounts:

# Send cUSDdef send_cusd(account, to, amount, contract_address):    # Get cUSD contract    cusd_contract = w3.eth.contract(address=contract_address, abi=ERC20_ABI)    # Estimate gas required    gas_estimate = cusd_contract.functions.transfer(to, w3.to_wei(amount, "ether")).estimate_gas(        {"from": account.address}    )    # Create a transaction    transaction = cusd_contract.functions.transfer(to, w3.to_wei(amount, "ether")).build_transaction(        {            "from": account.address,            "gas": gas_estimate,            "gasPrice": w3.eth.gas_price,            "nonce": w3.eth.get_transaction_count(account.address),        }    )    # Sign and send the transaction    signed_transaction = account.sign_transaction(transaction)    transaction_hash = w3.eth.send_raw_transaction(        signed_transaction.rawTransaction)    return transaction_hash

To send cUSD tokens from one account to another, use this function. It requires four arguments: the cUSD contract address, the amount to transfer, the account sending the tokens, and the account receiving the tokens.

By providing the contract address and its ABI to the w3.eth.contract() function, it first obtains the cUSD contract. It then uses the estimate_gas() function on the transfer() method of the contract to calculate the amount of gas needed for the transaction while passing the to address and the amount of cUSD to send in wei.

The build_transaction() function on the contract’s transfer() method is then used to generate a transaction object, passing the address, the amount of cUSD to send in wei, and other transaction parameters like the gas limit, gas price, and nonce.

The method uses the sign_transaction() function on the account object to sign the transaction after it has been formed. The function then uses the send_raw_transaction() function on the w3.eth object to send the signed transaction to the Celo network. It then gives back the transaction hash.

Essentially, this feature makes it possible to move cUSD tokens easily across accounts on the Celo network.

Step 4**: Test the Functions**

Next, let’s write a script that would call the functions that get a user cUSD balance and send cUSD from one account to another.

# Get CUSD balanceCUSD_ALFAJORES_CONTRACT_ADDRESS = "0x874069Fa1Eb16D44d622F2e0Ca25eeA172369bC1"print(    f"cUSD Balance: {get_cusd_balance(deployer.address, CUSD_ALFAJORES_CONTRACT_ADDRESS)} cUSD")# Send CUSDrecipient_address = "0xcdd1151b2bC256103FA2565475e686346CeFd813"amount_to_send = 1  # cUSDtransaction_hash = send_cusd(    deployer, recipient_address, amount_to_send, CUSD_ALFAJORES_CONTRACT_ADDRESS)print(f"Sent {amount_to_send} cUSD to {recipient_address}. Transaction hash: {transaction_hash.hex()}")

This code serves as an illustration of how to communicate with the Celo network using the get_cusd_balance() and send_cusd() functions.

The get_cusd_balance() function is used to print the deployer account’s cUSD balance before defining the cUSD contract address. The deployer account address and the cUSD contract address are passed to the function, which prints the outcome.

The send_cusd() method is then used to transfer the requested amount of cUSD from the deployer account to the recipient account. Next, the code specifies the recipient address and the amount of cUSD to send. It provides the send_cusd() method with the deployer account, receiver address, amount to send, and cUSD contract address.

The code ends by printing a message along with the transaction hash confirming the successful transfer of cUSD.

Ultimately, this code provides a basis for more intricate smart contract interactions in Python by showing how to use the two functions to communicate with cUSD tokens on the Celo network.

Finally, run the following code on your terminal to see how well the functions interacts with the Celo network:



In this tutorial, we’ve demonstrated how to use Python and the module to communicate with the Celo blockchain and Celo Dollars (cUSD). Connecting to the Celo network, examining the cUSD balance, and sending cUSD between accounts have all been covered.

Next Steps

You can research the following subjects as a foundation for this tutorial:

  • Acquire more information regarding the Celo platform.
  • To connect with additional smart contracts, delve deeper into the documentation.
  • Examine and interact with the other stablecoins of Celo.

About the Author

I am a React frontend developer with over 3 years of experience building for the web, a web3 developer, and a technical writer. Visit my GitHub profile to see some of the projects I have worked on and currently working on.



I think there is a typo here.

1 Like

Hi @Joshy I was just adding your piece to a pathway and I noticed your piece you didn’t make use of syntax like bullet point or numeric listing, pls always consider using it since it helps readers not get lost in reading the tutorial, leaving the page and going to run codes before coming back again

Ouu and don’t forget to correct the typo error mentioned earlier suggested


Hi @Joshy ,

As a lover of Python programming language, I follow the trend and got interested in this piece. Nice work here. While going through the tutorial, there are a few things that need to be fixed.


I have corrected the typo. Thanks for pointing it out :+1:


You’re doing well…keep up the good work

1 Like

Nice job, mate😎

1 Like