为调用指定来源
Please read Substrate to Polkadot SDK page first.
在向运行时添加模块中,您向Substrate 节点模板运行时添加了来自pallet_nicks的函数。
Nicks 模块允许区块链用户支付押金以预留他们控制的帐户的昵称。 它实现了以下功能:
set_name函数,用于启用帐户所有者在名称未被预留时设置其自身帐户的名称。clear_name函数,用于启用帐户所有者删除与帐户关联的名称并返还押金。kill_name函数,用于强制删除另一方的帐户名称而不返还押金。force_name函数,用于在不需要押金的情况下为另一方设置帐户名称。
本教程说明了如何使用不同的来源帐户调用这些函数,以及为什么使用不同的来源帐户调用这些函数很重要。
开始之前
在开始之前,请验证以下内容:
- 您已通过安装 Rust 和 Rust 工具链 为 Substrate 开发配置了您的环境。
- 您已在本地安装了 Substrate 节点模板。
- 您已在本地安装了 Substrate 前端模板。
- 您已完成向运行时添加模块教程,并成功编译了包含
nicks模块的运行时。 - 您通常熟悉软件开发和使用命令行界面。
教程目标
通过完成本教程,您将实现以下目标:
- 使用有权执行调用的帐户调用
set_name函数。 - 使用有权执行调用的帐户调用
clear_name函数。 - 使用无权执行调用的帐户调用
force_name函数。 - 使用没有管理权限的来源调用
kill_name函数。 - 使用
Root来源帐户调用kill_name函数。 - 查看如何使用不同的来源帐户调用函数会导致失败或成功的结果。
确定管理帐户
正如您在向运行时添加模块中看到的那样,nicks模块的Config特征声明了几个类型。
对于本教程,重点是ForceOrigin类型。
ForceOrigin类型用于指定可以执行某些操作的帐户。
对于此模块,ForceOrigin类型指定可以为其他帐户设置或删除名称的帐户。
通常,只有具有管理权限的帐户(例如根超级用户帐户)才能代表其他帐户执行操作。
在 Nicks 模块的情况下,只有帐户所有者或 Root 帐户才能设置或删除预留的昵称。
在您将 FRAME 系统Root来源标识为nicks模块管理员时,您在实现(impl)块中配置了此 Root 帐户。
例如:
type ForceOrigin = frame_system::EnsureRoot<AccountId>;在节点模板的开发链规范中,Sudo 模块配置为使用 Alice 帐户作为 FRAME 系统Root来源。
由于此配置,默认情况下,只有 Alice 帐户才能调用需要ForceOrigin类型的函数。
如果您尝试使用除 Alice 帐户以外的帐户调用kill_name或force_name,则该调用将无法执行。
为帐户设置名称
为了演示调用来源如何影响操作,让我们设置并尝试强制删除另一个帐户的帐户名称。 对于此演示,请确保您拥有:
- 以开发模式运行的节点模板:
./target/release/solo-template-node --dev - 正在运行并连接到本地节点的前端模板:
yarn start - 连接到本地 Web 服务器的浏览器:http://localhost:8000/
- 将前端模板中的活动帐户从 Alice 更改为 Bob。
-
在 Pallet Interactor 中选择外部函数:
- 选择
nicks模块。 - 选择
setName函数。 - 为帐户输入名称。
- 点击已签名以提交 Bob 签名的此事务。
由于 Bob 是此帐户的所有者,因此交易成功。 作为帐户的所有者,Bob 还可以执行已签名的
clearName函数来删除帐户的昵称。 - 选择
-
选择外部函数:
- 选择
nicks模块。 - 选择
clearName函数。 -
点击已签名以提交 Bob 签名的此事务。
由于 Bob 是此帐户的所有者,因此交易成功。 对于 Bob 要设置或删除另一个帐户的昵称,他必须使用为模块配置的
ForceOrigin调用forceName或killName函数。
- 选择
-
选择外部函数:
- 选择
nicks模块。 - 选择
forceName函数。 - 将 Charlie 的帐户地址复制并粘贴为目标。
- 为帐户输入名称。
- 点击已签名以提交 Bob 签名的此事务。
由于您使用 Bob 的帐户签署了此事务,因此该函数使用
Signed来源而不是Root来源进行调度。 在这种情况下,函数调用本身是成功的。 但是,名称预留无法完成,并且会发出BadOrigin错误。![BadOrigin 错误]()
正如您在事件中看到的那样,该事务导致从 Bob 的帐户中提取作为提交事务的费用,但没有状态更改,因为
Root来源没有提交事务。 未能更改状态还说明了用于数据库读取和写入的先验证后写入原则,以确保只有成功操作才会提交到磁盘。 - 选择
使用 Root 来源调度调用
Sudo 模块使您可以使用Root来源调度调用。
在 Nick 模块中,必须使用ForceOrigin配置指定的Root来源调用 forceName 和 killName 函数。
在前端模板中,您可以通过点击SUDO来访问 Sudo 模块以使用Root来源调度调用。
对于此演示,请确保您拥有:
- 以开发模式运行的节点模板:
./target/release/solo-template-node --dev - 正在运行并连接到本地节点的前端模板:
yarn start - 连接到本地 Web 服务器的浏览器:http://localhost:8000/
-
将活动帐户更改为 Alice。
如确定管理帐户中所述,在开发模式下运行链时,Alice 是与
Root来源关联的帐户。 -
在 Pallet Interactor 中选择外部函数:
- 选择
nicks模块。 - 选择
forceName函数。 - 将 Charlie 的帐户地址复制并粘贴为目标。
- 为帐户输入名称。
- 点击SUDO以使用
Root来源提交此事务。
![使用 SUDO 提交事务]()
- 选择
-
选择外部函数:
- 选择
nicks模块。 - 选择
killName函数。 - 将 Bob 的帐户地址复制并粘贴为目标。
- 点击SUDO以使用
Root来源提交此事务。
在这种情况下,Sudo 模块会发出
Sudid事件以通知网络参与者Root来源调度了一个调用,但发生了错误。![提交 killName 函数发出了错误]()
此调度错误包含两条元数据:
- 一个
index编号,指示发出错误的模块。 - 一个
error编号,指示该模块的Error枚举发出的错误。
index编号与模块在construct_runtime!宏中的位置相对应,construct_runtime!宏中的第一个模块的索引号为零 (0)。在此示例中,
index为6(第七个模块),error为2(第三个错误)。construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = opaque::Block, UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system, // index 0 RandomnessCollectiveFlip: pallet_randomness_collective_flip, // index 1 Timestamp: pallet_timestamp, // index 2 Aura: pallet_aura, // index 3 Grandpa: pallet_grandpa, // index 4 Balances: pallet_balances, // index 5 Nicks: pallet_nicks, // index 6 }无论
index的值如何,error值2都对应于 Nicks 模块中的Unnamed错误。 如果您期望 Bob 没有预留昵称或先前已清除名称预留,则会发生此错误。您可以确认 Alice 可以使用 SUDO 调用
killName函数来删除当前已预留名称的任何帐户的预留昵称。 - 选择
-
选择外部函数:
- 选择
nicks模块。 - 选择
killName函数。 - 将 Charlie 的帐户地址复制并粘贴为目标。
- 点击SUDO以使用
Root来源提交此事务。
![提交成功的 killName 事务]()
- 选择
下一步
本教程介绍了使用Root和Signed来源指定用于提交事务的帐户,并演示了使用不同的来源帐户调用函数的结果。
有几个教程可以作为学习更多关于 Substrate 开发的下一步。
除了教程之外,您可能还希望浏览以下资源以了解更多信息。



