solidity之实现一个捐赠合约

233 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

前言

当我们学习一定的智能合约的相关基础语法后,我们已经可以实现一些简单的合约了,这一篇主要通过实现一个收集捐款的合约来实战。当我们实现一个合约的时候,得清楚这个合约要实现什么功能,目的明确才好开发,因为合约一旦部署便不能更改。

功能点

因为我们是一个收集捐款的合约,所以一个很确定的功能当然是收钱的功能。有了收钱功能,当然还有提现功能,这是一起的,因此可以总结为:

  • 捐赠函数(发送金额到合约)
  • 提现函数 (可以把捐款提出来做消费)
  • 其他自定义函数

大概就需要这2个函数,接着就可以开发了。

合约实现步骤

确认全局变量

首先我们要实现一个捐赠函数,这个合约应该要记录捐款人、捐赠金额。捐款人可能有多个,因此需要一个数组来存储,我们还需要查询对应捐款人对应捐的款数,因此需要一个mapping映射, 我们还需要记录一下总金额,应该有一个totalMoney变量

同时需要注意的是还应该存放一个部署人地址,确保只有当前部署者能调用某些方法。

方法实现

  • 捐赠函数(fundme)

这个函数应该接收一个金额的参数,注意金额建议用分表示,因为不能出现小数点,这是solidity本身规则,它是没法保存小数点。 拿到金额以后把对应的捐赠人和金额存储到对应的数组和映射。

  • 提现函数(withdraw)

这个函数应该接收一个参数,表示提现的金额,每次调用,只需要把总金额减掉对应的数值就可以。

合约实现

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


error NotOwner();
contract Donate {
    mapping(address => int256) public addressToAmountFunded; //捐款人对应的金额映射
    address[] public funders; //所有的捐款人

    address public  i_owner;

    int256 public totalMoney; //存储的总金额


    constructor(){
         i_owner = msg.sender;
    }

      modifier onlyOwner {
        // require(msg.sender == owner);
        if (msg.sender != i_owner) revert NotOwner();
        _;
    }
    

    function fundme(int256 money) public {
        addressToAmountFunded[msg.sender] += money;
        funders.push(msg.sender);
        totalMoney += money;   
    }

    function withdraw(int256 money) onlyOwner public{
        require(money < totalMoney,"not such money");
        totalMoney -= money;
     
    }

    //获取捐款人金额
    function getDonateList(address funder) public view returns(int256) {
         return addressToAmountFunded[funder];
    }
    
}

部署上述合约,在下图上可以测试。

image.png

这里我们捐款1000分当前部署者是我自己,相当于我这个部署者调用捐款,即我自己捐了1000分,即10元,这里的数值都是按分表示。 调用fundme函数后,可以查询totalMoney,为1000,说明捐赠成功了。同时可以查询映射里面,我这个地址捐赠的值,也可以看到是1000,说明逻辑处理都ok。

image.png

接下来是做提现的测试,调用withdraw函数,输入金额500,调用成功后,查看totalMoney可以看到声誉500了,说明正确。 如果我们输入大于totalMoney的值,那么就会报错,这里用到了require函数,判断条件,不符合则报错。

同时还用到了modifier关键字,这是一个修复符,表示要满足modifier修饰的函数里面的条件,才可以继续往下执行,这里定义了一个名称 的modifier 条件,在我们需要的函数后面 加上就能生效了。

image.png

总结

当然这是一个很基础的合约,实际要是真有这样的捐赠合约实现,应该会更严格,这是一个基础版,可以扩展。并且实际跟业务结合的话,更多的要让其更加透明化,自动化、也要更安全。