Authpaper Sales Smart Contract Part 3 getting data from website (oraclizeAPI)

We originally plan to write articles at least once a week. However the sudden increase in airdrop request, website UI updates and company audit broke our plan. Sorry to keep you waiting. We start writing this series again.

You may would like to take a look to our new website here: https://authpaper.io

From now on, we will keep posting article every week. However, the article may not be only related to smart contract. We may include other articles like tutorials on airdrop and bounty, and company information.

Let’s us continue the journey. For those who would like to view the whole contract, it can be found here:
https://github.com/SolonAuthpaper/AUPC_sales_contract

In the last article, we have talked about the default function, which is executed whenever someone send ETH to the contract. Upon receiving the ETH, the contract checks if it stores the number of referral already in savedLevels dictionary. If yes, the contract will calculate the discount to distribute the AUPC to the purchasers, and marketing awards to the referrers.

If no, we will need to query the referral levels and referrer information of the purchaser from our website. We use oraclize API to do it.

Oraclize API (now called Provable, https://provable.xyz/) is the leading oracle service for smart contracts and blockchain applications, serving thousands of requests every day on platforms like Ethereum, Rootstock, R3 Corda, Hyperledger Fabric and EOS.

The solution developed by Oraclize is instead to demonstrate that the data fetched from the original data-source is genuine and untampered. This is accomplished by accompanying the returned data together with a document called authenticity proof. The authenticity proofs can build upon different technologies such as auditable virtual machines and Trusted Execution Environments.

(Copy from https://docs.oraclize.it/)

In other words, this is a service for a smart contract to read web data.

Once a query is fired inside smart contract, it will send the information as well as some gas to the Oraclize smart contract. Once the data is queried, it will call the callback function of the original smart contract to return the data (in string). The data is queried asymmetrically.

To implement, it can be as simple as this.

The line import…… includes the oraclize contract code so that the contract can use the oraclize function. When querying a data is needed, oraclize_query() is called.

The first input is the type of data source. In most cases it is “URL”, meaning it is reading data from a webpage or HTTP API. For other source types, you may read https://docs.oraclize.it/#general-concepts-data-source-types

The second input is the url to query. Besides getting the text and handle the data format in the callback function, oraclize API also supports parsing JSON, XML, HTML and binary data. If the data to query is in JSON format (e.g. {“result”=>”{\”tt\”=>\”0\”},”status”=>”success”}), and the contract only needs part of the data (e.g. just the 0 in result=>tt), the second input can be written like json(https://api.kraken.com/0/public/Ticker?pair=ETHUSD).result.tt) so that only the concerned data is returned to the contract. It reduces the code complexity, but increases the gas cost of making the query.

The third input is optional, which is the gas limit of making the call. By default, it is 200,000 and is enough for most cases. If the callback function takes a lot of works, like in our case, one need to set a higher gas limit or the call will fail. Setting the correct gas limit is hard, but important. If the gas limit is too low, the query will fail as the callback function cannot be executed completely. If the gas limit is too high, remaining gas will go to oraclize and will not refund.

In our contract, we set it to be 600,000, or 0.01205968011458582 ether. It is because we found that our callback function takes up to 0.011 transaction fee. Setting gas limit below 0.012 ether is not feasible. On the other hand, it means with minimal purchase 0.1 ETH, and up to 15% of the ETH received to be distributed as marketing referral reward, 6 query can be called at most. We limit the number of queries to be 5.

The function will return a bytes32 queryId, which is used to identify the query data in the callback function. As the call is made asymmetrically, it is good to define a dictionary using the queryId as index to store the data needed when the callback function is called.

The first input of the callback function is the queryId as received when calling the query. The second input is the result in string.

In the callback function, the first line is to check of the data comes from the Oraclize. It is necessary as everyone can call the callback function. The checking prevents others to input phishing data to the smart contract. It is also recommended to query HTTPS data to prevent HTTP phishing.

We add the line delete oraclizeCallbacks[myid] at the end of the function. It is to prevent multiple calls of the same callback and prevent sending out tokens multiple times. But it is not necessary.

Now goes to the callback function of the token sales contract.

We need to keep the purchase address and amount of ETH sent in to calculate the tokens to distribute. Also there are two kinds of query, one is getting the number of referrer levels to calculate discount, another is getting the referrer of the address concerned. So we also define an enum to distinguish the two queries and define a struct rewardNode to keep all data possibly needed to pass from making the query to the callback function.

After making the query and the callback function is called, the smart contract reads the necessary data from the dictionary oraclizeCallbacks. If it is about getting the levels (the query made from the default function), the queried result is parsed into integer, stored to that no need to query again in next 24 hours, and pass to the purchaseAUPC function to calculate the discount and distribute the tokens.

purchaseAUPC function may also create web query to find the referrer of the current address. In this case, the address which pays the ETH for token (baseAddress), last referrer found (lastParent) and the levels of the referrer from the baseAddress are kept inside the rewardNode. When such queries are returned, the callback function will parse the result into an address, stored, and pass to the sendUpline for distributing the marketing reward to the referrer.

This is all information about the oraclize part of our token sales smart contract. For more details on Oraclize, please read their support documents (especially the pricing part): https://docs.oraclize.it/

In the next article, we will talk about the last part of the token distribution journey, purchaseAUPC and sendUpline functions.