Building a Crowdfunding Platform on Celo with Python

Building a Crowdfunding Platform on Celo with Python https://celo.academy/uploads/default/optimized/2X/8/8f355939551c6c3f16d8f3a7255334dcd210513f_2_1024x576.png
none 0.0 0

Introduction

Crowdfunding is a fundraising strategy that allows individuals or sets of individuals to acquire the necessary funding they need for their projects or ideas. Celo is a fully open-source blockchain that allows developers to build smart contracts and DAPPS (decentralized applications). In this tutorial, we will learn how to build a Crowdfunding application with Python on Celo. We will create a smart contract and deploy it on Celo Alfajores with the Python Web3.py library.

Prerequisites

To understand this tutorail, you must be familiar with:

  • Building Smart contracts
  • The Python programming language

Requirements

You sould have the following installed on you computer to execute allt that is entailed in this tutorial:

Setting up the Project

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

mkdir celo-crowdfunding-python
cd celo-crowdfunding-python

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

python3 -m venv env
source env/bin/activate

To install the ganache-cli, web3.py, and python-dotenv:

npm install ganache --global
pip3 install python-dotenv web3

Creating the Smart Contract

Next, we have to build a smart contract for our crowdfunding application.
Create a file called Crowdfunding.sol in a directory of your project.

Crowdfunding.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Crowdfunding {
    address public owner;
    uint256 public totalContributions;
    uint256 public goal;
    bool public completed;
    mapping(address => uint256) public contributions;
    event Contribute(address indexed contributor, uint256 amount);
    constructor(uint256 _goal) public {
        owner = msg.sender;
        goal = _goal;
    }
    function contribute() public payable {
        require(!completed, "Crowdfunding has been completed.");
        require(msg.value > 0, "Contribution amount must be greater than 0.");
        contributions[msg.sender] += msg.value;
        totalContributions += msg.value;
        emit Contribute(msg.sender, msg.value);
        if (totalContributions >= goal) {
            completed = true;
        }
    }
    function withdraw() public {
        require(completed, "Crowdfunding has not been completed.");
        require(msg.sender == owner, "Only the owner can withdraw the funds.");
        payable(msg.sender).transfer(totalContributions);
    }
}

The smart contract above enables contributors to contribute to a crowdfunding campaign. The contract is completed once the total contributions reach the specified value by the owner of the campaign.

  • A _goal argument is specified in the constructor function which is used to set the amount needed to be reached by the campaign.
  • he contribute function is marked as payable (allows the function to accept payments from contributors) which adds the contributed amount to the totalContributions and ends the campaign once the goal has been reached.
  • The withdraw function makes sure that the owner of the campaign is the only one allowed to access the total contributions.

Deploying the Smart Contract

After we’ve created the smart contract, the next step is to compile and deploy the smart contract.

Run the following commaand to intall py-solx which is a python wrapper around the solc solidity compiler:

pip install py-solc

Create a new file called deploy.py and paste the following code:

deploy.py


import json
from solcx import compile_standard, install_solc
from web3 import Web3
import os
from dotenv import load_dotenv
load_dotenv()
with open("./Crowdfunding.sol", "r") as file:
    crowdfunding_file = file.read()
    # print(crowdfunding_file)
# Install Solidity compiler.
_solc_version = "0.6.0"
install_solc(_solc_version)
# Compile Crowdfunding smart contract with solcx.
compiled_sol = compile_standard(
    {
        "language": "Solidity",
        "sources": {"Crowdfunding.sol": {"content": crowdfunding_file}},
        "settings": {
            "outputSelection": {
                "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]}
            }
        },
    },
    solc_version=_solc_version,
)
# print(compiled_sol)
# Write compiled smart contract as JSON.
with open("compiled_sol.json", "w") as file:
    json.dump(compiled_sol, file)
# Get byte code
bytecode = compiled_sol["contracts"]["Crowdfunding.sol"]["Crowdfunding"]["evm"][
    "bytecode"
]["object"]
# Get ABI from JSON contract.
abi = compiled_sol["contracts"]["Crowdfunding.sol"]["Crowdfunding"]["abi"]

Run the following command to generate a JSON file called compiled_sol.json in your root directory:

python deploy.py

This compiled JSON file would contain the ABI (Application Binary Interface) and bytes code that communicates with the EVM machine.

Connect to a Local Blockchahin with Ganache Cli

Next, we need to connect to a local blockchain to interact with our smart contract:

Run the following on you terminal to connect to ganache:

ganache-cli --deterministic

You should see a ilst of private keys and public addresses to use to connect to your local blockchain and an RPC URL:

Add the following code to deploy.py:

# for connecting to ganache
w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))
chain_id = 1337
my_address = "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1"
private_key = os.getenv("PRIVATE_KEY")
print(private_key)

The address and private key are gotten from any of the ones that ganache provides for us and the URL is the RPC URL that ganache is running on your PC.

For security purposes, it is best to store your private key as an environment variable.

Create a .env file and add your private key to it.

.env

PRIVATE_KEY='0x......'

Run the following command to deploy your contract on ganache:

python deploy.py

Deploying on Celo Testnet

Let us deploy our application on celo Test also know as Alfajores.

Add the following code to deploy.py

deploy.py

# Deploy to test net (Celo)

w3 = Web3(Web3.HTTPProvider("https://alfajores-forno.celo-testnet.org"))
chain_id = 44787
my_address = "0x892B6Ca9F2213f011D850F397944e77bd0b1Bca3" # celo wallet
private_key = os.getenv("PRIVATE_TESTNET_KEY") # celo wallet
# create the contract in python
Crowdfunding = w3.eth.contract(abi=abi, bytecode=bytecode)
# print(Crowdfunding)
# Get latest transaction
nonce = w3.eth.get_transaction_count(my_address)
# print(nounce)
# Build a transaction
transaction = Crowdfunding.constructor().build_transaction({ "chainId": chain_id, "from": my_address, "nonce": nonce })
# print(transaction)
# Sign a transaction
signed_tx = w3.eth.account.sign_transaction(transaction, private_key=private_key)
# print(signed_tx)
# Send a transaction
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
contract_address = tx_receipt['contractAddress']
print(f'Contract deployed at address: {contract_address}')

In the code above, RPC URL and chain ID are gotten from the Celo Alfajores network. The contract method on the w3.eth class takes in the ABI and bytecode to create the contract. The build_transaction builds a transaction and is passed as an argument to the sign_transaction which signs the transaction. The send_raw_transaction method finally sends the transaction and produces a receipt that contains the contract address of the deployed contract.

Conclusion

In this article, you learned how to create a crowdfunding application with Celo Python SDK. You implemented functionalities such as, creating the crowdfunding smart contract logic, and deploying it to the Celo blockchain

Next Steps

To learn more about building on Celo using Python, you can explore the following resources:

References

About the Author

Israel Okunaya is an ace writer with a flair for simplifying complexities and a knack for storytelling. He leverages over four years of experience to meet the most demanding writing needs in different niches, especially food and travel, blockchain, and marketing. He sees blockchain as a fascinating yet tricky affair. So, he is given to simplifying its complexities with text and video tutorials.

3 Likes

You floored everything with simplicity. Thanks for making this easy.

1 Like