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)