The CLI is provided as a pre-built binary with every release and also as a docker image.
Download and run the latest release​
wget https://github.com/tellor-io/telliot/releases/latest/download/telliotchmod +x telliot
docker run -v $(pwd)/local:/configs tellor/telliot:master mine
tested with google cloud, but should work with any k8s cluster.
gcloud auth login --project projectNamegcloud container clusters get-credentials main --zone europe-west2-a --project projectName
Deploy the cli
(by default deployed to run as a miner)
git clone https://github.com/tellor-io/telliotcd telliotexport NAME=mainmkdir -p .local/configs/$NAME​# Create the secret file.cp configs/.env.example .local/configs/$NAME/.env # Edit the file after the copy.kubectl create secret generic telliot-$NAME --from-env-file=.local/configs/$NAME/.env​cp configs/config.json .local/configs/$NAME/config.json # Edit the file after the copy.​# Copy the index, manual. These can be used as it without editing.cp configs/indexes.json .local/configs/$NAME/indexes.jsoncp configs/manualData.json .local/configs/$NAME/manualData.json# Add the configs.kubectl create configmap telliot-$NAME --from-file=.local/configs/$NAME/config.json --from-file=.local/configs/$NAME/indexes.json --from-file=.local/configs/$NAME/manualData.json -o yaml --dry-run=client | kubectl apply -f -​# Copy the deployment and create it.cp configs/manifests/telliot.yml .local/configs/$NAME/telliot.ymlsed -i "s/telliot-main/telliot-$NAME/g" .local/configs/$NAME/telliot.ymlkubectl apply -f .local/configs/$NAME/telliot.yml
export NAME= # Put an instance name here. Something short as some properties are limited by length(e.g `export NAME=PR320`).# Run all the other commands from initial k8s setup.
export REPO= # Your docker repository name.docker build . -t $REPO/telliot:latestdocker push $REPO/telliot:latest​sed -i "s/tellor\/telliot:master/$REPO\/telliot:latest/g" .local/configs/$NAME/telliot.ymlkubectl apply -f .local/configs/$NAME/telliot.yml
Optionally deploy the monitoring stack with Prometheus and Grafana.
kubectl apply -f configs/manifests/monitoring-persist.ymlkubectl apply -f configs/manifests/monitoring.yml
config.json
is where you will enter your wallet address and configure the CLI for your machine.
wget https://raw.githubusercontent.com/tellor-io/telliot/master/configs/config.json
Open config.json and update the following values:
Set "publicAddress"
to the public key for the Ethereum wallet you plan to use for mining. Remove the 0x prefix at the beginning of the address.
Most commands require some secrets and these are kept in a separate configs/.env
. This is a precaution so that are not accidentally exposed as part of the main config. Make a copy of the env.example
and edit with your secrets.
Mine at your own risk.
Mining requires you to deposit 500 Tellor Tributes use as a security deposit. If you are a malicious actor (aka submit a bad value), the community can vote to slash your tokens.
Mining also requires submitting on-chain transactions on Ethereum. These transactions cost gas (ETH) and can sometimes be significant if the cost of gas on EThereum is high (i.e. the network is clogged). Please reach out to the community to find the best tips for keeping gas costs under control or at least being aware of the costs.
If you are building a competing client, please contact us. The miner specifications are off-chain and the validity of the mining process hinges on the consensus of the community to determine what proper values are. Competing clients that change different pieces run the risk of being disputed by the community.
There is no guarantee of profit from mining. There is no promise that Tellor Tributes currently hold or will ever hold any value.
If you are building a competing client, please contact us. A lot of the miner specifications are off-chain and a significant portion of the mining process hinges on the consensus of the Tellor community to determine what proper values are. Competing clients that change different pieces run the risk of being disputed by the community.
As an example, request ID 4 is BTC/USD. If the APIs all go down, it is the responsibility of the miner to still submit a valid BTC/USD price. If they do not, they risk being disputed and slashed. For these reasons, please contribute openly to the official telliot miner (or an open source variant), as consensus here is key. If your miner gets a different value than the majority of the other miners, you risk being punished!
For over a decade now, the Bitcoin network has shown how proof-of-work can incentivize individuals and companies to compete for the honor of finding block rewards and achieving consensus. This phenomenon is global and anonymous. The network is democratized and decentralized because the creators have no direct control over who is providing computing power on their network.
Tellor takes this concept and applies it directly to the delivery of oracle data. Anyone who is able may start up telliot
and begin competing for blocks. There is no whitelisting. Miners compete very much the same way that Bitcoin miners do, but with a twist. Tellor Miners must also run a database from which to pull values to submit to the Tellor oracle. When a "block" is found, the winners submit their data.
Mining is one of the most exciting ways to help Tellor grow and become a leader in the DeFi / Oracle space. Here are a few things to consider before jumping in:
As of now, mining requires you to deposit 500 Tellor Tributes. This is a security deposit. If you are a malicious actor (aka submit a bad value), the community can vote to slash your 500 tokens.
Mining requires access to an Ethereum node. If you don’t have your own node, you can use an Infura API endpoint.
Miners must hold a balance of ETH to cover gas fees, which can be significant. Please reach out to the community to find the best tips for keeping gas costs under control.
The guide that follows assumes that you have access to a suitable machine running linux to use for mining. For information about what constitutes a "suitable machine", we recommend reaching out to the community.
Run the following commands:
wget https://raw.githubusercontent.com/tellor-io/telliot/master/configs/indexes.json
Tellor currently has one data point which must be manually created. The rolling 3 month average of the US PCE . It is updated monthly. Make sure to keep this file up to date.
Run the following command:
wget https://raw.githubusercontent.com/tellor-io/telliot/master/configs/manualData.json
For testing purposes, or if you want to hardcode in a specific value to enter, you can use the manualdata.json file to add manual data for a given requestID. Similar to the manual data structure, you add the request ID, a given value (with granularity), and a date on which the manual data expires.
The following example shows request ID 4, inputting a value of 9000 with a 1,000,000 granularity. Note the date is a unix timestamp.
"4":{"VALUE":9000000000,"DATE":1596153600}
telliot --config=./configs/config.json mine
There are mining pools available for mining TRB without staking any tokens. The pool server operator stakes the tokens for you, and you receive rewards roughly proportional to your hashrate as a fraction of the pool's hashrate.
Each pool has different fees and instructions for hooking up. Be sure to read your pool's documentation. Feel free to reach out to the community if you need help with mining pools.
Add the following lines to your config file:
"enablePoolWorker": true,"poolURL": "<poolURL>",
Where the poolURL is the link to your pool. (e.g. http://tellorpool.org )
You can change the job duration if needed. This is the time in seconds to grab information from the pool. The default time is 15 seconds.
"poolJobDuration":10
You do not need to stake 500 TRB if you plan to mine on a pool.
You will need 500 TRB to run your own server for mining. Your stake is locked for a minimum of 7 days after you run the command to request withdrawal.
Run the following command to deposit your stake:
tellor --config=./configs/config.json stake deposit
To unstake your tokens, you need to request a withdraw:
telliot --config=./configs/config.json stake request
One week after the request, the tokens are free to move at your discretion after running the command:
telliot --config=./configs/config.json stake withdraw
Tellor as a system only functions properly if parties actively monitor the tellor network and dispute bad values. Expecting parties to manually look at every value submitted is obviously burdensome. The Tellor disputer automates this fact checking of values.
The way that it works is that the dataServer component will store historical values (e.g. the last 10 minutes) and then compare any submitted values to the min/max of the historical values. If the value submitted is outside a certain threshold (e.g. 10% of the min/max), then the party will be notified and they can choose if they wish to dispute the bad value.
To start the disputer, add the following line to your config file IN THE TRACKERS ARRAY:
"disputeChecker"
Now when running the dataServer, you will store historical values and check for whether the submitted values were within min/max of the range of historical values given a threshold (e.g. 1% outside). The variables for configuring the time range of the historical values and the threshold are as follows:
disputeTimeDelta: 5,disputeThreshold: 0.01,
Where 5 and .01 are the defaults, the variables are the amount of time in minutes to store historical values for comparison and the threshold outside the min/max of the values (e.g. 0.01 = 1%);
If the disputer is successful and finds a submitted outside of your acceptable range, a text file containing pertinent information will be created in your working directory (the one you're running the miner out of) in the format: "possible-dispute-(blocktime).txt"
Advanced usage! If you are setting up a Tellor miner for the first time, it might be a good idea to skip this section and come back after you're up and running with one miner.
If you are running multiple miners, there is no reason to run multiple databases (the values you will submit should be identical). In addition, querying the same API from multiple processes can lead to rate limits on the public APIs. To get around this, you can utilize a system where you run one.
In this example will 5 miners connected to a single data server. These 5 miners will start the mining process and the 1 data server will be how each of the 5 miners fetch data from the internet. The network topology of this setup is as follow:
<-> Miner (0xE037) <-><-> Miner (0xcdd8) <->Tellor <-> Miner (0xb9dD) <-> Data Server <-> Internet(on chain) <-> Miner (0x2305) <-><-> Miner (0x3233) <->
The data server pulls data from the internet, the 5 staked miners pull data from the data server and submit on-chain to the Tellor Core smart contracts. The following instructions cover setting this up locally.
wget https://raw.githubusercontent.com/tellor-io/telliot/master/configs/config.jsoncp config.json config1.jsontelliot --config=config1.json dataServer
Edit config1.json
to include the following:
{"publicAddress": "0xE037EC8EC9ec423826750853899394dE7F024fee","contractAddress": "0x7DdC408C0Cd13D3543156AE2bc5772C56E91AA0f","databaseURL":"http://localhost7545","serverWhitelist": ["0xE037EC8EC9ec423826750853899394dE7F024fee","0xcdd8FA31AF8475574B8909F135d510579a8087d3","0xb9dD5AfD86547Df817DA2d0Fb89334A6F8eDd891","0x230570cD052f40E14C14a81038c6f3aa685d712B","0x3233afA02644CCd048587F8ba6e99b3C00A34DcC"],"serverHost": "localhost","serverPort": 5000,"ethClientTimeout": 3000,"trackerCycle": 10,"requestData":1,"gasMultiplier": 1,"gasMax":10,"gpuConfig":{"default":{"disabled": true}},"trackers": ["balance","currentVariables","disputeStatus","gas","top50","tributeBalance","indexers"],"dbFile": "./tellorDB""envFile": ".env1"}
After saving this config1.json
file. Create 4 copies of this file and edit the dbFile
, publicAddress
, envFile
location for each of the files to include the other 5 staked miner addresses (the command below do this for you with cp
and sed
):
cp config1.json config2.jsoncp config1.json config3.jsoncp config1.json config4.jsoncp config1.json config5.json​sed -i -e 's/.env1/.env2/' config2.jsonsed -i -e 's/.env1/.env3/' config3.jsonsed -i -e 's/.env1/.env4/' config4.jsonsed -i -e 's/.env1/.env5/' config5.json​sed -i -e 's/tellorDB/tellorDB2/' config2.jsonsed -i -e 's/tellorDB/tellorDB3/' config3.jsonsed -i -e 's/tellorDB/tellorDB4/' config4.jsonsed -i -e 's/tellorDB/tellorDB5/' config5.json​sed -i -e '1,/0xE037EC8EC9ec423826750853899394dE7F024fee/ s/0xE037EC8EC9ec423826750853899394dE7F024fee/0xcdd8FA31AF8475574B8909F135d510579a8087d3/' config2.jsonsed -i -e '1,/0xE037EC8EC9ec423826750853899394dE7F024fee/ s/0xE037EC8EC9ec423826750853899394dE7F024fee/0xb9dD5AfD86547Df817DA2d0Fb89334A6F8eDd891/' config3.jsonsed -i -e '1,/0xE037EC8EC9ec423826750853899394dE7F024fee/ s/0xE037EC8EC9ec423826750853899394dE7F024fee/0x230570cD052f40E14C14a81038c6f3aa685d712B/' config4.jsonsed -i -e '1,/0xE037EC8EC9ec423826750853899394dE7F024fee/ s/0xE037EC8EC9ec423826750853899394dE7F024fee/0x3233afA02644CCd048587F8ba6e99b3C00A34DcC/' config5.json
Create .env
file with the private key for each miner.
echo "ETH_PRIVATE_KEY=4bdc16637633fa4b4854670fbb83fa254756798009f52a1d3add27fb5f5a8e16" > .env1echo "ETH_PRIVATE_KEY=d32132133e03be292495035cf32e0e2ce0227728ff7ec4ef5d47ec95097ceeed" > .env2echo "ETH_PRIVATE_KEY=d13dc98a245bd29193d5b41203a1d3a4ae564257d60e00d6f68d120ef6b796c5" > .env3echo "ETH_PRIVATE_KEY=4beaa6653cdcacc36e3c400ce286f2aefd59e2642c2f7f29804708a434dd7dbe" > .env4echo "ETH_PRIVATE_KEY=78c1c7e40057ea22a36a0185380ce04ba4f333919d1c5e2effaf0ae8d6431f14" > .env5​​echo "NODE_URL=https://mainnet.infura.io/v3/xxxxxxxxxxxxx" >> .env1echo "NODE_URL=https://mainnet.infura.io/v3/xxxxxxxxxxxxx" >> .env2echo "NODE_URL=https://mainnet.infura.io/v3/xxxxxxxxxxxxx" >> .env3echo "NODE_URL=https://mainnet.infura.io/v3/xxxxxxxxxxxxx" >> .env4echo "NODE_URL=https://mainnet.infura.io/v3/xxxxxxxxxxxxx" >> .env5
Finaly, make 1 more copy of the config for the data server and update the serverHost
address to 0.0.0.0
:
cp config1.json config-dataserver.jsonsed -i -e 's/\"serverHost\": \"localhost\"/\"serverHost\": \"0.0.0.0\"/' config-dataserver.json
The stakes have already been deposited for these Addresses so you can now move on to starting up each of the miners.
You can do this in 6 separate terminals locally. Run each of the command in each of the terminals and confirm they start up correctly.
Terminal # | Command | Description |
1 | ./telliot --config=config-dataserver.json dataserver | Data Server |
2 | ./telliot --config=config1.json mine -r | Staked Miner 1 |
3 | ./telliot --config=config2.json mine -r | Staked Miner 2 |
4 | ./telliot --config=config3.json mine -r | Staked Miner 3 |
5 | ./telliot --config=config4.json mine -r | Staked Miner 4 |
6 | ./telliot --config=config5.json mine -r | Staked Miner 5 |
At this point, you will have 7 terminals running: 6 terminals for the telliot
and 1 terminal for running Ganache. You should see your miners are submitting transactions and if you want to check that the network difficulty is rising, you can use Truffle's console again and run the following commands:
let difficulty = await oracle.getUintVar("0xb12aff7664b16cb99339be399b863feecd64d14817be7e1f042f97e3f358e64e")difficulty.toNumber()