跳转至

智能合约 API 函数

原文:https://docs.elrond.com/developers/developer-reference/elrond-wasm-api-functions

Rust 框架提供了Elrond VM API 函数和账户级内置函数的包装器。它们被分成多个模块,按类别分组:

  • BlockchainApi:提供一般的区块链信息,范围从帐户余额、NFT 元数据/角色到关于当前和先前块的信息(nonce、epoch 等)。)
  • CallValueApi:在可支付端点中使用,提供关于作为支付接收的代币的信息(代币类型、nonce、数量)
  • CryptoApi:提供对哈希和签名检查等加密功能的支持
  • SendApi:处理所有类型的帐户转移和智能合约呼叫/部署/升级,以及对 ESDT 本地内置功能的支持

api 的源代码可以在这里找到:https://github . com/elrond network/elrond-wasm-RS/tree/master/elrond-wasm/src/API

区块链 API

这个 API 可以通过self.blockchain()访问。可用功能:

get _ sc _ address

get_sc_address() -> ManagedAddress 

返回智能合约自己的地址。

获取 _ 所有者 _ 地址

get_owner_address() -> ManagedAddress 

返回所有者的地址。

查 _ 来电 _ 是 _ 车主

check_caller_is_owner() 

如果调用方不是所有者,则终止执行并发出错误信号。

使用#[only_owner]端点注释,而不是直接调用这个函数。

获取 _ 分片 _ 地址

get_shard_of_address(address: &ManagedAddress) -> u32 

返回作为参数传递的地址碎片。

是 _ 智能 _ 合约

is_smart_contract(address: &ManagedAddress) -> bool 

如果作为参数传递的地址是智能合约地址,则返回true,对于简单帐户,返回false

get _ caller

get_caller() -> ManagedAddress 

返回当前调用方。

请记住,对于 SC 查询,该函数将返回 SC 自己的地址,因此使用该 API 函数的视图函数不会有预期的行为。

获取 _ 平衡

get_balance(address: &ManagedAddress) -> BigUint 

返回给定地址的 EGLD 余额。

这只适用于与智能合约位于同一个碎片中的地址。

get _ sc _ balance

get_sc_balance(token: &EgldOrEsdtTokenIdentifier, nonce: u64) -> BigUint 

返回智能合约的 EGLD/ESDT/NFT 余额。

对于可替换的 ESDT,nonce 应该为 0。要获得 EGLD 平衡,您可以简单地将EgldOrEsdtTokenIdentifier::egld()作为参数传递。

get _ tx _ hash

get_tx_hash() -> ManagedByteArray<Self::Api, 32> 

返回当前的发送哈希。

在异步调用的情况下,原始调用和相关回调中的 tx 散列是相同的。

get _ gas _ left

get_gas_left() - > u64 

返回调用时剩余的气体。

这对于昂贵的操作很有用,比如遍历存储中的一组用户并发送奖励。

用完燃气的智能合约调用将恢复所有操作,因此该函数可用于在用完燃气之前返回,保存一个检查点,并在第二次调用时继续。

获取 _ 块 _ 时间戳

get_block_timestamp() -> u64 

get _ block _ nonce

get_block_nonce() -> u64 

get _ block _ round

get_block_round() -> u64 

get _ block _ epoch

get_block_epoch() -> u64 

这些功能主要用于设置截止日期,所以它们被组合在一起。

获取 _ 区块 _ 随机 _ 种子

get_block_random_seed() -> ManagedByteArray<Self::Api, 48> 

返回块随机种子,可用于生成随机数。

这对于当前块中的所有调用都是相同的,因此可以通过某人在该轮开始时调用此调用,然后调用您的合约来预测。

get _ prev _ block _ timestamp

get_prev_block_timestamp() -> u64 

get _ prev _ block _ nonce

get_prev_block_nonce() -> u64 

get _ prev _ block _ round

get_prev_block_round() -> u64 

get _ prev _ block _ epoch

get_prev_block_epoch() -> u64 

get _ prev _ block _ random _ seed

get_prev_block_random_seed() -> ManagedByteArray<Self::Api, 48> 

与上面的函数相同,但用于前一个块而不是当前块。

获取 _ 当前 _esdt_nft_nonce

get_current_esdt_nft_nonce(address: &ManagedAddress, token_id: &TokenIdentifier) -> u64 

获取 SFT/NFT 的最后一个随机数。Nonces 在每次 ESDTNFTCreate 操作后递增。

这仅适用于设置了 ESDTNFTCreateRole 的帐户,并且仅适用于与智能合约位于同一分片中的帐户。

该函数通常与self.blockchain().get_sc_address()一起用于创建 SFT/NFT 的智能合约。

get _ esdt _ balance

get_esdt_balance(address: &ManagedAddress, token_id: &TokenIdentifier, nonce: u64) -> BigUint 

获取指定地址的 ESDT/SFT/NFT 余额。

这只适用于与智能合约位于同一个碎片中的地址。

对于可替换的 ESDT,nonce 应该为 0。对于 EGLD 平衡,使用get_balance代替。

get _ esdt _ token _ data

get_esdt_token_data(address: &ManagedAddress, token_id: &TokenIdentifier, nonce: u64) -> EsdtTokenData<Self::Api> 

获取由指定地址拥有的特定代币类型的 ESDT 代币属性。

EsdtTokenData有以下格式:

pub struct EsdtTokenData<M: ManagedTypeApi> {
    pub token_type: EsdtTokenType,
    pub amount: BigUint<M>,
    pub frozen: bool,
    pub hash: ManagedBuffer<M>,
    pub name: ManagedBuffer<M>,
    pub attributes: ManagedBuffer<M>,
    pub creator: ManagedAddress<M>,
    pub royalties: BigUint<M>,
    pub uris: ManagedVec<M, ManagedBuffer<M>>,
} 

token_type是一个枚举,可以具有下列值之一:

pub enum EsdtTokenType {
    Fungible,
    NonFungible,
    SemiFungible,
    Meta,
    Invalid,
} 

您将只收到代币类型的基本区别,即只有FungibleNonFungible(智能合约无法区分不可替代、半可替代和元代币)。

amount是账户当前拥有的余额。

frozen为布尔值,表示账户是否被冻结。

hash是 NFT 的杂凑。一般来说,这将是attributes的散列,但是这不是强制的。此外,哈希长度也不固定。

name是 NFT 的名称,通常在前端应用程序中用作显示名称。

attributes可以包含任何用户自定义的数据。如果您知道格式,您可以使用EsdtTokenData::decode_attributes方法来反序列化它们。

creator是创作者的地址。

0 到 10,000 之间的一个数字,表示创作者获得的任何销售价格的百分比。这是用在 ESDT NFT 市场,但没有以任何其他方式强制执行。(这些百分比的工作方式是 5,444 将是 54.44%,您将计算它:价格* 5,444 / 10,000。该约定用于授予一些额外的精度)

uris列出 URIs 给的一个图像/音频/视频,它代表给定的 NFT。

这只适用于与智能合约位于同一个碎片中的地址。

大多数情况下,该函数与作为地址的self.blockchain().get_sc_address()一起使用,以获取智能合约拥有的代币的属性,或者在当前执行的调用中被转移到智能合约的代币的属性。

get _ esdt _ local _ roles

get_esdt_local_roles(token_id: &TokenIdentifier) -> EsdtLocalRoleFlags 

以位标志形式获取为智能合约设置的 ESDTLocalRoles。返回的类型包含检查角色是否存在以及迭代所有角色的方法。

这是通过简单地读取受保护的存储器来完成的,但是这是一个使用方便的函数。

调用值 API

这个 API 可以通过self.call_value()访问。替代方法是使用#[payment]注释,但是我们不再推荐它们。他们有制造混乱的历史,尤其是对新用户。

可用功能:

egld _ value

egld_value() -> BigUint 

返回当前交易中传输的 EGLD 的数量。将为 ESDT 转账返回 0。

所有 _ esdt _ 转账

all_esdt_transfers() -> ManagedVec<EsdtTokenPayment<Self::Api>> 

返回所有 ESDT 转移。当您期望可变的传输次数时,这很有用。

将付款返回到结构的ManagedVec中,该结构包含代币类型、代币 ID、代币 nonce 和被转移的金额:

pub struct EsdtTokenPayment<M: ManagedTypeApi> {
    pub token_identifier: TokenIdentifier<M>,
    pub token_nonce: u64,
    pub amount: BigUint<M>,
} 

多 _esdt

multi_esdt<const N: usize>() -> [EsdtTokenPayment<Self::Api>; N] 

以数组形式返回固定数量的 ESDT 传输。如果 ESDT 传送的数量与N不同,将发出错误信号。

例如,如果您总是期望在您的端点中正好有 3 笔付款,您可以这样使用此函数: let [payment_a, payment_b, payment_c] = self.call_value().multi_esdt();

single _ esdt

single_esdt() -> EsdtTokenPayment<Self::Api> 

如果恰好收到一笔 ESDT 代币,则返回收到的代币付款。在多次传送或不传送的情况下将发出错误信号。

单一 _ 可替代 _esdt

single_fungible_esdt(&self) -> (TokenIdentifier, BigUint) 

类似于上面的功能,还强制支付为可替换的 ESDT。

egld _ or _ single _ 可替换 _esdt

egld_or_single_fungible_esdt(&self) -> (EgldOrEsdtTokenIdentifier<Self::Api>, BigUint) 

与上述功能相同,但也允许接收 EGLD。

egld _ or _ single _ esdt

egld_or_single_esdt() -> EgldOrEsdtTokenPayment<Self::Api> 

允许接收 EGLD 或任何单个 ESDT 代币。

加密 API

这个 API 可以通过self.crypto()访问。它提供散列函数和签名验证。因为这些函数是众所周知的,并且有自己的文档,所以我们在这一节就不详细介绍了。

哈希函数:

sha256

sha256(data: &ManagedBuffer) -> ManagedByteArray<Self::Api, 32> 

keccak 256

keccak256(data: &ManagedBuffer) -> ManagedByteArray<Self::Api, 32> 

ripem 160

ripemd160(data: &ManagedBuffer) -> ManagedByteArray<Self::Api, 20> 

签名验证功能:

验证 _ ed25519 _ 遗留 _ 托管

verify_ed25519_legacy_managed<const MAX_MESSAGE_LEN: usize>(key: &ManagedByteArray<Self::Api, 32>, message: &ManagedBuffer, signature: &ManagedByteArray<Self::Api, 64>) -> bool 

验证 _bls

verify_bls(key: &[u8], message: &[u8], signature: &[u8]) -> bool 

验证 _secp256k1

verify_secp256k1(key: &[u8], message: &[u8], signature: &[u8]) -> bool 

验证 _ 定制 _secp256k1

verify_custom_secp256k1(key: &[u8], message: &[u8], signature: &[u8], hash_type: MessageHashType) -> bool 

MessageHashType是一个枚举,表示用于创建message参数的哈希算法。如果消息是“纯文本”,请使用ECDSAPlainMsg

pub enum MessageHashType {
    ECDSAPlainMsg,
    ECDSASha256,
    ECDSADoubleSha256,
    ECDSAKeccak256,
    ECDSARipemd160,
} 

为了能够在没有动态分配的情况下使用散列函数,我们在 Rust 中使用了一个称为const generics的概念。这允许函数作为泛型有一个常量值,而不是泛型中常见的特征类型。该值用于分配一个静态缓冲区,在该缓冲区中数据被临时复制,然后被传递给遗留 API。

要调用这样一个函数,调用应该是这样的:

let hash = self.crypto().sha256_legacy_managed::<200>(&data); 

其中200data的最大预期字节长度。

编码 _ secp256k1 _ der _ 签名

encode_secp256k1_der_signature(r: &[u8], s: &[u8]) -> BoxedBytes 

根据提供的相应椭圆曲线参数创建签名。

发送 API

这个 API 可以通过self.send()访问。它提供了发送代币、执行智能合约调用、调用内置函数等功能。

我们不会描述 API 中的每一个函数,因为那样会造成混乱。我们将只描述推荐使用的那些(因为它们大多是更复杂的低级函数的包装)。

对于智能合约到智能合约的调用,使用代理,如合约调用部分所述。

事不宜迟,让我们来看看可用的函数:

直达

direct(to: &ManagedAddress, token: &EgldOrEsdtTokenIdentifier, nonce: u64, amount: &BigUint) 

使用一些可选的附加数据,对目标地址执行简单的 EGLD/ESDT/NFT 传输。如果要发送 EGLD,只需通过EgldOrEsdtTokenIdentifier::egld()。对于 EGLD 和可替代 ESDT,nonce都应该是 0。

如果目的地是不可支付的智能合约,这将失败,但是只有当目的地 SC 在同一个碎片中时,当前执行的交易才会失败,因此,对存储所做的任何改变都将持续。但是代币不会丢失,因为它们会自动返回。

即使无效的目标不会恢复,非法传输也会返回错误并恢复。非法转账是指会给 SC 留下特定代币的负余额的任何转账。

如果您不确定目的地的账户类型,您可以使用Blockchain API中的is_smart_contract功能。

如果您需要更多的控制,请使用direct_with_gas_limit功能。

direct _ egld

direct_egld(to: &ManagedAddress, amount: &BigUint) 

direct函数的 EGLD-transfer 版本。

direct _ esdt

direct_esdt(to: &ManagedAddress, token_id: &TokenIdentifier, token_nonce: u64, amount: &BigUint) 

direct功能的 ESDT 专用版本。这样你就不用把TokenIdentifier包装成EgldOrEsdtTokenIdentifier了。

直接 _ 多

direct_multi(to: &ManagedAddress, payments: &ManagedVec<EsdtTokenPayment<Self::Api>>) 

direct_esdt功能的多传输版本。请记住,不能用这个函数传输 EGLD,只能传输 ESDTs。

变更 _ 所有者 _ 地址

change_owner_address(child_sc_address: &ManagedAddress, new_owner: &ManagedAddress) 

将目标子合约的所有权更改为另一个地址。如果当前合约不是child_sc_address合约的所有者,这将失败。

这也意味着当前合约将不能调用子合约的#[only_owner]函数、升级或再次改变所有者。

esdt_local_mint(token: &TokenIdentifier, nonce: u64, amount: &BigUint) 

允许同步铸造 ESDT/SFT(取决于现时)。之后继续执行。请注意,SC 必须设置了ESDTLocalMintESDTNftAddQuantity角色,否则将出现“不允许操作”的错误。

对于 sft,您必须在添加额外数量之前使用esdt_nft_create

此功能不能用于 NFTs。

esdt _ local _ burn

esdt_local_burn(token: &TokenIdentifier, nonce: u64, amount: &BigUint) 

esdt_local_mint的逆操作,永久删除代币。请注意,SC 必须设置了ESDTLocalBurnESDTNftBurn角色,否则会出现“不允许操作”的错误。

与 mint 函数不同,这可以用于 NFT。

esdt_nft_create<T: elrond_codec::TopEncode>(token: &TokenIdentifier, amount: &BigUint, name: &ManagedBuffer, royalties: &BigUint, hash: &ManagedBuffer, attributes: &T, uris: &ManagedVec< ManagedBuffer>) -> u64 

创建一个新的 SFT/NFT,并返回其 nonce。

必须设置ESDTNftCreate角色,否则将失败并显示“不允许操作”。

token是 SFT/NFT 品牌的标识符。

amount是要铸造的代币数量。对于 NFTs,这应该是“1”。

name是代币的显示名称,将在浏览器、市场等中使用。

royalties是一个介于 0 和 10,000 之间的数字,代表创作者获得的任何销售金额的百分比。这种表示用于能够具有更高的精度。例如,像55.66%这样的百分比被存储为5566。这些特许权使用费是不强制执行的,将主要用于“官方”NFT 市场。

hash是代币的用户定义哈希。推荐值是 sha256(属性),但可以是任何值。

attributes可以是任何可序列化的用户定义结构,更具体地说,可以是实现TopEncode特征的任何类型。在撰写本文时,属性格式还没有真正的标准,但将来可能会改变。

uris是 NFTs 视频/音频表示的链接列表,大多数情况下,这些是图像、视频或歌曲的链接。如果为空,框架将自动添加一个“空”URI。

esdt_nft_create_compact<T: elrond_codec::TopEncode>(token: &TokenIdentifier, amount: &BigUint, attributes: &T) -> u64 

esdt_nft_create相同,但用默认值填充大多数参数。主要用于将 NFTs 作为信息手段而非展示目的的合约中。

出售 _nft

sell_nft(nft_id: &TokenIdentifier, nft_nonce: u64, nft_amount: &BigUint, buyer: &ManagedAddress, payment_token: &EgldOrEsdtTokenIdentifier, payment_nonce: u64, payment_amount: &BigUint) -> BigUint 

将 SFTs/NFTs 发送到目标地址,同时自动计算并向创作者发送 NFT 版税。返回扣除版税后剩余的金额。

(nft_id, nft_nonce, nft_amount)是将要发送到buyer地址的 sft/NFT。

是用来支付创作者版税的代币。

这个函数的目的主要是用在类似市场的智能合约中,合约向用户出售 NFT。

nft_add_uri(token_id: &TokenIdentifier, nft_nonce: u64, new_uri: ManagedBuffer) 

将 URI 添加到选定的 NFT。SC 必须拥有 NFT 并拥有能够使用该功能的ESDTRoleNFTAddURI

如果需要一次添加多个 URIs,可以使用nft_add_multiple_uri函数,该函数以一个ManagedVec<ManagedBuffer>作为参数。

NFT _ 更新 _ 属性

nft_update_attributes<T: TopEncode>(token_id: &TokenIdentifier, nft_nonce: u64, new_attributes: &T) 

将所选 NFT 的属性更新为提供的值。SC 必须拥有 NFT 并拥有能够更新属性的ESDTRoleNFTUpdateAttributes

结论

尽管 elrond-wasm 中还有其他各种 API,但它们对用户来说大多是隐藏的。这些是您将在日常智能合约开发中使用的工具。



回到顶部