Rust NEAR协议代币库near-token的使用,NEAR生态中代币创建与管理的Rust解决方案
Rust NEAR协议代币库near-token的使用,NEAR生态中代币创建与管理的Rust解决方案
near-token是一个用于在NEAR协议中处理代币的Rust库。该库提供了NearToken类型以及各种单位转换和构造方法,使得在NEAR生态系统中处理代币变得简单高效。
基础用法
首先需要将near-token添加为项目依赖:
cargo add near-token
基础使用示例展示了如何创建NearToken对象并进行单位转换:
use near_token::NearToken;
fn main() {
// 从NEAR单位创建代币对象
const TEN_NEAR: NearToken = NearToken::from_near(10);
// 验证各种单位转换
assert_eq!(TEN_NEAR.to_string(), "10.00 NEAR");
assert_eq!(TEN_NEAR.as_near(), 10);
assert_eq!(TEN_NEAR.as_millinear(), 10000);
assert_eq!(TEN_NEAR.as_yoctonear(), 10000000000000000000000000);
// 从字符串解析代币金额
let input_str = "0.123456 NEAR";
let input_near: NearToken = input_str.parse().unwrap();
assert_eq!(
input_near,
NearToken::from_yoctonear(123456000000000000000000)
);
}
serde序列化支持
要启用serde序列化功能,需要添加对应特性:
cargo add near-token --features serde
序列化示例展示了如何将NearToken用于可序列化结构:
// 可序列化的转账详情结构
#[derive(serde::Serialize)]
struct TransferDetails {
amount: NearToken,
}
fn main() {
const TEN_NEAR: NearToken = NearToken::from_near(10);
let details = TransferDetails { amount: TEN_NEAR };
assert_eq!(
serde_json::to_string(&details).unwrap(),
r#"{"amount":"10000000000000000000000000"}"#
);
}
borsh序列化支持
要启用borsh序列化功能,需要添加对应特性:
cargo add near-token --features borsh
borsh序列化示例:
use borsh::{to_vec, BorshSerialize};
use near_token::NearToken;
// 支持borsh序列化的结构
#[derive(BorshSerialize)]
struct TransferDetails {
amount: NearToken,
}
fn main() {
const TEN_NEAR: NearToken = NearToken::from_near(10);
let details = TransferDetails { amount: TEN_NEAR };
assert_eq!(
to_vec(&details).unwrap(),
vec![0, 0, 0, 74, 72, 1, 20, 22, 149, 69, 8, 0, 0, 0, 0, 0]
);
}
NEAR代币基础
NEAR代币是NEAR区块链网络的原生资产,用于支付网络交易费用和存储租金。所有智能合约的执行和状态存储都需要消耗NEAR代币。
完整代币合约示例
以下是一个完整的代币合约实现,展示了代币的创建、转移和序列化操作:
use near_token::NearToken;
use serde::{Serialize, Deserialize};
use borsh::{BorshSerialize, BorshDeserialize};
// 代币转移结构体,支持多种序列化方式
#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
pub struct TokenTransfer {
pub sender: String, // 发送方账户
pub receiver: String, // 接收方账户
pub amount: NearToken, // 转账金额
pub memo: Option<String>, // 可选备注
}
impl TokenTransfer {
// 创建新的转账
pub fn new(sender: &str, receiver: &str, amount: NearToken) -> Self {
Self {
sender: sender.to_string(),
receiver: receiver.to_string(),
amount,
memo: None,
}
}
// 添加备注
pub fn with_memo(mut self, memo: &str) -> Self {
self.memo = Some(memo.to_string());
self
}
}
// 代币合约实现
#[derive(Debug, Default, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
pub struct TokenContract {
pub name: String, // 代币名称
pub symbol: String, // 代币符号
pub total_supply: NearToken, // 总供应量
pub balances: std::collections::HashMap<String, NearToken>, // 账户余额
}
impl TokenContract {
// 创建新代币合约
pub fn new(name: &str, symbol: &str, total_supply: NearToken) -> Self {
let mut contract = Self {
name: name.to_string(),
symbol: symbol.to_string(),
total_supply,
balances: std::collections::HashMap::new(),
};
// 初始化合约创建者拥有全部代币
contract.balances.insert("owner".to_string(), total_supply);
contract
}
// 执行转账
pub fn transfer(&mut self, transfer: &TokenTransfer) -> Result<(), String> {
// 检查发送方余额
let sender_balance = self.balances.get(&transfer.sender)
.ok_or_else(|| format!("Sender {} not found", transfer.sender))?;
// 验证余额是否充足
if *sender_balance < transfer.amount {
return Err("Insufficient balance".to_string());
}
// 执行转账操作
*self.balances.entry(transfer.sender.clone()).or_default() -= transfer.amount;
*self.balances.entry(transfer.receiver.clone()).or_default() += transfer.amount;
Ok(())
}
}
fn main() {
// 创建代币合约,总供应量1000 NEAR
let total_supply = NearToken::from_near(1000);
let mut contract = TokenContract::new("My Token", "MTK", total_supply);
// 创建转账交易
let transfer = TokenTransfer::new("owner", "alice", NearToken::from_near(100))
.with_memo("First transfer");
// 执行转账
match contract.transfer(&transfer) {
Ok(_) => println!("Transfer successful!"),
Err(e) => println!("Transfer failed: {}", e),
}
// 序列化为JSON
let json = serde_json::to_string(&transfer).unwrap();
println!("Serialized transfer: {}", json);
// 序列化为Borsh
let borsh_data = borsh::to_vec(&transfer).unwrap();
println!("Borsh serialized length: {}", borsh_data.len());
}
许可证
near-token库采用MIT和Apache-2.0双重许可证,用户可以根据需要选择其中一种。
1 回复
Rust NEAR协议代币库near-token的使用 - NEAR生态中代币创建与管理的Rust解决方案
概述
near-token
是一个用于NEAR协议生态系统的Rust库,它简化了在NEAR区块链上创建和管理代币的过程。这个库为开发者提供了与NEAR代币标准(NEP-141)交互的工具,使得在Rust中实现代币功能变得更加容易。
主要功能
- 代币创建和初始化
- 代币转账功能
- 余额查询
- 元数据管理
- 跨合约调用支持
完整示例代码
以下是基于near-token库创建完整代币合约的示例:
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::LazyOption;
use near_sdk::json_types::U128;
use near_sdk::{env, near_bindgen, AccountId, Balance, PanicOnDefault, Promise};
use near_token::Token;
// 代币元数据结构
#[derive(BorshDeserialize, BorshSerialize)]
pub struct TokenMetadata {
pub spec: String,
pub name: String,
pub symbol: String,
pub icon: Option<String>,
pub reference: Option<String>,
pub reference_hash: Option<[u8; 32]>,
pub decimals: u8,
}
// 主合约结构
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)]
pub struct MyToken {
token: Token,
metadata: LazyOption<TokenMetadata>,
}
#[near_bindgen]
impl MyToken {
// 初始化合约
#[init]
pub fn new(
owner_id: AccountId,
name: String,
symbol: String,
decimals: u8,
icon: Option<String>,
reference: Option<String>,
reference_hash: Option<String>,
) -> Self {
// 初始化代币
let mut token = Token::new(
name.clone(),
symbol.clone(),
decimals,
owner_id.clone(),
);
// 设置初始元数据
let metadata = TokenMetadata {
spec: "nep-141".to_string(),
name,
symbol,
icon,
reference,
reference_hash: reference_hash.map(|s| {
let mut hash = [0u8; 32];
hex::decode_to_slice(s, &mut hash).unwrap();
hash
}),
decimals,
};
Self {
token,
metadata: LazyOption::new(b"m", Some(metadata)),
}
}
// 转账功能
pub fn transfer(&mut self, receiver_id: AccountId, amount: U128) {
self.token.transfer(
&env::predecessor_account_id(),
&receiver_id,
amount.into(),
);
}
// 带消息的转账(用于跨合约调用)
pub fn transfer_call(
&mut self,
receiver_id: AccountId,
amount: U128,
msg: String,
) -> Promise {
self.token.transfer_call(
&env::predecessor_account_id(),
&receiver_id,
amount.into(),
msg,
)
}
// 查询余额
pub fn ft_balance_of(&self, account_id: AccountId) -> U128 {
self.token.balance_of(&account_id).into()
}
// 铸造新代币(仅所有者可调用)
pub fn mint(&mut self, account_id: AccountId, amount: U128) {
assert_eq!(
env::predecessor_account_id(),
self.token.owner_id(),
"Only owner can mint"
);
self.token.mint(&account_id, amount.into());
}
// 销毁代币
pub fn burn(&mut self, amount: U128) {
self.token.burn(&env::predecessor_account_id(), amount.into());
}
// 获取元数据
pub fn ft_metadata(&self) -> TokenMetadata {
self.metadata.get().unwrap()
}
// 更改所有者(仅当前所有者可调用)
pub fn change_owner(&mut self, new_owner: AccountId) {
assert_eq!(
env::predecessor_account_id(),
self.token.owner_id(),
"Only owner can change owner"
);
self.token.change_owner(new_owner);
}
}
// 实现NEP-141标准的方法
impl MyToken {
pub fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option<String>) {
self.transfer(receiver_id, amount);
if let Some(memo) = memo {
env::log_str(&format!("Memo: {}", memo));
}
}
pub fn ft_transfer_call(
&mut self,
receiver_id: AccountId,
amount: U128,
memo: Option<String>,
msg: String,
) -> Promise {
if let Some(memo) = memo {
env::log_str(&format!("Memo: {}", memo));
}
self.transfer_call(receiver_id, amount, msg)
}
pub fn ft_total_supply(&self) -> U128 {
self.token.total_supply().into()
}
}
部署和测试
使用near-cli部署和测试合约:
# 编译合约
RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release
# 创建子账户
near create-account token.myaccount.testnet --masterAccount myaccount.testnet
# 部署合约
near deploy --wasmFile target/wasm32-unknown-unknown/release/my_token.wasm --accountId token.myaccount.testnet
# 初始化合约
near call token.myaccount.testnet new '{
"owner_id": "myaccount.testnet",
"name": "My Token",
"symbol": "MTK",
"decimals": 24,
"icon": null,
"reference": null,
"reference_hash": null
}' --accountId myaccount.testnet
# 铸造代币
near call token.myaccount.testnet mint '{
"account_id": "myaccount.testnet",
"amount": "1000000"
}' --accountId myaccount.testnet
# 查询余额
near view token.myaccount.testnet ft_balance_of '{"account_id": "myaccount.testnet"}'
总结
这个完整示例展示了如何使用near-token库实现一个符合NEP-141标准的代币合约,包括:
- 代币创建和初始化
- 转账功能实现
- 余额查询
- 元数据管理
- 跨合约调用支持
- 权限控制
near-token库提供了构建NEAR生态代币所需的核心功能,开发者可以在此基础上进一步扩展业务逻辑。