如何比较 substrate 模块中的特征类型和字符串类型?
How do I compare the trait type with the string type in substrate module?
我要用户输入地址to:T::AccountIdAccountId
,它会与我设置的地址let disable_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
进行比较。我的问题是如何比较这两种不同的类型? if (receiver != disable_address)
,谢谢。
我的代码
use frame_support::{decl_storage, decl_module, dispatch::DispatchResult};
use frame_system::ensure_signed;
decl_storage! {
trait Store for Module<T: Trait> as VerifiableCreds {
storeValue: u32;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
#[weight = 0]
fn verify(origin, to:T::AccountId) -> DispatchResult
{
let sender = ensure_signed(origin)?;
let receiver = to;
let disable_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
if (receiver != disable_address)
{
//do something
}
Ok(())
}
}
}
您提供的是地址的 SS58 表示形式,这不是进行比较的良好起点。
您应该将 SS58 转换为其 byte/hex 表示:
使用:https://www.shawntabrizi.com/substrate-js-utilities/
5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
> 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
然后你要比较AccountId
的编码版本,看看它是否匹配上面十六进制的字节形式:
let account_bytes: Vec<u8> = to.encode();
let match_bytes: Vec<u8> = hex_literal::hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"].into();
if account_bytes == match_bytes { ... }
类似的东西...但总的来说,我绝不会推荐以这种方式编写代码。首先,您假设您的帐户是某种格式的运行时。想象一下另一个使用不同帐户格式的链,例如以太坊 20 字节表示而不是 32 字节表示。像这样的任何硬编码逻辑都将无法工作。
相反,您应该提供配置特征:
type DisableAddress: Get<Self::AccountId>;
那么你应该这样匹配:
if to == T::DisableAddress::get() { ... }
然后您将在运行时执行我上面显示的相同字节转换逻辑。
在这个采购托盘的 PR 中有一个很好的例子:https://github.com/paritytech/polkadot/pull/1369/files#diff-e5e76e02c0d16e79c70b024cbe3c6ea56f3249382a0f987ba203c34fcb40ed66R954
我要用户输入地址to:T::AccountIdAccountId
,它会与我设置的地址let disable_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
进行比较。我的问题是如何比较这两种不同的类型? if (receiver != disable_address)
,谢谢。
我的代码
use frame_support::{decl_storage, decl_module, dispatch::DispatchResult};
use frame_system::ensure_signed;
decl_storage! {
trait Store for Module<T: Trait> as VerifiableCreds {
storeValue: u32;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
#[weight = 0]
fn verify(origin, to:T::AccountId) -> DispatchResult
{
let sender = ensure_signed(origin)?;
let receiver = to;
let disable_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
if (receiver != disable_address)
{
//do something
}
Ok(())
}
}
}
您提供的是地址的 SS58 表示形式,这不是进行比较的良好起点。
您应该将 SS58 转换为其 byte/hex 表示:
使用:https://www.shawntabrizi.com/substrate-js-utilities/
5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
> 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
然后你要比较AccountId
的编码版本,看看它是否匹配上面十六进制的字节形式:
let account_bytes: Vec<u8> = to.encode();
let match_bytes: Vec<u8> = hex_literal::hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"].into();
if account_bytes == match_bytes { ... }
类似的东西...但总的来说,我绝不会推荐以这种方式编写代码。首先,您假设您的帐户是某种格式的运行时。想象一下另一个使用不同帐户格式的链,例如以太坊 20 字节表示而不是 32 字节表示。像这样的任何硬编码逻辑都将无法工作。
相反,您应该提供配置特征:
type DisableAddress: Get<Self::AccountId>;
那么你应该这样匹配:
if to == T::DisableAddress::get() { ... }
然后您将在运行时执行我上面显示的相同字节转换逻辑。
在这个采购托盘的 PR 中有一个很好的例子:https://github.com/paritytech/polkadot/pull/1369/files#diff-e5e76e02c0d16e79c70b024cbe3c6ea56f3249382a0f987ba203c34fcb40ed66R954