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日

#1003 in 魔法豆

Download history 1461/week @ 2024-03-14 1075/week @ 2024-03-21 894/week @ 2024-03-28 821/week @ 2024-04-04 984/week @ 2024-04-11 1006/week @ 2024-04-18 941/week @ 2024-04-25 1067/week @ 2024-05-02 983/week @ 2024-05-09 1304/week @ 2024-05-16 694/week @ 2024-05-23 1801/week @ 2024-05-30 552/week @ 2024-06-06 778/week @ 2024-06-13 840/week @ 2024-06-20 547/week @ 2024-06-27

2,847 每月下载
用于 47 个 crate (9 个直接使用)

Apache-2.0

410KB
9K SLoC

ink!

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

linux codecov coveralls loc stack-exchange

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


初学者指南  •   ink! 文档门户  •   开发者文档


更多相关链接

目录

玩转ink!

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

如果您想本地设置,可以使用我们的 substrate-contracts-node 进行快速入门。这是一个简单的包含智能合约功能的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合约的特质并实现了它。
  • erc721 - 一个Erc721 NFT代币的示例实现。
  • dns - 一个简单的DomainNameService智能合约。
  • …还有更多,只需在文件夹中翻找即可 🙃。

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

cargo contract build

现在你应该可以在合约的target文件夹中找到一个<name>.contract文件。

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

工作原理

  • Substrate的模块化实体运行时聚合框架(FRAME)包含一个模块,该模块实现了一个API,用于典型函数智能合约需要的存储、查询账户信息等。这个模块被称为contracts
  • contracts需要智能合约作为Wasm blob上传到区块链。
  • 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(选择器=S:u32)] 适用于ink!消息和ink!构造函数。 指定为标记实体指定的具体调度选择器。这允许合约作者精确控制其API的选择器,从而使重命名API而不会中断成为可能。
#[ink(选择器= _)] 适用于ink!消息。 指定了一个后备消息,如果没有任何其他ink!消息与选择器匹配,则会调用该消息。
#[ink(命名空间=N:string)] 适用于ink!特质实现块。 更改特质实现中所有ink!消息和ink!构造函数的结果选择器。允许区分具有重叠消息或构造函数名称的特质实现。请谨慎使用并仔细考虑!
#[ink(impl)] 适用于ink!实现块。 告诉ink!代码生成器,某些实现块应被授予访问ink!内部权限,即使它不包含任何ink!消息或ink!构造函数。

有关这些的更详细描述以及有关#[ink::contract]宏的详细信息,请参阅此处

特质定义

使用#[ink::trait_definition]来定义您自己的特质定义,然后ink!智能合约可以实施。例如,请参阅examples/trait-erc20合约,了解如何使用它或文档以获取详细信息。

链下测试

#[ink::test]过程宏启用链下测试。例如,请参阅examples/erc20合约,了解如何使用它或文档以获取详细信息。

开发者文档

我们有一个非常全面的文档门户,但如果您正在寻找crate级别的文档本身,则这些是相关链接

crate 文档 描述
ink ink!公开的语言功能。有关您可以在#[ink::contract]中使用属性的详细描述,请参阅此处
ink_storage ink!中可用的数据结构。
ink_env 与智能合约Wasm执行器交互的底层接口。还包含链下测试API
ink_prelude 无_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)

贡献

有关更多信息,请参阅我们的贡献指南

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

许可

本存储库中的所有代码均采用Apache License 2.0许可。

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

依赖项

~1.2–2MB
~42K SLoC