Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.1+commit.c8a2cb62.js&optimize=false&gist=
pragma solidity >0.4.99 <0.6.0;
// import paymentProcessor interface
// import oracleTypeRegistry interface
// import oracleRegistry interface
// import requestRegistry interface
contract Owned {
address owner;
modifier onlyOwner {
require(msg.sender == owner, "can only be called by owner");
_;
}
constructor() public {
owner = msg.sender;
}
}
contract OracleTypes {
enum TypeState { Proposed, Active, Deprecated }
struct OracleType {
TypeState state;
OracleProvider provider;
}
}
interface OracleConsumer {
function callback(bytes32 _requestId, bytes calldata _result) external;
}
interface OracleProvider {
function makeRequest(bytes calldata _args) external returns (bytes32 _requestId);
}
contract OracleRequestRegistry is Owned {
struct Request {
OracleConsumer consumer;
OracleProvider provider;
}
mapping(bytes32 => Request) requests;
function createRequest(bytes32 _requestId, OracleConsumer _consumer, OracleProvider _provider) public {
requests[_requestId] = Request({consumer: _consumer, provider: _provider});
}
function getRequest(bytes32 _requestId) public view returns (OracleConsumer _consumer, OracleProvider _provider) {
Request memory req = requests[_requestId];
return (req.consumer, req.provider);
}
function getConsumer(bytes32 _requestId) public view returns (OracleConsumer _consumer) {
return requests[_requestId].consumer;
}
}
contract OracleTypeRegistry is Owned, OracleTypes {
mapping (bytes32 => OracleType) public oracleTypes;
function proposeOracleType(bytes32 _oracleTypeId, OracleProvider _oracleInterface) public {
// save oracle type as Proposed
oracleTypes[_oracleTypeId] = OracleType({state: TypeState.Proposed, provider: _oracleInterface});
}
function setOracleTypeState(bytes32 _oracleTypeId, TypeState _newState) public onlyOwner {
// transition oracle state
oracleTypes[_oracleTypeId].state = _newState;
}
function getOracleInterface(bytes32 _oracleTypeId) public view returns (OracleProvider _provider, TypeState _state) {
return (oracleTypes[_oracleTypeId].provider, oracleTypes[_oracleTypeId].state);
}
}
contract OracleBrokerFront is OracleTypes, OracleProvider {
OracleTypeRegistry typeRegistry;
OracleRequestRegistry requestRegistry;
constructor (OracleTypeRegistry _typeRegistry, OracleRequestRegistry _requestRegistry) public {
typeRegistry = _typeRegistry;
requestRegistry = _requestRegistry;
}
function makeRequest(bytes32 _oracleType, bytes memory _args) public returns (bytes32 _requestId) {
/** TODO: check if msg.sender is allowed to call oracle **/
(OracleProvider provider, TypeState state) = typeRegistry.getOracleInterface(_oracleType);
require(state == TypeState.Active);
_requestId = provider.makeRequest(_args);
requestRegistry.createRequest(_requestId, OracleConsumer(msg.sender), provider);
}
function callback(bytes32 _requestId, bytes memory _result) public {
OracleConsumer consumer = requestRegistry.getConsumer(_requestId);
consumer.callback(_requestId, _result);
}
}
/** Some sample OracleProviders: **/
contract oraclize {
function query(uint256 timestamp, string memory datasource, string memory arg, uint256 gasLimit) public returns (bytes32);
}
contract OraclizeProvider is OracleProvider, oraclize {
/* we need to deal with different versions of OracleBrokerFront */
mapping (bytes32 => OracleBrokerFront) oracleBrokerFronts;
function makeRequest(bytes memory _args) public returns (bytes32 _requestId) {
uint256 timestamp;
uint256 gaslimit;
string memory datasource;
string memory arg;
(timestamp, datasource, arg, gaslimit) = abi.decode(_args, (uint256, string, string, uint256));
_requestId = oraclize.query(timestamp, datasource, arg, gaslimit);
oracleBrokerFronts[_requestId] = OracleBrokerFront(msg.sender);
}
function __callback(bytes32 _requestId, string memory _result, bytes memory _proof) public {
OracleBrokerFront brokerFront = oracleBrokerFronts[_requestId];
delete oracleBrokerFronts[_requestId];
brokerFront.callback(_requestId, abi.encode(_result, _proof));
}
}
contract HttpProvider is Owned, OracleProvider{
uint256 requestCounter;
mapping (bytes32 => OracleBrokerFront) oracleBrokerFronts;
event CallOracle(string URL);
function makeRequest(bytes memory _args) public returns (bytes32 _requestId) {
_requestId = keccak256(abi.encode(requestCounter));
requestCounter += 1;
oracleBrokerFronts[_requestId] = OracleBrokerFront(msg.sender);
emit CallOracle(abi.decode(_args, (string)));
}
function callback(bytes32 _requestId, string memory _result) public onlyOwner {
OracleBrokerFront brokerFront = oracleBrokerFronts[_requestId];
delete oracleBrokerFronts[_requestId];
brokerFront.callback(_requestId, abi.encode(_result));
}
}
contract ComputeProvider is Owned, OracleProvider{
function makeRequest(bytes memory _args) public returns (bytes32 _requestId) {
_requestId = bytes32(0);
(uint256 x, uint256 y) = abi.decode(_args, (uint256, uint256));
OracleBrokerFront(msg.sender).callback(_requestId, abi.encode(x + y));
}
}
contract LoadBalancingOracle is Owned, OracleProvider {
uint256 requestCounter;
mapping (bytes32 => OracleBrokerFront) oracleBrokerFronts;
OracleProvider[] oracles;
uint256 nextOracle = 0;
function registerParticipatingOracle(OracleProvider _participant) public {
oracles.push(_participant);
}
function getNextOracle() public returns (OracleProvider _next) {
require(oracles.length > 0);
_next = oracles[nextOracle];
nextOracle = nextOracle >= oracles.length ? 0 : nextOracle + 1;
}
function makeRequest(bytes memory _args) public returns (bytes32 _requestId) {
_requestId = keccak256(abi.encode(requestCounter));
requestCounter += 1;
oracleBrokerFronts[_requestId] = OracleBrokerFront(msg.sender);
return OracleProvider(getNextOracle()).makeRequest(_args);
}
function callback(bytes32 _requestId, bytes memory _result) public {
OracleBrokerFront brokerFront = oracleBrokerFronts[_requestId];
delete oracleBrokerFronts[_requestId];
brokerFront.callback(_requestId, abi.encode(_result));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.