30个版本 (14个稳定版)
| 5.0.0 | 2024年3月11日 |
|---|---|
| 5.0.0-rc.2 | 2024年2月28日 |
| 5.0.0-rc | 2023年11月30日 |
| 4.3.0 | 2023年8月24日 |
| 3.0.0-rc4 | 2021年7月22日 |
#1154 in 魔法豆
5,719 每月下载量
在 51 个crate(2个直接使用) 中使用
105KB
1.5K SLoC
Parity的ink!用于编写智能合约
ink! 是一个用于在基于 Substrate 框架的区块链上用Rust语言编写智能合约的嵌入式领域特定语言(eDSL)。ink!合约被编译为WebAssembly。
更多相关链接
- Substrate Stack Exchange — 回答ink!问题的论坛
cargo-contract— ink!合约的命令行工具- Contracts UI —— 合约实例化和交互的前端
- Substrate Contracts Node —— 简单的 Substrate 区块链,包含智能合约功能
- Awesome ink! - Parity's ink! 的精选优秀项目列表
- 我们在 Matrix 和 Discord(在
ink_smart-contracts频道)上发布公告。
目录
玩转 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 文件,它们都位于您的合约的 target 文件夹中。该 .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-Erc721NFT代币的示例实现。dns- 一个简单的DomainNameService智能合约。- ……等等,更多内容请查看文件夹 🙃。
要构建单个示例,请导航到示例的根目录并运行
cargo contract build
现在您应该在合约的target文件夹中找到一个名为<name>.contract的文件。
有关如何将此文件上传到链的信息,请参阅玩转它部分或我们的智能合约研讨会。
工作原理
- 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(可支付)] |
适用于ink!消息。 | 允许在ink!消息调用中接收价值。ink!构造函数隐式为可支付。 |
#[ink(选择器=S:u32)] |
适用于ink!消息和ink!构造函数。 | 指定一个具体的调度选择器,用于标记实体。这允许合约作者精确控制其API的选择器,使得在不破坏的情况下重命名API成为可能。 |
#[ink(选择器= _)] |
适用于ink!消息。 | 指定当没有其他ink!消息与选择器匹配时调用的回退消息。 |
#[ink(命名空间=N:string)] |
适用于ink!特性实现块。 | 更改特性实现中所有ink!消息和ink!构造函数的结果选择器。允许在具有重叠消息或构造函数名称的特性实现之间消除歧义。请谨慎使用并仔细考虑! |
#[ink(实现)] |
适用于ink!实现块。 | 告诉ink!代码生成器,某些实现块应被授予访问ink!内部权限,即使它不包含任何ink!消息或ink!构造函数。 |
有关这些和有关#[ink::contract]宏的详细信息,请参阅此处。
特质定义
使用#[ink::trait_definition]来定义您自己的特性定义,然后ink!智能合约可以实现。例如,请参阅examples/trait-erc20合约,了解如何使用它或文档以获取详细信息。
链下测试
#[ink::test]过程宏启用链下测试。例如,请参阅examples/erc20合约,了解如何使用这些或文档以获取详细信息。
开发者文档
我们有一个非常全面的文档门户,但如果您正在寻找 crate 级别的文档本身,那么以下是一些相关链接
| 包 | 文档 | 描述 |
|---|---|---|
ink |
ink!公开的语言特性。有关可以在#[ink::contract]中使用的属性的详细描述,请参阅此处。 |
|
ink_storage |
ink!中可用的数据结构。 | |
ink_env |
与智能合同Wasm执行器交互的低级接口。还包括链下测试API。 | |
ink_prelude |
无_std和std访问alloc crate类型的通用API。 |
社区徽章
常规设计
[](https://github.com/paritytech/ink)
平面设计
[](https://github.com/paritytech/ink)
贡献
有关更多信息,请访问我们的贡献指南。
请使用位于 scripts/check-* 目录下的脚本,以便对工作区或所有示例运行检查。请在向PR推送工作之前完成此操作。
许可
本存储库中的所有代码均根据 Apache License 2.0 许可。
如果您对我们的产品许可有任何疑问,请联系我们。
依赖项
~4–5.5MB
~96K SLoC