Created
December 5, 2018 07:17
-
-
Save christoph2806/aa2e44a9ff8af9fd065ddb1474fb369a to your computer and use it in GitHub Desktop.
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=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
// Now forward request to concrete provider | |
_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 => OracleConsumer) oracleConsumers; | |
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); | |
oracleConsumers[_requestId] = OracleConsumer(msg.sender); | |
} | |
function __callback(bytes32 _requestId, string memory _result, bytes memory _proof) public { | |
OracleConsumer consumer = oracleConsumers[_requestId]; | |
delete oracleConsumers[_requestId]; | |
consumer.callback(_requestId, abi.encode(_result, _proof)); | |
} | |
} | |
contract HttpProvider is Owned, OracleProvider{ | |
uint256 requestCounter; | |
mapping (bytes32 => OracleConsumer) oracleConsumers; | |
event CallHttpOracle(string URL); | |
function makeRequest(bytes memory _args) public returns (bytes32 _requestId) { | |
_requestId = keccak256(abi.encode(requestCounter)); | |
requestCounter += 1; | |
oracleConsumers[_requestId] = OracleConsumer(msg.sender); | |
emit CallHttpOracle(abi.decode(_args, (string))); | |
} | |
function callback(bytes32 _requestId, string memory _result) public onlyOwner { | |
OracleConsumer consumer = oracleConsumers[_requestId]; | |
delete oracleConsumers[_requestId]; | |
consumer.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)); | |
OracleConsumer(msg.sender).callback(_requestId, abi.encode(x + y)); | |
} | |
} | |
contract LoadBalancingOracle is Owned, OracleProvider { | |
uint256 requestCounter; | |
mapping (bytes32 => OracleConsumer) oracleConsumers; | |
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; | |
oracleConsumers[_requestId] = OracleConsumer(msg.sender); | |
return OracleProvider(getNextOracle()).makeRequest(_args); | |
} | |
function callback(bytes32 _requestId, bytes memory _result) public { | |
OracleConsumer consumer = oracleConsumers[_requestId]; | |
delete oracleConsumers[_requestId]; | |
consumer.callback(_requestId, abi.encode(_result)); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment