Using chainlink pricing data on xdaichain

Time:2021-12-3

**Using chainlink pricing data on xdaichain

With the accelerated iteration of defi application innovation on Ethereum network, the free combination of various defi protocols and the blessing of Oracle bridging external data, defi application protocols with higher logical complexity are emerging. On the one hand, for developers, the cost of deploying a smart contract project with a certain complexity begins to rise gradually, and the cost of more than a dozen to dozens of Ethereum is very expensive. On the other hand, for users, the gas cost of using these defi protocols is also gradually increasing. Because Ethereum itself is limited by the low TPS brought by POW consensus algorithm (mainstream at this stage, non Ethereum 2.0), the transaction fee becomes higher, but the higher is the result of the market game caused by more users.

From another positive point of view, the large number of users reflects the prosperity of the ecology and the high attention of the market. Innovation is endless in the middle of Ethereum ecology. Therefore, how to maintain the smart contract application while still remaining in Ethereum ecology and reduce handling charges and improve transaction speed is the topic that layer 2 network wants to explore.

In this article, we will demonstrate how to deploy smart contracts on layer 2 network xdaichain through examples, and provide high-quality and tamper proof external data for smart contracts deployed on xdaichain through chainlink oracle. In the case part, we will show how chainlink’s pricing mechanism is used on xdaichain.
https://xdai-faucet.top/ , you can get 0.01xdai.

Using chainlink pricing data on xdaichain

However, in writing, when visiting this faucet, it was found that xdai could not be obtained through this website. Through debug, it was found that too many visitors could not be requested. Some developers in the official community gave the answer that it was temporarily unavailable because it was a token of real value. In the community, you can ask the administrator to give 0.01xdai for development and testing and tell your wallet address, or you can buy Dai and use the asset bridge: https://docs.tokenbridge.net/xdai-bridge/about Convert to xdai on xdaichain.

Another note: when asking this question in the community, some other users will directly send a private letter to you. They often give some so-called websites such as walletconnect against the avatar and name of the community administrator (the community allows the name and avatar to be the same as the real administrator, and the private chat will not display the tag in the community). Generally speaking, it is impossible to connect due to database update, Then give a phishing website. You need to enter your own private key or mnemonic words to reconnect. This belongs to cheating private information. Pay attention to prevention.

POA Sokol test network information addition

POA Sokol network is another side chain implementation based on POA consensus algorithm, in which POA consensus algorithm can be regarded as an improvement of dpos algorithm, which requires the nodes participating in the election to provide real-world credit information.

It is much easier to obtain the test token POA on the POA Sokol network. The steps expand as follows.

Step 1: set wallet network information

Click metamask menu bar, select network, and drop down toCustom RPC, click to enter and configure the network information as follows:

Using chainlink pricing data on xdaichain
Key information fields are as follows:

  • RPC address: https://sokol.poa.network
  • Chain ID: 77
  • Native token symbol: Poa
  • Block browser address: https://blockscout.com/poa/sokol

After configuration, click Save to view the wallet balance:

Using chainlink pricing data on xdaichain

Next, go to the test token acquisition step.

Step 2: get the test token

Access test token address:https://faucet-sokol.herokuapp.com/,And enter your wallet address:

Using chainlink pricing data on xdaichain

Using chainlink pricing data on xdaichain

Using chainlink pricing data on xdaichain
There are two ways to view the wallet address balance:

  • Through the browser, enter your wallet address to view

    • https://blockscout.com/poa/sokol/address/0x28383b9717ca0468C580dF7b970A4897a0f11202/transactions
  • After the transaction is completed, view it in metamask

The displayed balance is 100 POA
Using chainlink pricing data on xdaichain
Using chainlink pricing data on xdaichain

Generally speaking, this step is almost the same as the process of obtaining tokens on the Kovan test website. It should be noted that the RPC information of the wallet is different.

Xdaichain network information supplement

The network RPC information configured in the wallet of xdaichain is as follows:

  • RPC address: https://dai.poa.network
  • Chain ID: 100
  • Native token: xdai
  • Block browser address: https://blockscout.com/poa/xdai

Using chainlink pricing data on xdaichain

When the wallet is ready, we will start the project creation and deployment phase based ontruffleFramework, which is essential for the development of engineering contract projects.

Using pricefeed in xdai smart contracts

Note: the project engineering documents of this part are hosted in GitHub warehouse at: https://github.com/Bingyy/Use-Chainlink-On-xDAIChain

The following shows how to create a project from scratch and deploy it.

1. Project creation

If not installed on the machinetruffle, you can execute from the command line:

npm install -g truffle

Create a new project name: use chainlink on xdaichain

mkdir Use-Chainlink-On-xDAIChain
cd Use-Chainlink-On-xDAIChain

truffleProject initialization:

truffle init

truffleThe project structure is as follows:
Using chainlink pricing data on xdaichain
thereclientDirectory nontruffleIncluded in the project,buildThe directory is the location where ABI data is stored after the contract is compiled. We mainly write contracts, contract deployment scripts and project configuration information.

2. Contract preparation

staycontractsFolder, create a new contract:GetETHUSDPrice.sol, as follows:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.8.0;

contract GetETHUSDPrice {
  uint256 eth_ usd_ price; //  For safety reasons, safemath is recommended

    function setETHUSDPrice(uint256 _price) external {
        eth_usd_price = _price;
    }
    function getETHUSDPrice() public view returns(uint256) {
        return eth_usd_price;
    }
}

This contract has a state variable,eth_usd_priceIt is used to save the real price data obtained from chainlink.

3. Contract deployment

3.1 preparation of configuration file

edittruffle-config.js

const HDWalletProvider = require('@truffle/hdwallet-provider');
// const infuraKey = "fj4jll3k.....";
//
const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
const privateKey = fs.readFileSync(".secret").toString().trim();

Here, the project script depends on@truffle/hdwallet-provider, installation:

npm install @truffle/hdwallet-provider

Mnemonic or private key signature is required during deployment, and a file is created in the top-level directory of the project,.secret, if you want to save the project using GitHub repository, note that this file name is added to the.gitignoreOtherwise, sensitive information will be disclosed and losses will be caused.

Configure network information innetworksAdd to field:

sokol: {
      provider: () => new HDWalletProvider(privateKey, `https://sokol.poa.network`),
      network_id: 77,
      gas: 500000,
      gasPrice: 1000000000
},

xdai: {
      provider: () => new HDWalletProvider(privateKey, "https://dai.poa.network"),
      network_id: 100,
      gas: 500000,
      gasPrice: 1000000000
 },

For convenience, you can directly configure both network information here, and specify the network name during deployment.

3.2 contract deployment script

staymigrationsCreate a new script under the directory,3_get_ethusd_price.js, as follows:

const GetETHUSDPrice = artifacts.require("GetETHUSDPrice");

module.exports = function (deployer) {
    deployer.deploy(GetETHUSDPrice);
};

truffleThe number of deployment scripts is meaningful and will be executed in sequence. We can also execute a single deployment script. The number here needs to be arranged according to the contract in the current project.

3.3 execute deployment command

truffle migrate -f 3 --to 3 --network xdai --skip-dry-run

Parameter explanation: only execute the third script, and pay attention to adding--skip-dry-run, if this instruction is not added, it will be deployed toxdai-forkOn the network, this is a simulated network, not a real network, and cannot be checked in the block browser. You can alsotruffle-configConfigure fields inskipDryRun, it is specially placed on the command line to emphasize.

The deployment process is as follows:

3_get_ethusd_price.js
=====================

   Deploying 'GetETHUSDPrice'
   --------------------------
   > transaction hash:    0x1ee31f52fcccef0899e31d040233222f51949998046ac9762528089bff2d4980
   > Blocks: 2            Seconds: 9
   > contract address:    0xd3a86c2b36fD3DA6bbd64423d1a494eed47a2052
   > block number:        14137854
   > block timestamp:     1611206580
   > account:             0x28383b9717ca0468C580dF7b970A4897a0f11202
   > balance:             0.009903595
   > gas used:            96405 (0x17895)
   > gas price:           1 gwei
   > value sent:          0 ETH
   > total cost:          0.000096405 ETH

   > Saving artifacts
   -------------------------------------
   > Total cost:         0.000096405 ETH


Summary
=======
> Total deployments:   1
> Final cost:          0.000096405 ETH

Here, ETH is shown as the unit, which is actually the POA token consumed. The native token on POA Sokol is POA, which is equivalent to eth on Ethereum network.

Now that the contract deployment is completed, it can be seen that the cost of deploying the contract is very low compared with Ethereum. After the contract deployment is completed, we enter the step of interacting with the contract.

4. Interaction with contracts

Create a in the project folderclientFolder for storing interactive scripts. We will passNode.jsTo write scripts and useweb3.jsLibrary, installation:

npm install web3

In order to interact with the contract, we need to know the ABI of the contract and the deployed contract address.

const Web3 = require('web3')
const fs = require('fs');

const HDWalletProvider = require('@truffle/hdwallet-provider');

//Account related sensitive information, private key signature, no 0x prefix
const privateKey = fs.readFileSync("../.secret").toString().trim();

//Account address: your own account address
const account1 = '0x28383b9717ca0468C580dF7b970A4897a0f11202'

Here, you need an interactive account address and a certain test token. This paper takes the deployment contract account as an example.

Set RPC:

//Set up RPC for Sokol network
const provider = new HDWalletProvider(privateKey, 'https://sokol.poa.network')
const web3 = new Web3(provider)

//RPC on Kovan needs to be obtained from infra
const provider_kovan = new HDWalletProvider(privateKey, 'https://kovan.infura.io/v3/afc48dd54b2b408aa43e79ce09c5d1f5')
const web3_kovan = new Web3(provider_kovan)

We need two hereweb3Examples, one for POA Sokol network and the other for Kovan network.

Deployed contract information:

//The side chain contract information is used to access the price feeding data
const GetETHUSDPriceABI = [{ "inputs": [{ "internalType": "uint256", "name": "_price", "type": "uint256" }], "name": "setETHUSDPrice", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "getETHUSDPrice", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }]
const GETETHUSDPriceAddress = "0xd3a86c2b36fD3DA6bbd64423d1a494eed47a2052"

The ABI data of the corresponding contract can be found in the build / contracts directory. In addition, it is recommended to condense it into one line in the code. You can use the online conversion tool: https://tools.knowledgewalls.com/online-multiline-to-single-line-converter

Build contract instance:

const getETHUSDPriceInstance = new web3.eth.Contract(GetETHUSDPriceABI, GETETHUSDPriceAddress)

Now we have an interactive contract instance, but before that, we need to know how to use the price feeding contract of chainlink on Kovan. We don’t need to deploy, we just need to know its ABI and contract address, where the contract address can be accessed: https://docs.chain.link/docs/reference-contracts , find the contract address in the Kovan section. The address is:0x9326BFA02ADD2366b30bacB125260Af641031331

The ABI of the contract can be obtained in the Kovan block browser:

https://kovan.etherscan.io/address/0x9326BFA02ADD2366b30bacB125260Af641031331

In order to interact with it, we also need to get its instance. The code is as follows:

// KOVAN ETHUSD PriceFeed ABI
const ETHUSDPriceFeedABI = [{ "inputs": [{ "internalType": "address", "name": "_aggregator", "type": "address" }, { "internalType": "address", "name": "_accessController", "type": "address" }], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "int256", "name": "current", "type": "int256" }, { "indexed": true, "internalType": "uint256", "name": "roundId", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "updatedAt", "type": "uint256" }], "name": "AnswerUpdated", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "roundId", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "startedBy", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "startedAt", "type": "uint256" }], "name": "NewRound", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }], "name": "OwnershipTransferRequested", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }], "name": "OwnershipTransferred", "type": "event" }, { "inputs": [], "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "accessController", "outputs": [{ "internalType": "contract AccessControllerInterface", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "aggregator", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_aggregator", "type": "address" }], "name": "confirmAggregator", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "description", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "_roundId", "type": "uint256" }], "name": "getAnswer", "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint80", "name": "_roundId", "type": "uint80" }], "name": "getRoundData", "outputs": [{ "internalType": "uint80", "name": "roundId", "type": "uint80" }, { "internalType": "int256", "name": "answer", "type": "int256" }, { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "_roundId", "type": "uint256" }], "name": "getTimestamp", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "latestAnswer", "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "latestRound", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "latestRoundData", "outputs": [{ "internalType": "uint80", "name": "roundId", "type": "uint80" }, { "internalType": "int256", "name": "answer", "type": "int256" }, { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "latestTimestamp", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [{ "internalType": "address payable", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], "name": "phaseAggregators", "outputs": [{ "internalType": "contract AggregatorV2V3Interface", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "phaseId", "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_aggregator", "type": "address" }], "name": "proposeAggregator", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "proposedAggregator", "outputs": [{ "internalType": "contract AggregatorV2V3Interface", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint80", "name": "_roundId", "type": "uint80" }], "name": "proposedGetRoundData", "outputs": [{ "internalType": "uint80", "name": "roundId", "type": "uint80" }, { "internalType": "int256", "name": "answer", "type": "int256" }, { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "proposedLatestRoundData", "outputs": [{ "internalType": "uint80", "name": "roundId", "type": "uint80" }, { "internalType": "int256", "name": "answer", "type": "int256" }, { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_accessController", "type": "address" }], "name": "setController", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_to", "type": "address" }], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "version", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }]
const ETHUSDPriceFeedAddress = "0x9326BFA02ADD2366b30bacB125260Af641031331"

Example of price feeding contract:

const ETHUSDPriceFeedInstance = new web3_kovan.eth.Contract(ETHUSDPriceFeedABI, ETHUSDPriceFeedAddress)

Write two functions, one to obtain data from our own deployed contract, and the other to read the feeding data of chainlink from Kovan and update it to the POA Sokol chain.

//Update the data on Kovan to the side chain
async function setETHUSDPriceOnSideChain() {
    // step 1: get data
    let res = await ETHUSDPriceFeedInstance.methods.latestRoundData().call({
        from: account1
    })
    const ETHUSDPrice = res.answer;
    console.log("ETHUSD Price is: ", ETHUSDPrice) // BigNumber 
    // step 2: set data to sidechain
    getETHUSDPriceInstance.methods.setETHUSDPrice(ETHUSDPrice).send({
        from: account1
    }).on('receipt', receipt => {
        console.log('receipt: ', receipt)
    })
}

//Obtain ethusd price information from the side chain
async function getETHUSDPriceFromSideChain() {
    //Read this feed contract
    let price = await getETHUSDPriceInstance.methods.getETHUSDPrice().call({
        from: account1
    })
    console.log("latest price: ", price)
}

4. The script obtains chainlink feed data

callsetETHUSDPriceOnSideChainFunction to update ethusd price information data to the side chain by callinggetETHUSDPriceFromSideChainFunction to obtain price information from the side chain.

latest price:  132972000000

5. Xdaichain smart contract deployment and interaction

Deployment requires only:

truffle migrate -f 3 --to 3 --network xdai --skip-dry-run

The contract address deployed on xdaichain is:0xe8713F35044eFf25C6340b6837C777F0d04a8461

Several information needs to be modified to interact with the contract on xdaichain:

const provider = new HDWalletProvider(privateKey, 'https://dai.poa.network')
const web3 = new Web3(provider)

const GETETHUSDPriceAddress = "0xe8713F35044eFf25C6340b6837C777F0d04a8461"

Other information does not need to be modified, and the use process is the same.
https://tools.knowledgewalls.com/online-multiline-to-single-line-converter
GitHub address: https://github.com/Bingyy/Use-Chainlink-On-xDAIChain
Xdai documentation: https://www.xdaichain.com/
Xdai faucet address: https://xdai-faucet.top/
POA faucet addresshttps://faucet-sokol.herokuapp.com/

If you are a developer, you want to quickly connect your application to chainlink’s price reference data, access developer documentation, and access discord technology discussion. If you want to arrange a call to discuss the integration of matic / chainlink more deeply, please contact here.
English channels
Website | Twitter | Reddit | YouTube | Telegram | Events | GitHub | Price Feeds | DeFi
Chinese Channel
Chinese official website | segmentfault | CSDN|