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!!
oracle
andoracleAddr
. If you haveOracleInterface internal oracle
it should be enough for any use (OracleInterface
is stored in the contract as an address).