33个版本 (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日 |
0.0.0 |
|
#561 in 神奇豆
每月下载量 3,266
用于 65 个crate(24个直接使用)
470KB
7.5K SLoC
更多相关链接
- Substrate Stack Exchange — 回答 ink! 问题的论坛
cargo-contract
— ink! 合约的 CLI 工具- Contracts UI —— 智能合约创建和交互的前端
- Substrate Contracts Node —— 简单的 Substrate 区块链,包含智能合约功能
- Awesome ink! - Parity ink! 的精选优秀项目列表
- 我们在 Matrix 和 Discord(在
ink_smart-contracts
频道)上发布公告。
目录
动手实践
要开始,请查看我们文档中的 入门 页面。
如果您想进行本地设置,可以使用我们的 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
文件夹中得到一个 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
文件包含 exactly 这段代码。运行 cargo contract build
来构建您的第一个 ink! 智能合约。
示例
在 examples
仓库中,您可以找到许多用 ink! 编写的示例。
其中一些最有趣的示例
basic_contract_ref
— 实现跨合约调用。trait-erc20
— 定义了Erc20
合约的 trait 并实现了它。erc721
—Erc721
NFT 代币的示例实现。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(主题)] |
适用于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 |
no_std和std访问alloc crate类型的通用API。 |
社区徽章
标准设计
[![Built with ink!](https://raw.githubusercontent.com/paritytech/ink/master/.images/badge.svg)](https://github.com/paritytech/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许可。
如果您对我们产品的许可有任何疑问,请联系我们。
依赖项
~3–6MB
~111K SLoC