1

I've build a smart contract and now I'm testing it using the python interface of web3.py. In my contract, I declared some private variables and I created getter functions with modifiers to return these private variables. However, if I'm calling the getter function, the private variable is returned, no matter which account is unlocked at that moment. When testing in Remix, the value is not returned if accessed from the same account. Does someone know if this is a web3.py bug or has it something to do with the contract logic?

pragma solidity ^0.4.16;

contract exampleContract {
    uint256 private value;
    address public owner;

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

    function exampleContract(uint256 _value) public {
        owner = msg.sender;
        value = _value;
    }

    function viewValue() onlyOwner public returns(uint256) {
        return(value);
    }
}

Edit:

I think it has something to do with the Concise Contract class of web3.py. Using the web3.py function call(), what is the default send address if none is provided via a transact dictionary?

from web3 import Web3, IPCProvider
from web3.contract import ConciseContract

ipc_path = '/path/to/geth.ipc'
web3 = Web3(IPCProvider(ipc_path)
contract = web3.eth.contract(abi = abi, address = address, ContractFactoryClass = ConciseContract)
contract.viewValue() #Who is the sender when unlocking of an account is not required?
2

In my contract, I declared some private variables and I created getter functions with modifiers to return these private variables

It's important to understand that these values are not really "private". Anyone could inspect the blockchain to uncover these values. The private keyword only makes it less convenient.

If it's a bad thing that anyone can read your private value, then you'll need to find another way to accomplish your goal.

What is the default send address if none is provided via a transact dictionary?

It's the same as the default sender in a transaction: it defaults to web3.eth.defaultAccount or whatever your client default sender is.

Since you want to make a call, you should supply a call dictionary. That would look like:

contract.viewValue(call={'from': SENDING_ACCOUNT})

It's worth repeating: this is not an effective mechanism for hiding the value from the world.

0

It is most likely related to the logic how you set the value.

The Ethereum node will return the old value until the transaction where you call exampleContract(uint256 _value) is mined.

Depending your Ethereum node setup, which was not described in question, this might instant, few seconds or few minutes.

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.