
요구사항
1. 일정 기간 동안 이더를 지불하여 모금에 참여 가능
2. 모금, 현재 모금액 보기, 모금액 수령 기능을 제공
기본 구조
Remix에 새로운 sol 파일을 만들고 기본 구조를 작성함
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract FundRaising {
}
모금 기간, 수혜자를 받는 생성자
최소 모금액은 0.01 이더로 설정하였고
모금 기간과 모금액을 수령할 사람은 생성자를 통해 설정함
contract FundRaising {
uint public constant MINIMUM_AMOUT = 1e16; // == 0.01ether 최소 모금액
uint public fundRaisingCloses;
address public beneficiary; // 모금을 가져갈 사람
constructor (uint _duration, address _beneficiary) {
fundRaisingCloses = block.timestamp + _duration;
beneficiary = _beneficiary;
}
}
모금을 하는 함수
이더를 받아야 하므로 payable을 선언
최소 모금액과, 모금 기간 안에 모금을 했는지 유효성 검사를 진행
모든 조건을 만족할 경우 모금한 사람의 정보를 배열에 저장
contract FundRaising {
...
address[] funders;
function fund() public payable{
require(msg.value >= MINIMUM_AMOUT, "MINUMUM AMOUNT: 0.01 ether");
require(block.timestamp < fundRaisingCloses, "FUND RAISING CLOSED");
address funder = msg.sender;
funders.push(funder);
}
}
현재 모금액을 볼 수있는 함수
현재 컨트랙트가 가지고 있는 잔액을 반환
값을 호출만 하므로 view로 선언
contract FundRaising {
...
function currentCollection() public view returns(uint256) {
return address(this).balance;
}
}
모금액 수령을 하는 함수
이더 전송이 일어나므로 payable 선언
modifier를 이용하여 수혜자 유효성 검사해봄
해당 함수를 호출한 사람이 수혜자가 맞는지, 모금 기간이 지났는지 유효성 검사
모든 조건을 만족하면 수혜자에게 모금액 전송
contract FundRaising {
...
modifier onlyBeneficiary() {
require(msg.sender == beneficiary);
_;
}
function withdraw() public payable onlyBeneficiary{
require(block.timestamp > fundRaisingCloses);
payable(msg.sender).transfer(address(this).balance);
}
}
전체 코드 보기
전체 코드
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract FundRaising {
uint public constant MINIMUM_AMOUT = 1e16; // == 0.01ether 최소 모금액
uint public fundRaisingCloses;
address public beneficiary; // 모금을 가져갈 사람
constructor (uint _duration, address _beneficiary) {
fundRaisingCloses = block.timestamp + _duration;
beneficiary = _beneficiary;
}
address[] funders;
function fund() public payable{
require(msg.value >= MINIMUM_AMOUT, "MINUMUM AMOUNT: 0.01 ether");
require(block.timestamp < fundRaisingCloses, "FUND RAISING CLOSED");
address funder = msg.sender;
funders.push(funder);
}
function currentCollection() public view returns(uint256) {
return address(this).balance;
}
modifier onlyBeneficiary() {
require(msg.sender == beneficiary);
_;
}
function withdraw() public payable onlyBeneficiary{
require(block.timestamp > fundRaisingCloses);
payable(msg.sender).transfer(address(this).balance);
}
}
결과
모금 기간은 120초, 수혜자는 첫 번째 계정으로 설정하고 컨트랙트 배포 진행

두 번째 계정으로 10 이더를 펀딩 진행

컨트랙트의 잔액 확인 결과
10 이더가 제대로 들어왔음

세 번째 계정으로 50 이더 펀딩 진행

현재 계정 상황
두 번째는 10 이더, 세 번째는 50 이더가 빠져나간 상황

수혜자인, 첫 번째 계정으로 모금액 받기 실행

첫 번째 계정에 모금액 들어와서 160 이더 된 것을 확인

당연히 컨트랙트의 잔액은 0 이더가 남아있게 됨

'프로그래밍 > 블록체인' 카테고리의 다른 글
Remix와 Ganache로 컨트랙트 호출 & 배포 해보기 (0) | 2022.08.25 |
---|---|
트랜잭션에 데이터 담아 보내기 (0) | 2022.08.24 |
이더리움 프라이빗 네트워크 만들고 MetaMask로 송금하기 (0) | 2022.08.23 |