众筹案例解析|Community Workshop 回顾
2023-08-01 18:25
Gear
2023-08-01 18:25
订阅此专栏
收藏此文章

7 月 28 日,Vara Community Workshop 圆满结束!本次 Workshop 介绍了如何在 Vara Network 上部署众筹合约。


具体教程请参考技术文档以及视频回放。

  • B 站回放:https://www.bilibili.com/video/BV16h4y157Zy/
  • 油管回放:https://youtu.be/rtlsfvjLyYc
  • PPT 链接: https://hackmd.io/@btwiuse/crowdsale
  • 同质化代币合约https://github.com/gear-foundation/dapps-sharded-fungible-token
  • 众筹合约https://github.com/gear-foundation/dapps-crowdsale
完成每期 Workshop 课后作业可获得 Vara 社区精美周边。
本期作业:

在 Vara Stable Testnet 上部署 https://github.com/gear-foundation/dapps-crowdsale 合约,并与合约交互,调用合约的 StartSale / Buy / EndSale 消息。

其中代币合约地址使用: debug_ft 0xd5be0fcf54cf648279a84d6b12399c976826343ad9c95722a22aec64e4ce526b

如果遇到任何技术问题,或者想提交 Workshop 作业,请加入 TG 开发者群。

  • https://t.me/gear_dev_cn 

什么是众筹?

公开发售投资全新的加密货币或其他数字资产,被称为加密货币众筹。众筹可以被新项目用来为开发和其他目的筹集资金。众筹是有时间限制,投资者可以将他们在活动中定新的代币在公开发售的融资目标达到和项目启动后,新的代币将作为未来的功能被推广。

本文中所描述的众筹智能合约实现范例是在 Gear 上实现和发布的 dApp 之一。这篇文章介绍了接口、数据结构、基本功能,并解释了它们的用途。你可以可以直接使用代码,也可以根据自己的场景进行修改。任何人都可以轻松创建自己的众筹应用,并在 Gear 网络上运行。

购买代币的初始资金由 Gear 同质化代币合约决定 - gFT。 合约源代码可在 GitHub 上找到。

  • gFT:https://wiki.gear-tech.io/docs/examples/gft-20/
  • 合约源代码:https://github.com/gear-foundation/dapps-crowdsale

教程代码

界面

源码
  1. messages.rs - 包含同质化币合约的功能。公开发售合约通过 transfer_tokens 函数与同质化代币合约进行交互。
pub async fn transfer_tokens(
    transaction_id: u64, // - associated transaction id
    token_id: &ActorId, // - the fungible token contract address
    from: &ActorId, // - the sender address
    to: &ActorId, // - the recipient address
    amount: u128, // - the amount of tokens
)

这个函数发送一个信息(action 在枚举 IcoAction 中定义)并得到一个回复(回复在枚举 IcoEvent 中定义)。

let _transfer_response = msg::send_for_reply_as::<ft_main_io::FTokenAction, FTokenEvent>(
    *token_address,
    FTokenAction::Message {
        transaction_id,
        payload: ft_logic_io::Action::Transfer {
            sender: *from,
            recipient: *to,
            amount: amount_tokens,
        }
        .encode(),
    },
    0,
    0,
)
.expect("Error in sending a message `FTokenAction::Message`")
.await
.expect("Error int transfer");
  1. asserts.rs - 包含断言功能: owner_message和`not_zero_address```。
  • owner_message - 检查 msg::source() 是否等于 owner。否则,会报错。
pub fn owner_message(owner: &ActorId, message: &str) {
    if msg::source() != *owner {
        panic!("{}: Not owner message", message)
    }
}
  • not_zero_address 检查 address 是否等于 ZERO_ID。否则,会报错:
pub fn not_zero_address(address: &ActorId, message: &str) {
    if address == &ZERO_ID {
        panic!("{}: Zero address", message)
    }
}
  1. lib.rs - 定义合约逻辑

代码结构

你需要在 Cargo.toml 文件中添加 hashbrown安装包以便使用 hashmap。

[dependecies]
# ...
hashbrown = "0.13.1"

该合约有以下结构:

use hashbrown::HashMap;

struct IcoContract {
    ico_state: IcoState,
    start_price: u128,
    price_increase_step: u128,
    time_increase_step: u128,
    tokens_sold: u128,
    tokens_goal: u128,
    owner: ActorId,
    token_address: ActorId,
    token_holders: HashMap<ActorId, u128>,
    transaction_id: u64,
    transactions: HashMap<ActorId, u64>,
}
  • ico_state 是 IcoState结构,由以下部分组成:
pub struct IcoState {
    pub ico_started: bool, // true if started
    pub start_time: u64, // time when started, otherwise is zero
    pub duration: u64, // duration, otherwise is zero
    pub ico_ended: bool, // true if ended
}
  • start_price - 代币初始价格
  • price_increase_step - 价格上涨幅度
  • time_increase_step - 价格上涨后的时间段
  • tokens_sold - 出售了多少代币
  • tokens_goal - 将出售多少代币
  • owner - 合约所有者
  • token_address - 同质化代币地址
  • token_holders - 买家名单和他们购买的代币数量
函数
  • 开始公开发售。只有所有者可以调用:
async fn start_ico(&mut self, config: IcoAction)

回复以下消息:

IcoEvent::SaleStarted {
    transaction_id,
    duration,
    start_price,
    tokens_goal,
    price_increase_step,
    time_increase_step,
},
  • 购买代币。任何余额充足的人都可以购买代币:
pub fn buy_tokens(&mut self, tokens_cnt: u128)

回复以下消息:

IcoEvent::Bought {
    buyer,
    amount,
    change,
}
  • 结束公开发售。只有所有者可以调用:
async fn end_sale(&mut self)

回复以下消息:

IcoEvent::SaleEnded
Metadata 和状态

Metadata 界面描述:

pub struct CrowdsaleMetadata;

impl Metadata for CrowdsaleMetadata {
    type Init = ();
    type Handle = InOut<IcoAction, IcoEvent>;
    type Others = ();
    type Reply = ();
    type Signal = ();
    type State = State;
}

使用 state()函数,显示完整合约状态信息:

#[no_mangle]
extern "C" fn state() {
    reply(common_state()).expect(
        "Failed to encode or reply with `<ContractMetadata as Metadata>::State` from `state()`",
    );
}

为了仅显示来自 State 的必要特定值,您需要编写一个独立的 crate。在这个 crate 中,指定函数将从State状态返回所需的值。例如 - gear-foundation/dapps-crowdsale/state:

#[metawasm]
pub trait Metawasm {
    type State = <CrowdsaleMetadata as Metadata>::State;

    fn current_price(state: Self::State) -> u128 {
        state.get_current_price()
    }

    fn tokens_left(state: Self::State) -> u128 {
        state.get_balance()
    }

    fn balance_of(address: ActorId, state: Self::State) -> u128 {
        state.balance_of(&address)
    }
}

历史文章

Gear 合约大揭秘

如何使用 gear-js SDK

如何部署 Gear 合约?

Gear Technologies 完成 1200 万美元融资

Gear 的技术优势

关于 GearFans

Gear 是波卡生态的计算组件,GearFans 是 Gear 爱好者社区。


官网:https://gear-tech.io/
Twitter:https://twitter.com/gear_techs
中文 Twitter:https://twitter.com/gear_fans 
Vara Twitter:https://twitter.com/VaraNetwork
Vara Twitter CN:https://twitter.com/VaraNetwork_CN
GitHub:https://github.com/gear-tech
Discord:https://discord.com/invite/7BQznC9uD9
Telegram 中文群:https://t.me/Gear_CN
Vara Telegram CN:https://t.me/varanetwork_cn
QQ 群:67770333

【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

Gear
数据请求中
查看更多

推荐专栏

数据请求中
在 App 打开