-
Notifications
You must be signed in to change notification settings - Fork 47
/
OraclizeOracle.sol
202 lines (186 loc) · 5.97 KB
/
OraclizeOracle.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
pragma solidity ^0.4.0;
import "Oracles/OraclizeFakeAPI.sol";
import "Oracles/AbstractOracle.sol";
/// @title Oraclize proxy resolver contract - On chain oracle to resolve events using Oraclize oracle.
/// @author Stefan George - <[email protected]>
contract OraclizeOracle is Oracle, usingOraclize {
/*
* Data structures
*/
// queryID => Result
mapping (bytes32 => Result) results;
// queryID => is winning outcome set?
mapping (bytes32 => bool) winningOutcomeSet;
// queryID =>
mapping (bytes32 => bytes32[]) eventData;
struct Result {
int result;
uint precision;
bytes proof;
}
/*
* Constants
*/
// Oracle meta data
string constant public name = "Oraclize wrapper Oracle";
/*
* Read and write functions
*/
/// @dev Contract constructor tells Oraclize to store TLSNotary proof with result.
function OraclizeOracle() {
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
}
/// @dev Callback called by Oraclize to set result.
/// @param queryID Query id of Oraclize query.
/// @param result Result returned as string.
/// @param proof TLSNotary proof.
function __callback(bytes32 queryID, string result, bytes proof) {
if (msg.sender != oraclize_cbAddress()) {
// Only Oraclize is allowed to call callback
throw;
}
results[queryID].result = parseToInt(result, results[queryID].precision);
results[queryID].proof = proof;
winningOutcomeSet[queryID] = true;
}
/// @dev Validates and registers event. Returns event identifier.
/// @param data Array of oracle addresses used for event resolution.
/// @return eventIdentifier Returns event identifier.
function registerEvent(bytes32[] data)
public
returns (bytes32 queryID)
{
uint dataSourceIndex = uint(data[0]);
string memory dataSource;
if (dataSourceIndex == 0) {
dataSource = "URL";
}
else if (dataSourceIndex == 1) {
dataSource = "WolframAlpha";
}
else if (dataSourceIndex == 2) {
dataSource = "Blockchain";
}
else {
// Wrong data source type
throw;
}
uint timestamp = uint(data[1]);
uint precision = uint(data[2]);
bytes32[] memory urlData = new bytes32[](data.length - 3);
for (uint i=3; i<data.length; i++) {
urlData[i-3] = data[i];
}
string memory url = bytes32ArrayToString(urlData);
// Send query to Oraclize
queryID = oraclize_query(timestamp, dataSource, url);
// Save query information
results[queryID].precision = precision;
eventData[queryID] = urlData;
EventRegistration(msg.sender, queryID);
}
/*
* Read functions
*/
/// @dev Returns if winning outcome is set for given event.
/// @param eventIdentifier Hash identifying an event.
/// @return isSet Returns if outcome is set.
function isOutcomeSet(bytes32 eventIdentifier)
constant
public
returns (bool isSet)
{
return winningOutcomeSet[eventIdentifier];
}
/// @dev Returns winning outcome for given event.
/// @param eventIdentifier Hash identifying an event.
/// @return outcome Returns outcome.
function getOutcome(bytes32 eventIdentifier)
constant
public
returns (int outcome)
{
return results[eventIdentifier].result;
}
/// @dev Returns string concatenating bytes32.
/// @param data Array of bytes32 strings.
/// @return concatenation Returns concatenated string.
function bytes32ArrayToString (bytes32[] data)
constant
public
returns (string concatenation)
{
bytes memory bytesString = new bytes(data.length * 32);
uint urlLength;
for (uint i=0; i<data.length; i++) {
for (uint j=0; j<32; j++) {
byte char = data[i][j];
if (char != 0) {
bytesString[urlLength] = char;
urlLength += 1;
}
}
}
bytes memory bytesStringTrimmed = new bytes(urlLength);
for (i=0; i<urlLength; i++) {
bytesStringTrimmed[i] = bytesString[i];
}
return string(bytesStringTrimmed);
}
/// @dev Parses a string to an integer.
/// @param _a String with number.
/// @param _b Number of decimal places.
/// @return mint Returns parsed integer.
function parseToInt(string _a, uint _b)
constant
public
returns (int mint)
{
bytes memory bresult = bytes(_a);
mint = 0;
bool decimals = false;
for (uint i=0; i<bresult.length; i++) {
if ((bresult[i] >= 48) && (bresult[i] <= 57)) {
if (decimals) {
if (_b == 0) {
break;
}
else {
_b--;
}
}
mint *= 10;
mint += int(bresult[i]) - 48;
}
else if (bresult[i] == 46) {
decimals = true;
}
}
mint *= int(10**_b);
if (bresult[0] == 45) {
mint *= -1;
}
}
/// @dev Returns data needed to identify an event.
/// @param eventIdentifier Hash identifying an event.
/// @return data Returns event data.
function getEventData(bytes32 eventIdentifier)
constant
public
returns (bytes32[] data)
{
return eventData[eventIdentifier];
}
/// @dev Returns total fees for oracle.
/// @param data Event data used for event resolution.
/// @return fee Returns fee.
/// @return token Returns token.
function getFee(bytes32[] data)
constant
public
returns (uint fee, address token)
{
fee = 0;
token = 0;
}
}