7 月 28 日,Vara Community Workshop 圆满结束!本次 Workshop 介绍了如何在 Vara Network 上部署众筹合约。
具体教程请参考技术文档以及视频回放。
在 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 上找到。
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");
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)
}
}
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 界面描述:
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 Technologies 完成 1200 万美元融资
关于 GearFans
Gear 是波卡生态的计算组件,GearFans 是 Gear 爱好者社区。
【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。