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

web3.py调用合约transact触发ContractLogicError执行回退问题求解

错误原因

核心问题出在Owner合约的权限初始化逻辑:

  • 你定义的Owned()是普通公共函数,不是合约构造函数,合约部署时不会自动执行,导致fileowner变量的初始值为零地址0x0000000000000000000000000000000000000000
  • upload函数携带onlyOwner修饰符,会校验交易发起者地址是否等于fileowner,你用Ganache账户调用时,地址和零地址不匹配,require校验失败触发交易回滚,就是你遇到的报错
  • Remix测试正常是因为你部署后手动调用了Owned()函数完成了初始化,而Python部署流程中没有这一步
解决方案

两种可选方案,任选一种即可:

方案1:修改合约逻辑,用构造函数自动完成初始化

修改smartcontract.sol的Owner合约代码,把Owned()函数替换为构造函数,部署时会自动执行初始化:

contract Owner {
    address public fileowner;
    
    // 替换原有Owned()函数为构造函数,部署时自动执行
    constructor() {
        fileowner = msg.sender;
    }
    
    // 其余原有代码保持不变
    modifier onlyOwner {
        require(msg.sender == fileowner);
        _;
    }
    function transferOwnership(address newOwner) public onlyOwner {
        fileowner = newOwner;
    }
    function getOwner() public view returns (address) {
        return fileowner;
    }
}

修改后重新编译部署合约即可,部署时会自动把部署者地址设为fileowner,权限校验可正常通过。

方案2:不修改合约,在Python部署流程中增加初始化调用

在Owner_contract.py的deploy函数末尾,新增对Owned()函数的调用,手动完成初始化:

def deploy(contract_file, contract_name):
    # 原有部署逻辑保持不变
    compiled_sol = compile_files([contract_file])
    interface = compiled_sol['{}:{}'.format(contract_file, contract_name)]
    
    contract = w3.eth.contract(abi=interface['abi'],
                    bytecode='0x'+interface['bin'],
                    bytecode_runtime=interface['bin-runtime'])

    tx_hash = contract.constructor(transaction={'from':w3.eth.accounts[0]}).transact()
    logger.info(f'Owner_tx_hash: {tx_hash}')
    
    tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    logger.info(f'Owner_tx_receipt: {tx_receipt}')
    
    contract_address = tx_receipt['contractAddress']
    logger.info(f'Owner_contract_address: {contract_address}')
    
    contract_instance = contract(contract_address)
    logger.info(f'Owner_contract_instance: {contract_instance}')
    
    # 新增以下行,手动调用Owned完成权限初始化
    contract_instance.functions.Owned().transact()

    return contract_instance
验证方法

部署完成后先调用getOwner()接口查看返回值,如果返回的是你部署用的Ganache第一个账户地址,说明初始化成功,再调用upload接口就不会触发回滚报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:09:04