10E polkadot substrate : 配置合约托盘

article/2025/8/26 8:06:01

• 介绍
• 添加托盘依赖项
• 实现 Contracts 配置特征
• 公开合约 API
• 更新外部节点
• 启动本地 Substrate 节点
• Substrate Tutorials , Substrate 教程
• Contact 联系方式

• 介绍

如果您完成了构建本地区块链教程,那么您已经知道 Substrate节点模板提供了一个工作运行时,其中包括一些供您入门的托盘。在将托盘添加到运行时中,您了解了将新托盘添加到运行时的基本常用步骤。但是,每个托盘都需要您配置特定的参数和类型。为了了解这意味着什么,本教程演示了向运行时添加更复杂的托盘。在本教程中,您将添加Contracts 托盘,以便您可以支持区块链的智能合约开发。

• 添加托盘依赖项

任何时候将托盘添加到运行时,都需要导入适当的 crate 并更新运行时的依赖项。对于 Contracts 托盘,您需要导入pallet-contractscrate。

• runtime/Cargo.toml在文本编辑器中打开配置文件。

• 通过将 crate 添加到依赖项列表中,导入pallet-contractscrate 以使其可用于节点模板运行时。

[dependencies.pallet-contracts]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
tag = 'latest'
version = '4.0.0-dev'[dependencies.pallet-contracts-primitives]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
tag = 'latest'
version = '4.0.0-dev'

• 将 Contracts 托盘添加到std功能列表中,以便在将运行时构建为原生 Rust 二进制文件时包含其功能。

[features]
default = ['std']
std = [#--snip--'pallet-contracts/std','pallet-contracts-primitives/std',#--snip--]

• 保存更改并关闭runtime/Cargo.toml文件。

• 实现 Contracts 配置特征

现在您已成功导入 Contracts 托盘箱,您可以将其添加到运行时。如果您浏览过其他教程,您可能已经知道每个托盘都有一个配置特征 - 称为Config- 运行时必须实现。

要Config在运行时实现 Contracts 托盘的特征:

• runtime/src/lib.rs在文本编辑器中打开文件。

• 找到pub use frame_support块并添加Nothing到特征列表中。

pub use frame_support::{construct_runtime, parameter_types,traits::{KeyOwnerProofSystem, Randomness, StorageInfo, Nothing},weights::{constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},IdentityFee, Weight,
},
StorageValue,
};

• 将WeightInfo属性添加到运行时。

/* After this line */
use pallet_transaction_payment::CurrencyAdapter;
/*** Add this line ***/
use pallet_contracts::weights::WeightInfo;

• 将 Contracts 托盘所需的常量添加到运行时。

/* After this block */
// Time is measured by number of blocks.
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
pub const HOURS: BlockNumber = MINUTES * 60;
pub const DAYS: BlockNumber = HOURS * 24;/* Add this block */
// Contracts price units.
pub const MILLICENTS: Balance = 1_000_000_000;
pub const CENTS: Balance = 1_000 * MILLICENTS;
pub const DOLLARS: Balance = 100 * CENTS;const fn deposit(items: u32, bytes: u32) -> Balance {items as Balance * 15 * CENTS + (bytes as Balance) * 6 * CENTS
}/// Assume ~10% of the block weight is consumed by `on_initialize` handlers.
/// This is used to limit the maximal weight of a single extrinsic.
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
/*** End Added Block ***/

• 将 Config 特征的参数类型和实现添加到运行时。

impl pallet_timestamp::Config for Runtime {
/* --snip-- */
}/*** Add this block ***/
parameter_types! {pub TombstoneDeposit: Balance = deposit(1,<pallet_contracts::Pallet<Runtime>>::contract_info_size());pub DepositPerContract: Balance = TombstoneDeposit::get();pub const DepositPerStorageByte: Balance = deposit(0, 1);pub const DepositPerStorageItem: Balance = deposit(1, 0);pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);pub const SurchargeReward: Balance = 150 * MILLICENTS;pub const SignedClaimHandicap: u32 = 2;pub const MaxValueSize: u32 = 16 * 1024;// The lazy deletion runs inside on_initialize.pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *BlockWeights::get().max_block;// The weight needed for decoding the queue should be less or equal than a fifth// of the overall weight dedicated to the lazy deletion.pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0))) / 5) as u32;pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
}impl pallet_contracts::Config for Runtime {type Time = Timestamp;type Randomness = RandomnessCollectiveFlip;type Currency = Balances;type Event = Event;type RentPayment = ();type SignedClaimHandicap = SignedClaimHandicap;type TombstoneDeposit = TombstoneDeposit;type DepositPerContract = DepositPerContract;type DepositPerStorageByte = DepositPerStorageByte;type DepositPerStorageItem = DepositPerStorageItem;type RentFraction = RentFraction;type SurchargeReward = SurchargeReward;type WeightPrice = pallet_transaction_payment::Module<Self>;type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;type ChainExtension = ();type DeletionQueueDepth = DeletionQueueDepth;type DeletionWeightLimit = DeletionWeightLimit;type Call = Call;/// The safest default is to allow no calls at all.////// Runtimes should whitelist dispatchables that are allowed to be called from contracts/// and make sure they are stable. Dispatchables exposed to contracts are not allowed to/// change because that would break already deployed contracts. The `Call` structure itself/// is not allowed to change the indices of existing pallets, too.type CallFilter = Nothing;type Schedule = Schedule;type CallStack = [pallet_contracts::Frame<Self>; 31];
}
/*** End added block ***/

• 将合同托盘中公开的类型添加到construct_runtime!宏中。

construct_runtime!(pub enum Runtime whereBlock = Block,NodeBlock = opaque::Block,UncheckedExtrinsic = UncheckedExtrinsic{/* --snip-- *//*** Add this ine ***/Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>},}
);

• 保存更改并关闭runtime/src/lib.rs文件。

• 通过运行以下命令检查您的运行时是否正确编译:

cargo check -p node-template-runtime

尽管运行时应该编译,但您还不能编译整个节点。

• 公开合约 API

一些托盘(包括合同托盘)公开了自定义运行时 API 和 RPC 端点。您无需启用 Contracts 托盘上的 RPC 调用即可在链上使用它。但是,公开 Contracts 托盘的 API 和端点很有用,因为这样做可以让您执行以下任务:

从链下读取合约状态。

在不进行事务的情况下调用节点存储。

要公开 Contracts RPC API:

• 在文本编辑器中打开runtime/Cargo.toml文件并添加依赖项部分以导入 Contracts RPC 端点运行时 API。

[dependencies.pallet-contracts-rpc-runtime-api]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
tag = 'latest'
version = '4.0.0-dev'

• 将 Contracts RPC API 添加到std功能列表中,以便在将运行时构建为原生 Rust 二进制文件时包含其功能。

[features]
default = ['std']
std = [#--snip--'pallet-contracts-rpc-runtime-api/std',
]

• 保存更改并关闭runtime/Cargo.toml文件。

• 打开文件并在运行时文件末尾附近的宏runtime/src/lib.rs中实现合约运行时 API 。impl_runtime_apis!lib.rs

impl_runtime_apis! {/* --snip-- *//*** Add this block ***/impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>for Runtime {fn call(origin: AccountId,dest: AccountId,value: Balance,gas_limit: u64,input_data: Vec<u8>,) -> pallet_contracts_primitives::ContractExecResult {let debug = true;Contracts::bare_call(origin, dest, value, gas_limit, input_data, debug)}fn instantiate(origin: AccountId,endowment: Balance,gas_limit: u64,code: pallet_contracts_primitives::Code<Hash>,data: Vec<u8>,salt: Vec<u8>,) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber> {let compute_rent_projection = true;let debug = true;Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, compute_rent_projection, debug)}fn get_storage(address: AccountId,key: [u8; 32],) -> pallet_contracts_primitives::GetStorageResult {Contracts::get_storage(address, key)}fn rent_projection(address: AccountId,) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {Contracts::rent_projection(address)}}/*** End added block ***/
}

• 保存更改并关闭runtime/src/lib.rs文件。

• 通过运行以下命令检查您的运行时是否正确编译:

cargo check -p node-template-runtime

• 更新外部节点

至此,您已完成将 Contracts 托盘添加到运行时。现在,您需要考虑外部节点是否需要任何相应的更新。要让 Contracts 托盘利用 RPC 端点 API,您需要将自定义 RPC 端点添加到节点配置中。

要将 RPC API 扩展添加到外部节点:

打开node/Cargo.toml文件并添加依赖项部分以导入 Contracts 和 Contracts RPC crates。

[dependencies]
jsonrpc-core = '15.1.0'
structopt = '0.3.8'
#--snip--
# *** Add the following lines ***[dependencies.pallet-contracts]
git = 'https://github.com/paritytech/substrate.git'
tag = 'latest'
version = '4.0.0-dev'[dependencies.pallet-contracts-rpc]
git = 'https://github.com/paritytech/substrate.git'
tag = 'latest'
version = '4.0.0-dev'

• node/src/rpc.rs在文本编辑器中打开文件。

Substrate 提供了一个 RPC 来与节点交互。但是,默认情况下它不包含对合同托盘的访问。要与合同托盘交互,您必须扩展现有的 RPC 并添加合同托盘及其 API。

use node_template_runtime::{opaque::Block, AccountId, Balance, Index, BlockNumber, Hash}; // NOTE THIS IS AN ADJUSTMENT TO AN EXISTING LINE
use pallet_contracts_rpc::{Contracts, ContractsApi};/* --snip-- *//// Instantiate all full RPC extensions.
pub fn create_full<C, P>(deps: FullDeps<C, P>,
) -> jsonrpc_core::IoHandler<sc_rpc::Metadata> where/* --snip-- */C: Send + Sync + 'static,C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,/*** Add This Line ***/C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,/* --snip-- */
{/* --snip-- */io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone())));/*** Add this block ***/// Contracts RPC API extensionio.extend_with(ContractsApi::to_delegate(Contracts::new(client.clone())));/*** End added block ***/io
}

• 保存更改并关闭node/src/rpc.rs文件。

• 通过运行以下命令检查您的运行时是否正确编译:

cargo check -p node-template-runtime

• 通过运行以下命令以发布模式编译节点:

cargo build --release

• 启动本地 Substrate 节点

在您的节点编译后,您就可以启动已通过Contracts 托盘中的智能合约功能增强的 Substrate 节点,并使用前端模板与其交互。

启动本地节点:

• 如有必要,打开终端外壳。

• 切换到 Substrate 节点模板的根目录。

• 通过运行以下命令以开发模式启动节点:

./target/release/node-template --dev

• 在新终端中,切换到安装前端模板的根目录。

• 通过运行以下命令启动前端模板的 Web 服务器:

yarn start

• 在浏览器中打开http://localhost:8000/以查看前端模板。

• 在 Pallet Interactor 组件中,确认选择了 Extrinsic。

• contracts从可调用的托盘列表中选择。
image

• Substrate Tutorials , Substrate 教程

CN 中文 Github Substrate 教程 : github.com/565ee/Substrate_CN
CN 中文 CSDN Substrate 教程 : blog.csdn.net/wx468116118
EN 英文 Github Substrate Tutorials : github.com/565ee/Substrate_EN
EN 英文 dev.to Substrate Tutorials : dev.to/565ee

• Contact 联系方式

Homepage : 565.ee
微信公众号 : wx468116118
微信 QQ : 468116118
GitHub : github.com/565ee
CSDN : blog.csdn.net/wx468116118
Email : 468116118@qq.com


http://chatgpt.dhexx.cn/article/UsPgYbwL.shtml

相关文章

Substrate之旅2:Substrate开发环境搭建

我们将基于Ubuntu 18.04来安装Substrate的开发环境。 我这边Ubuntu是安装在VMWorkstation虚拟机上的。 安装依赖 安装参考&#xff1a;https://docs.substrate.io/tutorials/v3/create-your-first-substrate-chain/#install-rust-and-the-rust-toolchain 但具体的操作步骤&…

认识substrate

了解substrate 前言从互联网发展看区块链未来--跨链跨链是未来 公链和联盟链可交互的联盟链polkadot组件substrate介绍区块链的构造组件substrate开发的特性 polkadot :substrate 之上建立如何通过substrate构造自己的链一键链上升级--永不分叉为什么需要链上升级 substrate与企…

CydiaSubstrate框架

往期推荐 Frida Native层HOOK Frida hook Java层 frida环境安装 Xposed框架安装、使用及插件开发 需要相关资料的朋友&#xff0c;可以【[加入此处即可打包获取]】 Cydia Substrate是一个基于Hook的代码修改框架&#xff0c;可以在Android、iOS平台使用&#xff0c;并实现…

创建Substrate 私有网络

创建Substrate 私有网络 所有区块链都要求网络中的节点就消息集及其顺序达成一致&#xff0c;以成功创建区块并从一个区块推进到下一个区块。每个块代表特定时间点的数据状态&#xff0c;节点对状态的一致称为共识。有几种不同的算法用于达成共识&#xff0c;包括&#xff1a;…

Build the Substrate Kitties Chain(中文翻译)

欢迎来到Substrate Kitties课程。 本课程将向您介绍如何构建一个可以创建并持有非同质化代币&#xff08;NFT&#xff0c;这个NFT名称为Substrate Kitties&#xff09;的区块链。课程分为部2部分&#xff1a; Part I 描述如何构建Kitties pallet&#xff0c;以及这个pallet怎样…

oracle substrate,Substrate 2.0 带来了哪些改变?

Substrate 已到了 2.0 版本的主要里程碑处。该区块链框架现在包含链下工作机(off-chain workers)和 70 多个可组合模块&#xff0c;并为构建优化的、与 Polkadot 兼容的、可投入生产的区块链奠定了坚实的基础。数十个实时区块链已经在运行 Substrate 2.0&#xff0c;包括Polkad…

Substrate 基础教程(Tutorials) -- 授权特定节点

五、授权特定节点 在添加可信节点中&#xff0c;您看到了如何使用一组已知的验证器节点构建一个简单的网络。该教程演示了一个简化版的许可网络&#xff08;permissioned network&#xff09;。在一个被许可的网络中&#xff0c;只有被授权的节点&#xff08;authorized nodes…

Substrate常见问题

目录标题 1. Rust nightly not installed, please install it!2. Rust WASM toolchain not installed, please install it!3. use pallet::*出错4. failed to load manifest for workspace member5. error: failed to run custom build command for node-template-runtime v4.0…

什么是 Substrate

如果你关注了 Polkadot 项目&#xff0c;可能会多次看到「Substrate」这个词。 它是 Polkadot 项目的重要组成部分&#xff0c;但有关它的信息非常少。 白皮书或黄皮书里找不到&#xff0c; 至少没有专门的介绍「Substrate」。 从较高的层面来看&#xff0c;Substrate 是一个可…

Substrate之旅3:Substrate是什么

Substrate 是从Polkadot 孵化出来的项目。它是一个用来搭建区块链的通用框架&#xff0c;具有以下特点&#xff1a; 可扩展。模块化。开源。 Substrate的框架与组件 框架 其中&#xff1a; P2P: libp2p网络协议&#xff0c;Substrate基于该协议实现了一个不带任何假设的&…

Substrate 基础 -- 教程(Tutorials)

官网 github DOC 面向未来的区块链框架 Substrate 使开发人员能够快速、轻松地构建适合任何用例的未来 证明区块链(future proof blockchains)。 Substrate 文档包括区块链构建器&#xff08;blockchain builders&#xff09;和parachain 项目团队的概念、过程和参考信息。…

【Android 逆向】substrate 框架 ( substrate 简介 | substrate 相关文档资料 )

文章目录 一、substrate 简介二、substrate 相关文档资料 一、substrate 简介 substrate 官网 : http://www.cydiasubstrate.com substrate 框架 是 Cydia 下的逆向工具 , 该框架是开源的 ; substrate 配合对应的 so 动态库 和 头文件 , 可以在 Android / iOS 平台中独立运行 …

ios tableView那些事(三)给tableView添加些图片

感觉光有数据的tableView很丑&#xff0c;那么我们就来美化下吧&#xff0c;加一些图片 #import <UIKit/UIKit.h> /*tableview 一定要用到这两个delegate UITableViewDataSource,UITableViewDelegate */ interface ViewController :UIViewController <UITableViewDa…

QT的TableView实现多级表头

QT的TableView实现多级表头 最近项目需要支持多级表头&#xff0c;QT本身不支持。可重写QHeaderView表头实现。 demo如下&#xff1a; FSItemDelegate.h #pragma once/* 自定义委托类 */ #include <QItemDelegate> #include <QSpinBox> #include <QDoubleSpin…

QML类型:TableView

一、描述 TableView 显示从内置 QML 类型&#xff08;如 ListModel 和 XmlListModel&#xff09;创建的模型中的数据&#xff0c;这些模型仅填充 TableView 中的第一列。要创建具有多列的模型&#xff0c;请使用 TableModel 或继承 QAbstractItemModel 的 C 模型。 TableView…

QML TableView表格使用示例

前言 QML中实现表格可以使用多种方式&#xff0c;比如直接使用ListView&#xff0c;定义每一行delegate&#xff0c;或者自定义Rectangle&#xff0c;放到Flipable中组合使用。Qt Quick Control1中 从5.1版本开始就提供了表格控件&#xff0c;但是感觉不怎么好用&#xff0c;在…

Qt TableView的简单使用

软件环境&#xff1a; ubuntu -------------------------------------------------------------------------------------------------------- 最终效果图&#xff1a; --------------------------------------------------------------------------------------------------…

PyQt5 TableView组件

一、话不多说&#xff0c;先看图 本次要实现的是主窗口内添加widget组件&#xff0c;widget内设置成垂直盒布局&#xff0c;然后在布局中添加tableView、PushButton组件 二、看main函数 if __name__ __main__:app QApplication(sys.argv)# 现在这创建 主窗口 &#xff08;不然…

优雅的开发TableView

前言 UITableView&#xff08;UITableViewController&#xff09;是iOS开发使用频率最高的一个组件。 不管是使用UITableView还是还是UITableViewController&#xff0c;在开发的时候&#xff0c;我们都需要实现两个协议&#xff1a; UITableViewControllerDataSourceUITabl…

JavaFX控件——TableView

在JavaFX 应用中对创建表格最重要的是TableView, TableColumn和TableCell这三个类。 你可以通过实现数据模型&#xff08;data model&#xff09; 和 实现 单元格工厂(cell factory) 来填充表格。 表格类提供了表格列嵌入式的排序能力和必要时调整列宽度的功能。 下面开始学…