一、说明
在ton链上开发运行用户可以自行mint代币的jetton合约。标准的jetton代币合约只有管理员才有权限执行代币jetton的mint操作,根据传入的输入参数给指定地址mint指定数量的jetton代币。但是考虑到jetton合约的去中心化离散程度和用户参与jetton代币的灵活性,由用户来自行mint铸造jetton合约是一种可选择的方案。
具体实现方案如下:
- 用户自行向合约地址或者铸造地址转账ton即可mint jetton
- 用户mint铸造jetton的规则可以关联用户转账的ton数量和其他属性变量,比如时间戳、钱包地址、持币地址数量等
- 用户完成jetton的铸造后会实时的展示在用户的钱包地址
- 在jetton合约中设置相关的参数限制,例如:最大铸造数量、最小ton转账数量、jetton最大mint总量、单个钱包地址限额等。
- 用户自行mint jetton是ICO的一种更方便方案
二、jetton核心合约代码实现
1. ton链上数据持久化操作代码
const int max_supply = 210000000000000000000; ;; 210000 mln
const int mintRate = 500000;
(int, slice, cell, cell) load_data() inline {
slice ds = get_data().begin_parse();
return (
ds~load_coins(), ;; total_supply
ds~load_msg_addr(), ;; admin_address
ds~load_ref(), ;; content
ds~load_ref() ;; jetton_wallet_code
);
}
() save_data(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) impure inline {
set_data(begin_cell()
.store_coins(total_supply)
.store_slice(admin_address)
.store_ref(content)
.store_ref(jetton_wallet_code)
.end_cell()
);
}
2. jetton代币mint操作核心函数代码
() mint_tokens(slice to_address, cell jetton_wallet_code, int amount, cell master_msg) impure {
cell state_init = calculate_jetton_wallet_state_init(to_address, my_address(), jetton_wallet_code);
slice to_wallet_address = calculate_jetton_wallet_address(state_init);
var msg = begin_cell()
.store_uint(msg_flag::bounceable, 6)
.store_slice(to_wallet_address)
.store_coins(amount)
.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
.store_ref(state_init)
.store_ref(master_msg);
send_raw_message(msg.end_cell(), PAY_FEES_SEPARATELY); ;; pay transfer fees separately, revert on errors
}
3. 用户通过向合约地址转账TON自行mint jetton的核心代码
int amount = 10000000; ;; for mint message
int buy_amount = msg_value - amount;
throw_unless(error::insufficient_tons_for_mint, buy_amount > 0);
int jetton_amount = buy_amount * mintRate; ;; rate mintRate jetton = 1 toncoin; multiply to price here
throw_if(error::mint_exceed_max_supply, (total_supply + jetton_amount) > max_supply);
var master_msg = begin_cell()
.store_uint(op::transfer(), 32)
.store_uint(0, 64) ;; quert_id
.store_coins(jetton_amount)
.store_coins(0) ;; no forward_amount
.store_uint(0, 1) ;; forward_payload in this slice, not separate cell
.end_cell();
mint_tokens(sender_address, jetton_wallet_code, amount, master_msg);
4. jetton wallet钱包合约接收jetton的核心代码功能函数
() receive_tokens (slice in_msg_body, slice sender_address, int my_ton_balance, int fwd_fee, int msg_value) impure {
;; NOTE we can not allow fails in action phase since in that case there will be
;; no bounce. Thus check and throw in computation phase.
(int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_data();
int query_id = in_msg_body~load_uint(64);
int jetton_amount = in_msg_body~load_coins();
balance += jetton_amount;
slice from_address = in_msg_body~load_msg_addr();
slice response_address = in_msg_body~load_msg_addr();
throw_unless(error::unauthorized_incoming_transfer,
equal_slices(jetton_master_address, sender_address)
|
equal_slices(calculate_user_jetton_wallet_address(from_address, jetton_master_address, jetton_wallet_code), sender_address)
);
int forward_ton_amount = in_msg_body~load_coins();
int ton_balance_before_msg = my_ton_balance - msg_value;
int storage_fee = min_tons_for_storage - min(ton_balance_before_msg, min_tons_for_storage);
msg_value -= (storage_fee + gas_consumption);
if(forward_ton_amount) {
msg_value -= (forward_ton_amount + fwd_fee);
slice either_forward_payload = in_msg_body;
var msg_body = begin_cell()
.store_uint(op::transfer_notification(), 32)
.store_uint(query_id, 64)
.store_coins(jetton_amount)
.store_slice(from_address)
.store_slice(either_forward_payload)
.end_cell();
var msg = begin_cell()
.store_uint(msg_flag::non_bounceable, 6) ;; we should not bounce here cause receiver can have uninitialized contract
.store_slice(owner_address)
.store_coins(forward_ton_amount)
.store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_ref(msg_body);
send_raw_message(msg.end_cell(), PAY_FEES_SEPARATELY);
}
if ((response_address.preload_uint(2) != 0) & (msg_value > 0)) {
var msg = begin_cell()
.store_uint(msg_flag::non_bounceable, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 010000
.store_slice(response_address)
.store_coins(msg_value)
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_uint(op::excesses(), 32)
.store_uint(query_id, 64);
send_raw_message(msg.end_cell(), IGNORE_ERRORS);
}
save_data(balance, owner_address, jetton_master_address, jetton_wallet_code);
}
至此,完成TON链上部署运行用户自行mint代币的jetton合约所有操作流程。
添加VX或者telegram获取全程线上免费指导
评论前必须登录!
注册