Merge pull request #2610 from poanetwork/ab-use-coin-gecko

use CoinGecko instead of CoinMarketcap for exchange rates
ab-add-unique-index-for-token-transfers
Ayrat Badykov 5 years ago committed by GitHub
commit 380263587d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 9
      apps/block_scout_web/lib/block_scout_web/views/chain_view.ex
  3. 3
      apps/explorer/config/config.exs
  4. 2
      apps/explorer/lib/explorer/chain.ex
  5. 4
      apps/explorer/lib/explorer/chain/supply/exchange_rate.ex
  6. 32
      apps/explorer/lib/explorer/exchange_rates/source.ex
  7. 39
      apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex
  8. 52
      apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex
  9. 12
      apps/explorer/lib/explorer/exchange_rates/source/token_bridge.ex
  10. 57
      apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs
  11. 59
      apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs
  12. 47
      apps/explorer/test/explorer/exchange_rates/source/token_bridge_test.exs
  13. 1806
      apps/explorer/test/support/fixture/exchange_rates/coin_gecko.json
  14. 103
      docs/env-variables.md

@ -9,6 +9,7 @@
- [#2497](https://github.com/poanetwork/blockscout/pull/2497) - Add generic Ordered Cache behaviour and implementation - [#2497](https://github.com/poanetwork/blockscout/pull/2497) - Add generic Ordered Cache behaviour and implementation
### Fixes ### Fixes
- [#2610](https://github.com/poanetwork/blockscout/pull/2610) - use CoinGecko instead of CoinMarketcap for exchange rates
- [#2640](https://github.com/poanetwork/blockscout/pull/2640) - SVG network icons - [#2640](https://github.com/poanetwork/blockscout/pull/2640) - SVG network icons
- [#2635](https://github.com/poanetwork/blockscout/pull/2635) - optimize ERC721 inventory query - [#2635](https://github.com/poanetwork/blockscout/pull/2635) - optimize ERC721 inventory query
- [#2626](https://github.com/poanetwork/blockscout/pull/2626) - Fixing 2 Mobile UI Issues - [#2626](https://github.com/poanetwork/blockscout/pull/2626) - Fixing 2 Mobile UI Issues

@ -3,6 +3,15 @@ defmodule BlockScoutWeb.ChainView do
alias BlockScoutWeb.LayoutView alias BlockScoutWeb.LayoutView
defp market_cap(:standard, %{available_supply: available_supply, usd_value: usd_value})
when is_nil(available_supply) or is_nil(usd_value) do
Decimal.new(0)
end
defp market_cap(:standard, %{available_supply: available_supply, usd_value: usd_value}) do
Decimal.mult(available_supply, usd_value)
end
defp market_cap(:standard, exchange_rate) do defp market_cap(:standard, exchange_rate) do
exchange_rate.market_cap_usd exchange_rate.market_cap_usd
end end

@ -31,8 +31,7 @@ config :explorer, Explorer.ChainSpec.GenesisData, enabled: false, chain_spec_pat
config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: true config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: true
config :explorer, Explorer.ExchangeRates.Source.CoinMarketCap, config :explorer, Explorer.ExchangeRates.Source.CoinGecko, coin_id: System.get_env("COIN_GECKO_ID", "poa-network")
pages: String.to_integer(System.get_env("COINMARKETCAP_PAGES") || "10")
balances_update_interval = balances_update_interval =
if System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL") do if System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL") do

@ -2727,7 +2727,7 @@ defmodule Explorer.Chain do
end end
defp supply_module do defp supply_module do
Application.get_env(:explorer, :supply, Explorer.Chain.Supply.CoinMarketCap) Application.get_env(:explorer, :supply, Explorer.Chain.Supply.ExchangeRate)
end end
@doc """ @doc """

@ -1,6 +1,6 @@
defmodule Explorer.Chain.Supply.CoinMarketCap do defmodule Explorer.Chain.Supply.ExchangeRate do
@moduledoc """ @moduledoc """
Defines the supply API for calculating supply for coins from coinmarketcap. Defines the supply API for calculating supply for coins from exchange_rate..
""" """
use Explorer.Chain.Supply use Explorer.Chain.Supply

@ -2,8 +2,6 @@ defmodule Explorer.ExchangeRates.Source do
@moduledoc """ @moduledoc """
Behaviour for fetching exchange rates from external sources. Behaviour for fetching exchange rates from external sources.
""" """
alias Explorer.ExchangeRates.Source.CoinMarketCap
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias HTTPoison.{Error, Response} alias HTTPoison.{Error, Response}
@ -12,34 +10,18 @@ defmodule Explorer.ExchangeRates.Source do
""" """
@spec fetch_exchange_rates(module) :: {:ok, [Token.t()]} | {:error, any} @spec fetch_exchange_rates(module) :: {:ok, [Token.t()]} | {:error, any}
def fetch_exchange_rates(source \\ exchange_rates_source()) do def fetch_exchange_rates(source \\ exchange_rates_source()) do
if(source == CoinMarketCap) do
fetch_exchange_rates_from_paginable_source(source)
else
fetch_exchange_rates_request(source) fetch_exchange_rates_request(source)
end end
end
defp fetch_exchange_rates_from_paginable_source(source, page \\ 1) do
case HTTPoison.get(source.source_url(page), headers()) do
{:ok, %Response{body: body, status_code: 200}} ->
cond do
body =~ Explorer.coin() -> {:ok, source.format_data(body)}
page == source.max_page_number -> {:error, "exchange rates not found for this network"}
true -> fetch_exchange_rates_from_paginable_source(source, page + 1)
end
{:ok, %Response{body: body, status_code: status_code}} when status_code in 400..502 ->
{:error, decode_json(body)["error"]}
{:error, %Error{reason: reason}} ->
{:error, reason}
end
end
defp fetch_exchange_rates_request(source) do defp fetch_exchange_rates_request(source) do
case HTTPoison.get(source.source_url(), headers()) do case HTTPoison.get(source.source_url(), headers()) do
{:ok, %Response{body: body, status_code: 200}} -> {:ok, %Response{body: body, status_code: 200}} ->
{:ok, source.format_data(body)} result =
body
|> decode_json()
|> source.format_data()
{:ok, result}
{:ok, %Response{body: body, status_code: status_code}} when status_code in 400..499 -> {:ok, %Response{body: body, status_code: status_code}} when status_code in 400..499 ->
{:error, decode_json(body)["error"]} {:error, decode_json(body)["error"]}
@ -83,7 +65,7 @@ defmodule Explorer.ExchangeRates.Source do
@spec exchange_rates_source() :: module() @spec exchange_rates_source() :: module()
defp exchange_rates_source do defp exchange_rates_source do
config(:source) || Explorer.ExchangeRates.Source.CoinMarketCap config(:source) || Explorer.ExchangeRates.Source.CoinGecko
end end
@spec config(atom()) :: term @spec config(atom()) :: term

@ -11,43 +11,50 @@ defmodule Explorer.ExchangeRates.Source.CoinGecko do
@behaviour Source @behaviour Source
@impl Source @impl Source
def format_data(data) do def format_data(%{"market_data" => _} = json_data) do
{:ok, price} = get_btc_price() {:ok, price} = get_btc_price()
btc_price = to_decimal(price) btc_price = to_decimal(price)
for item <- decode_json(data), market_data = json_data["market_data"]
not is_nil(item["total_supply"]) and not is_nil(item["current_price"]) do {:ok, last_updated, 0} = DateTime.from_iso8601(market_data["last_updated"])
{:ok, last_updated, 0} = DateTime.from_iso8601(item["last_updated"])
current_price = to_decimal(item["current_price"]) current_price = to_decimal(market_data["current_price"]["usd"])
id = item["id"] id = json_data["id"]
btc_value = if id != "btc", do: Decimal.div(current_price, btc_price), else: 1 btc_value = if id != "btc", do: Decimal.div(current_price, btc_price), else: 1
[
%Token{ %Token{
available_supply: to_decimal(item["total_supply"]), available_supply: to_decimal(market_data["circulating_supply"]),
total_supply: to_decimal(item["total_supply"]), total_supply: to_decimal(market_data["total_supply"]),
btc_value: btc_value, btc_value: btc_value,
id: id, id: json_data["id"],
last_updated: last_updated, last_updated: last_updated,
market_cap_usd: to_decimal(item["market_cap"]), market_cap_usd: to_decimal(market_data["market_cap"]["usd"]),
name: item["name"], name: json_data["name"],
symbol: item["symbol"], symbol: String.upcase(json_data["symbol"]),
usd_value: current_price, usd_value: current_price,
volume_24h_usd: to_decimal(item["total_volume"]) volume_24h_usd: to_decimal(market_data["total_volume"]["usd"])
} }
]
end end
end
@impl Source @impl Source
def source_url(currency \\ "usd") do def format_data(_), do: []
"#{base_url()}/coins/markets?vs_currency=#{currency}"
@impl Source
def source_url do
"#{base_url()}/coins/#{coin_id()}"
end end
defp base_url do defp base_url do
config(:base_url) || "https://api.coingecko.com/api/v3" config(:base_url) || "https://api.coingecko.com/api/v3"
end end
defp coin_id do
Application.get_env(:explorer, __MODULE__)[:coin_id]
end
defp get_btc_price(currency \\ "usd") do defp get_btc_price(currency \\ "usd") do
url = "#{base_url()}/exchange_rates" url = "#{base_url()}/exchange_rates"

@ -1,52 +0,0 @@
defmodule Explorer.ExchangeRates.Source.CoinMarketCap do
@moduledoc """
Adapter for fetching exchange rates from https://coinmarketcap.com.
"""
alias Explorer.ExchangeRates.{Source, Token}
import Source, only: [decode_json: 1, to_decimal: 1]
@behaviour Source
@impl Source
def format_data(data) do
for item <- decode_json(data), not is_nil(item["last_updated"]) do
{last_updated_as_unix, _} = Integer.parse(item["last_updated"])
last_updated = DateTime.from_unix!(last_updated_as_unix)
%Token{
available_supply: to_decimal(item["available_supply"]),
total_supply: to_decimal(item["total_supply"]),
btc_value: to_decimal(item["price_btc"]),
id: item["id"],
last_updated: last_updated,
market_cap_usd: to_decimal(item["market_cap_usd"]),
name: item["name"],
symbol: item["symbol"],
usd_value: to_decimal(item["price_usd"]),
volume_24h_usd: to_decimal(item["24h_volume_usd"])
}
end
end
@impl Source
def source_url do
source_url(1)
end
def source_url(page) do
"#{base_url()}/v1/ticker/?start=#{page - 1}00"
end
def max_page_number, do: config(:pages)
defp base_url do
config(:base_url) || "https://api.coinmarketcap.com"
end
@spec config(atom()) :: term
defp config(key) do
Application.get_env(:explorer, __MODULE__, [])[key]
end
end

@ -30,7 +30,7 @@ defmodule Explorer.ExchangeRates.Source.TokenBridge do
btc_value: original_token.btc_value, btc_value: original_token.btc_value,
id: original_token.id, id: original_token.id,
last_updated: original_token.last_updated, last_updated: original_token.last_updated,
market_cap_usd: Decimal.mult(to_decimal(Chain.circulating_supply()), original_token.usd_value), market_cap_usd: market_cap_usd(Chain.circulating_supply(), original_token),
name: original_token.name, name: original_token.name,
symbol: original_token.symbol, symbol: original_token.symbol,
usd_value: original_token.usd_value, usd_value: original_token.usd_value,
@ -38,6 +38,14 @@ defmodule Explorer.ExchangeRates.Source.TokenBridge do
} }
end end
defp market_cap_usd(nil, _original_token), do: Decimal.new(0)
defp market_cap_usd(supply, original_token) do
supply
|> to_decimal()
|> Decimal.mult(original_token.usd_value)
end
@impl Source @impl Source
def source_url do def source_url do
secondary_source().source_url() secondary_source().source_url()
@ -45,7 +53,7 @@ defmodule Explorer.ExchangeRates.Source.TokenBridge do
@spec secondary_source() :: module() @spec secondary_source() :: module()
defp secondary_source do defp secondary_source do
config(:secondary_source) || Explorer.ExchangeRates.Source.CoinMarketCap config(:secondary_source) || Explorer.ExchangeRates.Source.CoinGecko
end end
@spec config(atom()) :: term @spec config(atom()) :: term

@ -18,34 +18,6 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do
} }
""" """
@json_mkt_data """
[
{
"id": "poa-network",
"symbol": "poa",
"name": "POA Network",
"image": "https://assets.coingecko.com/coins/images/3157/large/poa.jpg?1520829019",
"current_price": 0.114782883773693,
"market_cap": 25248999.6735956,
"market_cap_rank": 185,
"total_volume": 2344442.13578437,
"high_24h": 0.115215129840519,
"low_24h": 0.101039753612939,
"price_change_24h": 0.0135970966607094,
"price_change_percentage_24h": 13.437753511298,
"market_cap_change_24h": 3058195.58191147,
"market_cap_change_percentage_24h": 13.7813644304017,
"circulating_supply": "219935174.0",
"total_supply": 252193195,
"ath": 0.935923393359191,
"ath_change_percentage": -87.731057963078,
"ath_date": "2018-05-10T09:45:31.809Z",
"roi": null,
"last_updated": "2018-10-23T01:25:31.764Z"
}
]
"""
describe "format_data/1" do describe "format_data/1" do
setup do setup do
bypass = Bypass.open() bypass = Bypass.open()
@ -59,31 +31,30 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do
Conn.resp(conn, 200, @json_btc_price) Conn.resp(conn, 200, @json_btc_price)
end) end)
{:ok, expected_date, 0} = "2018-10-23T01:25:31.764Z" |> DateTime.from_iso8601() json_data =
"#{File.cwd!()}/test/support/fixture/exchange_rates/coin_gecko.json"
|> File.read!()
|> Jason.decode!()
expected = [ expected = [
%Token{ %Token{
available_supply: Decimal.new("252193195"), available_supply: Decimal.new("220167621.0"),
total_supply: Decimal.new("252193195"), total_supply: Decimal.new("252193195.0"),
btc_value: Decimal.new("0.00001753101509231471092879666458"), btc_value: Decimal.new("0.000002055310963802830367634997491"),
id: "poa-network", id: "poa-network",
last_updated: expected_date, last_updated: ~U[2019-08-21 08:36:49.371Z],
market_cap_usd: Decimal.new("25248999.6735956"), market_cap_usd: Decimal.new("2962791"),
name: "POA Network", name: "POA Network",
symbol: "poa", symbol: "POA",
usd_value: Decimal.new("0.114782883773693"), usd_value: Decimal.new("0.01345698"),
volume_24h_usd: Decimal.new("2344442.13578437") volume_24h_usd: Decimal.new("119946")
} }
] ]
assert expected == CoinGecko.format_data(@json_mkt_data) assert expected == CoinGecko.format_data(json_data)
end end
test "returns nothing when given bad data", %{bypass: bypass} do test "returns nothing when given bad data" do
Bypass.expect(bypass, "GET", "/exchange_rates", fn conn ->
Conn.resp(conn, 200, @json_btc_price)
end)
bad_data = """ bad_data = """
[{"id": "poa-network"}] [{"id": "poa-network"}]
""" """

@ -1,59 +0,0 @@
defmodule Explorer.ExchangeRates.Source.CoinMarketCapTest do
use ExUnit.Case
alias Explorer.ExchangeRates.Token
alias Explorer.ExchangeRates.Source.CoinMarketCap
@json """
[
{
"id": "poa-network",
"name": "POA Network",
"symbol": "POA",
"rank": "103",
"price_usd": "0.485053",
"price_btc": "0.00007032",
"24h_volume_usd": "20185000.0",
"market_cap_usd": "98941986.0",
"available_supply": "203981804.0",
"total_supply": "254473964.0",
"max_supply": null,
"percent_change_1h": "-0.66",
"percent_change_24h": "12.34",
"percent_change_7d": "49.15",
"last_updated": "1523473200"
}
]
"""
describe "format_data/1" do
test "returns valid tokens with valid data" do
expected_date = ~N[2018-04-11 19:00:00] |> DateTime.from_naive!("Etc/UTC")
expected = [
%Token{
available_supply: Decimal.new("203981804.0"),
total_supply: Decimal.new("254473964.0"),
btc_value: Decimal.new("0.00007032"),
id: "poa-network",
last_updated: expected_date,
market_cap_usd: Decimal.new("98941986.0"),
name: "POA Network",
symbol: "POA",
usd_value: Decimal.new("0.485053"),
volume_24h_usd: Decimal.new("20185000.0")
}
]
assert expected == CoinMarketCap.format_data(@json)
end
test "returns nothing when given bad data" do
bad_data = """
[{"id": "poa-network"}]
"""
assert [] = CoinMarketCap.format_data(bad_data)
end
end
end

@ -1,32 +1,41 @@
defmodule Explorer.ExchangeRates.Source.TokenBridgeTest do defmodule Explorer.ExchangeRates.Source.TokenBridgeTest do
use Explorer.DataCase use Explorer.DataCase
alias Explorer.ExchangeRates.Source.CoinGecko
alias Explorer.ExchangeRates.Source.TokenBridge alias Explorer.ExchangeRates.Source.TokenBridge
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Plug.Conn
@json "#{File.cwd!()}/test/support/fixture/exchange_rates/coin_gecko.json"
|> File.read!()
|> Jason.decode!()
@json """ @json_btc_price """
[
{ {
"id": "poa-network", "rates": {
"name": "POA Network", "usd": {
"symbol": "POA", "name": "US Dollar",
"rank": "103", "unit": "$",
"price_usd": "0.485053", "value": 6547.418,
"price_btc": "0.00007032", "type": "fiat"
"24h_volume_usd": "20185000.0", }
"market_cap_usd": "98941986.0", }
"available_supply": "203981804.0",
"total_supply": "254473964.0",
"max_supply": null,
"percent_change_1h": "-0.66",
"percent_change_24h": "12.34",
"percent_change_7d": "49.15",
"last_updated": "1523473200"
} }
]
""" """
describe "format_data/1" do describe "format_data/1" do
test "bring a list with one %Token{}" do setup do
bypass = Bypass.open()
Application.put_env(:explorer, CoinGecko, base_url: "http://localhost:#{bypass.port}")
{:ok, bypass: bypass}
end
test "bring a list with one %Token{}", %{bypass: bypass} do
Bypass.expect(bypass, "GET", "/exchange_rates", fn conn ->
Conn.resp(conn, 200, @json_btc_price)
end)
assert [%Token{}] = TokenBridge.format_data(@json) assert [%Token{}] = TokenBridge.format_data(@json)
end end
end end

@ -14,54 +14,55 @@ $ export NETWORK=POA
``` ```
| Variable | Required | Description | Default | Version | Need recompile | | Variable | Required | Description | Default | Version | Need recompile | Deprecated in Version |
| --- | --- | --- | ---| --- | --- | | --- | --- | --- | ---| --- | --- | --- |
| `NETWORK`| :white_check_mark: | Environment variable for the main EVM network such as Ethereum Network or POA Network | POA Network | all | | | `NETWORK`| :white_check_mark: | Environment variable for the main EVM network such as Ethereum Network or POA Network | POA Network | all | | |
| `SUBNETWORK` | :white_check_mark: | Environment variable for the subnetwork such as Core or Sokol Network | Sokol Testnet | all | | | `SUBNETWORK` | :white_check_mark: | Environment variable for the subnetwork such as Core or Sokol Network | Sokol Testnet | all | | |
| `NETWORK_ICON` | :white_check_mark: | Environment variable for the main network icon or testnet icon. Two options are `_test_network_icon.html` and `_network_icon.html` | `_test_network_icon.html` | all | | | `NETWORK_ICON` | :white_check_mark: | Environment variable for the main network icon or testnet icon. Two options are `_test_network_icon.html` and `_network_icon.html` | `_test_network_icon.html` | all | | |
| `LOGO` | :white_check_mark: | Environment variable for the logo image location. The logo files names for different chains can be found [here](https://github.com/poanetwork/blockscout/tree/master/apps/block_scout_web/assets/static/images) | /images/blockscout_logo.svg | all | | | `LOGO` | :white_check_mark: | Environment variable for the logo image location. The logo files names for different chains can be found [here](https://github.com/poanetwork/blockscout/tree/master/apps/block_scout_web/assets/static/images) | /images/blockscout_logo.svg | all | | |
| `ETHEREUM_JSONRPC_VARIANT` | :white_check_mark: | This environment variable is used to tell the application which RPC Client the node is using (i.e. Geth, Parity, or Ganache) | parity | all | | | `ETHEREUM_JSONRPC_VARIANT` | :white_check_mark: | This environment variable is used to tell the application which RPC Client the node is using (i.e. Geth, Parity, or Ganache) | parity | all | | |
| `ETHEREUM_JSONRPC_HTTP_URL` | :white_check_mark: | The RPC endpoint used to fetch blocks, transactions, receipts, tokens. | localhost:8545 | all | | | `ETHEREUM_JSONRPC_HTTP_URL` | :white_check_mark: | The RPC endpoint used to fetch blocks, transactions, receipts, tokens. | localhost:8545 | all | | |
| `ETHEREUM_JSONRPC_TRACE_URL` | | The RPC endpoint specifically for the Geth/Parity client used by trace_block and trace_replayTransaction. This can be used to designate a tracing node. | localhost:8545 | all | | | `ETHEREUM_JSONRPC_TRACE_URL` | | The RPC endpoint specifically for the Geth/Parity client used by trace_block and trace_replayTransaction. This can be used to designate a tracing node. | localhost:8545 | all | | |
| `ETHEREUM_JSONRPC_WS_URL` | :white_check_mark: | The WebSockets RPC endpoint used to subscribe to the `newHeads` subscription alerting the indexer to fetch new blocks. | ws://localhost:8546 | all | | | `ETHEREUM_JSONRPC_WS_URL` | :white_check_mark: | The WebSockets RPC endpoint used to subscribe to the `newHeads` subscription alerting the indexer to fetch new blocks. | ws://localhost:8546 | all | | |
| `NETWORK_PATH` | | Used to set a network path other than what is displayed in the root directory. An example would be to add /eth/mainnet/ to the root directory. | (empty) | all | | | `NETWORK_PATH` | | Used to set a network path other than what is displayed in the root directory. An example would be to add /eth/mainnet/ to the root directory. | (empty) | all | | |
| `SECRET_KEY_BASE` | :white_check_mark: | Use mix phx.gen.secret to generate a new Secret Key Base string to protect production assets. | (empty) | all | | | `SECRET_KEY_BASE` | :white_check_mark: | Use mix phx.gen.secret to generate a new Secret Key Base string to protect production assets. | (empty) | all | | |
| `CHECK_ORIGIN` | | Used to check the origin of requests when the origin header is present. It defaults to false. In case of true, it will check against the host value. | false | all | | | `CHECK_ORIGIN` | | Used to check the origin of requests when the origin header is present. It defaults to false. In case of true, it will check against the host value. | false | all | | |
| `PORT` | :white_check_mark: | Default port the application runs on is 4000 | 4000 | all | | | `PORT` | :white_check_mark: | Default port the application runs on is 4000 | 4000 | all | | |
| `COIN` | :white_check_mark: | The coin here is checked via the Coinmarketcap API to obtain USD prices on graphs and other areas of the UI | POA | all | | | `COIN` | :white_check_mark: | The coin here is checked via the CoinGecko API to obtain USD prices on graphs and other areas of the UI | POA | all | | |
| `METADATA_CONTRACT` | | This environment variable is specifically used by POA Network to obtain Validators information to display in the UI. | (empty) | all | | | `METADATA_CONTRACT` | | This environment variable is specifically used by POA Network to obtain Validators information to display in the UI. | (empty) | all | | |
| `VALIDATORS_CONTRACT` | | This environment variable is specifically used by POA Network to obtain the Emission Fund contract. | (empty) | all | | | `VALIDATORS_CONTRACT` | | This environment variable is specifically used by POA Network to obtain the Emission Fund contract. | (empty) | all | | |
| `SUPPLY_MODULE` | | This environment variable is used by the xDai Chain in order to tell the application how to calculate the total supply of the chain. | false | all | | | `SUPPLY_MODULE` | | This environment variable is used by the xDai Chain in order to tell the application how to calculate the total supply of the chain. | false | all | | |
| `SOURCE_MODULE` | | This environment variable is used to calculate the exchange rate and is specifically used by the xDai Chain. | false | all | | | `SOURCE_MODULE` | | This environment variable is used to calculate the exchange rate and is specifically used by the xDai Chain. | false | all | | |
| `DATABASE_URL` | | Production environment variable to define the Database endpoint. | (empty) | all | | | `DATABASE_URL` | | Production environment variable to define the Database endpoint. | (empty) | all | | |
| `POOL_SIZE` | | Production environment variable to define the number of database connections allowed. | 20 | all | | | `POOL_SIZE` | | Production environment variable to define the number of database connections allowed. | 20 | all | | |
| `ECTO_USE_SSL` | | Production environment variable to use SSL on Ecto queries. | true | all | | | `ECTO_USE_SSL` | | Production environment variable to use SSL on Ecto queries. | true | all | | |
| `DATADOG_HOST` | | Host configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/) | (empty) | all | | | `DATADOG_HOST` | | Host configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/) | (empty) | all | | |
| `DATADOG_PORT` | | Port configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/). | (empty} | all | | | `DATADOG_PORT` | | Port configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/). | (empty} | all | | |
| `SPANDEX_BATCH_SIZE` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | `SPANDEX_BATCH_SIZE` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | |
| `SPANDEX_SYNC_THRESHOLD` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | | `SPANDEX_SYNC_THRESHOLD` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | |
| `HEART_BEAT_TIMEOUT` | | Production environment variable to restart the application in the event of a crash. | 30 | all | | | `HEART_BEAT_TIMEOUT` | | Production environment variable to restart the application in the event of a crash. | 30 | all | | |
| `HEART_COMMAND` | | Production environment variable to restart the application in the event of a crash. | systemctl restart explorer.service | all | | | `HEART_COMMAND` | | Production environment variable to restart the application in the event of a crash. | systemctl restart explorer.service | all | | |
| `BLOCKSCOUT_VERSION` | | Added to the footer to signify the current BlockScout version. | (empty) | v1.3.4+ | | | `BLOCKSCOUT_VERSION` | | Added to the footer to signify the current BlockScout version. | (empty) | v1.3.4+ | | |
| `RELEASE_LINK` | | The link to Blockscout release notes in the footer. | <u>https: //github.com/poanetwork/</u> <br /><u>blockscout/releases/</u> <br /> <u>tag/${BLOCKSCOUT_VERSION}</u> | v1.3.5+ | | | `RELEASE_LINK` | | The link to Blockscout release notes in the footer. | <u>https: //github.com/poanetwork/</u> <br /><u>blockscout/releases/</u> <br /> <u>tag/${BLOCKSCOUT_VERSION}</u> | v1.3.5+ | | |
| `ELIXIR_VERSION` | | Elixir version to install on the node before Blockscout deploy. | (empty) | all | | | `ELIXIR_VERSION` | | Elixir version to install on the node before Blockscout deploy. | (empty) | all | | |
| `BLOCK_TRANSFORMER` | | Transformer for blocks: base or clique. | base | v1.3.4+ | | | `BLOCK_TRANSFORMER` | | Transformer for blocks: base or clique. | base | v1.3.4+ | | |
| `GRAPHIQL_TRANSACTION` | | Default transaction in query to GraphiQL. | (empty) | v1.2.0+ | :white_check_mark: | | `GRAPHIQL_TRANSACTION` | | Default transaction in query to GraphiQL. | (empty) | v1.2.0+ | :white_check_mark: | |
| `FIRST_BLOCK` | | The block number, where indexing begins from. | 0 | v1.3.8+ | | | `FIRST_BLOCK` | | The block number, where indexing begins from. | 0 | v1.3.8+ | | |
| `LAST_BLOCK` | | The block number, where indexing stops. | (empty) | v2.0.3+ | | | `LAST_BLOCK` | | The block number, where indexing stops. | (empty) | v2.0.3+ | | |
| `TXS_COUNT_CACHE_PERIOD` | | Interval in seconds to restart the task, which calculates the total txs count. | 60 * 60 * 2 | v1.3.9+ | | | `TXS_COUNT_CACHE_PERIOD` | | Interval in seconds to restart the task, which calculates the total txs count. | 60 * 60 * 2 | v1.3.9+ | | |
| `ADDRESS_WITH_BALANCES` <br /> `_UPDATE_INTERVAL`| | Interval in seconds to restart the task, which calculates addresses with balances. | 30 * 60 | v1.3.9+ | | | `ADDRESS_WITH_BALANCES` <br /> `_UPDATE_INTERVAL`| | Interval in seconds to restart the task, which calculates addresses with balances. | 30 * 60 | v1.3.9+ | | |
| `LINK_TO_OTHER_EXPLORERS` | | true/false. If true, links to other explorers are added in the footer | (empty) | v1.3.0+ | | | `LINK_TO_OTHER_EXPLORERS` | | true/false. If true, links to other explorers are added in the footer | (empty) | v1.3.0+ | | |
| `COINMARKETCAP_PAGES` | | the number of pages on coinmarketcap to list in order to find token's price | 10 | v1.3.10+ | | | `COINMARKETCAP_PAGES` | | the number of pages on coinmarketcap to list in order to find token's price | 10 | v1.3.10+ | | master |
| `SUPPORTED_CHAINS` | | Array of supported chains that displays in the footer and in the chains dropdown. This var was introduced in this PR [#1900](https://github.com/poanetwork/blockscout/pull/1900) and looks like an array of JSON objects. | (empty) | v2.0.0+ | | | `SUPPORTED_CHAINS` | | Array of supported chains that displays in the footer and in the chains dropdown. This var was introduced in this PR [#1900](https://github.com/poanetwork/blockscout/pull/1900) and looks like an array of JSON objects. | (empty) | v2.0.0+ | | |
| `BLOCK_COUNT_CACHE_PERIOD ` | | time to live of cache in seconds. This var was introduced in [#1876](https://github.com/poanetwork/blockscout/pull/1876) | 600 | v2.0.0+ | | | `BLOCK_COUNT_CACHE_PERIOD ` | | time to live of cache in seconds. This var was introduced in [#1876](https://github.com/poanetwork/blockscout/pull/1876) | 600 | v2.0.0+ | | |
| `ALLOWED_EVM_VERSIONS ` | | the comma-separated list of allowed EVM versions for contracts verification. This var was introduced in [#1964](https://github.com/poanetwork/blockscout/pull/1964) | "homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg" | v2.0.0+ | | | `ALLOWED_EVM_VERSIONS ` | | the comma-separated list of allowed EVM versions for contracts verification. This var was introduced in [#1964](https://github.com/poanetwork/blockscout/pull/1964) | "homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg" | v2.0.0+ | | |
| `AVERAGE_BLOCK_CACHE_PERIOD` | | Update of average block cache, in seconds | 30 minutes | v2.0.2+ | | `AVERAGE_BLOCK_CACHE_PERIOD` | | Update of average block cache, in seconds | 30 minutes | v2.0.2+ | |
| `MARKET_HISTORY_CACHE_PERIOD` | | Update of market history cache, in seconds | 6 hours | v2.0.2+ | | `MARKET_HISTORY_CACHE_PERIOD` | | Update of market history cache, in seconds | 6 hours | v2.0.2+ | |
| `DISABLE_WEBAPP` | | If `true`, endpoints to webapp are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | | `DISABLE_WEBAPP` | | If `true`, endpoints to webapp are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | |
| `DISABLE_READ_API` | | If `true`, read-only endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | | `DISABLE_READ_API` | | If `true`, read-only endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | |
| `DISABLE_WRITE_API` | | If `true`, write endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | | `DISABLE_WRITE_API` | | If `true`, write endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | |
| `DISABLE_INDEXER` | | If `true`, indexer application doesn't run | `false` | v2.0.3+ | :white_check_mark: | | `DISABLE_INDEXER` | | If `true`, indexer application doesn't run | `false` | v2.0.3+ | :white_check_mark: | |
| `WEBAPP_URL` | | Link to web application instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | | `WEBAPP_URL` | | Link to web application instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | |
| `API_URL` | | Link to API instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | | `API_URL` | | Link to API instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | |
| `CHAIN_SPEC_PATH` | | Chain specification path (absolute file system path or url) to import block emission reward ranges and genesis account balances from | (empty) | master | | | `CHAIN_SPEC_PATH` | | Chain specification path (absolute file system path or url) to import block emission reward ranges and genesis account balances from | (empty) | master | | |
| `COIN_GECKO_ID` | | CoinGecko coin id required for fetching an exchange rate | poa-network | master | | |

Loading…
Cancel
Save