MultiversX加密验证API技能Skill multiversx-crypto-verification

该技能涉及在MultiversX智能合约中使用哈希函数(如SHA256、Keccak256、RIPEMD160)和签名验证算法(如Ed25519、secp256k1、secp256r1、BLS),用于数据加密、身份验证和链上逻辑编码。关键词:MultiversX, 加密验证, 哈希, 签名, 智能合约, 区块链, 以太坊兼容, 比特币地址, BLS聚合签名, DER编码, 安全认证。

智能合约 0 次安装 0 次浏览 更新于 3/21/2026

名称:multiversx-crypto-verification 描述:MultiversX智能合约中的加密操作。用于数据哈希(SHA256、Keccak256、RIPEMD160)、验证签名(Ed25519、secp256k1、secp256r1、BLS)或在链上逻辑中编码签名。

MultiversX加密验证 — self.crypto() API参考

MultiversX智能合约中哈希和签名验证的完整参考(SDK v0.64+)。

哈希函数

所有哈希函数都接受&ManagedBuffer(或任何可借用为ManagedBuffer的类型)并返回固定大小的ManagedByteArray

方法 返回类型 输出大小 使用场景
.sha256(data) ManagedByteArray<A, 32> 32字节 通用哈希、默克尔树
.keccak256(data) ManagedByteArray<A, 32> 32字节 以太坊兼容性、EIP-712
.ripemd160(data) ManagedByteArray<A, 20> 20字节 比特币地址派生(少见)
// 哈希消息
let message = ManagedBuffer::from("要哈希的数据");
let hash: ManagedByteArray<Self::Api, 32> = self.crypto().sha256(&message);

// 用于以太坊兼容性的哈希
let eth_hash = self.crypto().keccak256(&abi_encoded_data);

签名验证

关键区别:Panic vs Bool

基于Panic — 无效签名时交易立即失败。无法进行错误处理。当无效签名等于未经授权的操作时使用。

基于Bool — 返回true/false。合约继续执行。当需要优雅的错误处理或多个验证尝试时使用。

方法 返回 无效签名时
verify_ed25519(key, message, signature) () Panics — 交易以“无效签名”失败
verify_bls(key, message, signature) () Panics
verify_secp256r1(key, message, signature) () Panics
verify_bls_signature_share(key, message, signature) () Panics
verify_bls_aggregated_signature(keys, message, signature) () Panics
verify_secp256k1(key, message, signature) bool 返回false
verify_custom_secp256k1(key, message, signature, hash_type) bool 返回false

方法签名

// 基于Panic(无返回值)
fn verify_ed25519(
    &self,
    key: &ManagedBuffer<A>,       // 32字节公钥
    message: &ManagedBuffer<A>,   // 任意消息
    signature: &ManagedBuffer<A>, // 64字节签名
)

fn verify_bls(
    &self,
    key: &ManagedBuffer<A>,       // 96字节BLS公钥
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>, // 48字节BLS签名
)

fn verify_secp256r1(
    &self,
    key: &ManagedBuffer<A>,       // 33或65字节公钥
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,
)

fn verify_bls_signature_share(
    &self,
    key: &ManagedBuffer<A>,
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,
)

fn verify_bls_aggregated_signature(
    &self,
    keys: &ManagedVec<A, ManagedBuffer<A>>,  // BLS公钥列表
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,             // 聚合签名
)

// 基于Bool
fn verify_secp256k1(
    &self,
    key: &ManagedBuffer<A>,
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,  // DER编码或原始(至少2字节)
) -> bool

fn verify_custom_secp256k1(
    &self,
    key: &ManagedBuffer<A>,
    message: &ManagedBuffer<A>,
    signature: &ManagedBuffer<A>,
    hash_type: MessageHashType,    // 消息哈希方式
) -> bool

MessageHashType枚举

用于verify_custom_secp256k1以指定消息的预哈希方式:

pub enum MessageHashType {
    ECDSAPlainMsg,      // 消息未哈希(原始)
    ECDSASha256,        // 消息已SHA-256哈希
    ECDSADoubleSha256,  // 消息已双重SHA-256哈希(比特币)
    ECDSAKeccak256,     // 消息已Keccak-256哈希(以太坊)
    ECDSARipemd160,     // 消息已RIPEMD-160哈希
    ECDSABlake2b,       // 消息已Blake2b哈希
}

DER签名编码

将原始(r, s)组件转换为secp256k1的DER格式:

fn encode_secp256k1_der_signature(
    &self,
    r: &ManagedBuffer<A>,  // 32字节r组件
    s: &ManagedBuffer<A>,  // 32字节s组件
) -> ManagedBuffer<A>      // DER编码签名

算法选择指南

算法 何时使用
Ed25519 MultiversX原生签名。验证来自链的用户/智能合约签名。默认选择。
secp256k1 以太坊/比特币兼容性。桥接合约、跨链验证。
secp256r1 NIST P-256 / WebAuthn / Apple Secure Enclave。基于密钥的认证。
BLS 验证器签名、多签名聚合、门限方案。
BLS聚合 验证多个验证器的单个聚合签名。

常见模式

Ed25519签名门控(MultiversX原生)

#[endpoint(executeWithSignature)]
fn execute_with_signature(
    &self,
    data: ManagedBuffer,
    signature: ManagedBuffer,
) {
    let signer = self.trusted_signer().get();
    // 无效则Panic — 交易自动回滚
    self.crypto().verify_ed25519(
        &signer,
        &data,
        &signature,
    );
    // 仅在签名有效时到达
    self.process_data(&data);
}

以太坊签名验证(优雅处理)

#[endpoint(verifyEthSignature)]
fn verify_eth_signature(
    &self,
    key: ManagedBuffer,
    message: ManagedBuffer,
    signature: ManagedBuffer,
) -> bool {
    // 返回bool — 优雅处理失败
    let valid = self.crypto().verify_custom_secp256k1(
        &key,
        &message,
        &signature,
        MessageHashType::ECDSAKeccak256,
    );
    require!(valid, "无效以太坊签名");
    valid
}

多验证器BLS聚合检查

#[endpoint(verifyValidators)]
fn verify_validators(
    &self,
    validator_keys: ManagedVec<ManagedBuffer>,
    message: ManagedBuffer,
    aggregated_sig: ManagedBuffer,
) {
    // 聚合签名无效则Panic
    self.crypto().verify_bls_aggregated_signature(
        &validator_keys,
        &message,
        &aggregated_sig,
    );
}

基于哈希的承诺-揭示

#[endpoint(commit)]
fn commit(&self, hash: ManagedByteArray<Self::Api, 32>) {
    let caller = self.blockchain().get_caller();
    self.commitments(&caller).set(hash);
}

#[endpoint(reveal)]
fn reveal(&self, value: ManagedBuffer) {
    let caller = self.blockchain().get_caller();
    let stored_hash = self.commitments(&caller).get();
    let computed_hash = self.crypto().sha256(&value);
    require!(stored_hash == computed_hash, "哈希不匹配");
    self.commitments(&caller).clear();
    self.process_reveal(&caller, &value);
}

secp256k1的DER编码

// 当您有原始r,s组件时(例如,来自预言机)
let r = ManagedBuffer::from(&r_bytes[..]);
let s = ManagedBuffer::from(&s_bytes[..]);
let der_sig = self.crypto().encode_secp256k1_der_signature(&r, &s);

let valid = self.crypto().verify_secp256k1(&pubkey, &message, &der_sig);

反模式

// 错误:尝试捕获Ed25519失败 — 它会Panic,无法捕获
let result = self.crypto().verify_ed25519(&key, &msg, &sig);
// ← verify_ed25519返回(),不是Result。如果无效,交易已失败。

// 正确:将Ed25519用作门控(Panic是预期行为)
self.crypto().verify_ed25519(&key, &msg, &sig);
// 仅在有效时继续执行

// 错误:使用verify_secp256k1但不检查bool
self.crypto().verify_secp256k1(&key, &msg, &sig);
// ← 编译正常但忽略结果!签名实际上未被检查。

// 正确:始终检查bool返回值
let valid = self.crypto().verify_secp256k1(&key, &msg, &sig);
require!(valid, "无效签名");

// 错误:对以太坊签名使用错误的哈希类型
self.crypto().verify_custom_secp256k1(&key, &msg, &sig, MessageHashType::ECDSASha256);
// ← 以太坊使用Keccak256,不是SHA256

// 正确:将哈希类型与链匹配
self.crypto().verify_custom_secp256k1(&key, &msg, &sig, MessageHashType::ECDSAKeccak256);