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

Hedera Rust SDK交易编码失败:KEY_PREFIX_MISMATCH错误求助

问题分析与解决方案

出现KEY_PREFIX_MISMATCH错误的核心原因是交易中涉及的账户ID(包括节点账户、转出/转入账户)的网络ID与客户端使用的网络不匹配,导致签名密钥的网络前缀和交易要求的网络前缀不一致。

Rust SDK中,AccountId::from_str(无网络指定)和AccountId::from默认会使用主网(网络ID 1),而如果你的客户端是测试网(网络ID 0),就会出现这种不匹配。对比JavaScript SDK,它会自动根据客户端的网络为未指定网络的账户ID设置对应网络,因此不会出错。

具体修改方案

1. 修正节点账户ID的网络匹配

手动指定节点账户时,需要将其网络ID设置为与客户端一致:

// 替换原node_account_ids的设置
let node_id = AccountId::from(3).set_network_id(self.client.get_network_id()?);
transaction.node_account_ids([node_id])

2. 修正转出/转入账户ID的网络匹配

确保交易中使用的转出、转入账户ID的网络ID与客户端网络一致:

// 从客户端获取当前网络ID,覆盖账户的默认网络
let network_id = self.client.get_network_id()?;
let sender_account_id = data.sender_account_id.set_network_id(network_id);
let receiver_account_id = data.reciever_account_id.set_network_id(network_id);

// 使用修正后的账户ID添加转账
transaction.hbar_transfer(sender_account_id, -data.amount)
           .hbar_transfer(receiver_account_id, data.amount)

3. 调整签名流程(按需)

你的需求是将冻结后的交易发给转出用户签名,因此不需要提前用operator签名,可以去掉transaction.sign_with_operator(&self.client)?;这一行。后续转出用户签名后,再由operator签名并提交交易即可。

修改后的完整代码片段

#[async_trait]
impl HederaServiceContract for HederaService {
    async fn make_unsigned_transaction(&self, data: TransactionData) -> Result<String, Error> {
        let network_id = self.client.get_network_id()?;
        
        let mut transaction = TransferTransaction::new();
        let node_id = AccountId::from(3).set_network_id(network_id);
        let sender_account_id = data.sender_account_id.set_network_id(network_id);
        let receiver_account_id = data.reciever_account_id.set_network_id(network_id);

        transaction
            .node_account_ids([node_id])
            .hbar_transfer(sender_account_id, -data.amount)
            .hbar_transfer(receiver_account_id, data.amount)
            .transaction_memo(data.memo)
            .freeze_with(&self.client)?;

        // 移除提前签名的步骤,保留未签名的冻结交易
        // transaction.sign_with_operator(&self.client)?;

        let tx_bytes = transaction.to_bytes()?;
        let base64_tx = general_purpose::STANDARD.encode(tx_bytes);

        Ok(base64_tx)
    }
}

额外检查点

  • 确认转出用户使用的私钥网络前缀与交易网络一致(测试网密钥前缀为0x00,主网为0x01)。
  • 如果你的账户ID字符串包含网络后缀(如0.0.123.testnet),Rust SDK会自动识别网络ID,无需手动设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:52:56