You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在near_sdk_rs智能合约中实现消息签名的链上验证?

在NEAR智能合约(near_sdk_rs)中实现消息签名与验证

NEAR基于Ed25519加密算法处理签名验证,在near_sdk_rs中可直接利用SDK提供的工具类实现消息签名的链上验证,核心是校验签名、消息与公钥的匹配关系,甚至可关联到具体NEAR账号。

核心实现步骤

1. 基础签名验证(仅校验签名与公钥、消息的匹配)

通过解析传入的公钥、签名,调用SDK内置方法确认签名有效性:

use near_sdk::{near_bindgen, PublicKey, crypto::Signature};

#[near_bindgen]
#[derive(Default)]
pub struct Contract;

#[near_bindgen]
impl Contract {
    /// 验证消息签名是否匹配指定公钥
    pub fn verify_signature(&self, message: Vec<u8>, signature: Vec<u8>, public_key: Vec<u8>) -> bool {
        // 解析公钥,失败则返回false
        let pk = match PublicKey::from_bytes(&public_key) {
            Ok(pk) => pk,
            Err(_) => return false,
        };
        // 解析签名,失败则返回false
        let sig = match Signature::from_bytes(&signature) {
            Ok(sig) => sig,
            Err(_) => return false,
        };
        // 核心验证:签名是否由该公钥对目标消息生成
        sig.verify(&message, &pk)
    }
}

2. 进阶:验证签名者为指定NEAR账号

若需确认签名者是具体账号,可先获取该账号的所有关联公钥,再逐一验证签名是否匹配:

use near_sdk::{near_bindgen, crypto::Signature, env};

#[near_bindgen]
impl Contract {
    /// 验证签名是否来自指定NEAR账号
    pub fn verify_signature_for_account(&self, message: Vec<u8>, signature: Vec<u8>, account_id: String) -> bool {
        // 查询目标账号的绑定公钥列表
        let account = match env::view_account(&account_id) {
            Ok(account) => account,
            Err(_) => return false,
        };
        // 遍历公钥逐一验证
        for pk in account.public_keys {
            match Signature::from_bytes(&signature) {
                Ok(sig) => {
                    if sig.verify(&message, &pk) {
                        return true;
                    }
                },
                Err(_) => continue,
            }
        }
        // 所有公钥均不匹配则返回false
        false
    }
}

关键注意事项

  • 消息一致性:前端签名的消息与合约接收的消息必须完全一致(包括编码格式,如字符串转字节需用UTF-8),否则验证会失败。
  • 签名生成规范:前端需使用NEAR官方工具生成签名,比如near-api-js的signMessage方法,确保签名符合Ed25519标准。
  • 公钥获取方式:前端可通过NEAR钱包API获取用户公钥(如window.nearConnection.signer.getPublicKey(accountId, networkId)),再传递给合约。
  • 权限补充校验:针对敏感操作,除签名验证外,还可结合env::predecessor_account_id()确认调用者身份,实现多重安全校验。

内容的提问来源于stack exchange,提问作者marethyu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:30:59