0

See the contracts at the bottom. You will notice that the contracts are identical, except that the first contract's authority field is marked public, while the second isn't.

The second contract works fine. I can call hash(), test(), whatever, and everything works as expected.

However, nothing works with the first contract. I can use neither call() nor transact() on any function (although estimateGas() works fine). Instead, I get the following error:

eth_abi.exceptions.InsufficientDataBytes: Tried to read 32 bytes. Only got 0 bytes

web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?

I'm not sure what the problem is, can anyone enlighten me? Here are the contracts:

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

}

and

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

}

As requested, here is the Python code making the call:

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()
  • Hard to say like that. Could you provide your js code? Are you sure you have the correct ABI? – Eli Drion Apr 16 '18 at 17:56
  • It's definitely the correct ABI, I have tested with both contracts countless times. I'm actually using web3.py, but yeah I'll post the code now! – Cathal Apr 16 '18 at 18:32
  • Check the status code in the transaction receipt before extracting the contract address. 0 means there was a deployment failure. – carver Apr 16 '18 at 19:26
  • @carver Unfortunately it's a private network and I never enabled Byzantium when I started it. I have checked the transaction though and everything seems to be OK. I don't understand why it would be any different to the one without "public". – Cathal Apr 17 '18 at 11:52
  • @carver I enabled Byzantium on the network, and the status flag is 0 when I use the bad contract. Any ideas why this might be? Remix IDE isn't saying there's anything wrong with the contract. – Cathal Apr 19 '18 at 9:41
0

The problem was that I didn't provide enough gas for the contract constructor to execute.

As suggested in the comments, I checked the transaction status, which was 0. I then realized the gasUsed was equal to the gas provided.

After increasing the gas for the deployment transaction, the contract ran fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.