0

I am trying to call a fairly simple contract on a private blockchain:

function getOwner() public returns (address) {
    return owner;
}

And here is my running it from an interactive Python shell:

>>> e.unlock_account()

>>> instance.functions.getOwner().transact()
HexBytes('0x4f366ba7bb7ae0ef70e48c3ce7eb4f920d7079e90a10bfea36fc9fbbb48d52fe')

That works fine, but I need the function return value, not the transaction hash. So I believe I need to then call it right?

>>> e.unlock_account()

>>> instance.functions.getOwner().call({'from': e.account})

... error trace ...
eth_abi.exceptions.InsufficientDataBytes: Tried to read 32 bytes.  Only got 0 bytes
... more error traces ...
raise BadFunctionCallOutput(msg) from e
web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?

Has anyone any idea what I'm doing wrong?


Edit: I have tested it with another even more basic contract, and it seems to work fine. The contracts only differ in that the one that works returns an int..

function reveal() public view returns (int) {
    return number;
}

When I call() the function above, it returns the correct number.


Edit 2: I removed all of the functions from the contract related to setting an owner address, and now everything works. I have supplied the before and after versions of the contract, in case anyone else comes across the same issue. I still have no idea what is causing the contract not to work with addresses.. Is it something to do with the constructor? Any explanations are appreciated!

BEFORE EDIT (NOT WORKING)    

pragma solidity ^0.4.0;

contract CryptoCert {

struct Award {
    bool isValid;
    string hash;
}

struct Authority {
    bool isValid;
    string hash;
    address[] representatives;
    Award[] awards;
}

address private owner;

mapping(address => Authority) authorities;

modifier onlyOwner() {
    require(msg.sender == owner);
    _;
}

modifier onlyBy(address _address) {
    require(msg.sender == _address);
    _;
}

function CryptoCert() public {
    owner = msg.sender;
}

function kill() external {
    if (msg.sender == owner) {
        selfdestruct(owner);
    }
}

function createAuthority(address _address, string _hash) public onlyOwner {
    authorities[_address].hash = _hash;
    authorities[_address].isValid = true;
}

function addAuthorizedAddress(address _authAddress, address _repAddress) public onlyBy(_authAddress) {
    authorities[_authAddress].representatives.push(_repAddress);
}

function getAuthorityHash(address _address) public view returns (uint) {
    if (authorities[_address].isValid) {
        return 1;
    } else {
        return 0;
    }
}

function getOwner() public view returns (address) {
    return owner;
}

function test() public pure returns (string) {
    return "nigchicken69";
}

}

And after...

AFTER EDIT (WORKING)

pragma solidity ^0.4.0;

contract CryptoCert2 {

    struct Award {
        bool isValid;
        string hash;
    }

    struct Authority {
        bool isValid;
        string hash;
        address[] representatives;
        Award[] awards;
    }

    mapping(address => Authority) authorities;

    function createAuthority(address _address, string _hash) public {
        authorities[_address].hash = _hash;
        authorities[_address].isValid = true;
    }

    function addAuthorizedAddress(address _authAddress, address _repAddress) public {
        authorities[_authAddress].representatives.push(_repAddress);
    }

    function getAuthorityHash(address _address) public view returns (uint) {
        if (authorities[_address].isValid) {
            return 1;
        } else {
            return 0;
        }
    }

}
  • The error suggests that the contract isn't deployed at that address in the chain that web3 is connected to. Maybe wrong connection parameters, maybe the contract isn't deployed, maybe the address for the contract is wrong. – carver Apr 14 '18 at 18:08
  • I figured the same, but I've double and triple checked all the parameters. The contract is definitely there and live. I have updated the post with another very simple contract which seems to work fine. – Cathal Apr 14 '18 at 18:37
  • 1
    Solidity 0.4.0 is 1.5 years old. Can you try with 0.4.19 or .20? – carver Apr 14 '18 at 19:58
0

Calling read functions is easy:

print('returned value: {}'.format(contractInstance.functions.getXyz().call()))

Make sure you install the latest Python and web3.py version 4

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.