# FluxAggregator

This page outlines the uses of the FluxAggregator contract for the node operators that feed data into it.

# Contract Deploy

Import all the files located in tvm-contracts/v2.0 into Tronscan and compile the FluxAggregator.sol.

After compiling finished, you should type the arguments that the constructor needs.

Here is the paraphrase:

  • _win: The address of the WIN token.
  • _paymentAmount: The amount paid of WIN paid to each oracle per submission, in wei (units of 10⁻6 WIN).
  • _timeout: the number of seconds after the previous round that are allowed to lapse before allowing an oracle to skip an unfinished round.
  • _validator: an optional contract address for validating external validation of answers.
  • _minSubmissionValue: an immutable check for a lower bound of what submission values are accepted from an oracle.
  • _maxSubmissionValue: an immutable check for an upper bound of what submission values are accepted from an oracle.
  • _decimals: represents the number of decimals to offset the answer by.
  • _description: a short description of what is being reported.

WINkLink node(s) can be deployed after the contracts are deployed. The code repository for WINkLink node project is available on GitHub at: Winklink Repo (opens new window)

WARNING

The current node implementation includes an adapter for accessing token price via exchange APIs. For security reasons, run the node in a stable network environment outside Mainland China.

# Node Deployment

The node service deployment is the same as before as the service is compatible with both types of Aggregators.

# Node Account Preparation

To link each WINkLink node to a TRON account for calling the Oracle contract to submit data, developers need to generate the account address and the private key. Developers can test the TRX token on the Testnet Faucet page, which is used to pay the handling fees for calling the smart contracts.

Developers can generate account address and private key via one of the following methods:

WARNING

It is recommended that the developer generate the address and private key offline to avoid private key leakage through an untrusted network.

# Required Environment

The WINkLink node relies on a running MySQL instance. Developers can use the system package manager or Docker of the target environment to deploy a MySQL instance

TIP

Here we assume that the username and the password for the MySQL instance deployed locally are root:root respectively. Please use a strong password or other verification methods in the production environment.

WINkLink node is written in Java language and requires JRE/JDK environment. It is recommended to use Oracle JDK8. The node also requires a Nodejs environment. It is necessary to install Nodejs(npm) >= 10.0.

# Executable Program Access for the Node

Developers can compile the code by following the steps below:

# jdk8 and nodejs(npm) >= 10.0 are needed
git clone [email protected]:wink-link/winklink.git
cd winklink/

# compile
./gradlew build -x test

After compilation, node-v1.0.jar will be stored in node/build/libs/ under the project source code directory.

WARNING

The compilation process omits the test (-x test), because the test instance includes the API test instance for token price on exchanges, which will require a stable network environment outside Mainland China.

# Node Configuration

WINkLink node is configured using spring boot. All configuration files are under the subdirectory node/src/main/resource. With application.yml you can specify a db profile to be used.

# application.yml
server:
    port: 8080
spring:
    # dev|pro
    profiles:
        active: dev # Specify the profile file here, namely `application-dev.yml`
    jackson:
        time-zone: GMT+8
        date-format: yyyy-MM-dd HH:mm:ss
    servlet:
        multipart:
            maxRequestSize: 104857600 #100MB

# ... (omitted)

In application-[ACTIVE_PROFILE_NAME].yml you can specify a MySQL database connection configuration. By default dev uses local instance. The username and the password are root:root.

After the node configuration file is confirmed, it is required to create a key.store file and write the private key of the node account:

privatekey=*****(32 bye hex-decoded private key)

TIP

For security reasons, it's essential to use files to ingest private information instead of relying on command line input. In a production environment, it's important to set the appropriate permissions for the private file "key.store." This can be done by setting the file permission to "600," which restricts read and write access to the file to its owner only.

# Start A Node

All configuration files need to be copied to the directory that your node is running in, use the command cp node/src/main/resource/*.yml ./.

Start your WINkLink node using the following command:

java -jar node/build/libs/node-v1.0.jar -k key.store

Configuration items can also be specified using a command line. For example:

java -jar node/build/libs/node-v1.0.jar --server.port=8081 --spring.profiles.active=dev --key key.store

Determine whether your WINkLink node is running properly using the following command:

tail -f logs/tron.log

WARNING

Your node account must have enough TRX tokens for contract calls. You can apply testnet tokens at Testnet Faucet.

# Add a Job to Your Node

WINkLink nodes are responsible for providing various data services, with each service being represented by a unique 32-byte ID known as a "job". For end users, (Oracle address, job ID) uniquely identifies the data service provided by a WINkLink node. It's worth noting that a single WINkLink node can support multiple data services at once.

When your WINkLink node is running properly, you can add a job to your node via HTTP API:

Example: (change the address parameter below to the Oracle contract address deployed in the steps above)

curl --location --request POST 'http://localhost:8080/job/specs' \
  --header 'Content-Type: application/json' \
    --data-raw '{
    "initiators": [
        {
        "type": "runlog",
        "params": {
            "address": "TR9jYcLWAcQfbKcP5oau1ccSbeW7mdnqg8"
        }
        }
    ],
    "tasks": [
        {
        "type": "httpget",
        "params": {
            "get": "https://www.okex.com/api/spot/v3/instruments/TRX-USDT/ticker",
            "path": "last"
        }
        },
        {
        "type": "multiply",
        "params": {
            "times": 1000000
        }
        },
        {
        "type": "trontx"
        }
    ]
    }'

# Query Job

Request example:

curl --location --request GET 'http://localhost:8080/job/specs'

# Authorize an Oracle

The node account requires authorization to submit data to the FluxAggregator contract, otherwise an error not enabled oracle will be reported.

The owner of the FluxAggregator contract is required to call the contract below and add the node account to the whitelist:

/**
   * @notice called by the owner to remove and add new oracles as well as
   * update the round related parameters that pertain to total oracle count
   * @param _removed is the list of addresses for the new Oracles being removed
   * @param _added is the list of addresses for the new Oracles being added
   * @param _addedAdmins is the admin addresses for the new respective _added
   * list. Only this address is allowed to access the respective oracle's funds
   * @param _minSubmissions is the new minimum submission count for each round
   * @param _maxSubmissions is the new maximum submission count for each round
   * @param _restartDelay is the number of rounds an Oracle has to wait before
   * they can initiate a round
   */
function changeOracles(
    address[] calldata _removed,
    address[] calldata _added,
    address[] calldata _addedAdmins,
    uint32 _minSubmissions,
    uint32 _maxSubmissions,
    uint32 _restartDelay
  )

Example:

changeOracles([],["TDc8oFEB5aqYyGMK3zSfuEJ41j7URQxD59","TJPKPFYBtn8yM7mEUJNwnYX8YKjxfgoP6H","TTZzvdeA5ZQpDixruQXMMD9fFPQ7PCYZMh","TCLNYnrbXrqS676Sb4u2WYwixwYpYGYoWC","TADNgieuqyqQMpSTN7fRmNnhh5Sc4oJKjn","TX5PiqoSuyjk3jqaj17KtYKgdKZM9maZVP","TPeALa1FYuazqtNrcqy6nvrQv59BYXdTAc"],["TAhNC17cPeEKhjMzKTyQ5GdMvTUuZYW5cC","TJjHMPQoJQqdZTrcpTh5bE1ECcTmpu7xbs","TMXASYRUzkbsoL2nY6JYW17Attu9fsXgEr","TTe9jH71oxKtH5SVu2dXEZhdngqnwy3XbE","TQZFvyNeKvYspsJuqZ4wJmmWWFDsCdf9iT","TLgVzdvMfbcX341WZrnBFGJ8MR2Lyd23kA","TDBH7V93xEEW11oA2XG9HXaf2saRywS5Xz"],5,7,4)

Contract calls can be made via any of the following tools or libraries:

# Withdrawing funds

Keep in mind the oracle variable is currently your node's address rather than your oracle contract's address.