简介
- polkadot JS 通过一个钱包对一组数据签名后,将签名和数据上传到链上,如何进行签名验证呢“验签”,接下来我写一个例子展示一下过程
建立一个Pallet函数用于签名验证
- 原理上没什么好说的,直接看代码吧,首先是签名验证函数。
use frame_support::sp_runtime::app_crypto::TryFrom;
use frame_support::sp_runtime::traits::{IdentifyAccount, Verify};
use frame_support::sp_runtime::MultiSignature;
use frame_support::sp_runtime::MultiSigner;
use sp_application_crypto::sr25519;
use sp_application_crypto::sr25519::Public;
use sp_application_crypto::sr25519::Signature;
impl<T: Config> Pallet<T> {
fn check_signed_valid(public_id: Public, signature: &[u8], msg: &[u8]) -> bool {
let signature = Signature::try_from(signature);
let signature = signature.unwrap();
let multi_sig = MultiSignature::from(signature); // OK
let multi_signer = MultiSigner::from(public_id);
multi_sig.verify(msg, &multi_signer.into_account())
}
}
函数的使用
- 这里是使用的代码片段,展示了参数部分和调用的部分。
#[pallet::weight(1234)]
pub fn reveal_puzzle(
origin: OriginFor<T>,
answer_signed: Vec<u8>,
answer_hash:Vec<u8>
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
// 提取公钥
let encode_data: Vec<u8> = who.encode();
// 公钥应该是32位的
assert!(32 == encode_data.len());
let raw_data = encode_data.try_into();
let raw_data = raw_data.unwrap();
let public = sp_core::sr25519::Public::from_raw(raw_data);
Self::check_signed_valid(
public,
// 这边要注意先要吧签名的16进制decode成&[u8]
&hex::decode(answer_signed.as_slice()).expect("Hex invalid")[..],
answer_hash.as_slice()
),
结束