15个版本 (6个重大更新)
0.7.2 | 2022年12月16日 |
---|---|
0.7.1 | 2022年11月19日 |
0.6.1 | 2022年9月22日 |
0.4.0 | 2022年7月11日 |
#1978 in 魔法豆
每月下载量:158
115KB
2K SLoC
此包将重命名为 near-sdk-contract-tools
near-contract-tools
为NEAR协议开发智能合约的有用函数和宏。
此包收集了NEAR智能合约开发中的常见工具和模式
不要与 near-contract-standards
混淆,它包含标准NEP的官方实现。此crate旨在与 near-contract-standards
相辅相成。
警告: 这仍然是一款早期软件,版本之间可能会有破坏性更改。我会尽力保持文档和变更日志的更新。如果您发现任何问题,请毫不犹豫地创建一个问题。
优点
- 需要更少的代码行数
- 在没有near-contract-tools的情况下,实现非同质化代币事件(铸造、转移和销毁)需要约100行代码。使用near-contract-tools,您可以在约40行代码中实现它们。
- 更易于阅读
- 遵循一致的模式
- 每次您使用事件宏时,它都会以相同的方式实现事件。请参考此链接。如果没有它,您需要确保
emit
、emit_many
等所有功能(以及它们以相同的方式工作)。
- 每次您使用事件宏时,它都会以相同的方式实现事件。请参考此链接。如果没有它,您需要确保
- 更全面
- 接近合约标准也没有实现特性,这是near-contract-tools提供的另一个改进。
您可以将这个常用工具和模式的集合(主要以derive宏的形式)视为NEAR版的OpenZeppelin。
入门指南
rustup target add wasm32-unknown-unknown
cargo init
cargo add near-contract-tools
cargo add near-sdk
# https://raen.dev/guide/intro/getting-set-up.html
cargo install raen
# Implement a contract. See `workspaces-tests/src/bin/simple_multisig.rs` for example until we offer better examples here. Then:
near dev-deploy $(raen build --release -q)
示例用法
安装NEAR CLI后,调用如下:
near call dev-1662491554455-22903649156976 new --account-id example-acct-alice.testnet
near call dev-1662491554455-22903649156976 obtain_multisig_permission --account-id example-acct-alice.testnet
near call dev-1662491554455-22903649156976 request '{"action": "hello"}' --account-id example-acct-alice.testnet
near call dev-1662491554455-22903649156976 approve '{"request_id": 0}' --account-id example-acct-alice.testnet
near call dev-1662491554455-22903649156976 obtain_multisig_permission --account-id example-acct-bob.testnet
near call dev-1662491554455-22903649156976 approve '{"request_id": 0}' --account-id example-acct-bob.testnet
near call dev-1662491554455-22903649156976 execute '{"request_id": 0}' --account-id example-acct-bob.testnet
构建和测试
如果尚未安装,请安装cargo-make
cargo install cargo-make
运行测试
cargo test
cd workspaces-tests
cargo make test
示例
另请参阅:完整的集成测试。
所有者
use near_sdk::{near_bindgen, AccountId};
use near_contract_tools::{owner::Owner, Owner};
#[derive(Owner)]
#[near_bindgen]
struct Contract {
// ...
}
#[near_bindgen]
impl Contract {
#[init]
pub fn new(owner_id: AccountId) -> Self {
let mut contract = Self {
// ...
};
Owner::init(&mut contract, &owner_id);
contract
}
pub fn owner_only(&self) {
Self::require_owner();
// ...
}
}
Owner
derive宏向区块链公开以下方法
fn own_get_owner(&self) -> Option<AccountId>;
fn own_get_proposed_owner(&self) -> Option<AccountId>;
fn own_renounce_owner(&mut self);
fn own_propose_owner(&mut self, account_id: Option<AccountId>);
fn own_accept_owner(&mut self);
事件
可以将#[event]
宏应用于结构体或枚举。
use near_contract_tools::{event, standard::nep297::Event};
#[event(standard = "nft", version = "1.0.0")]
pub struct MintEvent {
pub owner_id: String,
pub token_id: String,
}
let e = MintEvent {
owner_id: "account".to_string(),
token_id: "token_1".to_string(),
};
// Emits the event to the blockchain
e.emit();
可转让代币
要创建一个兼容NEP-141和NEP-148标准的合约,该合约会发出符合标准的事件(NEP-141、NEP-297)。
use near_contract_tools::FungibleToken;
use near_sdk::near_bindgen;
#[derive(FungibleToken)]
#[fungible_token(
name = "My Fungible Token",
symbol = "MYFT",
decimals = 18,
no_hooks
)]
#[near_bindgen]
struct FungibleToken {
// ...
}
每个标准的独立宏也存在。
宏组合
有人可能希望在单个合约中组合多个宏的功能。所有宏都编写为可以独立工作,因此这应该不会出现问题。然而,有时可能希望宏以组合的方式一起工作。例如,为了使可转让代币可暂停,请使用可转让代币钩子要求在执行代币转让之前取消合约的暂停。
use near_contract_tools::{
pause::Pause,
standard::nep141::{Nep141Hook, Nep141Transfer},
FungibleToken, Pause,
};
use near_sdk::near_bindgen;
#[derive(FungibleToken, Pause)]
#[fungible_token(name = "Pausable Fungible Token", symbol = "PFT", decimals = 18)]
#[near_bindgen]
struct Contract {}
impl Nep141Hook for Contract {
fn before_transfer(&mut self, _transfer: &Nep141Transfer) {
Contract::require_unpaused();
}
}
注意:可以使用#[nep141(no_hooks)]
或#[fungible_token(no_hooks)]
禁用钩子。
自定义Crate
如果您是库开发者,修改了near-contract-tools
宏使用的某个crate(如serde
或near-sdk
),或者以不同名称使用crate,您可以在宏中指定crate名称,如下所示
#[event(
// ...
crate = "near_contract_tools",
macros = "near_contract_tools_macros",
serde = "serde",
)]
// ...
#[derive(Owner)]
#[owner(
// ...
near_sdk = "near_sdk",
)]
其他技巧
内部方法与外部方法
内部方法无法通过区块链调用。外部方法是公共的,可以被其他合约调用。
提案模式
提出所有权(而不是直接转让)通常是良好的实践,因为它可以防止您意外将所有权转让给无法访问的帐户(这将杀死合约)。
展开
cargo expand
将生成一个包含所有生成的宏的巨大Rust文件
cargo install cargo-expand
cargo expand > expanded.rs
所有者特性
为了实现所有者特性,您只需实现一个函数:“root”。
槽
请参阅src/slot.rs。它们是存储键的非常薄的包装器。它提供了一种命名空间/键组合功能,还提供了“读取”、“写入”、“存在”、“删除”等功能。
关于NEAR功能的提醒
-
在 near_sdk 中,
assert_one_yocto()
是一个需要完整访问密钥(通过要求存入一个 yoctonear,NEAR 的最小单位)的功能。这为什么重要呢?
如果用户将他们的 NEAR 账户连接到 dapp 并授予 dapp 代表他们调用此智能合约上函数的权限,那么 dapp 仍然 无法代表他们调用 此函数(即任何调用
assert_one_yocto()
的函数)。唯一添加此要求(强制交易由完整访问密钥签名)的方式是要求进行一些非零转账。
贡献
入门指南
首先,运行 git config core.hooksPath hooks/
安装此目录的钩子(不会影响其他项目的 git 钩子工作)。
作者
- Jacob Lindahl @sudo_build
依赖关系
~5.5–7.5MB
~144K SLoC