【需求分析】
众筹里面需要有2类角色:接收者和捐赠者,其中接收者可以对应多个捐赠者。下面是这两类角色属性分析:
接收者:接收者地址、众筹总金额、当前众筹金额、捐赠者的个数
捐赠者: 捐赠者地址、捐赠金额
1.接收者
我们按照上面的要求创建了一个接收者对象,里面包含其属性
`
//接收者对象
struct Recipient{
address recipient_address; //接收者地址
uint goal; //筹资金额目标
uint amount; //当前筹资金额
uint contributor_amount; //捐赠者数量
mapping(uint => Contributor) map; //通过id与捐赠者关联
}`
2.捐赠者
`
//捐赠者对象
struct Contributor{
address contributor_address; //捐赠者地址
uint contributor_money; //捐赠金额
}`
3.创建一个众筹事件
address _address:代表的是当前发起众筹用户的地址
uint _goal:代表的是需要筹集的资金总额是多少
// 发起一个众筹事件
function create_crowdfunding(address _address,uint _goal) public {
// 将接受者id加1
recipientId++;
// 创建接受者对象,并通过id与其绑定
recipient_map[recipientId] = Recipient(_address,_goal,0,0);
}
4.为创建众筹者捐赠
address Newaddress:捐赠者地址
uint _recipientId:接收者的id
//发起捐赠
function contribute(address Newaddress,uint _recipientId) public payable{
// 通过id获取接受者对象
Recipient storage _recipient = recipient_map[_recipientId];
// 当前接受者金额加上获赠的金额
_recipient.amount += msg.value;
//捐赠人数加1
_recipient.contributor_amount++;
// 将接受者id与捐赠者绑定在一起
_recipient.map[_recipient.contributor_amount]=Contributor(Newaddress,msg.value);
}
5.判断众筹是否完成
通过传入接收者id来判断该对象是否完成了众筹
// 判断众筹任务是否完成
function Iscompelte(uint _recipientId)public returns(bool){
// 通过id获取接受者对象
Recipient storage _recipient = recipient_map[_recipientId];
// 判断筹集资金是否达到与其目标
if(_recipient.amount >= _recipient.goal){
//将众筹到的资金转移到接受者合约地址
_recipient.recipient_address.transfer(_recipient.amount);
return true;
}
return false;
}
6.完整代码
pragma solidity ^0.4.24;
contract crowd_funding{
//捐赠者对象
struct Contributor{
address contributor_address; //捐赠者地址
uint contributor_money; //捐赠金额
}
//接收者对象
struct Recipient{
address recipient_address; //接收者地址
uint goal; //筹资金额目标
uint amount; //当前筹资金额
uint contributor_amount; //捐赠者数量
mapping(uint => Contributor) map; //通过id与捐赠者关联
}
uint public recipientId; //接受者id
mapping(uint => Recipient) recipient_map; //通过id将接受者信息关联
// 发起一个众筹事件
function create_crowdfunding(address _address,uint _goal) public {
// 将接受者id加1
recipientId++;
// 创建接受者对象,并通过id与其绑定
recipient_map[recipientId] = Recipient(_address,_goal,0,0);
}
//发起捐赠
function contribute(address Newaddress,uint _recipientId) public payable{
// 通过id获取接受者对象
Recipient storage _recipient = recipient_map[_recipientId];
// 当前接受者金额加上获赠的金额
_recipient.amount += msg.value;
//捐赠人数加1
_recipient.contributor_amount++;
// 将接受者id与捐赠者绑定在一起
_recipient.map[ _recipient.contributor_amount] = Contributor(Newaddress,msg.value);
}
// 判断众筹任务是否完成
function Iscompelte(uint _recipientId)public returns(bool){
// 通过id获取接受者对象
Recipient storage _recipient = recipient_map[_recipientId];
// 判断筹集资金是否达到与其目标
if(_recipient.amount >= _recipient.goal){
//将众筹到的资金转移到接受者合约地址
_recipient.recipient_address.transfer(_recipient.amount);
return true;
}
return false; }}
7.演示
1)首先选择一个账号部署合约
![在这里插入图片描述](https://img-blog.csdnimg.cn/5db1b8346ead4165a27b81df64178dd0.png)
2)合约部署完成之后在调用create_crowdfunding方法,传入两个参数,第一个参数为自己的地址,第二个参数为需要众筹的金额。
![在这里插入图片描述](https://img-blog.csdnimg.cn/d481be1cedf74373a81bf23676dd05f5.png)
3)调用recipientId方法获取id,然后更换地址调用contribute方法并将value更改为众筹的金额。之后进行传参,第一个参数为本地地址,第二个为获取的id。最后点击transact便实现了众筹。
![在这里插入图片描述](https://img-blog.csdnimg.cn/75c550a7964d482dbea572aca4710173.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/bdde7ea0ad56440d9c053f66f5ccd593.png)
4)最后想要查看是否众筹合约,便可以通过调用Iscompelte函数传入对应的id实现。在右下角的信息中查看返回值为true便为众筹成功。
![在这里插入图片描述](https://img-blog.csdnimg.cn/56454b727a224a16b91fb287bef232f1.png)