Substrate:如何验证 unsigned extrinsics 的发起者?
Substrate: How to validate the originator of unsigned extrinsics?
出于防止垃圾邮件的目的,我需要能够识别未签名的外部文件的来源。假设有一组已知的权威机构,我愿意从他们那里接受一个未签名的外部。我想检查 unsigned extrinsic 的发件人是否是此权限集的成员(并且他们是他们所说的人)。
据我所知,有几种不同的方法,我想更好地理解每种方法之间的差异以及所涉及的权衡。
添加签名作为调用参数并定义ValidateUnsigned
.
ImOnline
pallet 中使用了这种方法。粗略地说:
decl_module!(
// ...
fn my_unsigned_call(_origin,
args: MyArgs<T>,
authority: T::Authority,
signature: T::Signature) {
// Handle the call
todo!()
}
)
impl<T: Trait> frame_support::unsigned::ValidateUnsigned for Module<T> {
// ...
fn validate_unsigned(
_source: TransactionSource,
call: &Self::Call,
) -> TransactionValidity {
if let Call::my_unsigned_call(args, authority, signature) = call {
// Check the sender is in the approved authority set and verify sig
todo!();
}
}
}
实施 SignedExtension
for some metadata associated with the pallet trait. This is touched upon in the docs and seems to be implemented in the TransactionPayment
托盘。实施将是这样的:
struct SenderInfo<T> {
authority: T::Authority,
signature: T::Signature,
}
impl<T: Config + Send + Sync> SignedExtension for SenderInfo<T>
where
<T as frame_system::Config>::Call: IsSubType<Call<T>>,
{
// ...
fn validate_unsigned(
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize
) -> TransactionValidity {
// validate self.authority and self.signature
}
}
然后需要将此SignedExtension
聚合到运行时的SignedExtra
中。 (对吗?)
我倾向于使用第二个选项,因为它看起来更干净:它不需要我用方法调用中甚至没有使用的额外信息来污染我的方法签名。但这是否意味着提交给运行时的 任何 交易,无论签名还是未签名,都需要添加这个定制的 SignedExtra
?
还有什么我应该注意的其他注意事项吗?
我正在做一个非常相似的事情。
我可以用你的方法 1 做到这一点。
基本上我在那里检查两件事:
- 如果 payload 被正确签名 - 当你考虑它时,这只会告诉你关于用户的信息,但它不会检查用户是否是你的授权用户。
- 我会检查此帐户是否在我的权限列表中
我的工作示例可在此处获得https://github.com/korzewski/jackblock/blob/master/pallets/jackblock/src/lib.rs#L401
虽然这并不完美,因为我需要保留第二个授权列表并手动添加它们。
目前我正在尝试重构它,因此我的授权帐户与我的验证器(Aura pallet)相同。仍在寻找解决方案,也许您知道如何解决?基本上如何在我自己的 pallet 中重用 Aura pallet
出于防止垃圾邮件的目的,我需要能够识别未签名的外部文件的来源。假设有一组已知的权威机构,我愿意从他们那里接受一个未签名的外部。我想检查 unsigned extrinsic 的发件人是否是此权限集的成员(并且他们是他们所说的人)。
据我所知,有几种不同的方法,我想更好地理解每种方法之间的差异以及所涉及的权衡。
添加签名作为调用参数并定义
ValidateUnsigned
.ImOnline
pallet 中使用了这种方法。粗略地说:decl_module!( // ... fn my_unsigned_call(_origin, args: MyArgs<T>, authority: T::Authority, signature: T::Signature) { // Handle the call todo!() } ) impl<T: Trait> frame_support::unsigned::ValidateUnsigned for Module<T> { // ... fn validate_unsigned( _source: TransactionSource, call: &Self::Call, ) -> TransactionValidity { if let Call::my_unsigned_call(args, authority, signature) = call { // Check the sender is in the approved authority set and verify sig todo!(); } } }
实施
SignedExtension
for some metadata associated with the pallet trait. This is touched upon in the docs and seems to be implemented in theTransactionPayment
托盘。实施将是这样的:struct SenderInfo<T> { authority: T::Authority, signature: T::Signature, } impl<T: Config + Send + Sync> SignedExtension for SenderInfo<T> where <T as frame_system::Config>::Call: IsSubType<Call<T>>, { // ... fn validate_unsigned( call: &Self::Call, info: &DispatchInfoOf<Self::Call>, len: usize ) -> TransactionValidity { // validate self.authority and self.signature } }
然后需要将此
SignedExtension
聚合到运行时的SignedExtra
中。 (对吗?)
我倾向于使用第二个选项,因为它看起来更干净:它不需要我用方法调用中甚至没有使用的额外信息来污染我的方法签名。但这是否意味着提交给运行时的 任何 交易,无论签名还是未签名,都需要添加这个定制的 SignedExtra
?
还有什么我应该注意的其他注意事项吗?
我正在做一个非常相似的事情。
我可以用你的方法 1 做到这一点。 基本上我在那里检查两件事:
- 如果 payload 被正确签名 - 当你考虑它时,这只会告诉你关于用户的信息,但它不会检查用户是否是你的授权用户。
- 我会检查此帐户是否在我的权限列表中
我的工作示例可在此处获得https://github.com/korzewski/jackblock/blob/master/pallets/jackblock/src/lib.rs#L401
虽然这并不完美,因为我需要保留第二个授权列表并手动添加它们。
目前我正在尝试重构它,因此我的授权帐户与我的验证器(Aura pallet)相同。仍在寻找解决方案,也许您知道如何解决?基本上如何在我自己的 pallet 中重用 Aura pallet