Payments

In this Tutorial, we will be building a simple payment project where we get to donate to a smart contract using the RWA token.

Step 1: DOWNLOAD THE STARTERKITS

Download the starter kits below to get started in building fundme projects

follow the guidlines on the README.md file to get your starter kits ready.

Step 2: WRITING OUR FUNDME CONTRACT

Now that our environment is set up, on to more exciting stuff: writing our smart contract code

Open up the hardhat project in your favorite editor (we like VSCode). Smart contracts are written in a language called Solidity which is what we will use to write our NFT.sol smart contract.‌

Navigate to the contracts folder and create a new file called FundMe.sol

Below is our smart contract code, Copy and paste the contents below into your FundMe.sol file.

//SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

contract FundMe {
    address public owner;
    uint256 public totalDonations;
    address[] donators;
    
    mapping(address => uint256) public donations;

    event DonationReceived(address donor, uint256 amount);
    event FundsWithdrawn(address owner, uint256 amount);

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can perform this action");
        _;
    }
    constructor() {
        owner = msg.sender;
    }

    function donate() external payable {
        require(msg.value > 0, "Donation amount should be greater than zero");

        donations[msg.sender] += msg.value;
        totalDonations += msg.value;
        donators.push(msg.sender);

        emit DonationReceived(msg.sender, msg.value);
    }

    function withdrawFunds() external onlyOwner {
        uint256 amount = address(this).balance;
        require(amount > 0, "No funds to withdraw");
        payable(owner).transfer(amount);
        emit FundsWithdrawn(owner, amount);
    }

    function getDonationDetails(address _donor) external view returns (uint256) {
        return donations[_donor];
    }
}

So, what does this code do exactly? Let’s break it down, line-by-line.

  1. License Declaration(// SPDX-License-Identifier: MIT ): Specifies the software license for the code, which is the MIT license in this case.

  2. Pragma Directive(pragma solidity >=0.8.0 <0.9.0; ): Specifies the version of Solidity compiler that can compile this contract, which should be any version from 0.8.0 up to, but not including, 0.9.0.

  3. Contract Declaration(contract FundMe): Declares the start of a smart contract named FundMe.

  4. State Variables:

    • address public owner;: Stores the address of the contract owner and makes it publicly accessible.

    • uint256 public totalDonations;: Stores the total amount of donations received and makes it publicly accessible.

    • address[] donators;: Stores a list of addresses that have donated.

    • mapping(address => uint256) public donations;: Maps donor addresses to the amount they have donated and makes it publicly accessible.

  5. Events:

    • event DonationReceived(address donor, uint256 amount);: Declares an event that is emitted when a donation is received, including the donor's address and the donation amount.

    • event FundsWithdrawn(address owner, uint256 amount);: Declares an event that is emitted when funds are withdrawn, including the owner's address and the withdrawn amount.

  6. Modifier: modifier onlyOwner()

    • require(msg.sender == owner, "Only owner can perform this action");: Ensures that the function using this modifier can only be called by the contract owner.

    • _;: Placeholder that represents the function's body where the modifier is applied.

  7. Constructor: constructor()

    • owner = msg.sender;: Sets the owner of the contract to the address that deploys the contract.

  8. Function to Donate: function donate()

    • external payable: A function declared as external can only be called from outside the contract and When a function is marked as payable, it can receive RWA token, and the value sent with the transaction (in Wei) can be accessed using msg.value.

    • require(msg.value > 0, "Donation amount should be greater than zero");: Ensures that the donation amount is greater than zero.

    • donations[msg.sender] += msg.value;: Updates the donation amount for the sender's address.

    • totalDonations += msg.value;: Increases the total donations by the amount sent.

    • donators.push(msg.sender);: Adds the donor's address to the list of donators.

    • emit DonationReceived(msg.sender, msg.value);: Emits the DonationReceived event.

  9. Function to Withdraw Funds: function withdrawFunds()

    • external onlyOwner : A function declared as external can only be called from outside the contract and when a function is marked onlyOwner It ensures that only the owner of the contract can call this function.

    • uint256 amount = address(this).balance;: Retrieves the contract's current balance.

    • require(amount > 0, "No funds to withdraw");: Ensures that there are funds available to withdraw.

    • payable(owner).transfer(amount);: Transfers the contract's balance to the owner's address.

    • emit FundsWithdrawn(owner, amount);: Emits the FundsWithdrawn event.

  10. Function to Get Donation Details: function getDonationDetails(address _donor) external view returns (uint256)

    • return donations[_donor];: Returns the donation amount for the specified donor address.

STEP 3: UPDATE OUR DEPLOYMENT SCRIPTS

Navigate to the deploy/00_deploy_your_contract.ts folder , adding the following contents to it:

import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";

/**
 * Deploys a contract named "YourContract" using the deployer account and
 * constructor arguments set to the deployer address
 *
 * @param hre HardhatRuntimeEnvironment object.
 */
const deployYourContract: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
  /*

    When deploying to live networks (e.g `yarn deploy --network assetchain_testnet`), the deployer account
    should have sufficient balance to pay for the gas fees for contract creation.

    You can generate a random account with `yarn generate` which will fill DEPLOYER_PRIVATE_KEY
    with a random private key in the .env file (then used on hardhat.config.ts)
    You can run the `yarn account` command to check your balance in every network.
  */
  const { deployer } = await hre.getNamedAccounts();
  const { deploy } = hre.deployments;

  await deploy("FundMe", {
    from: deployer,
    // Contract constructor arguments
    log: true,
    // autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
    // automatically mining the contract deployment transaction. There is no effect on live networks.
    autoMine: true,
  });

  // Get the deployed contract to interact with it after deploying.
  // const yourContract = await hre.ethers.getContract<Contract>("Greeter", deployer);
 
};

export default deployYourContract;


// Tags are useful if you have multiple deploy files and only want to run one of them.
// e.g. yarn deploy --tags Greeter
deployYourContract.tags = ["FundMe"];

STEP 4: DEPLOY OUR CONTRACT

We’re finally ready to deploy our smart contract! Navigate back to the root of your hardhat project directory, and in the command line run:

yarn deploy --network assetchain_testnet

You should then see something like:

"FundMe" at 0xcaa32C250fbC0cDd13A09c385e33b83e7D3e15F7

Congratulations! Your Fundme contract is successfully depolyed on Asset Chain Blockchain.

If we go to the Asset Chain explorer and search for our contract address or transaction hash. we should be able to see that it has been deployed successfully.

STEP 5: BUILDING OUR FRONTEND AND INTERACTING WITH OUR FRONTEND

coming soon....

Below are link to preview project

STEP 5: ASSIGNMENT

coming soon....

if you have questions, join our Telegram and say hello 👋. We're Active!

Last updated