-
Notifications
You must be signed in to change notification settings - Fork 0
Contract를 학습한다.(clone: crowdfunding) #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
4BFC
wants to merge
21
commits into
develop
Choose a base branch
from
contract-fet/1
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…packages, setup for clone-project images
…ges in the hardhat.config
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
환경 설정
contract를 개발하기 위해서는 여러 환경을 세팅하는 방법이 있다. 대표적으로 Truffle과 Remix IDE가 있다. Truffle같은 경우에는 Linux 환경에서 최적화 되어 있는 환경이기 때문에 이를 제외하고 Remix IDE를 VSC와 연동해서 contract를 개발하는 방법을 먼저 소개 하겠다.
우선 vsc에서 아래와 같은 명령어를 실행한다.
그러면 서버가 동작을 하는데 이때, Remix IDE에 접속해서
Connect to Local Filesystem
을 클릭한다. 그러면 자연스럽게 vsc환경에 Remix IDE와 동일한 환경이 제공된다. 여기서 만약 방화벽 관련 Error가 발생을 하면 Remix IDE의 주소에서는 방화벽을 끌 수 있게 브라우저 환경을 세팅해야 한다. 그렇게 개발을 하고compile
과deploy
는 Remix IDE에서 실행하면 된다. 단, 사용을 해보니 해당 환경은 contract를 개발하기에는 편리하나 계속 Remix IDE를 신경쓰고 이와 연동을 유지하기 위해서 여러 제약 조건이 따르기 때문에 조금은 불편하다 느꼈다. 그래서 이를 대체하기 위해서 다음과 같은 SDK를 사용하기로 했다.ThirdWeb.js
해당 SDK는 contract 관리부터 contract를 컨트롤 할 수 있는 환경을 제공해주는 SDK이다. 쉽게 말해서 supabase와 비슷한 개념이라 생각하면 된다. 여기서 개발을 하고
deploy
를 하면 빠르게 나의 contract를 볼 수 있고 이를 관리 할 수 있다. thirdweb으로 개발할 수 있는 환경을 세팅하는 방법은 다음과 같다.생각 보다 간단하고 작업환경을 만들기가 어렵지 않았다. 이제 contract를 살펴보자.
Contract
Campaign 설정 및 기본 제공, 필요한 데이터
우리 contract가 사용될 목적과 방향은 다음과 같다. 캠페인을 통해서 기부할 수 있는 기능을 제공하려 한다. 그러기 위해서는 캠페인에 필요한 정보들부터 구성해야 한다. 해당 코드는 다음과 같다. (기본 문법은 숙지가 되었다는 전제로 설명할 예정이다.)
이렇게 구조가 짜여져 있고 우리가 제공, 제공 받을 캠페인을 저장할 상태 변수를 만들어 줘야 한다.
코드를 보면 Campaign을
unit256
데이터 타입으로 바인딩을 해서 campaigns 변수로 정의를 한 것이다. 그렇게 key(uint256), value(Campaign)로 구성 한 것이다. 여기서 특이한 점은 uint256인 key값을 따로 0으로 정의하지 않았다. 이유는 solidity에서 mapping은 key가 0으로 자동 설정되기 때문이다.numberOfCampaigns
은 Campaign가 생성되면서 생성된 구조체의 index값을 표현하기 위해서 정의된 값이다.Campaign 생성하기 (createCampaign)
이제 기본적인 campaign에 필요한 정보를 담고 추적할 수 있는 환경은 얼추 만들어 졌다. 이제는 생성하고 데이터를 저장해야 하는데 이를 구현한 코드는 다음과 같다.
우선 함수의 매개변수로
_owner, _title, _description, _target, _deadline, _image
들로 이루어 져있다. 이것들은 campaign을 생성할 때, 필요한 정보들을 바탕으로 구성 되어 있다. 이제 클라이언트가 위 함수에 접근하고 해당 데이터를 모두 입력하고 승인을 했다면 해당 데이터가 저장 되어야 한다. 코드는 다음과 같다.우리가 앞서 정의한 index값으로 새로 생성된 campaings를
Campaign
구조체(데이터)타입으로 선언한 단수형campaign
에 저장한다.storage
여기서 storage는
Solidity의 데이터 위치(Data Location)
를 지정하는 키워드이다. Solidity에서는 데이터를 저장할 때 데이터의 저장 위치를 반드시 명시해야 한다. 조금 더 설명하자면storage
는 영구 저장(블록체인)이 되고memory
는 함수 실행 중에만 임시적으로 저장하게 된다.calldata
는 읽기 전용 임시 저장소이며 주로 외부 함수입력값
에 사용된다. 다시 설명하자면storage
는 원본 데이터에 직접적인 영향을 주고memory
는 데이터를 임시 복사 하기 때문에 원본 데이터에 영향을 주지 않는다.require
require는 if문과 같은 조건문이다. 단, 이 둘의 명확한 차이는 있다. require는 실패 시 트랜잭션을 되돌린다. 즉, 데이터를 원상태로 복구시켜 데이터의 변화를 주지 않는 것이다.
require(campaign.deadline < block.timestamp, "The deadline should be a date in the future.");
해당 코드를 살펴보면campaign.deadline
이 현재 시간보다 미래인지 확인하는 조건문이다. 이를 통해서 contract의 조건 검사와 에러 처리를 하면서 트랙잭션을 관리한다.block.timestamp
는 블록이 채굴된 시간으로, 현재 블록체인의 시간을 의미한다. 그리고 마지막 인자의 메시지 같은 경우 실패한 경우 반환되는 error 메시지이다.여기까지 함수로부터
numberOfCampaigns
으로 선택된campaings
객체에 각 매개변수로 부터 받은 데이터를 저장하고numberOfCampaigns
의 값을 증가 시킨다. 이로인해numberOfCampaigns
의 본래의 값은 증가한다. 여기서 눈여겨 봐야할 것은numberOfCampaigns
가 return 되는데 이유는 우리가 저장한 Campaign의 구조체 index 값을 반환하기 위해서numberOfCampaigns -1
을 반환하는 것이다.기부 기능 구현 (donateToCampaign)
우리가 기부를 받는 함수를 구현하기 위해서는 다음과 같은 코드로 구현이 되어야 한다.
사용자가 캠페인에 기부(ETH)를 할 수 있다. 여기서 msg는 사용자가 요청한 ETH의 양이 된다.
(bool sent,) = payable(campaign.owner).call{value:amount}("");
해당 코드는 기부받은 금액을 캠패인 생성자에게 전송하게 되고call
은 ETH를 안전하게 전송하는 함수이다.여기서 저수준 함수에서 call의 반환값(tuple) bool의 상태가sent
로 전달이 되는 반환 값이며sent
가 true이면 성공, false이면 실패이다. 이에 맞춰서 반환 받은 sent에 따라서amountColledted
의 값이 요청한amount
만큼 증가 하게 된다.기부자 조회 구현 (getDonators)
기부자의 목록과 기부금액을 조회 할 수 있는 간단한 함수이다.
위 코드를 살펴보면 함수의 매개변수를 통해서 _id값으로 우리가 mapping한 campaings에 해당 id를 조회해서 결과들을 반환한다.
전체 캠페인 조회 함수
현재 존재하는 모든 캠페인을 반환하는 함수이다. 코드는 다음과 같다.
코드를 살펴보면 우선
Campaign[] memory allCampaigns = new Campaign[](numberOfCampaigns);
동적 배열을 만들어 캠페인을 복사한다. 이후 각 저장되어 있는 값들을 복사한allCampaigns
에 모두 넣어서 이를 반환한다.이렇게 전반적인 코드를 살펴보았다. 이제 우리는 이 contract를 thirdweb을 통햇 배포를 하고 해당 contract의 상태에 따라 변경이 가능한 함수,변수 들이 있고 그렇지 않은 함수, 변수들이 정해지게 된다. 이 기준은 view, pure 키워드에 따라 상태가 달라진다. 즉, 위 코드에서 우리가 public, private 뒤에 붙는 키워드 view, paybale에 따라서 Read와 Write 상태가 분리되는 것이다. 좀 더 나아가서 해당 상태에 따라
트랜잭션
,가스비
의 유무가 결정되는데 Read는 트랜잭션, 가스비는 전혀 발생하지 않고 반대로 write는 둘 다 비용이 발생하게 된다.