如何在智能合约中验证SECP256K1签名消息?NEAR链实现方案咨询
NEAR智能合约验证Ed25519签名实现方案
1. 依赖选择说明
不需要单独引入near-crypto crate,4.0及以上版本的near-sdk已经内置了签名验证相关的原生方法,直接使用即可,还能避免依赖冲突、Wasm编译体积过大的问题。
2. 完整实现代码
use near_sdk::{env, near_bindgen}; use near_sdk::crypto::{PublicKey, Signature}; #[near_bindgen] #[derive(Default, Clone)] pub struct Contract {} #[near_bindgen] impl Contract { /// 验证ed25519签名 /// 参数说明: /// - data: 原始签名消息的字节数组,必须和前端签名时的输入完全一致 /// - signature_base64: 前端生成的签名base64字符串 /// - public_key_base58: 签名者公钥的base58字符串(即NEAR生态通用的公钥展示格式) pub fn verify_ed25519_signature(&self, data: Vec<u8>, signature_base64: String, public_key_base58: String) -> bool { // 解析公钥,自动识别ed25519类型,无需手动指定签名算法 let public_key = match PublicKey::try_from(public_key_base58) { Ok(pk) => pk, Err(_) => return false, }; // 解析签名 let signature = match Signature::try_from(signature_base64) { Ok(sig) => sig, Err(_) => return false, }; // 执行签名验证 signature.verify(&data, &public_key) } }
3. 前端传参注意事项
你现有前端代码的输出可以直接传给合约,不需要额外编码转换:
- 原始消息字节要和签名时完全一致,不要额外加前缀、做编码转换
- 签名值直接调用
signature.toString()即可得到符合要求的base64格式字符串 - 公钥直接调用
signerKeyPair.getPublicKey().toString()即可得到符合要求的base58格式字符串
4. 避坑提示
- 不要直接照搬你找到的near-core示例代码,示例中指定的
KeyType::SECP256K1是另一种签名算法,和你使用的ed25519不匹配,PublicKey的解析方法会自动识别公钥前缀的算法标识,不需要手动指定算法类型 - 不要在合约逻辑中使用
unwrap(),一旦解析失败会直接触发合约panic,改用match处理错误返回false更符合业务安全性要求
内容的提问来源于stack exchange,提问作者Tony Ra
相关产品推荐
相关产品推荐

