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