Die öffentliche Adressvariable verursacht eine BadFunctionCall-Ausnahme

Siehe die Verträge unten. Sie werden feststellen, dass die Verträge identisch sind, mit der Ausnahme, dass das Autoritätsfeld des ersten Vertrags als öffentlich gekennzeichnet ist, das des zweiten jedoch nicht.

Der zweite Vertrag funktioniert einwandfrei. Ich kann hash(), test(), was auch immer aufrufen, und alles funktioniert wie erwartet.

Beim ersten Vertrag klappt allerdings nichts. Ich kann weder call() noch transact() für irgendeine Funktion verwenden (obwohl schätztGas() gut funktioniert). Stattdessen erhalte ich folgenden Fehler:

eth_abi.exceptions.InsufficientDataBytes: Es wurde versucht, 32 Bytes zu lesen. Habe nur 0 Bytes bekommen

web3.exceptions.BadFunctionCallOutput: Konnte keine Transaktion mit/Aufrufvertragsfunktion durchführen, wird der Vertrag korrekt bereitgestellt und die Kette synchronisiert?

Ich bin mir nicht sicher, was das Problem ist, kann mich jemand aufklären? Hier die Verträge:

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;
    }
    
}

Und

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;
    }
    
}

Wie gewünscht, hier ist der Python-Code, der den Aufruf durchführt:

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()
Schwer so zu sagen. Könnten Sie Ihren js-Code bereitstellen? Sind Sie sicher, dass Sie das richtige ABI haben?
Es ist auf jeden Fall das richtige ABI, habe ich mit beiden Verträgen unzählige Male getestet. Ich verwende eigentlich web3.py, aber ja, ich werde den Code jetzt posten!
Überprüfen Sie den Statuscode im Transaktionsbeleg, bevor Sie die Vertragsadresse extrahieren. 0bedeutet, dass ein Bereitstellungsfehler aufgetreten ist.
@carver Leider ist es ein privates Netzwerk und ich habe Byzantium nie aktiviert, als ich es gestartet habe. Ich habe die Transaktion jedoch überprüft und alles scheint in Ordnung zu sein. Ich verstehe nicht, warum es anders sein sollte als ohne "Öffentlichkeit".
@carver Ich habe Byzantium im Netzwerk aktiviert und das Status-Flag ist 0, wenn ich den schlechten Vertrag verwende. Irgendwelche Ideen, warum das sein könnte? Remix IDE sagt nicht, dass etwas mit dem Vertrag nicht stimmt.

Antworten (1)

Das Problem war, dass ich nicht genug Gas für die Ausführung des Vertragskonstrukteurs bereitgestellt habe.

Wie in den Kommentaren vorgeschlagen, überprüfte ich den Transaktionsstatus, der 0 war. Dann stellte ich fest, dass das verbrauchte Gas dem bereitgestellten Gas entsprach.

Nach Erhöhung des Gases für die Bereitstellungstransaktion lief der Vertrag problemlos.