OneChain零基础速成:发布代币

前置声明 操作系统 Distributor ID: Debian Description: Debian GNU/Linux 13 (trixie) Release: 13 Codename: trixie 桌面环境:Xfce 浏览器 Chrome 拓展程序:

前置声明

操作系统

  • Distributor ID: Debian

    Description: Debian GNU/Linux 13 (trixie)

    Release: 13

    Codename: trixie

  • 桌面环境:Xfce

浏览器

OneChain版本

  • main分支指向onechain-1.1.1(参考GitHub

主网 or 测试网

请注意,本文所有操作都是基于测试网的,截至2026年1月13日,one client安装默认都是指向测试网。

环境安装

  • Rust

  • One Client

Rust

参考Rust官网

sudo apt install curl
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

默认安装就好,不用墨迹。

安装好之后关闭终端,打开一个新的,这rustcargo命令就生效了。

One Client

参考开发文档——How to build OneChain binaries

sudo apt install git gcc cmake clang
mkdir ~/onechain
export CARGO_TARGET_DIR=~/onechain
cargo install --locked --git https://github.com/one-chain-labs/onechain.git one --features tracing

让子弹飞,电脑的风扇会呼呼呼的转起来~

工程搭建

创建工程

参考开发文档——Write a Move Package

mkdir ~/onechain/contracts
cd ~/onechain/contracts
one move new sprite

工程结构如下:

.
├── Move.toml
├── sources
│   └── sprite.move
└── tests
    └── sprite_tests.move

使用自己喜欢的代码编辑器开始操作吧!推荐Cursor + Move插件(mysten)

配置工程

Move.toml

[package]
name = "sprite"
edition = "2024.beta"

[dependencies]
One = { git = "https://github.com/one-chain-labs/onechain.git", subdir = "crates/sui-framework/packages/one-framework", rev = "onechain-1.1.1", override = true }

[addresses]
sprite = "0x0"

开发合约

这里一步到位,直接发布OTW类型的代币,安全性更高。OTW类型的代币发布完后,需要额外执行一步操作finalize_registration,发布的时候会提到。

sources/sprite.move

/// Module: sprite
module sprite::sprite;

use one::coin::{Self, DenyCapV2};
use one::coin_registry;
use one::deny_list::DenyList;

/// 代币的 witness 类型(必须是模块名的大写形式)
public struct SPRITE has drop {}

/// 初始化函数,部署时自动调用
fun init(witness: SPRITE, ctx: &mut TxContext) {
    // 创建代币,9位小数
    let (mut currency, mut treasury_cap) = coin_registry::new_currency_with_otw(
        witness,
        9,                                      // 小数位数
        b"SPR".to_string(),                     // 符号
        b"Sprite".to_string(),                  // 名称
        b"Sprite on OneChain".to_string(),      // 描述
        b"https://xxx.xxx/logo.png".to_string(),
        ctx,
    );


    // 铸造 10 亿代币 (10^9 * 10^9 = 10^18)
    let total_supply = treasury_cap.mint(1_000_000_000_000_000_000, ctx);
    // 放弃铸币权限,只允许销毁(通缩模型)
    currency.make_supply_burn_only(treasury_cap);

    // 标记为受监管的代币
    let deny_cap = currency.make_regulated(true, ctx);

    // 完成初始化,获取元数据管理权限
    let metadata_cap = currency.finalize(ctx);

    // 将铸造的代币转给部署者
    transfer::public_transfer(total_supply, ctx.sender());
    // 监管权限转给部署者
    transfer::public_transfer(deny_cap, ctx.sender());
    // 元数据管理权限转给部署者
    transfer::public_transfer(metadata_cap, ctx.sender());
}

public fun add_addr_from_deny_list(
    denylist: &mut DenyList,
    denycap: &mut DenyCapV2<SPRITE>,
    denyaddy: address,
    ctx: &mut TxContext,
) {
    coin::deny_list_v2_add(denylist, denycap, denyaddy, ctx);
}

public fun remove_addr_from_deny_list(
    denylist: &mut DenyList,
    denycap: &mut DenyCapV2<SPRITE>,
    denyaddy: address,
    ctx: &mut TxContext,
) {
    coin::deny_list_v2_remove(denylist, denycap, denyaddy, ctx);
}

编译合约

one move build

发布合约

在OneWallet获取钱包地址和私钥

这一步不用我多说了吧...

获取测试网的原生代币OCT

第一次使用one client会帮你生成一个地址和私钥,用于执行各种操作,不用管,一路回车就好了。

提示你选择key scheme直接填0就好了,选择ed25519。

后续我们会导入自己的地址私钥。

one client faucet --address <YOUR_WALLET_ADDRESS>

虽然可以一直取用,但其实两三个就够用了,别瞎TM去刷。

配置one client

查看私钥

one keytool list

可以看到已经存在一个由one client默认生成的地址和私钥了。

转换私钥

反正就是目前从OneWallet复制出来的私钥是0x这种开头的,需要用one keytool进行转换。

one keytool convert <YOUR_PRIVATE_KEY>

然后会显示如下:

╭────────────────┬──────────────────────────────────────────────────────────────────────────╮
│ bech32WithFlag │  suiprivkey1qqqtpzhnkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  │
│ base64WithFlag │  AACwivOwisA/S+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx                            │
│ hexWithoutFlag │  00b08af3b08ac03f4bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx        │
│ scheme         │  ed25519                                                                  │
╰────────────────┴──────────────────────────────────────────────────────────────────────────╯

导入私钥

one keytool import <bech32WithFlag> ed25519 --alias <别名>

切换为默认私钥

使用one client publish就会使用默认私钥。

one client switch --address <钱包地址或别名>

可选:修改私钥别名(我还专门去查了这玩意怎么改,丢)

one keytool update-alias <原来的别名> <新的别名>

发布

one client publish

查看自己地址下的代币资产:

https://onescan.cc/testnet/account?address=<YOUR_WALLET_ADDRESS>

finalize_registration

因为咱们发布的代币的类型是OTW的,所以必须执行这一步操作,否则代币合约不会在链上真正生效。

one client call --package 0x2 --module coin_registry --function finalize_registration --type-args <PACKAGE_ID::MODULE_NAME::TOKEN_NAME> --args 0xc <CURRENCY_OBJECT_ID>

PACKAGE_ID::MODULE_NAME::TOKEN_NAME示例如下:

0x55d1b8fe8cb75d2bfee9939bc5a0732e0859492a5330c8dfccb50baa49c35421::sprite::SPRITE

CURRENCY_OBJECT_ID示例如下:

0xc857b8e5fd0efd51834c4b2ea59b535410f6758fcc638b7b36142fa0e06c5e8d

如何获取CURRENCY_OBJECT_ID

OneScan Testnet找到创建代币合约的那笔交易:

点击 RAW 切换显示原始数据。

找到上图的 objectId 替换为命令的参数。

FAQ

  • 代币发布成功,导入OneWallet时出现“No coin metadata found”?

如果你发布的代币是OTW类型的,那么需要在代币合约发布成功后,在链上调用一次finalize_registration方法,可以去看上面的finalize_registration段落。

评论