#智能合约 #edsl #parity #区块链 #parity-wasm

无 std ink_macro

[ink!] 基于 Rust 的嵌入式领域特定语言 (eDSL),用于编写 Substrate 框架上的智能合约

16 个版本 (7 个稳定版)

5.0.0 2024 年 3 月 11 日
5.0.0-rc.22024 年 2 月 28 日
5.0.0-rc2023 年 11 月 30 日
4.3.0 2023 年 8 月 24 日
4.0.0-beta2022 年 11 月 22 日

#27 in #parity-wasm

Download history 935/week @ 2024-04-14 1140/week @ 2024-04-21 749/week @ 2024-04-28 1013/week @ 2024-05-05 1151/week @ 2024-05-12 1030/week @ 2024-05-19 613/week @ 2024-05-26 1734/week @ 2024-06-02 520/week @ 2024-06-09 849/week @ 2024-06-16 773/week @ 2024-06-23 418/week @ 2024-06-30 442/week @ 2024-07-07 751/week @ 2024-07-14 752/week @ 2024-07-21 984/week @ 2024-07-28

2,944 个月下载量
用于 39 个 crate(通过 ink

Apache-2.0

1MB
15K SLoC

ink!

Parity 的 ink! 用于编写智能合约

linux codecov coveralls loc stack-exchange

squink,ink! 的吉祥物ink! 是一个嵌入式领域特定语言 (eDSL),用于在 Rust 中编写基于 Substrate 框架的区块链智能合约。ink! 合约被编译为 WebAssembly。


初学者指导教程  •   ink! 文档门户  •   开发者文档


更多相关链接

目录

动手试一试

开始的最佳方式是查看我们文档中的 入门 页面。

如果您想进行本地设置,可以使用我们的 substrate-contracts-node 进行快速入门。这是一个简单的 Substrate 区块链,它包括智能合约功能的 Substrate 模块——contracts 插件(有关更多信息,请参阅 它是如何工作的)。

我们还在 Rococo 上有一个名为“Contracts”的实时测试网。Rococo 是一个基于 Substrate 的并行链,支持 ink! 智能合约。有关使用此测试网的进一步说明,请参阅 我们的文档

可以使用 Contracts UI 将您的合约实例化到链上并与之交互。

用法

编译智能合约的前提是已安装 Rust 和 Cargo。以下是 安装指南

我们还建议安装 cargo-contract。这是一个 CLI 工具,有助于设置和管理用 ink! 编写的 WebAssembly 智能合约。

cargo install cargo-contract --force

使用 --force 确保您已更新到最新版本的 cargo-contract

为了初始化一个新的 ink! 项目,您可以使用以下命令

cargo contract new flipper

这将创建一个位于您工作目录中的 flipper 文件夹。该文件夹包含一个模板 Cargo.toml 和一个 lib.rs,它们都包含了使用 ink! 所必需的构建块。

lib.rs 包含我们的 hello world 合约——Flipper,我们将在下一节中对其进行解释。

为了构建合约,只需在 flipper 文件夹中执行以下命令

cargo contract build

结果,您将在合约的 target 文件夹中获得一个 flipper.wasm 文件、一个 flipper.json 文件和一个 <contract-name>.contract 文件。该 .contract 文件将 Wasm 和元数据合并为单个文件,需要在实例化合约时使用。

你好,世界! —— 翻转者

Flipper 合约是一个简单的合约,只包含一个 bool 值。

它提供了以下方法

  • 将其值从 true 翻转到 false(反之亦然)
  • 并返回当前状态。

下面是使用 ink! 的代码示例。

#[ink::contract]
mod flipper {
    /// The storage of the flipper contract.
    #[ink(storage)]
    pub struct Flipper {
        /// The single `bool` value.
        value: bool,
    }

    impl Flipper {
        /// Instantiates a new Flipper contract and initializes
        /// `value` to `init_value`.
        #[ink(constructor)]
        pub fn new(init_value: bool) -> Self {
            Self {
                value: init_value,
            }
        }

        /// Flips `value` from `true` to `false` or vice versa.
        #[ink(message)]
        pub fn flip(&mut self) {
            self.value = !self.value;
        }

        /// Returns the current state of `value`.
        #[ink(message)]
        pub fn get(&self) -> bool {
            self.value
        }
    }

    /// Simply execute `cargo test` in order to test your contract
    /// using the below unit tests.
    #[cfg(test)]
    mod tests {
        use super::*;

        #[ink::test]
        fn it_works() {
            let mut flipper = Flipper::new(false);
            assert_eq!(flipper.get(), false);
            flipper.flip();
            assert_eq!(flipper.get(), true);
        }
    }
}

在我们的示例文件夹中,flipper/src/lib.rs 文件中正好包含这段代码。运行 cargo contract build 命令来构建您的第一个 ink! 智能合约。

示例

examples 仓库中,您可以找到许多用 ink! 编写的示例。

其中一些最有趣的示例

  • basic_contract_ref — 实现跨合约调用。
  • trait-erc20 — 定义了一个用于 Erc20 合约的 trait 并实现了它。
  • erc721Erc721 NFT 令牌的一个示例实现。
  • dns — 一个简单的 DomainNameService 智能合约。
  • …等等,只需在文件夹里翻找一下 🙃。

要构建单个示例,请导航到示例的根目录,并运行

cargo contract build

现在您应该在合约的 target 文件夹中有一个名为 <name>.contract 的文件。

有关如何将此文件上传到链的信息,请参阅动手玩一玩部分或我们的智能合约研讨会

它是如何工作的

  • Substrate 的 模块化实体的运行时聚合框架 (FRAME) 包含一个模块,该模块实现了智能合约需要的典型函数的 API(存储、查询账户信息等)。这个模块被称为 contracts 插件,
  • contracts 插件要求智能合约以 Wasm 块的形式上传到区块链。
  • ink! 是一种针对 contracts 暴露的 API 的智能合约语言。因此,ink! 合约被编译为 Wasm。
  • 当执行 cargo contract build 时,将创建一个额外的文件 <contract-name>.json。它包含有关合约提供哪些方法供他人调用的信息。

ink! 宏和属性概述

入口点

在一个使用 #[ink::contract] 注解的模块中,这些属性是可用的

属性 适用范围 描述
#[ink(storage)] struct 定义上。 定义 ink! 存储结构。每个合约只能有一个 ink! 存储定义。
#[ink(message)] 适用于方法。 将 ink! 存储结构中的方法标记为消息,使其可供 API 调用合约。
#[ink(constructor)] 适用于方法。 将 ink! 存储结构中的方法标记为构造函数,使其可供 API 实例化合约。
#[ink(event)] struct 定义上。 定义 ink! 事件。合约可以定义多个 ink! 事件。
#[ink(anonymous)] 适用于 ink! 事件。 告诉 ink! 代码生成器将 ink! 事件视为匿名事件,在发出时省略事件签名作为主题。与 Solidity 中的匿名事件非常相似。
#[ink(signature_topic= _)] 适用于 ink! 事件。 指定事件的自定义签名主题,允许手动指定共享事件定义。
#[ink(topic)] 适用于 ink! 事件字段。 告诉 ink! 代码生成器为给定字段提供主题哈希。ink! 事件只能有有限数量的此类主题字段。与 Solidity 中的索引事件参数具有相似语义。
#[ink(payable)] 适用于 ink! 消息。 允许在 ink! 消息调用中接收值。ink! 构造函数隐式地是可支付。
#[ink(selector=数据类型:u32)] 适用于ink!消息和ink!构造函数。 指定了一个用于标记实体的具体调度选择器。这允许合约作者精确控制其API的选择器,使得在API重命名时不会出现错误。
#[ink(selector= _)] 适用于 ink! 消息。 指定了一个后备消息,当没有其他ink!消息与选择器匹配时将调用。
#[ink(命名空间=N:字符串)] 适用于ink!特质实现块。 更改特质实现中所有ink!消息和ink!构造函数的结果选择器。允许在具有重叠消息或构造函数名称的特质实现之间消除歧义。请谨慎使用并仔细考虑!
#[ink(impl)] 适用于ink!实现块。 告诉ink!代码生成器,某些实现块应被授予访问ink!内部权限,即使它不包含任何ink!消息或ink!构造函数。

有关这些以及更多详细信息,请参阅[此处](https://paritytech.github.io/ink/ink/attr.contract.html)以及有关#[ink::contract]宏的详细信息。

特质定义

使用#[ink::trait_definition]来定义您自己的特质定义,然后ink!智能合约可以实现这些定义。例如,请参阅[此处](https://github.com/paritytech/ink-examples/blob/v4.0.1/trait-erc20/lib.rs#L20-L22)合同了解如何使用它,或参阅[此处](https://paritytech.github.io/ink/ink/attr.trait_definition.html)的文档以获取详细信息。

链外测试

#[ink::test]过程宏可以启用链下测试。例如,请参阅[此处](https://github.com/paritytech/ink-examples/blob/v4.0.1/erc20/lib.rs#L276-L277)合同了解如何使用这些,或参阅[此处](https://paritytech.github.io/ink/ink/attr.test.html)的文档以获取详细信息。

开发者文档

我们有一个[非常全面的文档门户](https://use.ink),但如果您正在寻找crate级别的文档本身,那么以下是一些相关链接

存储库 文档 描述
ink ink!公开的语言功能。有关您可以在#[ink::contract]中使用属性的详细描述,请参阅[此处](https://paritytech.github.io/ink/ink/attr.contract.html)。
ink_storage ink!中可用的数据结构。
ink_env 与智能合约Wasm执行器交互的低级接口。还包含[链下测试API](https://paritytech.github.io/ink/ink_env/test/index.html)。
ink_prelude no_std和std访问alloc crate类型的常用API。

社区徽章

常规设计

Built with ink!

[![Built with ink!](https://raw.githubusercontent.com/paritytech/ink/master/.images/badge.svg)](https://github.com/paritytech/ink)

扁平设计

Built with ink!

[![Built with ink!](https://raw.githubusercontent.com/paritytech/ink/master/.images/badge_flat.svg)](https://github.com/paritytech/ink)

贡献

有关更多信息,请访问我们的[贡献指南](https://github.com/paritytech/ink/blob/011b775bd238600edc36ea3b67c9b9edd325a3c9/crates/ink/macro/CONTRIBUTING.md)。

使用位于scripts/check-*目录下的脚本,对工作区或所有示例运行检查。请在推送PR中的工作之前执行此操作。

许可

本存储库中的全部代码均根据[Apache License 2.0](https://github.com/paritytech/ink/blob/011b775bd238600edc36ea3b67c9b9edd325a3c9/crates/ink/macro/LICENSE)许可。

如果您对我们的产品许可有任何疑问,请联系我们

依赖项

~3–5MB
~97K SLoC