sui模拟pumpfun实现(1)Suimove在线发布coin技术探讨
move语言发布coin,需要编写代码, 提供一个otw ,每个coin是一个模块
// For Move coding conventions, see
// https://docs.sui.io/concepts/sui-move-concepts/conventions
module coin_simple::template {
use sui::coin::{Self};
use sui::url::{Self,Url};
use std::ascii;
use coin_manager::coin_manager;
/// The OTW for the Coin
public struct TEMPLATE has drop {}
const DECIMALS: u8 = 9;
const SYMBOL: vector<u8> = b"SYMBOL_TEMPLATE";
const NAME: vector<u8> = b"COIN_NAME_TEMPLATE";
const DESCRIPTION: vector<u8> = b"COIN_DESCRIPTION_TEMPLATE";
const URL: vector<u8> = b"IMAGE_URL_TEMPLATE";
/// Init the Coin
fun init(witness: TEMPLATE, ctx: &mut TxContext) {
let urlStr = ascii::string(URL);// 这个模版代码是未来会替换常量的,为了避免编译器优化,定义变量来获取内容
let image_url:Option<Url> = if (urlStr.length() > 0 ){ option::some(url::new_unsafe(urlStr)) } else{ option::none()};
let (treasury, metadata) = coin::create_currency(
witness, DECIMALS, SYMBOL, NAME, DESCRIPTION,image_url, ctx
);
//这是为了未来管理coin,提供一个管理模块
coin_manager::register_coin(treasury,metadata,ctx);
}
#[test_only]
public fun init_for_test( ctx: &mut TxContext) {
let witness = TEMPLATE{};
init(witness, ctx);
}
}
1) 生成一个模版工程
2) 网页上接收用户输入的coin的定制参数
3) 模版工程里面替换掉相关参数
需要用到 move_bytecode_template 库
4) 通过typescript发布新coin到sui链.
生成合约的二进制代码
sui move build --dump-bytecode-as-base64 >coin_bytecode.json
读取二进制代码
import module_bytes from './coin_bytecode.json'
function readCoinTemplateBytes() : [ Uint8Array,string[]]{
let bytecode : Uint8Array = fromBase64(module_bytes.modules[0]);
return [bytecode,module_bytes.dependencies];
}
修改二进制代码
export async function publishCoin(params : PublishCoinParams, signer : Keypair) : Promise<PublishResult>{
let publishResult : PublishResult = {isSucc:true};
let [bytecode,deps] = readCoinTemplateBytes();
let updated = template.update_identifiers(bytecode, {
"TEMPLATE": params.module_name.toUpperCase(),
"template": params.module_name
});
// Update DECIMALS
updated = template.update_constants(
updated,
bcs.u8().serialize(params.decimal).toBytes(), // new value
bcs.u8().serialize(9).toBytes(), // current value
'U8', // type of the constant
);
// Update SYMBOL
updated = template.update_constants(
updated,
bcs.string().serialize(params.symbol).toBytes(), // new value
bcs.string().serialize('SYMBOL_TEMPLATE').toBytes(), // current value
'Vector(U8)', // type of the constant
);
// Update NAME
updated = template.update_constants(
updated,
bcs.string().serialize(params.coin_name).toBytes(), // new value
bcs.string().serialize('COIN_NAME_TEMPLATE').toBytes(), // current value
'Vector(U8)', // type of the constant
);
// Update desc
updated = template.update_constants(
updated,
bcs.string().serialize(params.desc).toBytes(), // new value
bcs.string().serialize('COIN_DESCRIPTION_TEMPLATE').toBytes(), // current value
'Vector(U8)', // type of the constant
);
// Update URL
let url = params.imageUrl ? params.imageUrl : '';
updated = template.update_constants(
updated,
bcs.string().serialize(url).toBytes(), // new value
bcs.string().serialize('IMAGE_URL_TEMPLATE').toBytes(), // current value
'Vector(U8)', // type of the constant
);
const operator = signer.getPublicKey().toSuiAddress();
let tx = new Transaction();
let arr = updated as unknown as number[];
let modules :number [][] = [];
modules.push(arr)
const [upgradeCap] = tx.publish({ modules, dependencies:deps });
tx.transferObjects([upgradeCap], operator);
tx.setGasBudget(1e8);
let config = env.config();
const suiClient = new SuiClient({ url: getFullnodeUrl(config.env) });
let balance = await suiClient.getBalance({owner:operator});
const result = await suiClient.signAndExecuteTransaction({
signer: signer,
transaction: tx,
options: {
showEffects: true,
showObjectChanges : true,
///showObjectChanges:true,
showEvents:true
},
requestType: 'WaitForLocalExecution',
});
发布新币的模版在server端,需要读取 move_bytecode_template_bg.wasm文件,因此需要运行在服务器端.
发布新币的的gas费用,需要服务端的某个账户operator 做签名. 为了保证operator不亏钱. 需要在发布之前,先让发币的用户user,先转钱给operator
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!