la variable de dirección pública provoca la excepción BadFunctionCall

Ver los contratos en la parte inferior. Notará que los contratos son idénticos, excepto que el campo de autoridad del primer contrato está marcado como público, mientras que el segundo no lo está.

El segundo contrato funciona bien. Puedo llamar a hash(), test(), lo que sea, y todo funciona como se esperaba.

Sin embargo, nada funciona con el primer contrato. No puedo usar call() ni transact() en ninguna función (aunque la estimaciónGas() funciona bien). En su lugar, me sale el siguiente error:

eth_abi.exceptions.InsufficientDataBytes: Intenté leer 32 bytes. Solo obtuve 0 bytes

web3.exceptions.BadFunctionCallOutput: no se pudo realizar transacciones con/llamar a la función de contrato, ¿el contrato se implementó correctamente y la cadena se sincronizó?

No estoy seguro de cuál es el problema, ¿alguien puede aclararme? Estos son los contratos:

contract Award {
    
    address public authority;
    string public hash;
    
    bool itWorked = false;
    
    mapping(address => bool) users;
    
    function Award(string _hash) public {
        authority = msg.sender;
        hash = _hash;
    }
    
    function addUser(address _address) public {
        users[_address] = true;
    }
    
    function deleteUser(address _address) public {
        users[_address] = false;
    }
    
    function hasUser(address _address) public view returns (bool) {
        return users[_address];
    }

    function test() public pure returns (bool) {
        return true;
    }
    
}

y

contract Award {
    
    address authority;
    string public hash;
    
    bool itWorked = false;
    
    mapping(address => bool) users;
    
    function Award(string _hash) public {
        authority = msg.sender;
        hash = _hash;
    }
    
    function addUser(address _address) public {
        users[_address] = true;
    }
    
    function deleteUser(address _address) public {
        users[_address] = false;
    }
    
    function hasUser(address _address) public view returns (bool) {
        return users[_address];
    }

    function test() public pure returns (bool) {
        return true;
    }
    
}

Según lo solicitado, aquí está el código de Python que realiza la llamada:

contract = w3.eth.contract(abi=contract.abi, bytecode=contract.bytecode)
hash = contract.constructor('test_hash').transact(transaction={'from': self.account, 'gas': 410000})

while True:
        receipt = e.get_transaction_receipt(hash)

        if receipt:
            break

        sleep(2)

address = w3.w3.eth.getTransactionReceipt(hash)['contractAddress']

instance = w3.eth.contract(abi=contract.abi, address=address)

instance.functions.test().call()
Difícil de decir así. ¿Podría proporcionar su código js? ¿Estás seguro de que tienes el ABI correcto?
Definitivamente es el ABI correcto, lo he probado con ambos contratos innumerables veces. De hecho, estoy usando web3.py, ¡pero sí, publicaré el código ahora!
Verifique el código de estado en el recibo de la transacción antes de extraer la dirección del contrato. 0significa que hubo un error de implementación.
@carver Lamentablemente, es una red privada y nunca habilité Byzantium cuando la inicié. Sin embargo, he comprobado la transacción y todo parece estar bien. No entiendo por qué sería diferente al que no tiene "público".
@carver Habilité Byzantium en la red, y el indicador de estado es 0 cuando uso el contrato incorrecto. ¿Alguna idea de por qué esto podría ser? Remix IDE no dice que haya nada malo con el contrato.

Respuestas (1)

El problema fue que no proporcioné suficiente gas para que el constructor del contrato lo ejecutara.

Como se sugirió en los comentarios, verifiqué el estado de la transacción, que era 0. Luego me di cuenta de que el gas utilizado era igual al gas proporcionado.

Después de aumentar el gas para la transacción de despliegue, el contrato funcionó bien.