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

无法通过工厂合约设置自定义合约元数据的问题排查

问题原因与解决方案

问题根源

当工厂合约通过reply调用自定义合约的UpdateRewardMetadata时,自定义合约再发起ArchwayMsg::UpdateContractMetadata,此时调用该元数据更新消息的地址是自定义合约自身,而非作为管理员的工厂合约。Archway的元数据校验逻辑要求发起UpdateContractMetadata的地址必须是目标合约(即自定义合约)的管理员,显然自定义合约自己不是自身管理员,因此触发了"metadata can only be created by the contract admin"错误。

修复方案

让工厂合约直接发起Archway的元数据更新消息,跳过自定义合约的中转环节。修改工厂合约的reply逻辑如下:

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(deps: DepsMut<ArchwayQuery>, env: Env, msg: Reply) -> ArchwayResult<ContractError> {
    let config = CONFIG.load(deps.storage)?;

    if msg.id != INSTANTIATE_REPLY_ID {
        return Err(ContractError::InstantiateError {});
    };

    let reply = parse_reply_instantiate_data(msg);

    match reply {
        Ok(res) => {
            let msgs: Vec<CosmosMsg> = vec![
                // 直接由工厂合约发起元数据更新
                ArchwayMsg::UpdateContractMetadata {
                    contract_address: res.contract_address,
                    owner_address: Some(env.contract.address.to_string()),
                    rewards_address: Some(env.contract.address.to_string()),
                }
                .into(),
            ];

            Ok(Response::new().add_messages(msgs))
        }
        Err(err) => Err(ContractError::Std(StdError::GenericErr {
            msg: err.to_string()
        })),
    }
}

同时可以移除自定义合约中UpdateRewardMetadata相关的消息定义与实现,因为不再需要该中转逻辑。

补充说明

Archway合约元数据管理核心规则:

  • 只有合约的管理员地址才能发起UpdateContractMetadata消息
  • 这里的"发起地址"指的是直接发送该CosmosMsg的地址,而非调用链上层的发起方

修改后,工厂合约作为自定义合约的管理员直接发起元数据更新,就能通过权限校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:09:59