我不确定Substrate运行时中与Substrate UI有关的错误消息的行为,以及它们是否固有地导致事务失败。
例如,在democracy
SRML中,我看到以下行:
ensure!(!<Cancellations<T>>::exists(h), "cannot cancel the same proposal twice");
大概是一个宏,如果h
(建议哈希)已存在,则该宏可确保事务失败或停止处理。显然有一条消息与此错误相关。
当测试失败时,我是否可以假定事务失败(不执行其余SRML代码)?
如果是这样,我如何在Substrate UI中检测到故障,并可能看到消息本身?
如果没有,则可能在运行时模块中需要一些其他代码,这些代码会显式创建错误。我见过Err()
-但没有与ensure!()
答案 0 :(得分:3)
https://github.com/paritytech/substrate/pull/3433合并后,ExtrinsicFailed
事件现在包含一个DispatchError
,它将提供其他错误代码。
可用的文档很少,因此我仅以system
模块为例。
首先,您需要decl_error
,请注意错误变体只能是简单的C(例如枚举)
decl_error! {
/// Error for the System module
pub enum Error {
BadSignature,
BlockFull,
RequireSignedOrigin,
RequireRootOrigin,
RequireNoOrigin,
}
}
然后,您需要关联已声明的Error
类型
https://github.com/paritytech/substrate/blob/5420de3face1349a97eb954ae71c5b0b940c31de/srml/system/src/lib.rs#L253
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
type Error = Error;
然后,您可以在发生故障时通过调度调用返回Error
pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), Error>
where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
{
match o.into() {
Ok(RawOrigin::Root) => Ok(()),
_ => Err(Error::RequireRootOrigin),
}
}
现在,您只能从JS端看到两个数字,模块索引和错误代码。稍后可能会支持将错误详细信息包含在元数据中,以便前端将能够提供更好的响应。
答案 1 :(得分:0)
ensure!
宏的解释为:
#[macro_export]
macro_rules! fail {
( $y:expr ) => {{
return Err($y);
}}
}
#[macro_export]
macro_rules! ensure {
( $x:expr, $y:expr ) => {{
if !$x {
$crate::fail!($y);
}
}}
}
因此,基本上,这只是返回Err
的较快方法。在1.0时,错误味精将仅输出到stdout(至少我到目前为止已经测试过),不知道将来是否会将其包含在区块链中(因此可以在用户界面ui中查看)。