I'm trying to do a data access control system with smart contract. I have 3 entity:
- Client: who can get data and set address of Oracle
- Oracle: who can add data and have getData() function
- 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!!
Best Answer
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!