6 个版本 (破坏性更新)

0.10.0 2023年10月18日
0.9.0 2023年6月4日
0.7.0 2022年12月18日
0.6.0 2022年10月25日
0.2.0 2022年1月16日

#2509 in 神奇豆子

Download history 104/week @ 2024-03-11 113/week @ 2024-03-18 37/week @ 2024-03-25 124/week @ 2024-04-01 44/week @ 2024-04-08 86/week @ 2024-04-15 70/week @ 2024-04-22 54/week @ 2024-04-29 48/week @ 2024-05-06 61/week @ 2024-05-13 166/week @ 2024-05-20 99/week @ 2024-05-27 65/week @ 2024-06-03 46/week @ 2024-06-10 56/week @ 2024-06-17 72/week @ 2024-06-24

每月下载量 258
用于 secret-toolkit

自定义许可

105KB
2K SLoC

秘密合约开发工具包 - SNIP20 接口

⚠️ 此包是 secret-toolkit 包的子包。请参阅其 crate 页面以获取更多上下文。

这些函数旨在帮助您轻松与符合 SNIP20 规范的代币进行交互。

处理消息

您可以通过创建一个 HandleMsg 变体并调用 to_cosmos_msg 函数来生成应推送到 InitResponse 或 HandleResponse messages Vec 的 CosmosMsg。

或者,您可以调用每个 Handle 消息的单独函数来生成相应的回调 CosmosMsg。

示例

# use cosmwasm_std::{Uint128, StdError, StdResult, CosmosMsg, Response};
# use secret_toolkit_snip20::{transfer_msg};
#
# fn main() -> StdResult<()> {
let recipient = "ADDRESS_TO_TRANSFER_TO".to_string();
let amount = Uint128::from(10000u128);
let memo = Some("memo".to_string());
let padding = None;
let block_size = 256;
let callback_code_hash = "TOKEN_CONTRACT_CODE_HASH".to_string();
let contract_addr = "TOKEN_CONTRACT_ADDRESS".to_string();

let cosmos_msg = transfer_msg(
    recipient,
    amount,
    memo,
    padding,
    block_size,
    callback_code_hash,
    contract_addr,
)?;

let response = Ok(Response::new().add_message(cosmos_msg));
# response.map(|_r| ())
# }

要调用 SNIP-20 Handle 函数,您只需调用相应的工具函数,并将生成的 CosmosMsg 放入 InitResponse 或 HandleResponse 的 messages Vec 中。在此示例中,我们正在将 10000(代币最低面额)转移到接收者地址。我们没有使用 Transfer 消息的 padding 字段,而是将整个消息填充到 256 字节块。

您可能也注意到CreateViewingKey不支持。这是因为合约无法看到返回的观看密钥,因为CreateViewingKey被调用时,合约已经执行完成。如果合约需要观看密钥,它必须创建自己的足够复杂的观看密钥,并将其作为参数传递给SetViewingKey。您可以在Snip20参考实现中看到一个创建复杂观看密钥的例子。还强烈建议您使用block_size填充选项来隐藏合约生成的观看密钥的长度。

查询

这些是SNIP20代币可以从查询中返回的类型

# use cosmwasm_std::{Uint128, Coin};
# use serde::Serialize;
#
# #[derive(Serialize)]
pub struct TokenInfo {
    pub name: String,
    pub symbol: String,
    pub decimals: u8,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub total_supply: Option<Uint128>,
}

pub struct ExchangeRate {
    pub rate: Uint128,
    pub denom: String,
}

# #[derive(Serialize)]
pub struct Allowance {
    pub spender: String,
    pub owner: String,
    pub allowance: Uint128,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub expiration: Option<u64>,
}

pub struct Balance {
    pub amount: Uint128,
}

# #[derive(Serialize)]
pub struct Tx {
    pub id: u64,
    pub from: String,
    pub sender: String,
    pub receiver: String,
    pub coins: Coin,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub memo: Option<String>,
    pub block_time: Option<u64>,
    pub block_height: Option<u64>,
}

pub struct TransferHistory {
    pub total: Option<u64>,
    pub txs: Vec<Tx>,
}

# #[derive(Serialize)]
#[serde(rename_all = "snake_case")]
pub enum TxAction {
    Transfer {
        from: String,
        sender: String,
        recipient: String,
    },
    Mint {
        minter: String,
        recipient: String,
    },
    Burn {
        burner: String,
        owner: String,
    },
    Deposit {},
    Redeem {},
}

# #[derive(Serialize)]
pub struct RichTx {
    pub id: u64,
    pub action: TxAction,
    pub coins: Coin,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub memo: Option<String>,
    pub block_time: u64,
    pub block_height: u64,
}

pub struct TransactionHistory {
    pub total: Option<u64>,
    pub txs: Vec<RichTx>,
}

pub struct Minters {
    pub minters: Vec<String>,
}

您可以通过创建QueryMsg变体并调用query函数来查询SNIP20代币合约。

或者您可以分别调用每个查询的单独函数。

示例

# use cosmwasm_std::{StdError, QuerierWrapper, testing::mock_dependencies};
# use secret_toolkit_snip20::balance_query;
# let mut deps = mock_dependencies();
#
let address = "ADDRESS_WHOSE_BALANCE_IS_BEING_REQUESTED".to_string();
let key = "THE_VIEWING_KEY_PREVIOUSLY_SET_BY_THE_ADDRESS".to_string();
let block_size = 256;
let callback_code_hash = "TOKEN_CONTRACT_CODE_HASH".to_string();
let contract_addr = "TOKEN_CONTRACT_ADDRESS".to_string();

let balance =
    balance_query(deps.as_ref().querier, address, key, block_size, callback_code_hash, contract_addr);
#
# assert_eq!(
#     balance.unwrap_err().to_string(), 
#     "Generic error: Error performing Balance query: Generic error: Querier system error: No such contract: TOKEN_CONTRACT_ADDRESS"
# );

在这个例子中,我们正在对指定的地址/密钥对进行余额查询,并将响应存储在Balance变量中,该变量是上面定义的Balance类型。查询消息填充到256字节的块中。

依赖项

~2–3.5MB
~79K SLoC