솔라나 블록체인으로 스테이킹 스마트 계약 구축

요약

Solana는 Anatoly Yakavenko가 만든 분산형 블록체인 플랫폼입니다. Solana는 POH 메커니즘으로 인해 매우 빠른 400ms의 블록 시간을 가지고 있습니다. 솔라나 블록체인에 POH에 대한 자세한 정보는 쓰지 않겠습니다. 더 많은 정보를 얻고 싶다면 solana의 백서를 보시는 것을 추천합니다.

전제 조건
  • 녹 프로그래밍
  • Solana 툴 슈트(Solana CLI)
  • 앵커 프레임워크

  • 스테이킹 스마트 계약 프로그래밍을 구축하기 전에 위의 전제 조건을 PC에 설치해야 합니다. 작업을 위한 프로그래밍이 필요합니다.
    Rust는 매우 강력한 범용 프로그래밍 언어입니다.
    Solana Tool Suit — 여기에는 Solana CLI가 포함됩니다.
    Anchor는 여러 개발자 도구가 포함된 Solana 스마트 계약 개발을 위한 프레임워크입니다. 따라서 기본적으로 Anchor는 생명의 은인이며 스마트 계약을 개발하기가 정말 쉽습니다.

    시작하기

    시작하려면 콘솔에서 새 앵커 프로젝트를 만듭니다.
    anchor init basicStaking
    프로젝트 구조에서 다음 파일 및 폴더를 볼 수 있습니다.

    program — 솔라나 프로그램(스마트 컨트랙트)의 디렉토리입니다.

    test — 이것은 자바스크립트 테스트 코드가 있는 곳입니다.

    마이그레이션 — 배포 스크립트입니다.

    app — 프론트엔드가 구축될 곳입니다.

    프로그램 디렉토리에 있는 lib.rs 파일을 살펴보겠습니다.

    use anchor_lang::prelude::*;
    declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
    #[program]
    pub mod basicStaking {
        use super::*;
        pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {                  Ok(())
        }
    }
    #[derive(Accounts)]
    pub struct Initialize {}
    


    CLI로 작성된 가장 기본적인 프로그램입니다. 호출될 때 아무 것도 하지 않고 성공적으로 실행되는 초기화 함수가 있습니다. 초기화 구조체는 초기화 함수의 컨텍스트를 정의합니다.

    xToken을 소유한 이해 관계자는 스테이킹 스마트 계약에 일정 금액을 스테이킹합니다. 보유자가 일정 금액을 스테이킹하는 대신 스테이킹 계약은 일정 기간 후에 보상 토큰을 xToken으로 제공합니다.

    100,000,000 totalSupply로 Solana cli에서 xToken을 생성했다고 가정합니다. 이 부분이 잘 이해되지 않으면 solana 블록체인에서 사용자 정의 토큰을 생성하는 방법에 대한 solana 문서를 참조할 수 있습니다.

    또한 스테이킹 스마트 계약에는 이해 관계자에게 보상을 반환하기 위한 10,000,000 xToken이 포함됩니다.

    그것들은 TGE 단계 전에 토크노믹스에 의해 허용됩니다. TGE — 토큰 생성 이벤트.

    이제 간단한 스테이킹 스마트 컨트랙트를 구축해 봅시다.

    // pub mod utils;
    use {
    // crate::utils::*,
    anchor_lang::{prelude::*, solana_program::program::{invoke,invoke_signed}},
    spl_token::state,
    };
    declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
    #[program]
    pub mod basic_staking {
    use super::*;
    pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {
    Ok(())
    }
    pub fn stake(ctx:Context<Stake>,amount: u64) -> ProgramResult{
        let account = &mut ctx.accounts.holder;
        //invoke to transfer token into staking contract
        let token_program = ctx.accounts.token_program.clone();
        let source = ctx.accounts.stake_token.clone();
        let destination = ctx.accounts.stake_pot.clone();
       let authority = ctx.accounts.authority.clone();
      invoke(&spl_token::instruction::transfer(
             token_program.key,
             source.key,
             destination.key,
             authority.key,
             &[],
             amount,
            )?,
            &[source, destination, authority, token_program],
        );
       account.stake_amount += amount;
      let now_ts = Clock::get().unwrap().unix_timestamp;
      account.stake_time = now_ts;
      Ok(())
    }
    pub fn unstake(ctx:Context<Stake>,amount:u64) -> ProgramResult{
       let account = &mut ctx.accounts.holder;
      //invoke to transfer token into holder address
      account.stake_amount -= amount;
      let now_ts = Clock::get().unwrap().unix_timestamp;
      account.stake_time = now_ts;
      Ok(())
    }
    pub fn claim(ctx:Context<Stake>) -> ProgramResult{
       let account = &mut ctx.accounts.holder;
      //invoke to transfer reward token into holder
      Ok(())
    }
    }
    #[derive(Accounts)]
    pub struct Initialize {}
    #[derive(Accounts)]
    pub struct SetAuthority<'info>{
    #[account(mut, signer)]
    authority: AccountInfo<'info>,
    #[account(mut)]
    new_authority: AccountInfo<'info>,
    #[account(mut, owner = spl_token::id())]
    stake_pot:AccountInfo<'info>,
    #[account(address=spl_token::id())]
    token_program:AccountInfo<'info>,
    }
    #[derive(Accounts)]
    pub struct Stake<'info>{
    #[account(mut, signer)]
    authority: AccountInfo<'info>,
    #[account(mut,signer)]
    pub holder:Account<'info,StakeAccount>,
    #[account(mut, owner=spl_token::id())]
    stake_token: AccountInfo<'info>,
    #[account(mut, owner=spl_token::id())]
    stake_pot: AccountInfo<'info>,
    #[account(address=spl_token::id())]
    token_program:AccountInfo<'info>,
    }
    #[account]
    pub struct StakeAccount{
    pub stake_amount:u64,
    pub stake_time:i64,
    }
    


    StakeAccount 구조체는 계정에 스테이크 데이터를 저장할 카운트 변수를 포함합니다.

    Stake 구조체는 계정 생성을 위한 컨텍스트를 정의하는 명령 구조체입니다.

    우리는 스테이킹 로직을 구현하기 위해 스테이킹, 언스테이크, 클레임에 대한 세 가지 함수를 선언합니다. 그것들은 호출하라는 지시입니다.

    시원한. 우리는 이 놀라운 프로그램으로 끝났습니다.

    이제 테스트를 실행합니다.
    anchor test
    테스트가 통과되면 이제 프로그램을 배포할 수 있습니다. solana-test-validator가 실행 중인지 확인하십시오.
    anchor deploy
    결론

    스테이킹 논리를 기반으로 하는 일부 코드베이스로 인해 이 코드베이스를 사용하지 않을 수 있습니다. 스테이킹 계약을 실행하기 위한 많은 코드베이스가 있습니다. 이 글에서는 스테이킹 컨트랙트 구축 방법에 대해서만 설명했습니다. 따라서 여기에서 이러한 단계를 이해하는 것이 좋습니다. 오늘 내 기사를 고려해 주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기