1

I'm trying to do a data access control system with smart contract. I have 3 entity:

  1. Client: who can get data and set address of Oracle
  2. Oracle: who can add data and have getData() function
  3. RBAC: Role based access control, who manage permission

The system has also 2 interfaces for Oracle and RBAC for principal functions. When I test the system on JavaScript VM (on Remix) all is okay and I haven't problem. But when I trying to deploy this system on my private blockchain it's doesn't work. When I trying to set the Oracle address in the client contract I have the problem: "gas required exceeds allowance or always failing transaction and the function doesn't work". I checked if I used the correct account (is a function callable only by the owner of the contract) and is ok.

Here my setOracleAddress() function code (in client contract):

//data oracle  
address internal oracleAddr = 0x0000000000000000000000000000000000000000;
OracleInterface internal oracle = OracleInterface(oracleAddr); 

    function setOracleAddress(address _oracleAddress) external onlyOwner returns (bool) {
    oracleAddr = _oracleAddress;
    oracle = OracleInterface(oracleAddr);  
    return oracle.testConnection();
}

Here's the testConnection() code (in oracle contract):

/// @notice can be used by a client contract to ensure that they've connected to this contract interface successfully
/// @return true, unconditionally  
function testConnection() public pure returns (bool) {
    return true;  
}

In my genesis blockchain block I've the follow gas limit:

"gasLimit"   : "0x8000000",

Here's how I get the Oracle address:

/// @notice gets the address of this contract  
/// @return address  
function getAddress() public view returns (address) {
    return address(this);
}

Modifier onlyOwner() code:

  /**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
    require(msg.sender == owner);
    _;
}

I tried to increase the gasLimit in genesis block, to check the correct account and to update the software (truffle, geth, web3).

EDIT: I solved the problem of setting the address by adding to the genesis file the line

"ByzantiumBlock":0

But now I get the same error when I try to add test data.

Here's the code of addData() function:

    /// @notice puts a new pending data into the blockchain  
/// @param name descriptive name for the data (e.g. House001)
/// @param otherInfo about something like address (e.g. "Via roma 6, Torino")
/// @param sensorData sensor data
/// @return the unique id of the newly created data  
function addData(string memory name, string memory otherInfo, uint sensorData,  uint permissionMin, uint date) onlyOwner public returns (bytes32) {

    assert(permissionMin < rbac.getNumRole());

    //hash the crucial info to get a unique id  
    bytes32 id = keccak256(abi.encodePacked(name,otherInfo,date));  

    //require that the data be unique (not already added)  
    require(!dataExists(id));

    //add data
    uint newIndex = data.push(Data(id, name, otherInfo, sensorData, permissionMin, date, false))-1;  
    dataIdToIndex[id] = newIndex+1;

    //return the unique id of the new data
    return id;
}

Get numRole() function code:

uint numRole = 3;

 function getNumRole() public view returns(uint){
     return numRole;
 }

Struct Data code:

//defines a struct "Data"
struct Data {
    bytes32 id;
    string name;
    string otherInfo;
    uint sensorData;
    uint permission; 
    uint date;
    bool read;
}

Example of addData():

    /// @notice for testing  
function addTestData() external onlyOwner {
    addData("House001", "via Roma 2, Milano", 0,1, 20190504);

Error when forcing the execution

Any help? Thanks!!

  • Are you the owner of the contract when making the call? OTOH you do not need to have both oracle and oracleAddr. If you have OracleInterface internal oracle it should be enough for any use (OracleInterface is stored in the contract as an address). – Ismael Apr 10 at 16:10
  • Yes, I'm the owner of the contract. Thanks for the suggestion! – Tommaso Pessina Apr 11 at 12:17
  • I solved the problem of setting the address by adding in the genesis file: "ByzantiumBlock":0 But now I get the same error when I'm trying to add test data – Tommaso Pessina Apr 11 at 12:36
  • What do you mean with "add test data"? What is your contract code? How do you call your contract? ie parameters used. – Ismael Apr 11 at 16:53
  • Is a system for smart grid. There are some sensor that collect some data and put it into the blockchain (with addData(..) function). After that, it's present a Role Based Access Controll contract for manage the permission on what every "user" can read (retrive data from the blockchain) – Tommaso Pessina Apr 12 at 14:13
0
  1. What's your private chain running on? Do you know what version of Solidity you have access to? There are known bugs with making cross-contract function calls in relatively recent versions -- you may need to find a way to upgrade your private chain's software.
  2. Check out this answer from a few months back: https://stackoverflow.com/a/50951266/2128308 . If you're running a permissioned chain and have the gas price set to zero, that can lead to unexpected behavior.
  3. Geth's errors were garbage for a long time -- if a require() check failed, it looked the same as an out of gas error. Double check that you're actually an owner of the contract, your modifier might be blocking you out.

Good luck!

  • 1
    In fact was only a require() that has fail and after some check and some time, he settled down. (or so it seems apparently) – Tommaso Pessina Apr 17 at 12:56

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.