solidity实战-----编写一个简单的众筹合约

末蓝、 2022-12-05 12:26 374阅读 0赞

在学习完solidity编程基础之后,于是结合课程编写了一个简单的众筹合约。

【需求分析】

众筹里面需要有2类角色:接收者和捐赠者,其中接收者可以对应多个捐赠者。下面是这两类角色属性分析:

接收者:接收者地址、众筹总金额、当前众筹金额、捐赠者的个数

捐赠者: 捐赠者地址、捐赠金额

1.接收者

我们按照上面的要求创建了一个接收者对象,里面包含其属性

  1. //接收者对象
  2. struct Recipient{
  3. address recipient_address; //接收者地址
  4. uint goal; //筹资金额目标
  5. uint amount; //当前筹资金额
  6. uint contributor_amount; //捐赠者数量
  7. mapping(uint => Contributor) map; //通过id与捐赠者关联
  8. }

2.捐赠者

  1. //捐赠者对象
  2. struct Contributor{
  3. address contributor_address; //捐赠者地址
  4. uint contributor_money; //捐赠金额
  5. }

3.创建一个众筹事件

address _address:代表的是当前发起众筹用户的地址

uint _goal:代表的是需要筹集的资金总额是多少

  1. // 发起一个众筹事件
  2. function create_crowdfunding(address _address,uint _goal) public {
  3. // 将接受者id加1
  4. recipientId++;
  5. // 创建接受者对象,并通过id与其绑定
  6. recipient_map[recipientId] = Recipient(_address,_goal,0,0);
  7. }

4.为创建众筹者捐赠

address Newaddress:捐赠者地址

uint _recipientId:接收者的id

  1. //发起捐赠
  2. function contribute(address Newaddress,uint _recipientId) public payable{
  3. // 通过id获取接受者对象
  4. Recipient storage _recipient = recipient_map[_recipientId];
  5. // 当前接受者金额加上获赠的金额
  6. _recipient.amount += msg.value;
  7. //捐赠人数加1
  8. _recipient.contributor_amount++;
  9. // 将接受者id与捐赠者绑定在一起
  10. _recipient.map[ _recipient.contributor_amount] = Contributor(Newaddress,msg.value);
  11. }

5.判断众筹是否完成

通过传入接收者id来判断该对象是否完成了众筹

  1. // 判断众筹任务是否完成
  2. function Iscompelte(uint _recipientId)public returns(bool){
  3. // 通过id获取接受者对象
  4. Recipient storage _recipient = recipient_map[_recipientId];
  5. // 判断筹集资金是否达到与其目标
  6. if(_recipient.amount >= _recipient.goal){
  7. //将众筹到的资金转移到接受者合约地址
  8. _recipient.recipient_address.transfer(_recipient.amount);
  9. return true;
  10. }
  11. return false;
  12. }

6.完整代码

  1. pragma solidity ^0.4.24;
  2. contract crowd_funding{
  3. //捐赠者对象
  4. struct Contributor{
  5. address contributor_address; //捐赠者地址
  6. uint contributor_money; //捐赠金额
  7. }
  8. //接收者对象
  9. struct Recipient{
  10. address recipient_address; //接收者地址
  11. uint goal; //筹资金额目标
  12. uint amount; //当前筹资金额
  13. uint contributor_amount; //捐赠者数量
  14. mapping(uint => Contributor) map; //通过id与捐赠者关联
  15. }
  16. uint public recipientId; //接受者id
  17. mapping(uint => Recipient) recipient_map; //通过id将接受者信息关联
  18. // 发起一个众筹事件
  19. function create_crowdfunding(address _address,uint _goal) public {
  20. // 将接受者id加1
  21. recipientId++;
  22. // 创建接受者对象,并通过id与其绑定
  23. recipient_map[recipientId] = Recipient(_address,_goal,0,0);
  24. }
  25. //发起捐赠
  26. function contribute(address Newaddress,uint _recipientId) public payable{
  27. // 通过id获取接受者对象
  28. Recipient storage _recipient = recipient_map[_recipientId];
  29. // 当前接受者金额加上获赠的金额
  30. _recipient.amount += msg.value;
  31. //捐赠人数加1
  32. _recipient.contributor_amount++;
  33. // 将接受者id与捐赠者绑定在一起
  34. _recipient.map[ _recipient.contributor_amount] = Contributor(Newaddress,msg.value);
  35. }
  36. // 判断众筹任务是否完成
  37. function Iscompelte(uint _recipientId)public returns(bool){
  38. // 通过id获取接受者对象
  39. Recipient storage _recipient = recipient_map[_recipientId];
  40. // 判断筹集资金是否达到与其目标
  41. if(_recipient.amount >= _recipient.goal){
  42. //将众筹到的资金转移到接受者合约地址
  43. _recipient.recipient_address.transfer(_recipient.amount);
  44. return true;
  45. }
  46. return false;
  47. }
  48. }

7.演示

首先我们运行合约然后点击部署

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ZjIwMTc_size_16_color_FFFFFF_t_70

将刚才我们选中的用户地址:0xdd870fa1b7c4700f2bd7f44238821c26f7392148

填入到下面的框框中,然后自定义一个众筹金额,如下所示:

20200910162421769.png

点击 transact,在编译器中查看到如下所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ZjIwMTc_size_16_color_FFFFFF_t_70 1

接下来我们需要选择第一个用户地址为它进行捐赠

20200910162712253.png

输入捐赠金额2000wei

20200910162802747.png

然后在下面的contribute输入第一个用户地址:0xca35b7d915458ef540ade6068dfe2f44e8fa733c

以及需要捐赠的接收者id号,我们可以在下面 查看接收者的id

20200910163011542.png

然后输入进去,点击 transcat

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ZjIwMTc_size_16_color_FFFFFF_t_70 2

查看控制台如下所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ZjIwMTc_size_16_color_FFFFFF_t_70 3

此时我们还需要判断捐赠的金额是否达到我们预期的目标,如果满足我们将这比捐赠者捐赠的2000wei转移到接收者的合约地址上面,我们现在看看接收者合约地址上的余额是多少?

20200910163440739.png

我们点击Iscompelte,在里面输入接收者id:1

202009101639416.png

可以看到我们接收者账户余额多了2000wei

再看下控制台,返回true说明完成众筹了。

202009101640400.png

【总结】

上面测试的只是通过一个人直接捐赠来完成的,我们还可以通过多人来完成捐赠,这里就不一一测试了,通过这个简单的众筹合约基本上融汇了solidity编程中的基本概念。

参考资料:基于以太坊众筹合约实战

发表评论

表情:
评论列表 (有 0 条评论,374人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Linux手机1000万

    这两年众筹可以说非常热,而这家美国公司Purism在两年前就众筹了预装Qubes操作系统的Librem 13/15笔记本电脑新品。这个Qubes操作系统是以[Li