diff --git a/.gitignore b/.gitignore index 10501583560..95fdb84e3e6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ build/ _yardoc doc/ .idea/ +*.sw* diff --git a/source/includes/_ethereum.md b/source/includes/_ethereum.md index 8f8e616288d..cc30ba2dd4f 100644 --- a/source/includes/_ethereum.md +++ b/source/includes/_ethereum.md @@ -8,7 +8,7 @@ The interaction between Oraclize and an Ethereum smart contract is asynchronous. * Firstly, in the most common case, a transaction executing a function of a smart contract is broadcasted by a user. The function contains a special instruction which manifest to Oraclize, who is constantly monitoring the Ethereum blockchain for such instruction, a request for data. * Secondly, according to the parameters of such request, Oraclize will fetch or compute a result, build, sign and broadcast the transaction carrying the result. In the default configuration, such transaction will execute the `__callback` function which should be placed in the smart contract by its developer: for this reason, this transaction is referred in the documentation as the Oraclize callback transaction. -As said in previous sections, one of the fundamental characteristics of Oraclize is the capability of returning data to a smart contract together with one or more proofs of authenticity of the data. The generation of an authenticity proof is optional and it is a contract-wide setting which must be configured by the smart contract developer before the request for data is initiated. Oraclize always recommends the use of authenticity proofs for production deployments. +As said in previous sections, one of the fundamental characteristics of Oraclize is the capability of returning data to a smart contract together with one or more proofs of authenticity of the data. The generation of an authenticity proof is optional and it is a contract-wide setting which must be configured by the smart contract developer before the request for data is initiated. Oraclize always recommends the use of authenticity proofs for production deployments. ## Quick Start @@ -41,7 +41,7 @@ contract ExampleContract is usingOraclize { oraclize_query("URL", "json(https://api.pro.coinbase.com/products/ETH-USD/ticker).price"); } } -} +} ``` The most simple way to introduce the Ethereum - Oraclize integration, it is by showing a working example, such as the smart contract on the right. @@ -58,8 +58,8 @@ To ease development, Oraclize doesn't charge a contract for its first request of Only the first query is free. Ensure that the contract has a sufficient ETH balance to pay the following queries. The contract gets automatically charged on the `oraclize_query` call but fails if the balance is insufficient. - ### Simple Query + ```javascript // This code example will ask Oraclize to send as soon as possible // a transaction with the primary result (as a string) of the given @@ -87,7 +87,7 @@ A request for data is called **query**. The `oraclize_query` is a function, inhe * or a `WolframAlpha` formula * or an `IPFS` multihash -The number and type of supported arguments depends from the data-source in use. Beside, few more code example will be shown and commented. The datasource, as well as the authenticity proof chosen, determine the fee which the contract has to pay to Oraclize. +The number and type of supported arguments depends from the data-source in use. Beside, few more code example will be shown and commented. The datasource, as well as the authenticity proof chosen, determine the fee which the contract has to pay to Oraclize. ### Schedule a Query in the Future @@ -137,13 +137,12 @@ contract ExampleContract is usingOraclize { } ``` -Smart contracts using Oraclize can be effectively autonomous by implementing a new call to Oraclize into their ` __callback` method. -This can be useful for implementing periodic updates of some on-chain reference data, as with price feeds, or to periodically check for some off-chain conditions. +Smart contracts using Oraclize can be effectively autonomous by implementing a new call to Oraclize into their ` __callback` method. This can be useful for implementing periodic updates of some on-chain reference data, as with price feeds, or to periodically check for some off-chain conditions. -This modified version of the previous example will update the ETH/USD exchange rate every 60 seconds, until the contract has enough funds to pay for the Oraclize fee. +This modified version of the previous example will update the ETH/USD exchange rate every 60 seconds whilst the contract has enough funds to pay for the Oraclize fee. ### The Query ID @@ -258,6 +257,46 @@ When calling `oraclize_setCustomGasPrice` the parameter type is uint and represe +### Query Rebroadcasts + +When making Provable queries, users are able to specify custom gas limits and gas prices for them as outlined __[in this section here.](http://docs.oraclize.it/#ethereum-quick-start-custom-gas-limit-and-gas-price)__ However, due to the asynchronous nature of Provable queries and the volatility of gas-prices on the Ethereum Mainnet, a user may occasionally find themselves in a situation where the gas price they have requested for their callback transaction is no longer high enough to ensure the transaction gets mined quickly. This is especially true when using delayed queries, where the likelihood of the congestion level of the Ethereum network when the query was made being the same as when the delayed callback is due diminishes. + +In such cases, users have the ability to request a _rebroadcast_ of their transaction, via which the user may specify new, higher parameters for both the gas limit and the gas price: + +```javascript +uint256 newGasLimit = ; +uint256 newGasPrice = ; + +oraclize_requestCallbackRebroadcast( + , + newGasLimit, + newGasPrice + oraclize_getRebroadcastCost(newGasLimit, newGasPrice) +); +``` + +This way, the effects of the changing network conditions can be mitigated, ensuring callbacks are always received in a timely manner. + + + +Another useful feature of rebroadcasting is in giving a user a finer-control over the gas limit of their callback. Should a query be sent with an amount of gas too low for the `__callback()` to fully execute, the query would normally `revert()` and be wasted. Now a user has the ability to request a rebroadcast on that query and thus the opportunity to make changes to the gas limit in order to remedy the situation. + +In order to enable rebroadcasts, a contract writer must explicitly define the following in the storage of their contract: `bool public constant allowQueryRebroadcasts = true;`. Any attempts to rebroadcast a query destined for a contract which does not have the preceding line present will be unfulfilled. + +Just like a normal query, any over-payment is refunded, but always to the _final calling contract_. Which latter gives rise to two important caveats: + +- The first is that the refund will _always_ go to the final calling contract, and so if the call for a rebroadcast is proxied via another contract, the refund will always be made to the contract that implements the API, and not necessarily to the contract which initiated and paid for the call. + +- The second caveat is that the final calling contract will also require a payable `fallback()` function in order to receive refunds in such cases. If the payable fallback is omitted, any refund attempt will cause the query to `revert();`. + +Due to the above, it is strongly recommended that queries be paid for using their exact cost, which can be calculated via: `oraclize_getRebroadcastCost(, );` + + + ### Authenticity Proofs ```javascript @@ -308,7 +347,7 @@ When a smart contract requests for an authenticity proof, it **must** define a d The `oraclize_setProof` function expects the following format: `oraclize_setProof(proofType_ | proofStorage_ )` -Both proofType and proofStorage are byte constants defined in usingOraclize: +Both proofType and proofStorage are byte constants defined in usingOraclize: Available parameters for proofTypes are: @@ -334,7 +373,7 @@ Supported proofs can be verified. The following tools can be used: this.balance) { newOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee"); } else { @@ -373,8 +418,54 @@ contract KrakenPriceTicker is usingOraclize { ``` -You have to consider that your account will be debited for most of your Oraclize calls. If your contract is not covered with enough ETH, the query will fail. Depending on your contract logic you may want to check the price for your next query before it gets send. You can do this by calling `oraclize_getPrice` and check if it is higher than your current contract balance. If that's the case the `oraclize_query` will fail and you may want to handle it gracefully. You can also add a gaslimit parameter to the `oraclize_getPrice` function: `oraclize_getPrice(string datasource, uint gaslimit)`. Make sure that the custom gaslimit for `oraclize_getPrice` matches with the one you will use for `oraclize_query`. +Payment for Provable queries are debited directly from the contract that calls the `oraclize_query(...)'` function at the moment that function call is made. In order for that to succeed, either the contract itself needs to hold a balance of ETH, or the contract needs to implement logic to burden the contract-caller to supply the ETH. Either way, you may want to know ahead of time the price of the next query before making it. Provable provides a helper method to do just that: `oraclize_getPrice(string _datasource);`. + +If your contract is paying for queries from its own balance, it is possible gracefully handle the scenario where that balance has dropped below the cost of the query price using this helper function. Otherwise, if the balance is insufficient to cover the query at the time the query is attempted, it will fail via: `revert('Error settling query payment');`. The `update();` function in the sample contract on the right demonstrates how to implement the `oraclize_getPrice()` helper in order to perform this balance check before making a Provable query. +The `oraclize_getPrice` helper function is overloaded and so can also accept a gas limit parameter: `oraclize_getPrice(string _datasource, uint256 _gasLimit);`. This allowing you to get accurate prices for queries that use a gas limit different from the `200,000` default. + + + +`oraclize_getPrice` can also accept an `address` parameter, allowing you to discover prices for queries for _any_ contract, rather than just only the contract that is actually calling: `oraclize_getPrice(string _datasource, address _contractAddress);`. + +Finally, `oraclize_getPrice` can accept a combination of parameters allowing the discovery of very specific query prices for any datasource combined with any proof-type, using any custom gas limit, any custom gas price and for any desired contract: `oraclize_getPrice(string _datasource, uint256 _gasLimit, uint256 _gasPrice, bytes1 _proofType);` + + + +```javascript + +/** + * + * @notice All oraclize_getPrice(...) function overloads: + * + */ + +// For datasource prices... +oraclize_getPrice(string datasource); +oraclize_getPrice(bytes1 datasource); + +// For prices involing custom gas limits... +oraclize_getPrice(string datasource, uint256 _gasLimit); +oraclize_getPrice(bytes1 datasource, uint256 _gasLimit); + +// For query prices for addresses other than the calling contract... +oraclize_getPrice(string datasource, address _address); +oraclize_getPrice(bytes1 datasource, address _address); + +// For prices involving custom gas limits and custom gas prices... +oraclize_getPrice(string datasource, uint256 _gasLimit, uint256 _gasPrice); +oraclize_getPrice(bytes1 datasource, uint256 _gasLimit, uint256 _gasPrice); + +// For prices involving different datasource & prooftype combinations... +oraclize_getPrice(string datasource, uint256 _gasLimit, uint256 _gasPrice, bytes1 _proofType); +oraclize_getPrice(bytes1 datasource, uint256 _gasLimit, uint256 _gasPrice, bytes1 _proofType); + + +``` ### Mapping Query Ids @@ -422,12 +513,12 @@ It might occur that a callback function of a sent query gets called more than on ### Encrypted Queries Certain contexts, such as smart contracts on public blockchains, might require a level of privacy to protect data from public scrutiny. Developers can make encrypted Oraclize queries by encrypting a part (or all) of a query with the Oraclize public key. -The encrypted queries feature may be of interested to developers who want to deploy their blockchain applications of public networks. For example, if an application leverages data from an authenticated API, it would be dangerous to disclose the API key to anyway who is monitoring the public chain. +The encrypted queries feature may be of interest to developers who want to deploy their blockchain applications on public networks. For example, if an application leverages data from an authenticated API, it may be dangerous to disclose the API key to anybody who is monitoring the public chain. Oraclize therefore offers the possibility of encrypting the parameters contained in a query to Oraclize's public key: `044992e9473b7d90ca54d2886c7addd14a61109af202f1c95e218b0c99eb060c7134c4ae46345d0383ac996185762f04997d6fd6c393c86e4325c469741e64eca9` Only Oraclize will then be able to decrypt the request using its paired private key. -To encrypt the query, Oraclize provides a CLI tool, which can be found here. Alternatively, +To encrypt the query, Oraclize provides a CLI tool, which can be found here. Alternatively, The CLI command to encrypt an arbitrary string of text is then: `python encrypted_queries_tools.py -e -p 044992e9473b7d90ca54d2886c7addd14a61109af202f1c95e218b0c99eb060c7134c4ae46345d0383ac996185762f04997d6fd6c393c86e4325c469741e64eca9 "YOUR QUERY"` @@ -507,6 +598,97 @@ To protect the plaintext queries, an Elliptic Curve Integrated Encryption Scheme * An Elliptic Curve Diffie-Hellman Key Exchange (ECDH), which uses secp256k1 as curve and ANSI X9.63 with SHA256 as Key Derivation Function. This algorithm is used to derive a shared secret from the Oraclize public key and ad-hoc, randomly generated developer private key. * The shared secret is used by an AES-256 in Galois Counter Mode (GCM), an authenticated symmetric cipher, to encrypt the query string. The authentication tag is 16-bytes of length and the IV is chosen to be '000000000000' (96 bits of length). The IV can be set to the zero byte-array because each shared secret is thrown-away and use only once. Every time the encryption function is called a new developer private key is re-generated. The final ciphertext is the concatenation of the encoded point (i.e the public key of the developer), the authentication tag and the encrypted text. +### Cached Queries + +It is common for oracle-leveraging smart-contracts to be relatively simple in their external datasource needs. Frequently, a contract will have a static query that always calls the same endpoint with the same parameters. In such cases, Provable have implemented a method whereby queries can be _cached_ in order to make large gas savings when making the query. The gas-savings can be upwards of 50% of the original gas price of the query. + +To enable query caching, a contract must first make a standard Provable query using whichever datasource & parameters are required, and then save the `bytes32` query ID that Provable returns: `bytes32 cachedQueryID = oraclize_query(, );`. Next, a contract should enable caching of that specific query, using its ID, by calling: `oraclize_requestQueryCaching(cachedQueryId);`. + +Thereafter, a contract may make a _new_ query using the cached query’s parameters via: `oraclize_queryCached();`. This will return a _new_ queryID in order for the query to be tracked within your contract’s context. The new query made will have exactly the parameters of the query which was originally cached by the contract. + + + +See the example contract to the right for a contract that sets up and then uses cached queries in a recursive manner in order to benefit from the large gas savings when using a single, static query. + + + +```javascript + +pragma solidity >= 0.5.0 < 0.6.0; + +contract RecursiveCachedQueryExample is usingOraclize { + + bytes32 cachedQueryID; + string public priceETHXBT; + + event LogNewKrakenPriceTicker(string price); + event LogNewOraclizeQuery(string description); + + constructor() + payable + public + { + updateAndRequestQueryCaching(); // Note: Set the recursive queries going on contract creation... + } + /** + * + * @dev Notice here that we make a normal Provable query and save the + * returned query ID, which is then used to request caching of the + * specific query using that ID just saved. + * + */ + function updateAndRequestQueryCaching() + public + payable + { + emit LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer..."); + cachedQueryID = oraclize_query( + "URL", + "json(https://api.kraken.com/0/public/Ticker?pair=ETHXBT).result.XETHXXBT.c.0" + ); + oraclize_requestQueryCaching(cachedQueryID); + } + /** + * + * @dev Now here we are making the *same* Provable query as above but by + * simply calling `oraclize_queryCached(...)`. Notice too how we + * provide to it the cost of the query which is a required parameter. + * + */ + function updateCached() + public + payable + { + emit LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer..."); + oraclize_queryCached(oraclize_getPrice("URL")); + } + /** + * + * @dev When the Provable service returns our result and calls this + * callback, we call our *cached* version of the update function, + * thus continuing the asynchronous recursion. + * + */ + function __callback( + bytes32 myid, + string memory result, + bytes memory proof + ) + public + { + require(msg.sender == oraclize_cbAddress()); + updateCached(); + priceETHXBT = result; + emit LogNewKrakenPriceTicker(priceETHXBT); + } +} + +``` + ### Computation Data Source #### Passing Arguments to the Package @@ -525,29 +707,29 @@ contract Calculation is usingOraclize { event calculationResult(uint _result); // General Calculation: ((NUMBER_1 + NUMBER_2) * MULTIPLIER) / DIVISOR - + function Calculation() { - oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS); + oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS); } function __callback(bytes32 myid, string result, bytes proof) { require (msg.sender == oraclize_cbAddress()); calculationResult(parseInt(result)); } - + function testCalculation() payable { sendCalculationQuery(NUMBER_1, NUMBER_2, MULTIPLIER, DIVISOR); // = 105 } - + function sendCalculationQuery(string _NUMBER1, string _NUMBER2, string _MULTIPLIER, string _DIVISOR) payable { if (oraclize.getPrice("computation") > this.balance) { LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee"); } else { LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer.."); - oraclize_query("computation",["QmZRjkL4U72XFXTY8MVcchpZciHAwnTem51AApSj6Z2byR", - _NUMBER1, - _NUMBER2, - _MULTIPLIER, + oraclize_query("computation",["QmZRjkL4U72XFXTY8MVcchpZciHAwnTem51AApSj6Z2byR", + _NUMBER1, + _NUMBER2, + _MULTIPLIER, _DIVISOR]); } } @@ -555,7 +737,7 @@ contract Calculation is usingOraclize { ``` Arguments can be passed to the package by adding parameters to the query array. They will be accessible from within the Docker instances as environmental parameters. -Currenty the API supports up to 5 inline arguments, including the IPFS Hash: +Currenty the API supports up to 5 inline arguments, including the IPFS Hash: `oraclize_query("computation",["QmZRjkL4U72XFXTY8MVcchpZciHAwnTem51AApSj6Z2byR", _firstOperand, _secondOperand, _thirdOperand, _fourthOperand]);` ```shell @@ -588,10 +770,10 @@ pragma solidity ^0.4.18; import "github.com/oraclize/ethereum-api/oraclizeAPI.sol"; contract Calculation is usingOraclize { - + event calculationResult(uint _result); event LogNewOraclizeQuery(string description); - + function Calculation() payable { oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS); @@ -605,7 +787,7 @@ contract Calculation is usingOraclize { require (msg.sender == oraclize_cbAddress()); calculationResult(parseInt(result)); } - + function testCalculation( string _hash, string _number1, @@ -614,7 +796,7 @@ contract Calculation is usingOraclize { string _divisor, string _number3, string _number4) public payable { - + string[] memory numbers = new string[](7); numbers[0] = _hash; numbers[1] = _number1; @@ -623,10 +805,10 @@ contract Calculation is usingOraclize { numbers[4] = _divisor; numbers[5] = _number3; numbers[6] = _number4; - + sendCalculationQuery(numbers); } - + function sendCalculationQuery(string[] array) internal { if (oraclize.getPrice("computation") > this.balance) { LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee"); @@ -725,30 +907,148 @@ The random datasource is currently available on the Ethereum mainnet and on all The `oraclize_newRandomDSQuery` can be used for different kind of interactions, but the security can be incresed further by additing additional commitment data to the request. For example, for two party interactions, the `oraclize_newRandomDSQuery` can be modified as showon the side to include the sender address and the value send along as commitment data. This more strongly commitment the request for random bytes to current party, which are assumed to have a stake in the contract, making it impossible for miners to replay transactions on potential forks or reorg of the current chain. #### Multi-Party Interactions + In the case of multi-party interactions, such as voting schemes or lotteries, the commitment data can should include all participants addresses, to ensure that the transaction cannot be replayed by a miner on a fork or a reorged chain where a participant didn't put a stake. +### ERC20 Token Payments +```javascript -### ProofShield +/** + * + * @dev Provable helper functions for managing ERC20 Payments + * + */ -The Oraclize *ProofShield* is a concept first introduct at Devcon4, you can watch our presentation about "Scalable Onchain Verification for Authenticated Data Feeds and Offchain Computations" [here](https://www.youtube.com/watch?v=7uQdEBVu8Sk). +// Set payment method to token existing at +oraclize_setCustomTokenPayment(address ); + +// Approve an allowance of the token for the Provable service: +oraclize_approveTokenAllowance( + address , + uint256 +); + +// Or combine the above into a single call to this function: +oraclize_setAndApproveTokenAllowance( + address, + uint256 +); + +// Get the price of a query in tokens: +oraclize_getPriceERC20(uint256 ); + +// Revert back to paying with ETH and revoke the approved token amount: +oraclize_unsetAndRevokeCustomPayment(); + +``` + +Provable supports ERC20 token payments. In order to make queries using a token as payment rather than ETH, you must first call `oraclize_setCustomTokenPayment(address );` somewhere in your contract. The parameter `` is any of those existing on the whitelist of supported tokens. (The token whitelist will be announced soon!) + +Once the above is all set, the process of making queries is exactly the same as when using ETH, except you make your queries by calling: `oraclize_token_query()` instead. Query prices are exactly the same as when paying in ETH, but will be converted to their token equivalent automatically. -The ProofShield enables smart contracts to verify on-chain the authenticity proofs provided by Oraclize, this ensures that the authenticity of the data received is verified before going ahead and using the data. +The same as when paying for queries with ETH, when paying with a token you will need to ensure your contract has a sufficient balance of that token to cover the query cost, and that a balance has been `approved` to be used by the Provable connector contract which it is calling. (See the ERC20 token __[specification here](https://theethereum.wiki/w/index.php/ERC20_Token_Standard#Approve_And_TransferFrom_Token_Balance)__ for more information on token approval.) + +To make this simpler, the Provable API provides various helper functions which you can see on the right hand side. + + + +Just as when __[paying for queries using ETH](http://docs.oraclize.it/#ethereum-best-practices-pre-calculating-the-query-price)__, when paying using a token it is also possible to pre-calculate a query-price via: `oraclize_getPriceERC20();`. This returns the next query price expressed in units of the token that the your contract has set as its `customTokenPayment`. + +Additional parameters may be passed to get prices for more specific query types. See the information to the right for a full list of `oraclize_getPriceERC20` function overloads. + -To enable the ProofShield it is enough to set it via the `oraclize_setProof` function like you see in the following code: +In the case of a contract specifying a token payment, but sending enough ETH to cover the cost of the query, ETH will be used as payment rather than the token. +Should a contract wish to switch back to using ETH to pay for queries, rather than a token, it can do so by calling: `oraclize_unsetAndRevokeCustomPayment();`. This will unset the custom token payment option, and reset the allowance to the Provable contract to zero. ```javascript - oraclize_setProof(proofType_Android_v2 | proofShield_Ledger); +/** + * + * @dev The complete set of oraclize_getPriceERC20() overloads follow, + * allowing for price discovery of any query type. + * + */ + +// For datasource prices... +oraclize_getPriceERC20(string _datasource); +oraclize_getPriceERC20(bytes1 _datasource); + +// For prices involving custom gas limits... +oraclize_getPriceERC20(string _datasource, uint256 _gasLimit); +oraclize_getPriceERC20(bytes1 _datasource, uint256 _gasLimit); + +// For query prices for addresses other than the calling contract... +oraclize_getPriceERC20(string _datasource, address _contractAddress); +oraclize_getPriceERC20(bytes1 _datasource, address _contractAddress); + +// For query prices involving different contracts w/ custom gas limits... +oraclize_getPriceERC20(string _datasource, address _contractAddress, uint256 _gasLimit); +oraclize_getPriceERC20(bytes1 _datasource, address _contractAddress, uint256 _gasLimit); + +// For prices involving custom gas limits and custom gas prices... +oraclize_getPriceERC20(string _datasource, uint256 _gasLimit, uint256 _gasPrice); +oraclize_getPriceERC20(bytes1 _datasource, uint256 _gasLimit, uint256 _gasPrice); + +// For prices involving different _datasource & prooftype combinations... +oraclize_getPriceERC20(string _datasource, uint256 _gasLimit, uint256 _gasPrice, bytes1 _proofType); +oraclize_getPriceERC20(bytes1 _datasource, uint256 _gasLimit, uint256 _gasPrice, bytes1 _proofType); + +/** + * + * @dev Or have the same set of oraclize_getPriceERC20 overloads but which + * can be used for getting prices in *any* token, rather than only that + * which your contract has elected to use. + * + */ + +// For datasource prices in given token's units... +oraclize_getPriceERC20(address _tokenAddress, string _datasource) +oraclize_getPriceERC20(address _tokenAddress, bytes1 _datasource) + +// For prices in the given token's units & involving custom gas limits... +oraclize_getPriceERC20(string _datasource, uint256 _gasLimit, address _tokenAddress) +oraclize_getPriceERC20(bytes1 _datasource, uint256 _gasLimit, address _tokenAddress) + +// For query prices in the given token's units & for addresses other than the calling contract... +oraclize_getPriceERC20(string _datasource, address _contractAddress, address _tokenAddress) +oraclize_getPriceERC20(bytes1 _datasource, address _contractAddress, address _tokenAddress) + +// For prices in the given token's units & involving different contracts w/ custom gas limits... +oraclize_getPriceERC20(string _datasource, address _contractAddress, uint256 _gasLimit, address _tokenAddress) +oraclize_getPriceERC20(bytes1 _datasource, address _contractAddress, uint256 _gasLimit, address _tokenAddress) + +// For prices in a given token's units & involving different datasource & prooftype combinations... +oraclize_getPriceERC20(string _datasource, uint256 _gasLimit, uint256 _gasPrice, address _tokenAddress) +oraclize_getPriceERC20(bytes1 _datasource, uint256 _gasLimit, uint256 _gasPrice, address _tokenAddress) + +// For prices in a given token's units & involving different datasource & prooftype combinations... +oraclize_getPriceERC20(string _datasource, uint256 _gasLimit, uint256 _gasPrice, byte _proofType, address _tokenAddress) +oraclize_getPriceERC20(bytes1 _datasource, uint256 _gasLimit, uint256 _gasPrice, byte _proofType, address _tokenAddress) + +``` + +### ProofShield + +The Oraclize *ProofShield* is a concept first introduct at Devcon4, you can watch our presentation about "Scalable Onchain Verification for Authenticated Data Feeds and Offchain Computations" [here](https://www.youtube.com/watch?v=7uQdEBVu8Sk). + + -```` +The ProofShield enables smart contracts to verify on-chain the authenticity proofs provided by Oraclize, this ensures that the authenticity of the data received is verified before going ahead and using the data. +To enable the ProofShield it is enough to set it via the `oraclize_setProof` function like you see in the following code: `oraclize_setProof(proofType_Android_v2 | proofShield_Ledger);` Once the ProofShield is enabled, the received proof will not be the raw Authenticity Proof, but the ProofShield proof instead: some functions are provided so that the ProofShield proof can be verified on-chain. In order to verify it, you need to call from within the `__callback` method the function `oraclize_proofShield_proofVerify__returnCode(queryId, result, proof)` and ensure that it returns 0. @@ -792,5 +1092,33 @@ contract proofShieldExample is usingOraclize { } ``` +### Byte Datasources + +As a more advanced feature, Provable are providing all datasource `strings` as type `bytes1` as well as `strings`. The strings remain more readable (`URL`, `Random` and so on…) in Provable queries, but as with any string-related manipulation in Solidity, using them costs more gas-wise. As such, by offering the same set of datasources as a `bytes1` equivalent, advanced users may choose to declare their datasource in this manner instead and thus benefit from cheaper query gas-costs. + + + +``` javascript + +// Datasource strings and their `bytes1` equivalents: + +|---------------------------| +| `string` | `bytes1` | +|---------------------------| +| 'swarm' | 0xF8 | +| 'Blockchain' | 0xF9 | +| 'nested' | 0xFA | +| 'IPFS' | 0xFB | +| 'WolframAlpha' | 0xFC | +| 'computation' | 0xFD | +| 'Random' | 0xFE | +| 'URL' | 0xFF | +|---------------------------| + + +``` + ### More Examples More complete, complex examples are available on the dedicated Github repository: https://github.com/oraclize/ethereum-examples