Introduction to
A-Lin
Profile
- JAVA 5 years
- Javascript 3 years
- conference speaker
- JSDC.tw 2016
- Testing Day 2018
- Modern Web 2016, 2018
- coding coach
- alincode@gmail.com
What is Oraclize?
What is Oraclize?
- blockchain oracle service
- data provider
- the service can use in
- Ethereum
- EOS
- Rootstock
- Fabric
- etc...
Oraclize Engine
-
A data source type
-
A query
-
An authenticity proof type (Option)
1. Data Sources Type
Data Sources Type
-
URL
-
WolframAlpha
-
knowledge engine or answer engine
-
-
IPFS
-
InterPlanetary File System
-
-
random
-
computation
2. A query
pragma solidity ^0.4.11;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
contract ExampleContract is usingOraclize {
string public ETHUSD;
function updatePrice() payable {
oraclize_query(
"URL",
"json(https://api.gdax.com/products/ETH-USD/ticker).price");
}
function __callback(bytes32 myid, string result) {
if (msg.sender != oraclize_cbAddress()) revert();
ETHUSD = result;
}
}
Etherscan
Type : URL
-
if only one parameter is specified in the query, the service will default to perform an HTTP GET request.
-
if a second parameter is specified, then the service will perform an HTTP POST request.
HTTP GET request
function oraclize_query(string datasource, string arg)
oraclizeAPI internal returns (bytes32 id)
syntax :
example :
oraclize_query(
"URL",
"https://www.therocktrading.com/api/ticker/ETHEUR"
)
HTTP POST request
function oraclize_query(string datasource, string arg1, string arg2)
oraclizeAPI internal returns (bytes32 id)
syntax :
example :
oraclize_query(
"URL",
"json(https://shapeshift.io/sendamount).success.deposit",
'{
"pair":"eth_btc",
"amount":"1",
"withdrawal":"1AAcCo21EUc1jbocjssSQDzLna9Vem2UN5"
}'
)
Parsing Helpers
-
JSON Parsing
-
XML Parsing
-
HTML Parsing
-
Binary Parsing
JSON Parsing
oraclize_query("URL",
"json(
https://www.therocktrading.com/api/ticker/BTCEUR
).result.0.last")
{
result: [{
symbol: "ETHEUR",
currency: "EUR",
bid: 197.69,
ask: 197.7,
last: 197.69,
open: 195.27,
close: 198.45,
low: 193.29,
high: 199.99,
volume: 7556.48,
volume_traded: 38.007
}]
}
Type : computation
More advanced HTTP capabilities, such as Basic Authentication or OAuth, can be build by leveraging the computation data source type.
Type : computation
Type : computation
-
Step1: write your own Dockerfile
-
Step2: write your script, e.g. "url-requests.py"
-
Step3: zip all files in the "archive.zip"
-
Step4: upload "archive.zip" to IPFS, then get the IPFS hash
-
Step5: implement oraclize query
For example
Step1: write your own Dockerfile
FROM frolvlad/alpine-python3
MAINTAINER Oraclize "info@oraclize.it"
COPY url-requests.py /
RUN pip3 install requests
CMD python ./url-requests.py
#!/usr/bin/python
import sys
import ast
import requests
import os
# parse env args
arg = [os.environ['ARG0'], os.environ['ARG1']]
# parse 3rd arg into kwargs if available
if 'ARG2' in os.environ: kwargs = ast.literal_eval(os.environ['ARG2'])
else: kwargs = {}
# attempt the request
req = requests.request(arg[0], arg[1], **kwargs)
# print text result on single line
# print(json.loads(req.text))
print(req.text.replace('\n',''))
Step2: write your script
be careful last line,
output will send to Oraclize Service.
Step3: zip all files in the "archive.zip"
Step4: upload "archive.zip" to IPFS
ipfs daemon
ipfs add archive.zip
// output message:
//
// added QmRxtL9K2de7v7QBYCCrwcjZHjYmuKggZ8xaqZ6UUWvd1s archive.zip
function oraclize_query(string datasource, string[4] args)
oraclizeAPI internal returns (bytes32 id)
syntax :
Step5: implement smart contract
to oraclize query
import "github.com/Arachnid/solidity-stringutils/strings.sol";
using strings for *;
string _query = "json(QmdKK319Veha83h6AYgQqhx9YRsJ9MJE7y33oCXyZ4MqHE).user.displayName";
string _method = "GET";
string _url = "https://api.fitbit.com/1/user/-/profile.json";
string _kwargs = strConcat(
"{'headers': {'content-type': 'json', 'Authorization': 'Bearer ",
_access_token,
"'}}"
);
bytes32 queryId = oraclize_query("computation",
[ _query,
_method,
_url,
_kwargs]
);
-
"QmdKK31...yZ4MqHE" -> get from step4
-
second parameter is "string[4] args"
req = requests.request(arg[0], arg[1], **kwargs)
bytes32 queryId = oraclize_query("computation",
[ _query,
_method,
_url,
_kwargs]
);
smart contract
url-requests.py
But...
didn't encryption the token
string _kwargs = strConcat(
"{'headers': {'content-type': 'json', 'Authorization': 'Bearer ",
_access_token,
"'}}"
);
encryption of the token
function encrypt(data, next) {
const init = {
method: 'POST',
body: JSON.stringify(data),
};
fetch('https://api.oraclize.it/v1/utils/encryption/encrypt', init)
.then(processResponse)
.then(next)
.catch(console.error);
}
function encryptHeader(token, next) {
const header = `{'headers': {'content-type': 'json', 'Authorization': 'Bearer ${token}'}}`;
encrypt({ "message" : header }, function (data) {
// console.log(data);
if (data.success) {
next(null, data.result);
} else {
next(new Error("encrypt header fail"));
}
});
}
_encryptHeader
function request(string _encryptHeader, string _userId) public payable {
string memory _query
= "json(QmdKK319Veha83h6AYgQqhx9YRsJ9MJE7y33oCXyZ4MqHE).lifetime.total.steps";
string memory _method = "GET";
string memory _url = "https://api.fitbit.com/1/user/-/activities.json";
bytes32 queryId
= oraclize_query("computation", [ _query, _method, _url, _encryptHeader]);
}
3. Authenticity Proof Types
Authenticity Proof Types
-
TLSNotary Proof
-
Android Proof
-
Ledger Proof
Storage and Delivery
-
The authenticity proofs may be relatively large files.
-
the proof is uploaded and saved to IPFS, a decentralized and distributed storage system.
-
IPFS, by itself, doesn't provide any long-term guarantees of persistency, however as part of Oraclize's infrastructures it runs the IPFS persistence consortium.
contract proofShieldExample is usingOraclize {
event LogNewAuthenticatedResult(string);
mapping (bytes32 => bool) public pendingQueries;
function proofShieldExample() payable {
oraclize_setProof(proofType_Android_v2 | proofShield_Ledger);
}
function __callback(bytes32 queryId, string result, bytes proof) {
if (msg.sender != oraclize_cbAddress()) revert();
if (oraclize_proofShield_proofVerify__returnCode(queryId, result, proof) != 0) {
// the proof verification has failed
} else {
// the proof verification has passed
require(pendingQueries[queryId] == true);
delete pendingQueries[queryId];
LogNewAuthenticatedResult(result);
}
}
function sendQuery() payable {
string memory query = "json(https://www.bitstamp.net/api/v2/ticker/ethusd/).last";
bytes32 queryId = oraclize_query("URL", query);
pendingQueries[queryId] = true;
}
}
Custom gas and price
oraclize_setCustomGasPrice(4000000000);
uint constant CUSTOM_GASLIMIT = 150000;
if (oraclize_getPrice("URL", CUSTOM_GASLIMIT) > this.balance)
oraclize_query(
"URL",
"json(https://api.kraken.com/0/public/Ticker?pair=ETHXBT).result.XETHXXBT.c.0",
CUSTOM_GASLIMIT);
Price (USD)
Introduction_to_oraclize
By alincode
Introduction_to_oraclize
by alincode
- 1,408