# 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

{% embed url="<https://github.com/xendfinance/assetchain-starterkits>" %}

follow the guidlines on the [README.md](https://github.com/xendfinance/assetchain-starterkits/blob/main/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](https://code.visualstudio.com/)). 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.

```solidity
//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 <a href="#compile-contract" id="compile-contract"></a>

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

```typescript
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 <a href="#deploy-contract" id="deploy-contract"></a>

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`

{% hint style="success" %}
Congratulations! Your Fundme contract is successfully depolyed on Asset Chain Blockchain.
{% endhint %}

If we go to the [Asset Chain explorer ](https://testnet.assetchain.org/)and search for our contract address or transaction hash. we should be able to see that it has been deployed successfully.

{% embed url="<https://github.com/xendfinance/fund-me-tutorial/tree/updated/hardhat>" %}
updated codebase for the smart contract
{% endembed %}

### STEP 5: BUILDING OUR FRONTEND AND INTERACTING WITH OUR FRONTEND <a href="#deploy-contract" id="deploy-contract"></a>

coming soon....

Below are link to preview project

{% embed url="<https://fund-me-tutorial.pages.dev/>" %}

### STEP 5: ASSIGNMENT <a href="#deploy-contract" id="deploy-contract"></a>

coming soon....

if you have questions, join our [Telegram](https://t.me/XendFinanceDevs) and say hello 👋. We're Active!
