infrablockchain-docs
ko
ko
  • 인프라블록체인
    • 배우기
      • 아키텍처
        • 아키텍처
        • 네트워크 참여자
        • 파라체인
          • 시스템 파라체인
      • 프로토콜
        • 시스템 토큰
        • 트랜잭션 수수료
        • Proof of Transaction
      • Substrate
        • 배우기
          • 기초 지식
            • 암호학
            • 블록체인 기본 개념
            • 합의
            • 네트워크와 노드
            • 트랜잭션과 블록 기본 사항
            • 트랜잭션 수명주기
            • 오프체인 작업
            • 라이트 클라이언트
            • Substrate를 위한 Rust
            • 라이브러리 소개
            • 아키텍처와 Rust 라이브러리
            • 파일 구조
            • 계정, 주소 및 키
            • 트랜잭션 형식
            • 난수 생성
          • 프레임
            • FRAME 팔레트
            • FRAME 매크로
            • 커스텀 팔레트
            • 팔레트 커플링
            • Origin
            • 이벤트와 에러
            • 런타임 스토리지 구조
            • 상태 전이와 스토리지
            • SCALE 인코딩
            • 트랜잭션, Weight 및 수수료
            • 런타임 API
            • 런타임 업그레이드
            • 런타임 개발
          • 계정 데이터 구조
          • 주소 형식
          • 용어집
          • cli
            • 아카이브
            • 메모리 프로파일러
            • 노드 템플릿
            • 사이드카
            • srtool
            • 서브키
            • subxt
            • try-runtime
            • tx-wrapper
          • 런타임 개발
            • 기본
              • Genesis 상태 구성하기
              • 런타임 상수 구성
              • 체인 스펙을 커스텀하기
              • 팔레트 가져오기
              • 도우미 함수 사용하기
            • 합의 모델
              • 작업 증명을 사용하는 체인 구성
              • 하이브리드 노드 생성하기
            • 오프체인 워커
              • 오프체인 HTTP 요청하기
              • 오프체인 인덱싱
              • 오프체인 로컬 스토리지
            • 팔레트 설계
              • 크라우드펀딩 구성하기
              • 스토리지 구조체 (struct) 생성하기
              • 잠금 가능한 통화 구현
              • 무작위성 적용하기
              • 느슨한 팔레트 결합 사용하기
              • 타이트한 팔레트 결합 사용하기
            • 파라체인 개발
              • HRMP 채널 추가하기
              • 로컬 파라체인 노드 추가하기
              • 릴레이 체인에 연결하기
              • 솔로 체인을 변환하기
              • 론칭 준비
              • 콜레이터 선택
              • 파라체인 업그레이드
            • 스토리지 마이그레이션
              • 기본 저장소 마이그레이션
              • 스토리지 마이그레이션 트리거
            • 테스트
              • 기본 테스트 설정하기
              • 전송 함수 테스트하기
            • 도구
              • 체인을 위한 txwrapper 생성
              • REST 엔드포인트를 사용하여 체인 데이터 가져오기
              • try-runtime 사용하기
              • Wasm 바이너리 검증하기
            • 가중치
              • 벤치마크 추가
              • 수수료 계산하기
              • 조건부 가중치 사용
              • 사용자 정의 가중치 사용하기
        • 빌드하기
          • 제작할 것을 결정하세요
          • 빌드 프로세스
          • 결정론적 런타임 빌드
          • 체인 스펙
          • Genesis 구성
          • 애플리케이션 개발
          • RPC
          • 문제 해결
        • 튜토리얼
          • 설치하기
            • 개발자 도구
            • 리눅스 개발 환경
            • macOS 개발 환경
            • Rust 툴체인
            • Rust 문제 해결 방법
            • Windows 개발 환경
          • 빠른 시작
            • 코드 탐색하기
            • 런타임 수정하기
            • 노드 시작하기
            • Substrate 한눈에 보기
          • 블록체인 구축
            • 신뢰할 수 있는 노드 추가
            • 특정 노드 승인
            • 로컬 블록체인 구축하기
            • 네트워크 시뮬레이션
            • 실행 중인 네트워크 업그레이드
          • 애플리케이션 로직 구축
            • 런타임에 팔레트 추가하기
            • 오프체인 워커 추가
            • 사용자 정의 팔레트 게시
            • 함수 호출의 출처 지정하기
            • 사용자 정의 팔레트에서 매크로 사용하기
          • 유용한 도구들
            • EVM 계정에 접근하기
            • 이더리움 통합
            • 사이드카 엔드포인트 탐색하기
            • 경량 클라이언트 노드 통합
          • 스마트 컨트랙트
            • 스마트 컨트랙트
            • 토큰 계약 작성하기
            • 스마트 컨트랙트 개발하기
            • 첫 번째 계약 준비하기
            • 스마트 컨트랙트 문제 해결
            • 값 저장을 위한 맵 사용
      • XCM
        • XCM
        • XCM 형식
    • 서비스 체인
      • 인프라DID
      • 인프라EVM
      • URAuth(Universal Resource Auth)
    • 데브 옵스
      • 체인 빌드
      • 배포
      • 모니터링
    • 튜토리얼
      • 기초
        • 시스템 토큰 관리 프로세스
        • 시스템 토큰을 트랜잭션 수수료로 사용해보기
        • 트랜잭션에 투표 포함 시키기
        • 밸리데이터 보상 받기
      • 구축하기
        • 인프라릴레이체인 구축하기
        • 파라체인 구축하기
        • 메시지 전달 채널 열기
        • XCM을 이용하여 토큰 전송하기
        • Asynchronous Backing 적용하기
      • 테스트
        • 벤치마크
        • 런타임 확인
        • 디버그
        • 테스트 네트워크에서 파라체인 시뮬레이션하기
        • 단위 테스트
      • 서비스체인
        • 인프라DID
          • 구축하기
          • 공개키 추가하기
          • 서비스 엔드포인트 등록하기
          • DID 생성하기
        • 인프라EVM
          • 구축하기
          • EVM에 자금 입금 및 인출하기
          • ERC20 토큰 컨트랙트 배포하기
          • ERC721 토큰 컨트랙트 배포하기
          • ERC1155 토큰 컨트랙트 배포하기
  • 뉴날 데이터 마켓
Powered by GitBook
On this page
  • 시작하기 전에
  • 팔렛 구성하기
  • 자식 트라이(Trie) API 도우미 함수 작성하기
  • 디스패처 함수 작성하기
  • 예제
  • 자원
  1. 인프라블록체인
  2. 배우기
  3. Substrate
  4. 배우기
  5. 런타임 개발
  6. 팔레트 설계

크라우드펀딩 구성하기

FRAME 팔렛을 사용하여 크라우드펀딩 캠페인을 만드는 방법을 알려드립니다.

이 안내서에서는 여러 토큰 계정을 제어하고 자식 스토리지에 데이터를 저장하는 팔렛을 구축하는 방법을 보여줍니다. 이 구조는 크라우드펀딩 앱을 구축하는 데 유용합니다.

이 안내서에서는 작은 Merkle proof를 사용하여 기여자가 기여한 것을 증명할 수 있는 자식 스토리지 트라이의 사용에 초점을 맞출 것입니다. 간단한 기여 증명을 할 수 있다면 사용자는 크라우드론에 참여하여 보상을 받을 수 있습니다.

이 안내서에서는 각기 다른 크라우드펀드 캠페인을 위해 새로운 자식 트라이를 생성하는 방법을 보여줍니다. 사용자는 크라우드펀드를 시작할 수 있으며, 크라우드펀드의 목표 금액, 종료 시간 및 목표가 달성되면 풀된 자금을 받을 수 있는 수혜자를 지정할 수 있습니다. 펀드가 성공하지 못하면 원래 소유자에게 자금이 반환될 수 있습니다.

시작하기 전에

이 안내서를 따라가고 자체 팔렛에 크라우드펀딩 기능을 구현하려면 팔렛에 다음 종속성을 포함하십시오:

use frame_support::{
	ensure,
	pallet_prelude::*,
	sp_runtime::traits::{AccountIdConversion, Hash, Saturating, Zero},
	storage::child,
	traits::{Currency, ExistenceRequirement, Get, ReservableCurrency, WithdrawReasons},
	PalletId,
};
use frame_system::{pallet_prelude::*, ensure_signed};
use super::*;

이 안내서는 팔렛 로직에 따라 자체 오류와 이벤트를 생성하는 방법을 알고 있다고 가정합니다.

팔렛 구성하기

  1. 팔렛의 구성 특성을 선언합니다.

    Event 타입 외에도, 이 팔렛은 다음 특성이 필요합니다:

    • Currency - 크라우드펀드에 사용될 통화입니다.

    • SubmissionDeposit - 크라우드펀드 소유자가 보증금으로 보유해야 할 금액입니다.

    • MinContribution - 크라우드펀드에 기여할 수 있는 최소 금액입니다.

    다음 타입으로 특성을 확장합니다:

    /// 팔렛의 구성 특성.
    #[pallet::config]
    pub trait Config: frame_system::Config {
    	type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
    	type Currency: ReservableCurrency<Self::AccountId>;
    	type SubmissionDeposit: Get<BalanceOf<Self>>;
    	type MinContribution: Get<BalanceOf<Self>>;
    	type RetirementPeriod: Get<Self::BlockNumber>;
    }

    그리고 다음 타입 별칭을 추가합니다:

    pub type FundIndex = u32;
    type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
    type BalanceOf<T> = <<T as Config>::Currency as Currency<AccountIdOf<T>>>::Balance;
  2. 크라우드펀드 구성 정보를 저장하는 구조체를 생성합니다.

    #[derive(Encode, Decode, Default, PartialEq, Eq, TypeInfo)]
    #[cfg_attr(feature = "std", derive(Debug))]
    pub struct FundInfo<AccountId, Balance, BlockNumber> {
    	/// 캠페인이 성공하면 자금을 받을 계정입니다.
    	beneficiary: AccountId,
    	/// 예치금액입니다.
    	deposit: Balance,
    	/// 모금된 총 금액입니다.
    	raised: Balance,
    	/// 자금 조달이 성공해야 하는 블록 번호입니다.
    	end: BlockNumber,
    	/// `raised`의 상한입니다.
    	goal: Balance,
    }

    그리고 이를 더 쉽게 사용하기 위한 새로운 별칭을 생성합니다:

    type FundInfoOf<T> =
    	FundInfo<AccountIdOf<T>, BalanceOf<T>, <T as frame_system::Config>::BlockNumber>;
  3. 스토리지 아이템을 선언합니다.

    스토리지 아이템은 어떤 사용자가 어떤 펀드에 얼마나 기여했는지 추적합니다. 다음 타입을 정의하여 스토리지 아이템을 선언합니다:

    #[pallet::storage]
    #[pallet::getter(fn funds)]
    /// 모든 펀드에 대한 정보입니다.
    pub(super) type Funds<T: Config> = StorageMap<
    	_,
    	Blake2_128Concat,
    	FundIndex,
    	FundInfoOf<T>,
    	OptionQuery,
    >;
    
    #[pallet::storage]
    #[pallet::getter(fn fund_count)]
    /// 지금까지 할당된 펀드의 총 수입니다.
    pub(super) type FundCount<T: Config> = StorageValue<_, FundIndex, ValueQuery>;

자식 트라이(Trie) API 도우미 함수 작성하기

팔렛의 디스패처에게 자금 풀의 계정 ID를 제공하는 함수를 작성합니다.

  1. impl<T: Config> Pallet<T> 내부에 다음을 작성합니다:

    pub fn fund_account_id(index: FundIndex) -> T::AccountId {
    	const PALLET_ID: ModuleId = ModuleId(*b"ex/cfund");
    	PALLET_ID.into_sub_account(index)
    }
  2. pub fn id_from_index(index: FundIndex) -> child::ChildInfo {
    		let mut buf = Vec::new();
    		buf.extend_from_slice(b"crowdfnd");
    		buf.extend_from_slice(&index.to_le_bytes()[..]);
    
    		child::ChildInfo::new_default(T::Hashing::hash(&buf[..]).as_ref())
    }

디스패처 함수 작성하기

이 팔렛의 디스패처를 작성하는 방법에 대해 다음 단계를 안내합니다. 디스패처의 로직 내에서 여러 검사를 수행한 후, 각 함수는 연관된 메서드를 사용하여 Funds<T> 스토리지 맵을 변경합니다. 팔렛의 create 함수는 또한 2단계에서 생성한 FundInfo 구조체를 사용합니다.

  1. 새로운 펀드 생성하기

    fn create:

    • FundInfo 구조체를 사용하여 Funds 스토리지 아이템을 업데이트합니다.

    • Created 이벤트를 생성합니다.

  2. 기존 펀드에 기여하기

    fn contribute:

    • ensure!를 사용하여 사전 안전성 검사를 수행합니다.

    • T::Currency::transfer를 사용하여 기여를 펀드에 추가합니다.

    • 도우미 함수 contribution_put을 사용하여 자식 트라이에 기여를 기록합니다.

    • Contributed 이벤트를 생성합니다.

  3. 기여자의 전체 잔액을 펀드에서 인출하기

    fn withdraw:

    • ensure!를 사용하여 사전 안전성 검사를 수행합니다.

    • 새로운 잔액을 계산하고 자식 트라이 도우미 함수 funds, contribution_get, contribution_kill을 사용하여 스토리지를 업데이트합니다.

    • Withdrew 이벤트를 생성합니다.

  4. 퇴직 기간이 만료된 후 전체 크라우드펀드를 해산하기

    fn dissolve:

    • ensure!를 사용하여 사전 안전성 검사를 수행합니다.

    • 자식 트라이 도우미 함수 crowdfund_kill을 사용하여 스토리지에서 기여자 정보를 제거합니다.

    • Dissolved 이벤트를 생성합니다.

  5. 성공한 크라우드펀드의 수혜자에게 지급하기

    fn dispense:

    • 이 함수를 호출한 계정에 초기 예치금을 제공하여 스토리지를 정리하는 인센티브를 제공합니다.

    • <Funds<T>>::remove(index);와 Self::crowdfund_kill(index);를 사용하여 펀드를 스토리지에서 제거합니다. 이를 통해 모든 기여자를 한 번에 스토리지에서 제거합니다.

예제

자원

Previous팔레트 설계Next스토리지 구조체 (struct) 생성하기

Last updated 1 year ago

고유한 ID를 생성합니다:

다음과 같은 도우미 함수를 작성합니다. 이 함수들은 를 사용합니다:

pub fn contribution_put: 를 사용하여 관련된 자식 트라이에 기여를 기록합니다.

pub fn contribution_get: 을 사용하여 관련된 자식 트라이에서 기여를 조회합니다.

pub fn contribution_kil: 을 사용하여 관련된 자식 트라이에서 기여를 제거합니다.

pub fn crowdfund_kill: 를 사용하여 관련된 자식 트라이에서 모든 기여자 정보를 한 번에 제거합니다.

를 사용하여 불균형 변수를 생성합니다.

를 사용하여 자금을 반환합니다.

을 사용하여 해산자가 자금을 수집할 수 있도록 합니다.

수혜자와 호출자 모두 자금을 수집하기 위해 를 사용합니다.

ChildInfo
Child API
put
get
kill
kill_storage
T::Currency::withdraw
T::Currency::resolve_into_existing
T::Currency::resolve_creating
T::Currency::resolve_creating
pallet_simple_crowdfund
Currency Imbalance trait
Child trie API
extend_from_slice
using_encode