Icon Link签名验证

让我们定义一个名为 verify_signatures() 的辅助函数,它检查提供的每个签名的有效性,并拒绝任何无效的签名,确保所有签名都是唯一的。

将签名验证辅助函数复制到您的 main.sw 中:

fn verify_signature(i: u64) -> u64 {
    // Discard any out of bounds signatures
    if (i >= tx_witnesses_count()) {
        return 0;
    }
 
    let tx_hash = tx_id();
 
    let mut j = 0;
 
    while j < 3 {
        let current_signature = tx_witness_data::<B512>(j);
        
        let current_address = ec_recover_address(current_signature, tx_hash).unwrap();
 
        if current_address == SIGNERS[i] {
            return 1;
        }
 
        j += 1;
    }
    return 0;
}

如前所述,我们将利用交易见证和交易哈希来验证每个签名,将它们与之前配置的钱包进行匹配。

  1. 参数 i:此参数表示预定义的签名者列表中的一个签名者的索引,该列表在可配置项中定义。它用于识别函数当前正在尝试验证的签名者的签名。

  2. 签名验证循环:然后,函数进入一个循环,迭代至多三次。此循环表示尝试根据附加到交易的最多三个见证数据(签名)来验证签名。

    • 签名恢复:在循环内,对于由 j 定义的每次迭代,它使用 tx_witness_data::<B512>(j) 从交易的见证数据中检索当前签名(current_signature)。然后,它尝试使用 ec_recover_address 函数从当前签名和交易哈希作为输入来恢复生成此签名的地址(current_address)。

    • 地址匹配:在恢复地址后,函数检查此地址是否与 SIGNERS 列表中第 i 个签名者的地址匹配。如果找到匹配项,则意味着成功验证了一个签名者的签名,并且函数返回 1

while j < 3 {
    let current_signature = tx_witness_data::<B512>(j);
    
    let current_address = ec_recover_address(current_signature, tx_hash).unwrap();
 
    if current_address == SIGNERS[i] {
        return 1;
    }
 
    j += 1;
}
return 0;
  1. 返回值:如果找到了第 i 个签名者的匹配签名,则函数返回 1,表示验证成功。如果在检查最多三个签名后找不到匹配的签名,则函数返回 0,表示无法验证第 i 个签名者的签名。

这样可以灵活地进行签名验证,适应了签名者可以以任何顺序呈现所需签名的情况,并确保每个签名都被唯一地记录,而不允许来自同一钱包的重复签名。