Merge remote-tracking branch 'origin/master' into ab-add-checksum-plug

pull/2834/head
Victor Baranov 5 years ago
commit 3771dda43d
  1. 140
      .circleci/config.yml
  2. 6
      .tool-versions
  3. 85
      CHANGELOG.md
  4. 2
      apps/block_scout_web/README.md
  5. 4
      apps/block_scout_web/assets/.babelrc
  6. 2
      apps/block_scout_web/assets/css/_typography.scss
  7. 3
      apps/block_scout_web/assets/css/app.scss
  8. 10
      apps/block_scout_web/assets/css/components/_dashboard-banner.scss
  9. 1
      apps/block_scout_web/assets/css/components/_navbar.scss
  10. 1
      apps/block_scout_web/assets/css/components/_tooltip.scss
  11. 1
      apps/block_scout_web/assets/css/non-critical.scss
  12. 4
      apps/block_scout_web/assets/css/theme/_base_variables.scss
  13. 7
      apps/block_scout_web/assets/css/theme/_ethercore_variables-non-critical.scss
  14. 84
      apps/block_scout_web/assets/css/theme/_ethercore_variables.scss
  15. 3
      apps/block_scout_web/assets/css/theme/_lukso_variables.scss
  16. 3
      apps/block_scout_web/assets/css/theme/_variables-non-critical.scss
  17. 1
      apps/block_scout_web/assets/css/theme/_variables.scss
  18. 4
      apps/block_scout_web/assets/js/app.js
  19. 18
      apps/block_scout_web/assets/js/chart-loader.js
  20. 28
      apps/block_scout_web/assets/js/lib/async_listing_load.js
  21. 29
      apps/block_scout_web/assets/js/lib/awesomplete-util.js
  22. 2
      apps/block_scout_web/assets/js/lib/card_tabs.js
  23. 2
      apps/block_scout_web/assets/js/lib/clipboard_buttons.js
  24. 4
      apps/block_scout_web/assets/js/lib/coin_balance_history_chart.js
  25. 7
      apps/block_scout_web/assets/js/lib/currency.js
  26. 2
      apps/block_scout_web/assets/js/lib/indexing.js
  27. 61
      apps/block_scout_web/assets/js/lib/market_history_chart.js
  28. 57
      apps/block_scout_web/assets/js/lib/modals.js
  29. 18
      apps/block_scout_web/assets/js/lib/network_selector.js
  30. 4
      apps/block_scout_web/assets/js/lib/pretty_json.js
  31. 9
      apps/block_scout_web/assets/js/lib/try_eth_api.js
  32. 2
      apps/block_scout_web/assets/js/lib/utils.js
  33. 4
      apps/block_scout_web/assets/js/pages/address.js
  34. 8
      apps/block_scout_web/assets/js/pages/address/coin_balances.js
  35. 4
      apps/block_scout_web/assets/js/pages/address/internal_transactions.js
  36. 18
      apps/block_scout_web/assets/js/pages/address/logs.js
  37. 4
      apps/block_scout_web/assets/js/pages/address/transactions.js
  38. 2
      apps/block_scout_web/assets/js/pages/blocks.js
  39. 42
      apps/block_scout_web/assets/js/pages/chain.js
  40. 4
      apps/block_scout_web/assets/js/pages/pending_transactions.js
  41. 8
      apps/block_scout_web/assets/js/pages/token_counters.js
  42. 2
      apps/block_scout_web/assets/js/pages/transaction.js
  43. 2
      apps/block_scout_web/assets/js/pages/transactions.js
  44. 52
      apps/block_scout_web/assets/js/pages/verification_form.js
  45. 11
      apps/block_scout_web/assets/js/socket.js
  46. 16614
      apps/block_scout_web/assets/package-lock.json
  47. 65
      apps/block_scout_web/assets/package.json
  48. BIN
      apps/block_scout_web/assets/static/android-chrome-192x192.png
  49. BIN
      apps/block_scout_web/assets/static/android-chrome-512x512.png
  50. BIN
      apps/block_scout_web/assets/static/favicon-16x16.png
  51. BIN
      apps/block_scout_web/assets/static/favicon-32x32.png
  52. 10139
      apps/block_scout_web/assets/static/images/ethercore_logo.svg
  53. 5382
      apps/block_scout_web/assets/static/images/ethercore_testnet_logo.svg
  54. BIN
      apps/block_scout_web/assets/static/images/favicon-16x16.png
  55. BIN
      apps/block_scout_web/assets/static/images/favicon-32x32.png
  56. 0
      apps/block_scout_web/assets/static/images/favicon.ico
  57. 0
      apps/block_scout_web/assets/static/manifest.webmanifest
  58. BIN
      apps/block_scout_web/assets/static/mstile-150x150.png
  59. 69
      apps/block_scout_web/assets/webpack.config.js
  60. 3
      apps/block_scout_web/config/config.exs
  61. 3
      apps/block_scout_web/config/dev.exs
  62. 3
      apps/block_scout_web/config/prod.exs
  63. 97
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex
  64. 4
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex
  65. 23
      apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/stats_controller.ex
  66. 7
      apps/block_scout_web/lib/block_scout_web/endpoint.ex
  67. 92
      apps/block_scout_web/lib/block_scout_web/etherscan.ex
  68. 2
      apps/block_scout_web/lib/block_scout_web/notifier.ex
  69. 18
      apps/block_scout_web/lib/block_scout_web/router.ex
  70. 6
      apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex
  71. 6
      apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex
  72. 4
      apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex
  73. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_coin_balance/index.html.eex
  74. 49
      apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex
  75. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex
  76. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex
  77. 45
      apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex
  78. 8
      apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex
  79. 9
      apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
  80. 38
      apps/block_scout_web/lib/block_scout_web/templates/layout/app.html.eex
  81. 2
      apps/block_scout_web/lib/block_scout_web/templates/tokens/inventory/_token.html.eex
  82. 4
      apps/block_scout_web/lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex
  83. 1
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  84. 8
      apps/block_scout_web/lib/block_scout_web/views/address_token_transfer_view.ex
  85. 10
      apps/block_scout_web/lib/block_scout_web/views/address_view.ex
  86. 19
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/address_view.ex
  87. 23
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/block_view.ex
  88. 102
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/contract_view.ex
  89. 9
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/rpc_view.ex
  90. 8
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/stats_view.ex
  91. 21
      apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex
  92. 2
      apps/block_scout_web/lib/block_scout_web/views/smart_contract_view.ex
  93. 5
      apps/block_scout_web/lib/block_scout_web/views/tokens/instance/overview_view.ex
  94. 1
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  95. 7
      apps/block_scout_web/lib/block_scout_web/web_router.ex
  96. 10
      apps/block_scout_web/mix.exs
  97. 217
      apps/block_scout_web/priv/gettext/default.pot
  98. 217
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  99. 28
      apps/block_scout_web/test/block_scout_web/channels/address_channel_test.exs
  100. 6
      apps/block_scout_web/test/block_scout_web/controllers/address_contract_controller_test.exs
  101. Some files were not shown because too many files have changed in this diff Show More

@ -3,7 +3,7 @@ jobs:
build:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1-node-browsers
- image: circleci/elixir:1.9.4-node-browsers
environment:
MIX_ENV: test
# match POSTGRES_PASSWORD for postgres image below
@ -63,6 +63,10 @@ jobs:
command: npm install
working_directory: "apps/block_scout_web/assets"
- run:
command: npm rebuild node-sass
working_directory: "apps/block_scout_web/assets"
- save_cache:
key: v7-npm-install-{{ .Branch }}-{{ checksum "apps/block_scout_web/assets/package-lock.json" }}
paths: "apps/block_scout_web/assets/node_modules"
@ -129,7 +133,7 @@ jobs:
check_formatted:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1
- image: circleci/elixir:1.9.4
environment:
MIX_ENV: test
@ -143,7 +147,7 @@ jobs:
credo:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1
- image: circleci/elixir:1.9.4
environment:
MIX_ENV: test
@ -177,7 +181,7 @@ jobs:
dialyzer:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1
- image: circleci/elixir:1.9.4
environment:
MIX_ENV: test
@ -229,7 +233,7 @@ jobs:
eslint:
docker:
# Ensure .tool-versions matches
- image: circleci/node:12.13.0-browsers-legacy
- image: circleci/node:12.14.1-browsers-legacy
working_directory: ~/app
@ -247,7 +251,7 @@ jobs:
gettext:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1
- image: circleci/elixir:1.9.4
environment:
MIX_ENV: test
@ -271,7 +275,7 @@ jobs:
jest:
docker:
# Ensure .tool-versions matches
- image: circleci/node:12.13.0-browsers-legacy
- image: circleci/node:12.14.1-browsers-legacy
working_directory: ~/app
@ -286,7 +290,7 @@ jobs:
release:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1
- image: circleci/elixir:1.9.4
environment:
MIX_ENV: prod
@ -312,7 +316,7 @@ jobs:
sobelow:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1
- image: circleci/elixir:1.9.4
environment:
MIX_ENV: test
@ -336,7 +340,7 @@ jobs:
# test_geth_http_websocket:
# docker:
# # Ensure .tool-versions matches
# - image: circleci/elixir:1.9.1-node-browsers
# - image: circleci/elixir:1.9.4-node-browsers
# environment:
# MIX_ENV: test
# # match POSTGRES_PASSWORD for postgres image below
@ -345,7 +349,7 @@ jobs:
# PGUSER: postgres
# ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Geth.HTTPWebSocket"
# ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Geth"
# - image: circleci/postgres:10.3-alpine
# - image: circleci/postgres:10.10-alpine
# environment:
# # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
# POSTGRES_DB: explorer_test
@ -390,7 +394,7 @@ jobs:
# test_geth_mox:
# docker:
# # Ensure .tool-versions matches
# - image: circleci/elixir:1.9.1-node-browsers
# - image: circleci/elixir:1.9.4-node-browsers
# environment:
# MIX_ENV: test
# # match POSTGRES_PASSWORD for postgres image below
@ -399,7 +403,7 @@ jobs:
# PGUSER: postgres
# ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Geth.Mox"
# ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox"
# - image: circleci/postgres:10.3-alpine
# - image: circleci/postgres:10.10-alpine
# environment:
# # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
# POSTGRES_DB: explorer_test
@ -441,64 +445,64 @@ jobs:
# path: cover/excoveralls.html
# - store_test_results:
# path: _build/test/junit
test_parity_http_websocket:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1-node-browsers
environment:
MIX_ENV: test
# match POSTGRES_PASSWORD for postgres image below
PGPASSWORD: postgres
# match POSTGRES_USER for postgres image below
PGUSER: postgres
ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Parity.HTTPWebSocket"
ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Parity"
- image: circleci/postgres:10.3-alpine
environment:
# Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
POSTGRES_DB: explorer_test
# match PGPASSWORD for elixir image above
POSTGRES_PASSWORD: postgres
# match PGUSER for elixir image above
POSTGRES_USER: postgres
# test_parity_http_websocket:
# docker:
# # Ensure .tool-versions matches
# - image: circleci/elixir:1.9.4-node-browsers
# environment:
# MIX_ENV: test
# # match POSTGRES_PASSWORD for postgres image below
# PGPASSWORD: postgres
# # match POSTGRES_USER for postgres image below
# PGUSER: postgres
# ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Parity.HTTPWebSocket"
# ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Parity"
# - image: circleci/postgres:10.10-alpine
# environment:
# # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
# POSTGRES_DB: explorer_test
# # match PGPASSWORD for elixir image above
# POSTGRES_PASSWORD: postgres
# # match PGUSER for elixir image above
# POSTGRES_USER: postgres
working_directory: ~/app
# working_directory: ~/app
steps:
- attach_workspace:
at: .
# steps:
# - attach_workspace:
# at: .
- run:
command: ./bin/install_chrome_headless.sh
no_output_timeout: 2400
# - run:
# command: ./bin/install_chrome_headless.sh
# no_output_timeout: 2400
- run: mix local.hex --force
- run: mix local.rebar --force
# - run: mix local.hex --force
# - run: mix local.rebar --force
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:5432 -timeout 1m
# - run:
# name: Wait for DB
# command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run:
name: mix test --exclude no_parity
command: |
# Don't submit coverage report for forks, but let the build succeed
if [[ -z "$COVERALLS_REPO_TOKEN" ]]; then
mix coveralls.html --exclude no_parity --parallel --umbrella
else
mix coveralls.circle --exclude no_parity --parallel --umbrella ||
# if mix failed, then coveralls_merge won't run, so signal done here and return original exit status
(retval=$? && curl -k https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN -d "payload[build_num]=$CIRCLE_WORKFLOW_WORKSPACE_ID&payload[status]=done" && return $retval)
fi
# - run:
# name: mix test --exclude no_parity
# command: |
# # Don't submit coverage report for forks, but let the build succeed
# if [[ -z "$COVERALLS_REPO_TOKEN" ]]; then
# mix coveralls.html --exclude no_parity --parallel --umbrella
# else
# mix coveralls.circle --exclude no_parity --parallel --umbrella ||
# # if mix failed, then coveralls_merge won't run, so signal done here and return original exit status
# (retval=$? && curl -k https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN -d "payload[build_num]=$CIRCLE_WORKFLOW_WORKSPACE_ID&payload[status]=done" && return $retval)
# fi
- store_artifacts:
path: cover/excoveralls.html
- store_test_results:
path: _build/test/junit
# - store_artifacts:
# path: cover/excoveralls.html
# - store_test_results:
# path: _build/test/junit
test_parity_mox:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1-node-browsers
- image: circleci/elixir:1.9.4-node-browsers
environment:
MIX_ENV: test
# match POSTGRES_PASSWORD for postgres image below
@ -507,7 +511,7 @@ jobs:
PGUSER: postgres
ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Parity.Mox"
ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox"
- image: circleci/postgres:10.3-alpine
- image: circleci/postgres:10.10-alpine
environment:
# Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
POSTGRES_DB: explorer_test
@ -552,7 +556,7 @@ jobs:
coveralls_merge:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.9.1
- image: circleci/elixir:1.9.4
environment:
MIX_ENV: test
@ -571,7 +575,7 @@ workflows:
# This unfortunately will only fire if all the tests pass because of how `requires` works
- coveralls_merge:
requires:
- test_parity_http_websocket
# - test_parity_http_websocket
- test_parity_mox
# - test_geth_http_websocket
# - test_geth_mox
@ -591,7 +595,7 @@ workflows:
- eslint
- jest
- sobelow
- test_parity_http_websocket
# - test_parity_http_websocket
- test_parity_mox
# - test_geth_http_websocket
# - test_geth_mox
@ -613,9 +617,9 @@ workflows:
- sobelow:
requires:
- build
- test_parity_http_websocket:
requires:
- build
# - test_parity_http_websocket:
# requires:
# - build
- test_parity_mox:
requires:
- build

@ -1,3 +1,3 @@
elixir 1.9.1-otp-22
erlang 22.0
nodejs 10.11.0
elixir 1.9.4
erlang 22.2
nodejs 12.14.1

@ -1,21 +1,101 @@
## Current
### Features
- [#2875](https://github.com/poanetwork/blockscout/pull/2875) - Save contract code from Parity genesis file
- [#2834](https://github.com/poanetwork/blockscout/pull/2834) - always redirect to checksummed hash
### Fixes
- [#2996](https://github.com/poanetwork/blockscout/pull/2996) - Fix awesomplete lib loading in Firefox
- [#2993](https://github.com/poanetwork/blockscout/pull/2993) - Fix path definition for contract verification endpoint
- [#2990](https://github.com/poanetwork/blockscout/pull/2990) - Fix import of Parity spec file
- [#2989](https://github.com/poanetwork/blockscout/pull/2989) - Introduce API_PATH env var
- [#2988](https://github.com/poanetwork/blockscout/pull/2988) - Fix web manifest accessibility
- [#2967](https://github.com/poanetwork/blockscout/pull/2967) - Fix styles loading for firefox
- [#2950](https://github.com/poanetwork/blockscout/pull/2950) - Add `creationMethod` to `EthereumJSONRPC.Parity.Trace.Action.entry_to_elixir`
- [#2897](https://github.com/poanetwork/blockscout/pull/2897) - remove duplicate indexes
- [#2883](https://github.com/poanetwork/blockscout/pull/2883) - Fix long contracts names
### Chore
- [#2995](https://github.com/poanetwork/blockscout/pull/2995) - Support API_PATH env var in Docker file
## 3.0.0-beta
### Features
- [#2835](https://github.com/poanetwork/blockscout/pull/2835), [#2871](https://github.com/poanetwork/blockscout/pull/2871), [#2872](https://github.com/poanetwork/blockscout/pull/2872), [#2886](https://github.com/poanetwork/blockscout/pull/2886), [#2925](https://github.com/poanetwork/blockscout/pull/2925), [#2936](https://github.com/poanetwork/blockscout/pull/2936), [#2949](https://github.com/poanetwork/blockscout/pull/2949), [#2940](https://github.com/poanetwork/blockscout/pull/2940), [#2958](https://github.com/poanetwork/blockscout/pull/2958) - Add "block_hash" to logs, token_transfers and internal transactions and "pending blocks operations" approach
- [#2975](https://github.com/poanetwork/blockscout/pull/2975) - Refine UX of contracts verification
- [#2926](https://github.com/poanetwork/blockscout/pull/2926) - API endpoint: sum balances except burnt address
- [#2918](https://github.com/poanetwork/blockscout/pull/2918) - Add tokenID for tokentx API action explicitly
### Fixes
- [#2969](https://github.com/poanetwork/blockscout/pull/2969) - Fix contract constructor require msg appearance in constructor arguments encoded view
- [#2964](https://github.com/poanetwork/blockscout/pull/2964) - Fix bug in skipping of constructor arguments in contract verification
- [#2961](https://github.com/poanetwork/blockscout/pull/2961) - Add a guard that addresses is enum in `values` function in `read contract` page
- [#2960](https://github.com/poanetwork/blockscout/pull/2960) - Add BLOCKSCOUT_HOST to docker setup
- [#2956](https://github.com/poanetwork/blockscout/pull/2956) - Add support of 0.6.x version of compiler
- [#2955](https://github.com/poanetwork/blockscout/pull/2955) - Move socket path to env
- [#2938](https://github.com/poanetwork/blockscout/pull/2938) - utf8 copy tx input tooltip
- [#2934](https://github.com/poanetwork/blockscout/pull/2934) - RSK release 1.2.0 breaking changes support
- [#2933](https://github.com/poanetwork/blockscout/pull/2933) - Get rid of deadlock in the query to address_current_token_balance table
- [#2932](https://github.com/poanetwork/blockscout/pull/2932) - fix duplicate websocket connection
- [#2928](https://github.com/poanetwork/blockscout/pull/2928) - Speedup pending block ops int txs to fetch query
- [#2924](https://github.com/poanetwork/blockscout/pull/2924) - Speedup address to logs query
- [#2915](https://github.com/poanetwork/blockscout/pull/2915) - Speedup of blocks_without_reward_query
- [#2914](https://github.com/poanetwork/blockscout/pull/2914) - Reduce execution time of stream_unfetched_token_instances query
- [#2910](https://github.com/poanetwork/blockscout/pull/2910) - Reorganize queries and indexes for internal_transactions table
- [#2908](https://github.com/poanetwork/blockscout/pull/2908) - Fix performance of address page
- [#2906](https://github.com/poanetwork/blockscout/pull/2906) - fix address sum cache
- [#2902](https://github.com/poanetwork/blockscout/pull/2902) - Offset in blocks retrieval for average block time
- [#2900](https://github.com/poanetwork/blockscout/pull/2900) - check fetched instance metadata in multiple places
- [#2899](https://github.com/poanetwork/blockscout/pull/2899) - fix empty buffered task
- [#2887](https://github.com/poanetwork/blockscout/pull/2887) - increase chart loading speed
### Chore
- [#2959](https://github.com/poanetwork/blockscout/pull/2959) - Remove logs from test folder too in the cleaning script
- [#2954](https://github.com/poanetwork/blockscout/pull/2954) - Upgrade absinthe and ecto deps
- [#2947](https://github.com/poanetwork/blockscout/pull/2947) - Upgrade Circle CI postgres Docker image
- [#2946](https://github.com/poanetwork/blockscout/pull/2946) - Fix vulnerable NPM deps
- [#2942](https://github.com/poanetwork/blockscout/pull/2942) - Actualize Docker setup
- [#2896](https://github.com/poanetwork/blockscout/pull/2896) - Disable Parity websockets tests
- [#2873](https://github.com/poanetwork/blockscout/pull/2873) - bump elixir to 1.9.4
## 2.1.1-beta
### Features
- [#2862](https://github.com/poanetwork/blockscout/pull/2862) - Coin total supply from DB API endpoint
- [#2857](https://github.com/poanetwork/blockscout/pull/2857) - Extend getsourcecode API view with new output fields
- [#2822](https://github.com/poanetwork/blockscout/pull/2822) - Estimated address count on the main page, if cache is empty
- [#2821](https://github.com/poanetwork/blockscout/pull/2821) - add autodetection of constructor arguments
- [#2825](https://github.com/poanetwork/blockscout/pull/2825) - separate token transfers and transactions
- [#2787](https://github.com/poanetwork/blockscout/pull/2787) - async fetching of address counters
- [#2791](https://github.com/poanetwork/blockscout/pull/2791) - add ipc client
- [#2449](https://github.com/poanetwork/blockscout/pull/2449) - add ability to send notification events through postgres notify
- [#2822](https://github.com/poanetwork/blockscout/pull/2822) - Estimated address count on the main page, if cache is empty
### Fixes
- [#2864](https://github.com/poanetwork/blockscout/pull/2864) - add token instance metadata type check
- [#2855](https://github.com/poanetwork/blockscout/pull/2855) - Fix favicons load
- [#2854](https://github.com/poanetwork/blockscout/pull/2854) - Fix all npm vulnerabilities
- [#2851](https://github.com/poanetwork/blockscout/pull/2851) - Fix paths for front assets
- [#2843](https://github.com/poanetwork/blockscout/pull/2843) - fix realtime fetcher small skips feature
- [#2841](https://github.com/poanetwork/blockscout/pull/2841) - LUKSO dashboard height fix
- [#2837](https://github.com/poanetwork/blockscout/pull/2837) - fix txlist ordering issue
- [#2830](https://github.com/poanetwork/blockscout/pull/2830) - Fix wrong color of contract icon on xDai chain
- [#2829](https://github.com/poanetwork/blockscout/pull/2829) - Fix for stuck gas limit label and value
- [#2828](https://github.com/poanetwork/blockscout/pull/2828) - Fix for script that clears compilation/launching assets
- [#2800](https://github.com/poanetwork/blockscout/pull/2800) - return not found for not verified contract for token read_contract
- [#2806](https://github.com/poanetwork/blockscout/pull/2806) - Fix blocks fetching on the main page
- [#2803](https://github.com/poanetwork/blockscout/pull/2803) - Fix block validator custom tooltip
- [#2748](https://github.com/poanetwork/blockscout/pull/2748) - Rewrite token updater
- [#2704](https://github.com/poanetwork/blockscout/pull/2704) - refetch null values in token balances
- [#2690](https://github.com/poanetwork/blockscout/pull/2690) - do not stich json rpc config into module for net version cache
### Chore
- [#2878](https://github.com/poanetwork/blockscout/pull/2878) - Decrease loaders showing delay on the main page
- [#2859](https://github.com/poanetwork/blockscout/pull/2859) - Add eth_blockNumber API endpoint to eth_rpc section
- [#2846](https://github.com/poanetwork/blockscout/pull/2846) - Remove networks images preload
- [#2845](https://github.com/poanetwork/blockscout/pull/2845) - Set outline none for nav dropdown item in mobile view (fix for Safari)
- [#2844](https://github.com/poanetwork/blockscout/pull/2844) - Extend external reward types up to 20
- [#2827](https://github.com/poanetwork/blockscout/pull/2827) - Node js 12.13.0 (latest LTS release) support
- [#2818](https://github.com/poanetwork/blockscout/pull/2818) - allow hiding marketcap percentage
- [#2817](https://github.com/poanetwork/blockscout/pull/2817) - move docker integration documentation to blockscout docs
@ -51,8 +131,10 @@
- [#2799](https://github.com/poanetwork/blockscout/pull/2799) - fix catchup fetcher for empty node and db
- [#2783](https://github.com/poanetwork/blockscout/pull/2783) - Fix stuck value and ticker on the token page
- [#2781](https://github.com/poanetwork/blockscout/pull/2781) - optimize txlist json rpc
- [#2777](https://github.com/poanetwork/blockscout/pull/2777) - Remove duplicate blocks from changes_list before import
- [#2770](https://github.com/poanetwork/blockscout/pull/2770) - do not re-fetch token instances without uris
- [#2769](https://github.com/poanetwork/blockscout/pull/2769) - optimize token token transfers query
- [#2768](https://github.com/poanetwork/blockscout/pull/2768) - Remove nonconsensus blocks from cache after internal transactions importing
- [#2761](https://github.com/poanetwork/blockscout/pull/2761) - add indexes for token instances fetching queries
- [#2767](https://github.com/poanetwork/blockscout/pull/2767) - fix websocket subscriptions with token instances
- [#2765](https://github.com/poanetwork/blockscout/pull/2765) - fixed width issue for cards in mobile view for Transaction Details page
@ -95,6 +177,7 @@ fixed menu hovers in dark mode desktop view
- [#2724](https://github.com/poanetwork/blockscout/pull/2724) - fix ci by commenting a line in hackney library
- [#2708](https://github.com/poanetwork/blockscout/pull/2708) - add log index to logs view
- [#2723](https://github.com/poanetwork/blockscout/pull/2723) - get rid of ex_json_schema warnings
- [#2740](https://github.com/poanetwork/blockscout/pull/2740) - add verify contract rpc doc
## 2.0.4-beta

@ -21,7 +21,7 @@ This is a tool for inspecting and analyzing the POA Network blockchain from a we
To get BlockScout Web interface up and running locally:
* Setup `../explorer`
* Set up some default configuration with: `$ cp config/dev.secret.exs.example config/dev.secret.esx`
* Set up some default configuration with: `$ cp config/dev.secret.exs.example config/dev.secret.exs`
* Install Node.js dependencies with `$ cd assets && npm install && cd ..`
* Start Phoenix with `$ mix phx.server` (This can be run from this directory or the project root: the project root is recommended.)

@ -1,5 +1,3 @@
{
presets: [
'env'
]
"presets": ["@babel/preset-env"]
}

@ -3,7 +3,7 @@ $blue: #4b89fb !default;
$success: #34c0ad !default;
body {
font-family: $font-family-sans-serif;
font-family: $font-family;
font-size: 12px;
}

@ -16,6 +16,7 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
// Bootstrap Core CSS
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";
@import "theme/variables";
@ -60,7 +61,6 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
// Custom SCSS
@import "layout";
@import "typography";
@import "images-preload";
@import "code";
@import "helpers";
@import "elements";
@ -110,7 +110,6 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "components/log-search";
@import "components/radio";
@import "components/modal_variables";
@import "components/network-selector";
@import "components/new_smart_contract";
@import "components/radio_big";
@import "components/btn_no_border";

@ -53,14 +53,16 @@ $dashboard-banner-chart-axis-font-color: $dashboard-stats-item-value-color !defa
.dashboard-banner-chart {
flex-grow: 1;
margin: 0 0 35px 0;
margin: 15px 0 20px 0;
max-width: 350px;
position: relative;
min-height: 100px;
height: calc(100% - 86px);
@include media-breakpoint-down(md) {
flex-grow: 0;
margin-bottom: 20px;
margin-top: auto;
margin-top: 20px;
margin-bottom: auto;
max-width: 100%;
}
@ -227,4 +229,4 @@ $dashboard-banner-chart-axis-font-color: $dashboard-stats-item-value-color !defa
font-size: 0.9rem;
}
}
}
}

@ -25,6 +25,7 @@ $navbar-logo-width: auto !default;
.navbar-nav {
.nav-link {
outline: none;
align-items: center;
color: $header-links-color;
display: flex;

@ -10,6 +10,7 @@ $tooltip-color: #fff !default;
border-radius: 5px;
color: $tooltip-color;
padding: 15px;
font-size: 12px;
}
.arrow::before {

@ -1,5 +1,6 @@
// Bootstrap Core CSS
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";
@import "theme/variables-non-critical";

@ -255,11 +255,11 @@ $transition-cont: all 0.4s ease-in-out !default;
// Font, line-height, and color for body text, headings, and more.
// stylelint-disable value-keyword-case
$font-family-sans-serif: Nunito, "Helvetica Neue", Arial, sans-serif,
$font-family: Nunito, "Helvetica Neue", Arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace !default;
$font-family-base: $font-family-sans-serif !default;
$font-family-base: $font-family !default;
// stylelint-enable value-keyword-case
$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`

@ -0,0 +1,7 @@
// general
$primary: #3a6ea7;
$secondary: #558ac3;
$tertiary: #3a6ea7;
$additional-font: #bdbdff;
$btn-line-color: $tertiary; // button border and font color && hover bg color

@ -0,0 +1,84 @@
// general
$primary: #3a6ea7;
$secondary: #558ac3;
$tertiary: #3a6ea7;
$additional-font: #bdbdff;
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: $additional-font;
$footer-item-disc-color: $tertiary;
$footer-social-icon-color: #3a6ea7;
// dashboard
$dashboard-line-color-price: $secondary;
$dashboard-line-color-market: $tertiary;
$dashboard-banner-gradient-start: #7ba4d1;
$dashboard-banner-gradient-end: #3a6ea7;
$dashboard-banner-chart-legend-label-color: $additional-font;
$dashboard-stats-item-label-color: $additional-font;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
$dashboard-banner-network-plain-container-background-color: #2e5884; // stats bg
// navigation
$header-icon-border-color-hover: $tertiary; // top border on hover
$header-icon-color-hover: $tertiary; // nav icon on hover
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: $tertiary; // button border and font color && hover bg color
$btn-copy-color: $tertiary; // btn copy
$btn-qr-color: $tertiary; // btn qr-code
$btn-address-card-icon-color: $tertiary; // btn address color
$btn-contract-color: $tertiary;
//links & tile
$tile-body-a-color: $tertiary;
$tile-type-block-color: $tertiary;
$tile-type-progress-bar-color: $tertiary;
a.tile-title { color: $tertiary !important; }
// card
$card-background-1: $tertiary;
$card-tab-active: $tertiary;
// ETC theme's idiosyncrasies
.layout-container {
.navbar {
box-shadow: 0 0 30px 0 rgba(21, 53, 80, 0.12);
}
.dropdown-item:hover,
.dropdown-item.active,
.dropdown-item:focus {
background-color: rgba($tertiary, .1) !important;
color: $tertiary !important;
}
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
.footer-logo {
filter: brightness(0) invert(1);
}
}
// Badges
$badge-neutral-color: $tertiary;
$badge-neutral-background-color: rgba($tertiary, .1);
$api-text-monospace-color: $tertiary;
// Dark theme
$dark-primary: #8588ff;
$dark-secondary: #4ad7a7;
$dark-primary-alternate: #5b5ed8;

@ -56,6 +56,9 @@ $dashboard-banner-network-stats-static-image: "/images/lukso_dashboard_image.png
$dashboard-banner-network-plain-container-height: 150px;
.layout-container {
.dashboard-banner-container {
height: auto !important;
}
.dashboard-banner-container::after {
display: none;
}

@ -20,4 +20,5 @@
// @import "sokol_variables-non-critical";
// @import "tobalaba_variables-non-critical";
// @import "tomochain_variables-non-critical";
// @import "rsk_variables-non-critical";
// @import "rsk_variables-non-critical";
// @import "ethercore_variables-non-critical";

@ -21,6 +21,7 @@
// @import "tobalaba_variables";
// @import "tomochain_variables";
// @import "rsk_variables";
// @import "ethercore_variables";
// responsive breakpoints
$breakpoint-xs: 320px;

@ -20,9 +20,6 @@ import 'bootstrap'
import './locale'
// support of preload in Firefox
import '../node_modules/fg-loadcss/dist/cssrelpreload.min'
import './pages/address'
import './pages/address/coin_balances'
import './pages/address/transactions'
@ -46,7 +43,6 @@ import './lib/currency'
import './lib/from_now'
import './lib/indexing'
import './lib/loading_element'
import './lib/market_history_chart'
import './lib/pending_transactions_toggle'
import './lib/pretty_json'
import './lib/reload_button'

@ -0,0 +1,18 @@
import $ from 'jquery'
import { formatAllUsdValues, updateAllCalculatedUsdValues } from './lib/currency'
import { createMarketHistoryChart } from './lib/market_history_chart'
import { createCoinBalanceHistoryChart } from './lib/coin_balance_history_chart'
(function () {
const dashboardChartElement = $('[data-chart="marketHistoryChart"]')[0]
const coinBalanceHistoryChartElement = $('[data-chart="coinBalanceHistoryChart"]')[0]
if (dashboardChartElement) {
window.dashboardChart = createMarketHistoryChart(dashboardChartElement)
}
if (coinBalanceHistoryChartElement) {
window.coinBalanceHistoryChart = createCoinBalanceHistoryChart(coinBalanceHistoryChartElement)
}
formatAllUsdValues()
updateAllCalculatedUsdValues()
})()

@ -271,7 +271,7 @@ export function createAsyncLoadStore (reducer, initialState, itemKey) {
})
}
connectElements({store, elements})
connectElements({ store, elements })
firstPageLoad(store)
return store
}
@ -280,20 +280,20 @@ function firstPageLoad (store) {
const $element = $('[data-async-listing]')
function loadItemsNext () {
const path = store.getState().nextPagePath
store.dispatch({type: 'START_REQUEST'})
$.getJSON(path, {type: 'JSON'})
.done(response => store.dispatch(Object.assign({type: 'ITEMS_FETCHED'}, humps.camelizeKeys(response))))
.fail(() => store.dispatch({type: 'REQUEST_ERROR'}))
.always(() => store.dispatch({type: 'FINISH_REQUEST'}))
store.dispatch({ type: 'START_REQUEST' })
$.getJSON(path, { type: 'JSON' })
.done(response => store.dispatch(Object.assign({ type: 'ITEMS_FETCHED' }, humps.camelizeKeys(response))))
.fail(() => store.dispatch({ type: 'REQUEST_ERROR' }))
.always(() => store.dispatch({ type: 'FINISH_REQUEST' }))
}
function loadItemsPrev () {
const path = store.getState().prevPagePath
store.dispatch({type: 'START_REQUEST'})
$.getJSON(path, {type: 'JSON'})
.done(response => store.dispatch(Object.assign({type: 'ITEMS_FETCHED'}, humps.camelizeKeys(response))))
.fail(() => store.dispatch({type: 'REQUEST_ERROR'}))
.always(() => store.dispatch({type: 'FINISH_REQUEST'}))
store.dispatch({ type: 'START_REQUEST' })
$.getJSON(path, { type: 'JSON' })
.done(response => store.dispatch(Object.assign({ type: 'ITEMS_FETCHED' }, humps.camelizeKeys(response))))
.fail(() => store.dispatch({ type: 'REQUEST_ERROR' }))
.always(() => store.dispatch({ type: 'FINISH_REQUEST' }))
}
loadItemsNext()
@ -305,14 +305,14 @@ function firstPageLoad (store) {
$element.on('click', '[data-next-page-button]', (event) => {
event.preventDefault()
loadItemsNext()
store.dispatch({type: 'NAVIGATE_TO_OLDER'})
store.dispatch({ type: 'NAVIGATE_TO_OLDER' })
event.stopImmediatePropagation()
})
$element.on('click', '[data-prev-page-button]', (event) => {
event.preventDefault()
loadItemsPrev()
store.dispatch({type: 'NAVIGATE_TO_NEWER'})
store.dispatch({ type: 'NAVIGATE_TO_NEWER' })
event.stopImmediatePropagation()
})
}
@ -320,6 +320,6 @@ function firstPageLoad (store) {
const $element = $('[data-async-load]')
if ($element.length) {
const store = createStore(asyncReducer)
connectElements({store, elements})
connectElements({ store, elements })
firstPageLoad(store)
}

@ -38,13 +38,13 @@ window.AwesompleteUtil = (function () {
var lv = Array.isArray(data)
? { label: data[0], value: data[1] }
: typeof data === 'object' && 'label' in data && 'value' in data ? data : { label: data, value: data }
return {label: lv.label || lv.value, value: lv.value}
return { label: lv.label || lv.value, value: lv.value }
}
// Helper to send events with detail property.
function _fire (target, name, detail) {
// $.fire uses deprecated methods but other methods don't work in IE11.
return $.fire(target, name, {detail: detail})
return $.fire(target, name, { detail: detail })
}
// Look if there is an exact match or a mismatch, set awe-found, awe-not-found css class and send match events.
@ -74,7 +74,7 @@ window.AwesompleteUtil = (function () {
}
}
// Don't want to change the real input field, emulate a fake one.
fake = {input: {value: ''}}
fake = { input: { value: '' } }
// Determine how this suggestion would look like if it is replaced in the input field,
// it is an exact match if somebody types exactly that.
// Use the fake input here. fake.input.value will contain the result of the replace function.
@ -222,7 +222,7 @@ window.AwesompleteUtil = (function () {
awe.utilprops.url,
awe.utilprops.urlEnd,
awe.utilprops.loadall ? '' : val,
_onLoad.bind({awe: awe, xhr: xhr, queryVal: val}),
_onLoad.bind({ awe: awe, xhr: xhr, queryVal: val }),
xhr
)
} else {
@ -401,15 +401,15 @@ window.AwesompleteUtil = (function () {
// for arrays at top and subtop level
if (level < 2 && prop) {
// if a 'value' is specified and found a mathing property, create extra 'value' property.
if (value && (prop + '.').lastIndexOf(value + '.', 0) === 0) { result['value'] = result[prop] }
if (value && (prop + '.').lastIndexOf(value + '.', 0) === 0) { result.value = result[prop] }
// if a 'label' is specified and found a mathing property, create extra 'label' property.
if (label && (prop + '.').lastIndexOf(label + '.', 0) === 0) { result['label'] = result[prop] }
if (label && (prop + '.').lastIndexOf(label + '.', 0) === 0) { result.label = result[prop] }
}
if (level === 0) {
// Make sure that both value and label properties exist, even if they are nil.
// This is handy with limit 0 or 1 when the result doesn't have to contain an array.
if (value && !('value' in result)) { result['value'] = null }
if (label && !('label' in result)) { result['label'] = null }
if (value && !('value' in result)) { result.value = null }
if (label && !('label' in result)) { result.label = null }
}
return result
}
@ -506,17 +506,18 @@ window.AwesompleteUtil = (function () {
var boundOnKeydown = _onKeydown.bind(awe)
var boundOnInput = _onInput.bind(awe)
var boundSelect = _select.bind(awe)
var boundDetach = _detach.bind({awe: awe,
var boundDetach = _detach.bind({
awe: awe,
boundMatch: boundMatch,
boundOnInput: boundOnInput,
boundOnKeydown: boundOnKeydown,
boundSelect: boundSelect
})
var events = {
'keydown': boundOnKeydown,
'input': boundOnInput
keydown: boundOnKeydown,
input: boundOnInput
}
events['blur'] = events[_AWE_CLOSE] = events[_AWE_LOAD] = boundMatch
events.blur = events[_AWE_CLOSE] = events[_AWE_LOAD] = boundMatch
events[_AWE_SELECT] = boundSelect
$.bind(elem, events)
@ -552,7 +553,7 @@ window.AwesompleteUtil = (function () {
// Create function to copy a field from the selected autocomplete item to another DOM element.
// dataField can be null.
createCopyFun: function (sourceId, dataField, targetId) {
return _copyFun.bind({sourceId: sourceId, dataField: dataField, targetId: $(targetId) || targetId})
return _copyFun.bind({ sourceId: sourceId, dataField: dataField, targetId: $(targetId) || targetId })
},
// attach copy function to event listeners. prepop is optional and by default true.
@ -585,7 +586,7 @@ window.AwesompleteUtil = (function () {
// Create function for combobox button (btnId) to toggle dropdown list.
createClickFun: function (btnId, awe) {
return _clickFun.bind({btnId: btnId, awe: awe})
return _clickFun.bind({ btnId: btnId, awe: awe })
},
// Attach click function for combobox to click event.

@ -17,7 +17,7 @@ $(function () {
const siblings = $(this).siblings()
if (siblings.is(':hidden')) {
siblings.css({ 'display': 'flex' })
siblings.css({ display: 'flex' })
} else {
siblings.hide()
}

@ -3,7 +3,7 @@ import $ from 'jquery'
const clipboard = new ClipboardJS('[data-clipboard-text]')
clipboard.on('success', ({trigger}) => {
clipboard.on('success', ({ trigger }) => {
const copyButton = $(trigger)
copyButton.tooltip('dispose')

@ -8,7 +8,7 @@ export function createCoinBalanceHistoryChart (el) {
const $chartError = $('[data-chart-error-message]')
const dataPath = el.dataset.coin_balance_history_data_path
$.getJSON(dataPath, {type: 'JSON'})
$.getJSON(dataPath, { type: 'JSON' })
.done(data => {
$chartContainer.show()
@ -53,7 +53,7 @@ export function createCoinBalanceHistoryChart (el) {
},
scaleLabel: {
display: true,
labelString: window.localized['Ether']
labelString: window.localized.Ether
}
}]
}

@ -1,8 +1,6 @@
import $ from 'jquery'
import humps from 'humps'
import numeral from 'numeral'
import { BigNumber } from 'bignumber.js'
import socket from '../socket'
export function formatUsdValue (value) {
return `${formatCurrencyValue(value)} USD`
@ -45,6 +43,7 @@ export function formatAllUsdValues (root) {
formatAllUsdValues()
function tryUpdateCalculatedUsdValues (el, usdExchangeRate = el.dataset.usdExchangeRate) {
// eslint-disable-next-line no-prototype-builtins
if (!el.dataset.hasOwnProperty('weiValue')) return
const ether = weiToEther(el.dataset.weiValue)
const usd = etherToUSD(ether, usdExchangeRate)
@ -62,7 +61,3 @@ export function updateAllCalculatedUsdValues (usdExchangeRate) {
$('[data-usd-unit-price]').each((i, el) => tryUpdateUnitPriceValues(el, usdExchangeRate))
}
updateAllCalculatedUsdValues()
export const exchangeRateChannel = socket.channel(`exchange_rate:new_rate`)
exchangeRateChannel.join()
exchangeRateChannel.on('new_rate', (msg) => updateAllCalculatedUsdValues(humps.camelizeKeys(msg).exchangeRate.usdValue))

@ -20,6 +20,6 @@ export function updateIndexStatus (msg = {}) {
}
updateIndexStatus()
const indexingChannel = socket.channel(`blocks:indexing`)
const indexingChannel = socket.channel('blocks:indexing')
indexingChannel.join()
indexingChannel.on('index_status', (msg) => updateIndexStatus(humps.camelizeKeys(msg)))

@ -4,7 +4,6 @@ import humps from 'humps'
import numeral from 'numeral'
import { formatUsdValue } from '../lib/currency'
import sassVariables from '../../css/app.scss'
import { showLoader } from '../lib/utils'
const config = {
type: 'line',
@ -61,7 +60,7 @@ const config = {
mode: 'index',
intersect: false,
callbacks: {
label: ({datasetIndex, yLabel}, {datasets}) => {
label: ({ datasetIndex, yLabel }, { datasets }) => {
const label = datasets[datasetIndex].label
if (datasets[datasetIndex].yAxisID === 'price') {
return `${label}: ${formatUsdValue(yLabel)}`
@ -76,16 +75,36 @@ const config = {
}
}
function getDataFromLocalStorage (key) {
const data = window.localStorage.getItem(key)
return data ? JSON.parse(data) : []
}
function setDataToLocalStorage (key, data) {
window.localStorage.setItem(key, JSON.stringify(data))
}
function getPriceData (marketHistoryData) {
return marketHistoryData.map(({ date, closingPrice }) => ({x: date, y: closingPrice}))
if (marketHistoryData.length === 0) {
return getDataFromLocalStorage('priceData')
}
const data = marketHistoryData.map(({ date, closingPrice }) => ({ x: date, y: closingPrice }))
setDataToLocalStorage('priceData', data)
return data
}
function getMarketCapData (marketHistoryData, availableSupply) {
if (availableSupply !== null && typeof availableSupply === 'object') {
return marketHistoryData.map(({ date, closingPrice }) => ({x: date, y: closingPrice * availableSupply[date]}))
} else {
return marketHistoryData.map(({ date, closingPrice }) => ({x: date, y: closingPrice * availableSupply}))
if (marketHistoryData.length === 0) {
return getDataFromLocalStorage('marketCapData')
}
const data = marketHistoryData.map(({ date, closingPrice }) => {
const supply = (availableSupply !== null && typeof availableSupply === 'object')
? availableSupply[date]
: availableSupply
return { x: date, y: closingPrice * supply }
})
setDataToLocalStorage('marketCapData', data)
return data
}
// colors for light and dark theme
@ -102,7 +121,7 @@ if (localStorage.getItem('current-color-mode') === 'dark') {
class MarketHistoryChart {
constructor (el, availableSupply, marketHistoryData) {
this.price = {
label: window.localized['Price'],
label: window.localized.Price,
yAxisID: 'price',
data: getPriceData(marketHistoryData),
fill: false,
@ -123,8 +142,18 @@ class MarketHistoryChart {
}
this.availableSupply = availableSupply
config.data.datasets = [this.price, this.marketCap]
const isChartLoadedKey = 'isChartLoaded'
const isChartLoaded = window.sessionStorage.getItem(isChartLoadedKey) === 'true'
if (isChartLoaded) {
config.options.animation = false
} else {
window.sessionStorage.setItem(isChartLoadedKey, true)
}
this.chart = new Chart(el, config)
}
update (availableSupply, marketHistoryData) {
this.price.data = getPriceData(marketHistoryData)
if (this.availableSupply !== null && typeof this.availableSupply === 'object') {
@ -140,32 +169,24 @@ class MarketHistoryChart {
export function createMarketHistoryChart (el) {
const dataPath = el.dataset.market_history_chart_path
const $chartLoading = $('[data-chart-loading-message]')
const isTimeout = true
const timeoutID = showLoader(isTimeout, $chartLoading)
const $chartError = $('[data-chart-error-message]')
const chart = new MarketHistoryChart(el, 0, [])
$.getJSON(dataPath, {type: 'JSON'})
$(el).show()
$.getJSON(dataPath, { type: 'JSON' })
.done(data => {
const availableSupply = JSON.parse(data.supply_data)
const marketHistoryData = humps.camelizeKeys(JSON.parse(data.history_data))
$(el).show()
chart.update(availableSupply, marketHistoryData)
})
.fail(() => {
$(el).hide()
$chartError.show()
})
.always(() => {
$chartLoading.hide()
clearTimeout(timeoutID)
})
return chart
}
$('[data-chart-error-message]').on('click', _event => {
$('[data-chart-loading-message]').show()
$('[data-chart-error-message]').hide()
createMarketHistoryChart($('[data-chart="marketHistoryChart"]')[0])
})

@ -1,5 +1,4 @@
import $ from 'jquery'
import Chart from 'chart.js'
$(function () {
$('.js-become-candidate').on('click', function () {
@ -43,34 +42,34 @@ $(function () {
})
function setupStakesProgress (progress, total, modal) {
const stakeProgress = $(`${modal} .js-stakes-progress`)
const primaryColor = $('.btn-full-primary').css('background-color')
const backgroundColors = [
primaryColor,
'rgba(202, 199, 226, 0.5)'
]
const progressBackground = total - progress
// const stakeProgress = $(`${modal} .js-stakes-progress`)
// const primaryColor = $('.btn-full-primary').css('background-color')
// const backgroundColors = [
// primaryColor,
// 'rgba(202, 199, 226, 0.5)'
// ]
// const progressBackground = total - progress
// eslint-disable-next-line no-unused-vars
let myChart = new Chart(stakeProgress, {
type: 'doughnut',
data: {
datasets: [{
data: [progress, progressBackground],
backgroundColor: backgroundColors,
hoverBackgroundColor: backgroundColors,
borderWidth: 0
}]
},
options: {
cutoutPercentage: 80,
legend: {
display: false
},
tooltips: {
enabled: false
}
}
})
// // eslint-disable-next-line no-unused-vars
// const myChart = new window.Chart(stakeProgress, {
// type: 'doughnut',
// data: {
// datasets: [{
// data: [progress, progressBackground],
// backgroundColor: backgroundColors,
// hoverBackgroundColor: backgroundColors,
// borderWidth: 0
// }]
// },
// options: {
// cutoutPercentage: 80,
// legend: {
// display: false
// },
// tooltips: {
// enabled: false
// }
// }
// })
}
})

@ -36,7 +36,7 @@ $(function () {
window.location = $(this).attr('network-selector-item-url')
})
let setNetworkTab = (currentTab) => {
const setNetworkTab = (currentTab) => {
if (currentTab.hasClass('active')) return
networkSelectorTab.removeClass('active')
@ -45,31 +45,31 @@ $(function () {
$(`[network-selector-tab="${currentTab.attr('network-selector-tab-filter')}"]`).addClass('active')
}
let openNetworkSelector = () => {
const openNetworkSelector = () => {
mainBody.addClass('network-selector-visible')
networkSelectorOverlay.fadeIn(FADE_IN_DELAY)
setNetworkSelectorVisiblePosition()
}
let closeNetworkSelector = () => {
const closeNetworkSelector = () => {
mainBody.removeClass('network-selector-visible')
networkSelectorOverlay.fadeOut(FADE_IN_DELAY)
setNetworkSelectorHiddenPosition()
}
let getNetworkSelectorWidth = () => {
const getNetworkSelectorWidth = () => {
return parseInt(networkSelector.css('width')) || parseInt(networkSelector.css('max-width'))
}
let setNetworkSelectorHiddenPosition = () => {
return networkSelector.css({ 'right': `-${getNetworkSelectorWidth()}px` })
const setNetworkSelectorHiddenPosition = () => {
return networkSelector.css({ right: `-${getNetworkSelectorWidth()}px` })
}
let setNetworkSelectorVisiblePosition = () => {
return networkSelector.css({ 'right': '0' })
const setNetworkSelectorVisiblePosition = () => {
return networkSelector.css({ right: '0' })
}
let init = () => {
const init = () => {
setNetworkSelectorHiddenPosition()
}

@ -1,8 +1,8 @@
import $ from 'jquery'
function prettyPrint (element) {
let jsonString = element.dataset.json
let pretty = JSON.stringify(JSON.parse(jsonString), undefined, 2)
const jsonString = element.dataset.json
const pretty = JSON.stringify(JSON.parse(jsonString), undefined, 2)
element.innerHTML = pretty
}

@ -44,8 +44,9 @@ function parseInput (input) {
}
}
function dropDomain (url) {
return new URL(url).pathname
function composeRequestUrl () {
const url = $('[data-endpoint-url]').attr('data-endpoint-url')
return url
}
$('button[data-try-eth-api-ui-button-type="execute"]').click(event => {
@ -64,10 +65,8 @@ $('button[data-try-eth-api-ui-button-type="execute"]').click(event => {
clickedButton.html(loadingText)
}
const url = $('[data-endpoint-url]').attr('data-endpoint-url')
$.ajax({
url: dropDomain(url),
url: composeRequestUrl(),
type: 'POST',
data: JSON.stringify(formData),
dataType: 'json',

@ -17,7 +17,7 @@ export function showLoader (isTimeout, loader) {
const timeout = setTimeout(function () {
loader.removeAttr('hidden')
loader.show()
}, 1000)
}, 100)
return timeout
} else {
loader.hide()

@ -102,7 +102,7 @@ const elements = {
},
'[data-selector="fetched-coin-balance-block-number"]': {
load ($el) {
return {fetchedCoinBalanceBlockNumber: numeral($el.text()).value()}
return { fetchedCoinBalanceBlockNumber: numeral($el.text()).value() }
},
render ($el, state, oldState) {
if (oldState.fetchedCoinBalanceBlockNumber === state.fetchedCoinBalanceBlockNumber) return
@ -131,7 +131,7 @@ function loadCounters (store) {
function fetchCounters () {
$.getJSON(path)
.done(response => store.dispatch(Object.assign({type: 'COUNTERS_FETCHED'}, humps.camelizeKeys(response))))
.done(response => store.dispatch(Object.assign({ type: 'COUNTERS_FETCHED' }, humps.camelizeKeys(response))))
}
fetchCounters()

@ -4,7 +4,6 @@ import humps from 'humps'
import socket from '../../socket'
import { connectElements } from '../../lib/redux_helpers.js'
import { createAsyncLoadStore } from '../../lib/async_listing_load'
import { createCoinBalanceHistoryChart } from '../../lib/coin_balance_history_chart'
export const initialState = {
channelDisconnected: false
@ -47,7 +46,7 @@ if ($('[data-page="coin-balance-history"]').length) {
const store = createAsyncLoadStore(reducer, initialState, 'dataset.blockNumber')
const addressHash = $('[data-page="address-details"]')[0].dataset.pageAddressHash
store.dispatch({type: 'PAGE_LOAD', addressHash})
store.dispatch({ type: 'PAGE_LOAD', addressHash })
connectElements({ store, elements })
const addressChannel = socket.channel(`addresses:${addressHash}`, {})
@ -61,9 +60,4 @@ if ($('[data-page="coin-balance-history"]').length) {
msg: humps.camelizeKeys(msg)
})
})
const chartContainer = $('[data-chart="coinBalanceHistoryChart"]')[0]
if (chartContainer) {
createCoinBalanceHistoryChart(chartContainer)
}
}

@ -34,7 +34,7 @@ export function reducer (state, action) {
if (state.channelDisconnected || state.beyondPageOne) return state
const incomingInternalTransactions = action.msgs
.filter(({toAddressHash, fromAddressHash}) => (
.filter(({ toAddressHash, fromAddressHash }) => (
!state.filter ||
(state.filter === 'to' && toAddressHash === state.addressHash) ||
(state.filter === 'from' && fromAddressHash === state.addressHash)
@ -81,7 +81,7 @@ if ($('[data-page="address-internal-transactions"]').length) {
const store = createAsyncLoadStore(reducer, initialState, 'dataset.key')
const addressHash = $('[data-page="address-details"]')[0].dataset.pageAddressHash
store.dispatch({type: 'PAGE_LOAD', addressHash})
store.dispatch({ type: 'PAGE_LOAD', addressHash })
connectElements({ store, elements })
const addressChannel = socket.channel(`addresses:${addressHash}`, {})

@ -16,7 +16,7 @@ export function reducer (state, action) {
return Object.assign({}, state, omit(action, 'type'))
}
case 'START_SEARCH': {
return Object.assign({}, state, {pagesStack: [], isSearch: true})
return Object.assign({}, state, { pagesStack: [], isSearch: true })
}
default:
return state
@ -63,19 +63,21 @@ if ($('[data-page="address-logs"]').length) {
store.dispatch({
type: 'PAGE_LOAD',
addressHash: addressHash})
addressHash: addressHash
})
$element.on('click', '[data-search-button]', (event) => {
store.dispatch({
type: 'START_SEARCH',
addressHash: addressHash})
addressHash: addressHash
})
var topic = $('[data-search-field]').val()
var path = '/search_logs?topic=' + topic + '&address_id=' + store.getState().addressHash
store.dispatch({type: 'START_REQUEST'})
$.getJSON(path, {type: 'JSON'})
.done(response => store.dispatch(Object.assign({type: 'ITEMS_FETCHED'}, humps.camelizeKeys(response))))
.fail(() => store.dispatch({type: 'REQUEST_ERROR'}))
.always(() => store.dispatch({type: 'FINISH_REQUEST'}))
store.dispatch({ type: 'START_REQUEST' })
$.getJSON(path, { type: 'JSON' })
.done(response => store.dispatch(Object.assign({ type: 'ITEMS_FETCHED' }, humps.camelizeKeys(response))))
.fail(() => store.dispatch({ type: 'REQUEST_ERROR' }))
.always(() => store.dispatch({ type: 'FINISH_REQUEST' }))
})
$element.on('click', '[data-cancel-search-button]', (event) => {

@ -32,12 +32,12 @@ export function reducer (state, action) {
return state
}
return Object.assign({}, state, { items: [ action.msg.transactionHtml, ...state.items ] })
return Object.assign({}, state, { items: [action.msg.transactionHtml, ...state.items] })
}
case 'RECEIVED_NEW_REWARD': {
if (state.channelDisconnected) return state
return Object.assign({}, state, { items: [ action.msg.rewardHtml, ...state.items ] })
return Object.assign({}, state, { items: [action.msg.rewardHtml, ...state.items] })
}
default:
return state

@ -91,7 +91,7 @@ if ($blockListPage.length || $uncleListPage.length || $reorgListPage.length) {
)
connectElements({ store, elements })
const blocksChannel = socket.channel(`blocks:new_block`, {})
const blocksChannel = socket.channel('blocks:new_block', {})
blocksChannel.join()
blocksChannel.onError(() => store.dispatch({
type: 'CHANNEL_DISCONNECTED'

@ -7,11 +7,10 @@ import map from 'lodash/map'
import humps from 'humps'
import numeral from 'numeral'
import socket from '../socket'
import { exchangeRateChannel, formatUsdValue } from '../lib/currency'
import { updateAllCalculatedUsdValues, formatUsdValue } from '../lib/currency'
import { createStore, connectElements } from '../lib/redux_helpers.js'
import { batchChannel, showLoader } from '../lib/utils'
import listMorph from '../lib/list_morph'
import { createMarketHistoryChart } from '../lib/market_history_chart'
const BATCH_THRESHOLD = 6
@ -142,8 +141,8 @@ function withMissingBlocks (reducer) {
let chart
const elements = {
'[data-chart="marketHistoryChart"]': {
load ($el) {
chart = createMarketHistoryChart($el[0])
load () {
chart = window.dashboardChart
},
render ($el, state, oldState) {
if (!chart || (oldState.availableSupply === state.availableSupply && oldState.marketHistoryData === state.marketHistoryData) || !state.availableSupply) return
@ -259,26 +258,31 @@ if ($chainDetailsPage.length) {
loadBlocks(store)
bindBlockErrorMessage(store)
exchangeRateChannel.on('new_rate', (msg) => store.dispatch({
type: 'RECEIVED_NEW_EXCHANGE_RATE',
msg: humps.camelizeKeys(msg)
}))
const exchangeRateChannel = socket.channel('exchange_rate:new_rate')
exchangeRateChannel.join()
exchangeRateChannel.on('new_rate', (msg) => {
updateAllCalculatedUsdValues(humps.camelizeKeys(msg).exchangeRate.usdValue)
store.dispatch({
type: 'RECEIVED_NEW_EXCHANGE_RATE',
msg: humps.camelizeKeys(msg)
})
})
const addressesChannel = socket.channel(`addresses:new_address`)
const addressesChannel = socket.channel('addresses:new_address')
addressesChannel.join()
addressesChannel.on('count', msg => store.dispatch({
type: 'RECEIVED_NEW_ADDRESS_COUNT',
msg: humps.camelizeKeys(msg)
}))
const blocksChannel = socket.channel(`blocks:new_block`)
const blocksChannel = socket.channel('blocks:new_block')
blocksChannel.join()
blocksChannel.on('new_block', msg => store.dispatch({
type: 'RECEIVED_NEW_BLOCK',
msg: humps.camelizeKeys(msg)
}))
const transactionsChannel = socket.channel(`transactions:new_transaction`)
const transactionsChannel = socket.channel('transactions:new_transaction')
transactionsChannel.join()
transactionsChannel.on('transaction', batchChannel((msgs) => store.dispatch({
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
@ -288,11 +292,11 @@ if ($chainDetailsPage.length) {
function loadTransactions (store) {
const path = store.getState().transactionsPath
store.dispatch({type: 'START_TRANSACTIONS_FETCH'})
store.dispatch({ type: 'START_TRANSACTIONS_FETCH' })
$.getJSON(path)
.done(response => store.dispatch({type: 'TRANSACTIONS_FETCHED', msg: humps.camelizeKeys(response)}))
.fail(() => store.dispatch({type: 'TRANSACTIONS_FETCH_ERROR'}))
.always(() => store.dispatch({type: 'FINISH_TRANSACTIONS_FETCH'}))
.done(response => store.dispatch({ type: 'TRANSACTIONS_FETCHED', msg: humps.camelizeKeys(response) }))
.fail(() => store.dispatch({ type: 'TRANSACTIONS_FETCH_ERROR' }))
.always(() => store.dispatch({ type: 'FINISH_TRANSACTIONS_FETCH' }))
}
function bindTransactionErrorMessage (store) {
@ -325,14 +329,14 @@ export function placeHolderBlock (blockNumber) {
function loadBlocks (store) {
const url = store.getState().blocksPath
store.dispatch({type: 'START_BLOCKS_FETCH'})
store.dispatch({ type: 'START_BLOCKS_FETCH' })
$.getJSON(url)
.done(response => {
store.dispatch({type: 'BLOCKS_FETCHED', msg: humps.camelizeKeys(response)})
store.dispatch({ type: 'BLOCKS_FETCHED', msg: humps.camelizeKeys(response) })
})
.fail(() => store.dispatch({type: 'BLOCKS_REQUEST_ERROR'}))
.always(() => store.dispatch({type: 'BLOCKS_FINISH_REQUEST'}))
.fail(() => store.dispatch({ type: 'BLOCKS_REQUEST_ERROR' }))
.always(() => store.dispatch({ type: 'BLOCKS_FINISH_REQUEST' }))
}
function bindBlockErrorMessage (store) {

@ -102,7 +102,7 @@ if ($transactionPendingListPage.length) {
const store = createAsyncLoadStore(reducer, initialState, 'dataset.identifierHash')
connectElements({ store, elements })
const transactionsChannel = socket.channel(`transactions:new_transaction`)
const transactionsChannel = socket.channel('transactions:new_transaction')
transactionsChannel.join()
transactionsChannel.onError(() => store.dispatch({
type: 'CHANNEL_DISCONNECTED'
@ -118,7 +118,7 @@ if ($transactionPendingListPage.length) {
}), 1000)
})
const pendingTransactionsChannel = socket.channel(`transactions:new_pending_transaction`)
const pendingTransactionsChannel = socket.channel('transactions:new_pending_transaction')
pendingTransactionsChannel.join()
pendingTransactionsChannel.onError(() => store.dispatch({
type: 'CHANNEL_DISCONNECTED'

@ -68,11 +68,11 @@ function loadCounters (store) {
const $element = $('[data-async-counters]')
const path = $element.data() && $element.data().asyncCounters
function fetchCounters () {
store.dispatch({type: 'START_REQUEST'})
store.dispatch({ type: 'START_REQUEST' })
$.getJSON(path)
.done(response => store.dispatch(Object.assign({type: 'COUNTERS_FETCHED'}, humps.camelizeKeys(response))))
.fail(() => store.dispatch({type: 'REQUEST_ERROR'}))
.always(() => store.dispatch({type: 'FINISH_REQUEST'}))
.done(response => store.dispatch(Object.assign({ type: 'COUNTERS_FETCHED' }, humps.camelizeKeys(response))))
.fail(() => store.dispatch({ type: 'REQUEST_ERROR' }))
.always(() => store.dispatch({ type: 'FINISH_REQUEST' }))
}
fetchCounters()

@ -47,7 +47,7 @@ if ($transactionDetailsPage.length) {
const store = createStore(reducer)
connectElements({ store, elements })
const blocksChannel = socket.channel(`blocks:new_block`, {})
const blocksChannel = socket.channel('blocks:new_block', {})
blocksChannel.join()
blocksChannel.on('new_block', (msg) => store.dispatch({
type: 'RECEIVED_NEW_BLOCK',

@ -85,7 +85,7 @@ if ($transactionListPage.length) {
connectElements({ store, elements })
const transactionsChannel = socket.channel(`transactions:new_transaction`)
const transactionsChannel = socket.channel('transactions:new_transaction')
transactionsChannel.join()
transactionsChannel.onError(() => store.dispatch({
type: 'CHANNEL_DISCONNECTED'

@ -67,7 +67,7 @@ const elements = {
})
$('.js-btn-add-contract-library').on('click', function () {
let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group')
const nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group')
if (nextContractLibrary) {
nextContractLibrary.addClass('active')
@ -88,6 +88,26 @@ const elements = {
const $contractVerificationPage = $('[data-page="contract-verification"]')
function filterNightlyBuilds (filter) {
var select, options
select = document.getElementById('smart_contract_compiler_version')
options = select.getElementsByTagName('option')
for (const option of options) {
var txtValue = option.textContent || option.innerText
if (filter) {
if (txtValue.toLowerCase().indexOf('nightly') > -1) {
option.style.display = 'none'
} else {
option.style.display = ''
}
} else {
if (txtValue.toLowerCase().indexOf('nightly') > -1) {
option.style.display = ''
}
}
}
}
if ($contractVerificationPage.length) {
const store = createStore(reducer)
const addressHash = $('#smart_contract_address_hash').val()
@ -116,11 +136,39 @@ if ($contractVerificationPage.length) {
})
$(function () {
setTimeout(function () {
$('.nightly-builds-false').trigger('click')
}, 10)
$('.js-btn-add-contract-libraries').on('click', function () {
$('.js-smart-contract-libraries-wrapper').show()
$(this).hide()
})
$('.autodetectfalse').on('click', function () {
if ($(this).prop('checked')) { $('.constructor-arguments').show() }
})
$('.autodetecttrue').on('click', function () {
if ($(this).prop('checked')) { $('.constructor-arguments').hide() }
})
$('.nightly-builds-true').on('click', function () {
if ($(this).prop('checked')) { filterNightlyBuilds(false) }
})
$('.nightly-builds-false').on('click', function () {
if ($(this).prop('checked')) { filterNightlyBuilds(true) }
})
$('.optimization-false').on('click', function () {
if ($(this).prop('checked')) { $('.optimization-runs').hide() }
})
$('.optimization-true').on('click', function () {
if ($(this).prop('checked')) { $('.optimization-runs').show() }
})
$('.js-smart-contract-form-reset').on('click', function () {
$('.js-contract-library-form-group').removeClass('active')
$('.js-contract-library-form-group').first().addClass('active')
@ -130,7 +178,7 @@ if ($contractVerificationPage.length) {
})
$('.js-btn-add-contract-library').on('click', function () {
let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group')
const nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group')
if (nextContractLibrary) {
nextContractLibrary.addClass('active')

@ -1,7 +1,12 @@
import {Socket} from 'phoenix'
import {locale} from './locale'
import { Socket } from 'phoenix'
import { locale } from './locale'
const socket = new Socket('/socket', {params: {locale: locale}})
let websocketRootUrl = process.env.SOCKET_ROOT
if (!websocketRootUrl || websocketRootUrl === '/') {
websocketRootUrl = ''
}
const socket = new Socket(websocketRootUrl + '/socket', { params: { locale: locale } })
socket.connect()
export default socket

File diff suppressed because it is too large Load Diff

@ -8,8 +8,8 @@
"author": "POA Network",
"license": "GPL-3.0",
"engines": {
"node": "9.x",
"npm": "5.x"
"node": "12.x",
"npm": "6.x"
},
"scripts": {
"deploy": "webpack --mode production",
@ -21,52 +21,51 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^5.1.0-4",
"awesomplete": "1.1.2",
"bignumber.js": "^7.2.1",
"bootstrap": "^4.1.3",
"chart.js": "^2.7.2",
"clipboard": "^2.0.1",
"fg-loadcss": "^2.1.0",
"highlight.js": "^9.13.1",
"highlightjs-solidity": "^1.0.6",
"bignumber.js": "^9.0.0",
"bootstrap": "^4.3.1",
"chart.js": "^2.9.2",
"clipboard": "^2.0.4",
"highlight.js": "^9.16.2",
"highlightjs-solidity": "^1.0.8",
"humps": "^2.0.1",
"jquery": "^3.4.0",
"lodash": "^4.17.15",
"moment": "^2.22.1",
"nanomorph": "^5.1.3",
"moment": "^2.24.0",
"nanomorph": "^5.4.0",
"numeral": "^2.0.6",
"path-parser": "^4.1.1",
"path-parser": "^4.2.0",
"phoenix": "file:../../../deps/phoenix",
"phoenix_html": "file:../../../deps/phoenix_html",
"popper.js": "^1.14.3",
"popper.js": "^1.14.7",
"reduce-reducers": "^0.4.3",
"redux": "^4.0.0",
"urijs": "^1.19.1"
"urijs": "^1.19.2"
},
"devDependencies": {
"@babel/polyfill": "^7.0.0-beta.46",
"@babel/core": "^7.7.2",
"@babel/polyfill": "^7.7.0",
"@babel/preset-env": "^7.7.1",
"autoprefixer": "^8.4.1",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"copy-webpack-plugin": "^4.5.1",
"babel-loader": "^8.0.6",
"copy-webpack-plugin": "^5.0.5",
"css-loader": "^3.1.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^11.0.0-beta.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-standard": "^3.0.1",
"file-loader": "^1.1.11",
"jest": "^23.2.0",
"eslint": "^6.6.0",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"file-loader": "^4.2.0",
"jest": "^24.9.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.12.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^2.1.4",
"sass-loader": "^7.1.0",
"style-loader": "^0.21.0",
"terser-webpack-plugin": "^1.3.0",
"webpack": "^4.6.0",
"webpack-cli": "^3.0.8"
"postcss-loader": "^3.0.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"terser-webpack-plugin": "^2.2.1",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
},
"jest": {
"moduleNameMapper": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 762 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

@ -1,10 +1,11 @@
const path = require('path');
const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { ContextReplacementPlugin } = require('webpack');
const glob = require("glob");
const path = require('path')
const TerserJSPlugin = require('terser-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { ContextReplacementPlugin } = require('webpack')
const glob = require('glob')
const webpack = require('webpack')
function transpileViewScript(file) {
return {
@ -19,9 +20,12 @@ function transpileViewScript(file) {
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
}
]
}
}
@ -30,7 +34,7 @@ function transpileViewScript(file) {
const jsOptimizationParams = {
cache: true,
parallel: true,
sourceMap: true,
sourceMap: true
}
const awesompleteJs = {
@ -51,19 +55,19 @@ const awesompleteJs = {
{
loader: "css-loader",
}
],
},
],
]
}
]
},
optimization: {
minimizer: [
new TerserJSPlugin(jsOptimizationParams),
],
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '../css/awesomplete.css'
}),
})
]
}
@ -72,7 +76,8 @@ const appJs =
entry: {
app: './js/app.js',
stakes: './js/pages/stakes.js',
'non-critical': './css/non-critical.scss',
'chart-loader': './js/chart-loader.js',
'non-critical': './css/non-critical.scss'
},
output: {
filename: '[name].js',
@ -87,7 +92,10 @@ const appJs =
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
@ -95,17 +103,19 @@ const appJs =
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader"
loader: 'css-loader'
}, {
loader: "postcss-loader"
loader: 'postcss-loader'
}, {
loader: "sass-loader",
loader: 'sass-loader',
options: {
precision: 8,
includePaths: [
'node_modules/bootstrap/scss',
'node_modules/@fortawesome/fontawesome-free/scss'
]
sassOptions: {
precision: 8,
includePaths: [
'node_modules/bootstrap/scss',
'node_modules/@fortawesome/fontawesome-free/scss'
]
}
}
}
]
@ -127,10 +137,13 @@ const appJs =
filename: '../css/[name].css'
}),
new CopyWebpackPlugin([{ from: 'static/', to: '../' }]),
new ContextReplacementPlugin(/moment[\/\\]locale$/, /en/)
new ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
new webpack.DefinePlugin({
'process.env.SOCKET_ROOT': JSON.stringify(process.env.SOCKET_ROOT)
})
]
}
const viewScripts = glob.sync('./js/view_specific/**/*.js').map(transpileViewScript);
const viewScripts = glob.sync('./js/view_specific/**/*.js').map(transpileViewScript)
module.exports = viewScripts.concat(appJs, awesompleteJs);
module.exports = viewScripts.concat(appJs, awesompleteJs)

@ -42,7 +42,8 @@ config :block_scout_web, BlockScoutWeb.Endpoint,
url: [
scheme: System.get_env("BLOCKSCOUT_PROTOCOL") || "http",
host: System.get_env("BLOCKSCOUT_HOST") || "localhost",
path: System.get_env("NETWORK_PATH") || "/"
path: System.get_env("NETWORK_PATH") || "/",
api_path: System.get_env("API_PATH") || "/"
],
render_errors: [view: BlockScoutWeb.ErrorView, accepts: ~w(html json)],
pubsub: [name: BlockScoutWeb.PubSub]

@ -21,7 +21,8 @@ config :block_scout_web, BlockScoutWeb.Endpoint,
url: [
scheme: "http",
host: System.get_env("BLOCKSCOUT_HOST") || "localhost",
path: System.get_env("NETWORK_PATH") || "/"
path: System.get_env("NETWORK_PATH") || "/",
api_path: System.get_env("API_PATH") || "/"
],
https: [
port: (port && port + 1) || 4001,

@ -23,7 +23,8 @@ config :block_scout_web, BlockScoutWeb.Endpoint,
scheme: System.get_env("BLOCKSCOUT_PROTOCOL") || "https",
port: System.get_env("PORT"),
host: System.get_env("BLOCKSCOUT_HOST") || "localhost",
path: System.get_env("NETWORK_PATH") || "/"
path: System.get_env("NETWORK_PATH") || "/",
api_path: System.get_env("API_PATH") || "/"
]
config :block_scout_web, BlockScoutWeb.Tracer, env: "production", disabled?: true

@ -8,7 +8,20 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
alias Phoenix.View
import BlockScoutWeb.Chain,
only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1]
only: [current_filter: 1, next_page_params: 3, paging_options: 1, split_list_by_page: 1]
@transaction_necessity_by_association [
necessity_by_association: %{
[created_contract_address: :names] => :optional,
[from_address: :names] => :optional,
[to_address: :names] => :optional,
[token_transfers: :token] => :optional,
[token_transfers: :to_address] => :optional,
[token_transfers: :from_address] => :optional,
[token_transfers: :token_contract_address] => :optional,
:block => :required
}
]
def index(
conn,
@ -93,4 +106,86 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
not_found(conn)
end
end
def index(
conn,
%{
"address_id" => address_hash_string,
"type" => "JSON"
} = params
) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
options =
@transaction_necessity_by_association
|> Keyword.merge(paging_options(params))
|> Keyword.merge(current_filter(params))
transactions =
Chain.address_hash_to_token_transfers(
address_hash,
options
)
{transactions_paginated, next_page} = split_list_by_page(transactions)
next_page_path =
case next_page_params(next_page, transactions_paginated, params) do
nil ->
nil
next_page_params ->
address_token_transfers_path(
conn,
:index,
address_hash_string,
Map.delete(next_page_params, "type")
)
end
transfers_json =
Enum.map(transactions_paginated, fn transaction ->
View.render_to_string(
TransactionView,
"_tile.html",
conn: conn,
transaction: transaction,
current_address: address
)
end)
json(conn, %{items: transfers_json, next_page_path: next_page_path})
else
:error ->
unprocessable_entity(conn)
{:error, :not_found} ->
not_found(conn)
end
end
def index(
conn,
%{"address_id" => address_hash_string} = params
) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
render(
conn,
"index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
filter: params["filter"],
current_path: current_path(conn),
counters_path: address_path(conn, :address_counters, %{"id" => to_string(address_hash)})
)
else
:error ->
unprocessable_entity(conn)
{:error, :not_found} ->
not_found(conn)
end
end
end

@ -19,10 +19,6 @@ defmodule BlockScoutWeb.AddressTransactionController do
[created_contract_address: :names] => :optional,
[from_address: :names] => :optional,
[to_address: :names] => :optional,
[token_transfers: :token] => :optional,
[token_transfers: :to_address] => :optional,
[token_transfers: :from_address] => :optional,
[token_transfers: :token_contract_address] => :optional,
:block => :required
}
]

@ -1,7 +1,10 @@
defmodule BlockScoutWeb.API.RPC.StatsController do
use BlockScoutWeb, :controller
use Explorer.Schema
alias Explorer.{Chain, ExchangeRates}
alias Explorer.Chain.Cache.{AddressSum, AddressSumMinusBurnt}
alias Explorer.Chain.Wei
def tokensupply(conn, params) do
@ -21,7 +24,7 @@ defmodule BlockScoutWeb.API.RPC.StatsController do
end
end
def ethsupply(conn, _params) do
def ethsupplyexchange(conn, _params) do
wei_total_supply =
Chain.total_supply()
|> Decimal.new()
@ -29,7 +32,23 @@ defmodule BlockScoutWeb.API.RPC.StatsController do
|> Wei.to(:wei)
|> Decimal.to_string()
render(conn, "ethsupply.json", total_supply: wei_total_supply)
render(conn, "ethsupplyexchange.json", total_supply: wei_total_supply)
end
def ethsupply(conn, _params) do
cached_wei_total_supply = AddressSum.get_sum()
render(conn, "ethsupply.json", total_supply: cached_wei_total_supply)
end
def coinsupply(conn, _params) do
cached_coin_total_supply_wei = AddressSumMinusBurnt.get_sum_minus_burnt()
cached_coin_total_supply =
%Wei{value: Decimal.new(cached_coin_total_supply_wei)}
|> Wei.to(:ether)
render(conn, "coinsupply.json", cached_coin_total_supply)
end
def ethprice(conn, _params) do

@ -27,14 +27,11 @@ defmodule BlockScoutWeb.Endpoint do
android-chrome-512x512.png
apple-touch-icon.png
browserconfig.xml
favicon.ico
favicon-16x16.png
favicon-32x32.png
mstile-150x150.png
safari-pinned-tab.svg
site.manifest
robots.txt
)
),
only_matching: ~w(manifest)
)
# Code reloading can be explicitly enabled under the

@ -261,12 +261,20 @@ defmodule BlockScoutWeb.Etherscan do
"result" => "21265524714464"
}
@stats_ethsupplyexchange_example_value %{
"status" => "1",
"message" => "OK",
"result" => "101959776311500000000000000"
}
@stats_ethsupply_example_value %{
"status" => "1",
"message" => "OK",
"result" => "101959776311500000000000000"
}
@stats_coinsupply_example_value 101_959_776.3115
@stats_ethprice_example_value %{
"status" => "1",
"message" => "OK",
@ -299,7 +307,7 @@ defmodule BlockScoutWeb.Etherscan do
@block_eth_block_number_example_value %{
"jsonrpc" => "2.0",
"result" => "767969",
"result" => "0xb33bf1",
"id" => 1
}
@ -583,6 +591,12 @@ defmodule BlockScoutWeb.Etherscan do
example: ~s("Some Token Name")
}
@token_id_type %{
type: "integer",
definition: "id of token",
example: ~s("0")
}
@token_symbol_type %{
type: "string",
definition: "Trading symbol of the token.",
@ -746,6 +760,7 @@ defmodule BlockScoutWeb.Etherscan do
example: ~s("663046792267785498951364")
},
tokenName: @token_name_type,
tokenID: @token_id_type,
tokenSymbol: @token_symbol_type,
tokenDecimal: @token_decimal_type,
transactionIndex: @transaction_index_type,
@ -1772,9 +1787,35 @@ defmodule BlockScoutWeb.Etherscan do
]
}
@stats_ethsupplyexchange_action %{
name: "ethsupplyexchange",
description: "Get total supply in Wei from exchange.",
required_params: [],
optional_params: [],
responses: [
%{
code: "200",
description: "successful operation",
example_value: Jason.encode!(@stats_ethsupplyexchange_example_value),
model: %{
name: "Result",
fields: %{
status: @status_type,
message: @message_type,
result: %{
type: "integer",
description: "The total supply.",
example: ~s("101959776311500000000000000")
}
}
}
}
]
}
@stats_ethsupply_action %{
name: "ethsupply",
description: "Get total supply in Wei.",
description: "Get total supply in Wei from DB.",
required_params: [],
optional_params: [],
responses: [
@ -1789,7 +1830,7 @@ defmodule BlockScoutWeb.Etherscan do
message: @message_type,
result: %{
type: "integer",
description: "The total supply.",
description: "The total supply in Wei from DB.",
example: ~s("101959776311500000000000000")
}
}
@ -1798,6 +1839,30 @@ defmodule BlockScoutWeb.Etherscan do
]
}
@stats_coinsupply_action %{
name: "coinsupply",
description: "Get total coin supply from DB minus burnt number.",
required_params: [],
optional_params: [],
responses: [
%{
code: "200",
description: "successful operation",
example_value: Jason.encode!(@stats_coinsupply_example_value),
model: %{
name: "Result",
fields: %{
result: %{
type: "integer",
description: "The total supply from DB minus burnt number in coin dimension.",
example: 101_959_776.3115
}
}
}
}
]
}
@stats_ethprice_action %{
name: "ethprice",
description: "Get latest price in USD and BTC.",
@ -1946,7 +2011,24 @@ defmodule BlockScoutWeb.Etherscan do
@contract_verify_action %{
name: "verify",
description: "Verify a contract with its source code and contract creation information.",
description: """
Verify a contract with its source code and contract creation information.
<br/>
<br/>
<p class="api-doc-list-item-text">curl POST example:</p>
<br/>
<div class='tab-content'>
<div class='tab-pane fade show active'>
<div class="tile tile-muted p-1">
<div class="m-2">
curl -d '{"addressHash":"0xd6984e092b51337032cf0300c7291e4839be37e1","compilerVersion":"v0.5.4+commit.9549d8ff",
"contractSourceCode":"pragma solidity ^0.5.4;\n","name":"Test","optimization":false}'
-H "Content-Type: application/json" -X POST "https://blockscout.com/eth/kovan/api?module=contract&action=verify"
</pre>
</div>
</div>
</div>
""",
required_params: [
%{
key: "addressHash",
@ -2285,7 +2367,9 @@ defmodule BlockScoutWeb.Etherscan do
name: "stats",
actions: [
@stats_tokensupply_action,
@stats_ethsupplyexchange_action,
@stats_ethsupply_action,
@stats_coinsupply_action,
@stats_ethprice_action
]
}

@ -95,7 +95,7 @@ defmodule BlockScoutWeb.Notifier do
def handle_event({:chain_event, :internal_transactions, :realtime, internal_transactions}) do
internal_transactions
|> Stream.map(
&(InternalTransaction
&(InternalTransaction.where_nonpending_block()
|> Repo.get_by(transaction_hash: &1.transaction_hash, index: &1.index)
|> Repo.preload([:from_address, :to_address, transaction: :block]))
)

@ -54,10 +54,22 @@ defmodule BlockScoutWeb.Router do
get("/eth_rpc_api_docs", APIDocsController, :eth_rpc)
end
scope "/verify_smart_contract" do
pipe_through(:api)
url_params = Application.get_env(:block_scout_web, BlockScoutWeb.Endpoint)[:url]
api_path = url_params[:api_path]
path = url_params[:path]
post("/contract_verifications", BlockScoutWeb.AddressContractVerificationController, :create)
if path != api_path do
scope to_string(api_path) <> "/verify_smart_contract" do
pipe_through(:api)
post("/contract_verifications", BlockScoutWeb.AddressContractVerificationController, :create)
end
else
scope "/verify_smart_contract" do
pipe_through(:api)
post("/contract_verifications", BlockScoutWeb.AddressContractVerificationController, :create)
end
end
if Application.get_env(:block_scout_web, WebRouter)[:enabled] do

@ -3,7 +3,11 @@
<%= if @use_custom_tooltip == true do %>
<span><%= name %> (<%= short_hash(@address) %>...)</span>
<% else %>
<span data-toggle="tooltip" data-placement="top" title="<%= @address %>"><%= name %> (<%= short_hash(@address) %>...)</span>
<span data-toggle="tooltip" data-placement="top" title="<%= @address %>">
<span class="d-none d-md-none d-lg-inline d-xl-inline"><%= short_contract_name(name, 30) %></span>
<span class="d-inline d-md-inline d-lg-none d-xl-none"><%= short_contract_name(name, 10) %></span>
<span> (<%= BlockScoutWeb.AddressView.trimmed_hash(@address.hash) %>)</span>
</span>
<% end %>
<% else %>
<%= if assigns[:truncate] do %>

@ -4,6 +4,12 @@
class: "card-tab #{tab_status("transactions", @conn.request_path)}",
to: address_transaction_path(@conn, :index, @address.hash)
) %>
<%= link(
gettext("Token Transfers"),
class: "card-tab #{tab_status("token_transfers", @conn.request_path)}",
"data-test": "token_transfers_tab_link",
to: address_token_transfers_path(@conn, :index, @address.hash)
) %>
<%= link(
gettext("Tokens"),
class: "card-tab #{tab_status("tokens", @conn.request_path)}",

@ -62,7 +62,9 @@
<h3 class="address-detail-hash-title <%= if BlockScoutWeb.AddressView.contract?(@address) do %>contract-address<% end %>" data-test="address_detail_hash"><%= @address %></h3>
<div class="d-flex flex-column flex-lg-row justify-content-start text-muted">
<%= if address_name = primary_name(@address) do %>
<strong class="mr-4 mb-2 text-dark"><%= address_name %></strong>
<strong class="mr-4 mb-2 text-dark" title="<%= address_name %>">
<%= short_contract_name(address_name, 30) %>
</strong>
<% end %>
<%= if @address.token do %>
<span class="mr-4 mb-2">

@ -1,4 +1,6 @@
<section class="container" data-page="coin-balance-history">
<script defer src="<%= static_path(@conn, "/js/chart-loader.js") %>"></script>
<%= render BlockScoutWeb.AddressView, "overview.html", assigns %>
<section>

@ -35,6 +35,28 @@
</div>
</div>
<div class="smart-contract-form-group">
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, "Include nightly builds" %>
<div class="center-column">
<div class="form-radios-group">
<div class="radio-big">
<%= radio_button f, :nightly_builds, false, checked: true, class: "form-check-input nightly-builds-false" %>
<div class="radio-icon"></div>
<%= label :nightly_builds, :false, gettext("No"), class: "radio-text" %>
</div>
<div class="radio-big">
<%= radio_button f, :nightly_builds, true, class: "form-check-input nightly-builds-true", "aria-describedby": "nightly_builds-help-block" %>
<div class="radio-icon"></div>
<%= label :nightly_builds, :true, gettext("Yes"), class: "radio-text" %>
</div>
</div>
<%= error_tag f, :nightly_builds, id: "nightly_builds-help-block", class: "text-danger form-error" %>
</div>
<div class="smart-contract-form-group-tooltip">Select yes if you want to show nightly builds.</div>
</div>
</div>
<div class="smart-contract-form-group">
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, :compiler_version, gettext("Compiler") %>
@ -62,12 +84,12 @@
<div class="center-column">
<div class="form-radios-group">
<div class="radio-big">
<%= radio_button f, :optimization, false, checked: true, class: "form-check-input" %>
<%= radio_button f, :optimization, false, class: "form-check-input optimization-false" %>
<div class="radio-icon"></div>
<%= label :smart_contract_optimization, :false, gettext("No"), class: "radio-text" %>
</div>
<div class="radio-big">
<%= radio_button f, :optimization, true, class: "form-check-input", "aria-describedby": "optimization-help-block" %>
<%= radio_button f, :optimization, true, checked: true, class: "form-check-input optimization-true", "aria-describedby": "optimization-help-block" %>
<div class="radio-icon"></div>
<%= label :smart_contract_optimization, :true, gettext("Yes"), class: "radio-text" %>
</div>
@ -78,7 +100,7 @@
</div>
</div>
<div class="smart-contract-form-group">
<div class="smart-contract-form-group optimization-runs">
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, :name, gettext("Optimization runs") %>
<div class="center-column">
@ -100,6 +122,27 @@
</div>
<div class="smart-contract-form-group">
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, "Try to fetch contructor arguments automatically" %>
<div class="center-column">
<div class="form-radios-group">
<div class="radio-big">
<%= radio_button f, :autodetect_contructor_args, false, checked: true, class: "form-check-input autodetectfalse" %>
<div class="radio-icon"></div>
<%= label :autodetect_contructor_args, :false, gettext("No"), class: "radio-text" %>
</div>
<div class="radio-big">
<%= radio_button f, :autodetect_contructor_args, true, class: "form-check-input autodetecttrue", "aria-describedby": "autodetect_contructor_args-help-block" %>
<div class="radio-icon"></div>
<%= label :autodetect_contructor_args, :true, gettext("Yes"), class: "radio-text" %>
</div>
</div>
<%= error_tag f, :autodetect_contructor_args, id: "autodetect_contructor_args-help-block", class: "text-danger form-error" %>
</div>
</div>
</div>
<div class="smart-contract-form-group constructor-arguments">
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, :contructor_arguments, gettext("ABI-encoded Constructor Arguments (if required by the contract)") %>
<div class="center-column">

@ -2,7 +2,7 @@
<div class="row justify-content align-items-center">
<div class="col-md-7 d-flex flex-column mt-3 mt-md-0">
<%= link(
to: address_token_transfers_path(@conn, :index, @address.hash, @token.contract_address_hash),
to: address_token_transfers_path(@conn, :index, to_string(@address.hash), to_string(@token.contract_address_hash)),
class: "tile-title-lg",
"data-test": "token_transfers_#{@token.contract_address_hash}"
) do %>

@ -11,7 +11,7 @@
data-token-symbol="<%= token_balance.token.symbol %>"
>
<%= link(
to: token_path(@conn, :show, token_balance.token.contract_address_hash),
to: token_path(@conn, :show, to_string(token_balance.token.contract_address_hash)),
class: "dropdown-item"
) do %>
<div class="row">

@ -5,9 +5,54 @@
<div class="card">
<%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %>
<div data-async-load data-async-listing="<%= @current_path %>" class="card-body">
<%= if assigns[:token] do %>
<h2 class="card-title">
<span class="text-muted"><%= gettext "Tokens" %></span> / <%= token_name(@token) %>
</h2>
<% end %>
<%= if !assigns[:token] do %>
<div class="clearfix">
<h2 class="card-title float-left"><%= gettext "Transactions" %></h2>
<div class="dropdown float-right u-push-sm">
<button data-test="filter_dropdown" class="btn-dropdown-line dropdown-toggle" type="button"
id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Filter: <%= format_current_filter(@filter) %>
</button>
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
<%= link(
gettext("All"),
to: address_token_transfers_path(@conn, :index, to_string(@address.hash)),
class: "address__link address__link--active dropdown-item",
"data-test": "filter_option"
) %>
<%= link(
gettext("To"),
to: address_token_transfers_path(
@conn,
:index,
to_string(@address.hash),
filter: "to"
),
class: "address__link address__link--active dropdown-item",
"data-test": "filter_option"
) %>
<%= link(
gettext("From"),
to: address_token_transfers_path(
@conn,
:index,
to_string(@address.hash),
filter: "from"
),
class: "address__link address__link--active dropdown-item",
"data-test": "filter_option"
) %>
</div>
</div>
</div>
<% end %>
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>

@ -5,13 +5,6 @@
<div class="dashboard-banner-network-graph">
<!-- Graph -->
<div class="dashboard-banner-chart">
<div hidden data-chart-loading-message class="tile tile-muted text-center mt-5">
<span class="loading-spinner-small mr-2">
<span class="loading-spinner-block-1"></span>
<span class="loading-spinner-block-2"></span>
</span>
<%= gettext("Loading chart") %>...
</div>
<button data-chart-error-message class="alert alert-danger col-12 text-left mt-5" style="display: none;">
<span><%= gettext("There was a problem loading the chart.") %></span>
</button>
@ -79,6 +72,7 @@
</div>
</div>
</div>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/chart-loader.js") %>"></script>
</div>
<section class="container">
<div class="card card-chain-blocks">

@ -1,7 +1,7 @@
<link rel="preload" href="/css/awesomplete.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/css/awesomplete.css"></noscript>
<script src="/js/awesomplete.min.js"></script>
<script src="/js/awesomplete-util.min.js"></script>
<link rel="preload" href="<%= static_path(@conn, "/css/awesomplete.css") %>" as="style" onload="this.rel='stylesheet'">
<link rel="stylesheet" href="<%= static_path(@conn, "/css/awesomplete.css") %>">
<script src="<%= static_path(@conn, "/js/awesomplete.min.js") %>"></script>
<script src="<%= static_path(@conn, "/js/awesomplete-util.min.js") %>"></script>
<nav class="navbar navbar-dark navbar-expand-lg navbar-primary" data-selector="navbar" id="top-navbar">
<script>
if (localStorage.getItem("current-color-mode") === "dark") {
@ -168,7 +168,6 @@
</div>
</div>
</nav>
<%= render BlockScoutWeb.LayoutView, "_network_selector.html" %>
<script>
if (localStorage.getItem("current-color-mode") === "dark") {
var modeChanger = document.getElementById("dark-mode-changer");

@ -4,21 +4,34 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
<link rel="preload" href="/css/non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/css/non-critical.css"></noscript>
<link rel="preload" href="<%= static_path(@conn, "/css/non-critical.css") %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
<link rel="stylesheet" href="<%= static_path(@conn, "/css/non-critical.css") %>">
<link rel="apple-touch-icon" sizes="180x180" href="<%= static_path(@conn, "/apple-touch-icon.png") %>">
<link rel="icon" type="image/png" sizes="32x32" href="<%= static_path(@conn, "/favicon-32x32.png") %>">
<link rel="icon" type="image/png" sizes="16x16" href="<%= static_path(@conn, "/favicon-16x16.png") %>">
<link rel="manifest" href="<%= static_path(@conn, "/site.webmanifest") %>">
<link rel="icon" type="image/png" sizes="32x32" href="<%= static_path(@conn, "/images/favicon-32x32.png") %>">
<link rel="icon" type="image/png" sizes="16x16" href="<%= static_path(@conn, "/images/favicon-16x16.png") %>">
<link rel="manifest" href="<%= static_path(@conn, "/manifest.webmanifest") %>">
<link rel="mask-icon" href="<%= static_path(@conn, "/safari-pinned-tab.svg") %>" color="#5bbad5">
<link rel="shortcut icon" href="<%= static_path(@conn, "/favicon.ico") %>">
<link rel="shortcut icon" type='image/x-icon' href="<%= static_path(@conn, "/images/favicon.ico") %>">
<meta name="msapplication-TileColor" content="#7dd79f">
<meta name="msapplication-config" content="<%= static_path(@conn, "/browserconfig.xml") %>">
<meta name="theme-color" content="#ffffff">
<%= render_existing(@view_module, "_metatags.html", assigns) || render("_default_title.html") %>
<script defer data-cfasync="false">
window.localized = {
'Blocks Indexed': '<%= gettext("Blocks Indexed") %>',
'Block Processing': '<%= gettext("Block Mined, awaiting import...") %>',
'Indexing Tokens': '<%= gettext("Indexing Tokens") %>',
'Less than': '<%= gettext("Less than") %>',
'Market Cap': '<%= gettext("Market Cap") %>',
'Price': '<%= gettext("Price") %>',
'Ether': '<%= gettext("Ether") %>'
}
</script>
</head>
<body>
@ -51,18 +64,7 @@
</main>
<%= render BlockScoutWeb.LayoutView, "_footer.html", assigns %>
</div>
<script>
window.localized = {
'Blocks Indexed': '<%= gettext("Blocks Indexed") %>',
'Block Processing': '<%= gettext("Block Mined, awaiting import...") %>',
'Indexing Tokens': '<%= gettext("Indexing Tokens") %>',
'Less than': '<%= gettext("Less than") %>',
'Market Cap': '<%= gettext("Market Cap") %>',
'Price': '<%= gettext("Price") %>',
'Ether': '<%= gettext("Ether") %>'
}
</script>
<script src="<%= static_path(@conn, "/js/app.js") %>"></script>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/app.js") %>"></script>
<%= render_existing(@view_module, "scripts.html", assigns) %>
</body>
</html>

@ -10,7 +10,7 @@
<span class="d-flex flex-md-row flex-column mt-3 mt-md-0">
<span class="mr-1"><%= gettext "Token ID" %>:</span>
<span class="tile-title">
<%= link(@token_transfer.token_id, to: token_instance_path(@conn, :show, @token.contract_address_hash, to_string(@token_transfer.token_id))) %>
<%= link(@token_transfer.token_id, to: token_instance_path(@conn, :show, "#{@token.contract_address_hash}", "#{@token_transfer.token_id}")) %>
</span>
</span>

@ -8,7 +8,7 @@
<div class="col-md-7 col-lg-8 d-flex flex-column pr-2 pr-sm-2 pr-md-0">
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @token_transfer.transaction_hash %>
<span class="text-nowrap">
<%= link to: address_token_transfers_path(@conn, :index, @token_transfer.from_address, @token.contract_address_hash), "data-test": "address_hash_link" do %>
<%= link to: address_token_transfers_path(@conn, :index, to_string(@token_transfer.from_address), to_string(@token.contract_address_hash)), "data-test": "address_hash_link" do %>
<%= render(
BlockScoutWeb.AddressView,
"_responsive_hash.html",
@ -18,7 +18,7 @@
) %>
<% end %>
&rarr;
<%= link to: address_token_transfers_path(@conn, :index, @token_transfer.to_address, @token.contract_address_hash), "data-test": "address_hash_link" do %>
<%= link to: address_token_transfers_path(@conn, :index, to_string(@token_transfer.to_address), to_string(@token.contract_address_hash)), "data-test": "address_hash_link" do %>
<%= render(
BlockScoutWeb.AddressView,
"_responsive_hash.html",

@ -144,6 +144,7 @@
data-clipboard-text="<%= @transaction.input %>"
data-placement="top"
data-toggle="tooltip"
title='<%= gettext("Copy Txn Input") %>'
style="display: none;"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32.5 32.5" width="32" height="32">

@ -1,3 +1,11 @@
defmodule BlockScoutWeb.AddressTokenTransferView do
use BlockScoutWeb, :view
def format_current_filter(filter) do
case filter do
"to" -> gettext("To")
"from" -> gettext("From")
_ -> gettext("All")
end
end
end

@ -16,6 +16,7 @@ defmodule BlockScoutWeb.AddressView do
"contracts",
"decompiled_contracts",
"internal_transactions",
"token_transfers",
"read_contract",
"tokens",
"transactions",
@ -304,6 +305,7 @@ defmodule BlockScoutWeb.AddressView do
defp tab_name(["tokens"]), do: gettext("Tokens")
defp tab_name(["transactions"]), do: gettext("Transactions")
defp tab_name(["internal_transactions"]), do: gettext("Internal Transactions")
defp tab_name(["token_transfers"]), do: gettext("Token Transfers")
defp tab_name(["contracts"]), do: gettext("Code")
defp tab_name(["decompiled_contracts"]), do: gettext("Decompiled Code")
defp tab_name(["read_contract"]), do: gettext("Read Contract")
@ -321,6 +323,14 @@ defmodule BlockScoutWeb.AddressView do
"0x" <> short_address
end
def short_contract_name(name, max_length) do
part_length = Kernel.trunc(max_length / 4)
if String.length(name) <= max_length,
do: name,
else: "#{String.slice(name, 0, max_length - part_length)}..#{String.slice(name, -part_length, part_length)}"
end
def address_page_title(address) do
cond do
smart_contract_verified?(address) -> "#{address.smart_contract.name} (#{to_string(address)})"

@ -121,7 +121,7 @@ defmodule BlockScoutWeb.API.RPC.AddressView do
}
end
defp prepare_token_transfer(token_transfer) do
defp prepare_common_token_transfer(token_transfer) do
%{
"blockNumber" => to_string(token_transfer.block_number),
"timeStamp" => to_string(DateTime.to_unix(token_transfer.block_timestamp)),
@ -132,7 +132,6 @@ defmodule BlockScoutWeb.API.RPC.AddressView do
"contractAddress" => to_string(token_transfer.token_contract_address_hash),
"to" => to_string(token_transfer.to_address_hash),
"logIndex" => to_string(token_transfer.token_log_index),
"value" => get_token_value(token_transfer),
"tokenName" => token_transfer.token_name,
"tokenSymbol" => token_transfer.token_symbol,
"tokenDecimal" => to_string(token_transfer.token_decimals),
@ -146,12 +145,20 @@ defmodule BlockScoutWeb.API.RPC.AddressView do
}
end
defp get_token_value(%{token_type: "ERC-721"} = token_transfer) do
to_string(token_transfer.token_id)
defp prepare_token_transfer(%{token_type: "ERC-721"} = token_transfer) do
token_transfer
|> prepare_common_token_transfer()
|> Map.put_new(:tokenID, token_transfer.token_id)
end
defp prepare_token_transfer(%{token_type: "ERC-20"} = token_transfer) do
token_transfer
|> prepare_common_token_transfer()
|> Map.put_new(:value, to_string(token_transfer.amount))
end
defp get_token_value(token_transfer) do
to_string(token_transfer.amount)
defp prepare_token_transfer(token_transfer) do
prepare_common_token_transfer(token_transfer)
end
defp prepare_block(block) do

@ -3,6 +3,7 @@ defmodule BlockScoutWeb.API.RPC.BlockView do
alias BlockScoutWeb.API.RPC.{EthRPCView, RPCView}
alias Explorer.Chain.{Hash, Wei}
alias Explorer.EthRPC, as: EthRPC
def render("block_reward.json", %{block: block, reward: reward}) do
reward_as_string =
@ -23,7 +24,7 @@ defmodule BlockScoutWeb.API.RPC.BlockView do
end
def render("eth_block_number.json", %{number: number, id: id}) do
result = encode_quantity(number)
result = EthRPC.encode_quantity(number)
EthRPCView.render("show.json", %{result: result, id: id})
end
@ -31,24 +32,4 @@ defmodule BlockScoutWeb.API.RPC.BlockView do
def render("error.json", %{error: error}) do
RPCView.render("error.json", error: error)
end
defp encode_quantity(binary) when is_binary(binary) do
hex_binary = Base.encode16(binary, case: :lower)
result = String.replace_leading(hex_binary, "0", "")
final_result = if result == "", do: "0", else: result
"0x#{final_result}"
end
defp encode_quantity(value) when is_integer(value) do
value
|> :binary.encode_unsigned()
|> encode_quantity()
end
defp encode_quantity(value) when is_nil(value) do
nil
end
end

@ -4,6 +4,8 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
alias BlockScoutWeb.API.RPC.RPCView
alias Explorer.Chain.{Address, DecompiledSmartContract, SmartContract}
defguardp is_empty_string(input) when input == "" or input == nil
def render("listcontracts.json", %{contracts: contracts}) do
contracts = Enum.map(contracts, &prepare_contract/1)
@ -35,7 +37,11 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
"CompilerVersion" => "",
"DecompiledSourceCode" => "",
"DecompilerVersion" => decompiler_version(nil),
"OptimizationUsed" => ""
"OptimizationUsed" => "",
"OptimizationRuns" => "",
"EVMVersion" => "",
"ConstructorArguments" => "",
"ExternalLibraries" => ""
}
end
@ -43,6 +49,68 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
decompiled_smart_contract = latest_decompiled_smart_contract(address.decompiled_smart_contracts)
contract = address.smart_contract || %{}
optimization = Map.get(contract, :optimization, "")
contract_output = %{
"Address" => to_string(address.hash)
}
contract_output
|> set_decompiled_contract_data(decompiled_smart_contract)
|> set_optimization_runs(contract, optimization)
|> set_constructor_arguments(contract)
|> set_external_libraries(contract)
|> set_verified_contract_data(contract, address, optimization)
end
defp set_decompiled_contract_data(contract_output, decompiled_smart_contract) do
if decompiled_smart_contract do
contract_output
|> Map.put_new(:DecompiledSourceCode, decompiled_source_code(decompiled_smart_contract))
|> Map.put_new(:DecompilerVersion, decompiler_version(decompiled_smart_contract))
else
contract_output
end
end
defp set_optimization_runs(contract_output, contract, optimization) do
optimization_runs = Map.get(contract, :optimization_runs, "")
if optimization && optimization != "" do
contract_output
|> Map.put_new(:OptimizationRuns, optimization_runs)
else
contract_output
end
end
defp set_constructor_arguments(contract_output, %{constructor_arguments: arguments}) when is_empty_string(arguments),
do: contract_output
defp set_constructor_arguments(contract_output, %{constructor_arguments: arguments}) do
contract_output
|> Map.put_new(:ConstructorArguments, arguments)
end
defp set_constructor_arguments(contract_output, _), do: contract_output
defp set_external_libraries(contract_output, contract) do
external_libraries = Map.get(contract, :external_libraries, [])
if Enum.count(external_libraries) > 0 do
external_libraries_without_id =
Enum.map(external_libraries, fn %{name: name, address_hash: address_hash} ->
%{"name" => name, "address_hash" => address_hash}
end)
contract_output
|> Map.put_new(:ExternalLibraries, external_libraries_without_id)
else
contract_output
end
end
defp set_verified_contract_data(contract_output, contract, address, optimization) do
contract_abi =
if is_nil(address.smart_contract) do
"Contract source code not verified"
@ -51,27 +119,28 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
end
contract_optimization =
case Map.get(contract, :optimization, "") do
case optimization do
true ->
"1"
"true"
false ->
"0"
"false"
"" ->
""
end
%{
"Address" => to_string(address.hash),
"SourceCode" => Map.get(contract, :contract_source_code, ""),
"ABI" => contract_abi,
"ContractName" => Map.get(contract, :name, ""),
"DecompiledSourceCode" => decompiled_source_code(decompiled_smart_contract),
"DecompilerVersion" => decompiler_version(decompiled_smart_contract),
"CompilerVersion" => Map.get(contract, :compiler_version, ""),
"OptimizationUsed" => contract_optimization
}
if Map.equal?(contract, %{}) do
contract_output
else
contract_output
|> Map.put_new(:SourceCode, Map.get(contract, :contract_source_code, ""))
|> Map.put_new(:ABI, contract_abi)
|> Map.put_new(:ContractName, Map.get(contract, :name, ""))
|> Map.put_new(:CompilerVersion, Map.get(contract, :compiler_version, ""))
|> Map.put_new(:OptimizationUsed, contract_optimization)
|> Map.put_new(:EVMVersion, Map.get(contract, :evm_version, ""))
end
end
defp prepare_contract(%Address{
@ -80,10 +149,7 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
}) do
%{
"Address" => to_string(hash),
"ABI" => "Contract source code not verified",
"ContractName" => "",
"CompilerVersion" => "",
"OptimizationUsed" => ""
"ABI" => "Contract source code not verified"
}
end

@ -9,6 +9,15 @@ defmodule BlockScoutWeb.API.RPC.RPCView do
}
end
def render("show_value.json", data) do
{value, _} =
data
|> Decimal.to_string(:normal)
|> Float.parse()
value
end
def render("error.json", %{error: message} = assigns) do
%{
"status" => "0",

@ -7,10 +7,18 @@ defmodule BlockScoutWeb.API.RPC.StatsView do
RPCView.render("show.json", data: Decimal.to_string(token_supply))
end
def render("ethsupplyexchange.json", %{total_supply: total_supply}) do
RPCView.render("show.json", data: total_supply)
end
def render("ethsupply.json", %{total_supply: total_supply}) do
RPCView.render("show.json", data: total_supply)
end
def render("coinsupply.json", total_supply) do
RPCView.render("show_value.json", total_supply)
end
def render("ethprice.json", %{rates: rates}) do
RPCView.render("show.json", data: prepare_rates(rates))
end

@ -34,10 +34,17 @@ defmodule BlockScoutWeb.APIDocsView do
end)
end
def blockscout_url do
def blockscout_url(is_api) do
url_params = Application.get_env(:block_scout_web, BlockScoutWeb.Endpoint)[:url]
host = url_params[:host]
path = url_params[:path]
path =
if is_api do
url_params[:api_path]
else
url_params[:path]
end
scheme = Keyword.get(url_params, :scheme, "http")
if host != "localhost" do
@ -49,12 +56,18 @@ defmodule BlockScoutWeb.APIDocsView do
end
def api_url do
blockscout_url()
is_api = true
is_api
|> blockscout_url()
|> Path.join("api")
end
def eth_rpc_api_url do
blockscout_url()
is_api = true
is_api
|> blockscout_url()
|> Path.join("api/eth_rpc")
end
end

@ -10,7 +10,7 @@ defmodule BlockScoutWeb.SmartContractView do
def named_argument?(%{"name" => _}), do: true
def named_argument?(_), do: false
def values(addresses, type) when type == "address[]" do
def values(addresses, type) when is_list(addresses) and type == "address[]" do
addresses
|> Enum.map(&values(&1, "address"))
|> Enum.join(", ")

@ -4,7 +4,7 @@ defmodule BlockScoutWeb.Tokens.Instance.OverviewView do
alias BlockScoutWeb.CurrencyHelpers
alias Explorer.Chain.{Address, SmartContract, Token}
import BlockScoutWeb.APIDocsView, only: [blockscout_url: 0]
import BlockScoutWeb.APIDocsView, only: [blockscout_url: 1]
@tabs ["token_transfers", "metadata"]
@ -55,7 +55,8 @@ defmodule BlockScoutWeb.Tokens.Instance.OverviewView do
def qr_code(conn, token_id, hash) do
token_instance_path = token_instance_path(conn, :show, to_string(hash), to_string(token_id))
url = Path.join(blockscout_url(), token_instance_path)
is_api = false
url = Path.join(blockscout_url(is_api), token_instance_path)
url
|> QRCode.to_png()

@ -230,6 +230,7 @@ defmodule BlockScoutWeb.TransactionView do
def involves_token_transfers?(%Transaction{token_transfers: []}), do: false
def involves_token_transfers?(%Transaction{token_transfers: transfers}) when is_list(transfers), do: true
def involves_token_transfers?(_), do: false
def qr_code(%Transaction{hash: hash}) do
hash

@ -120,6 +120,13 @@ defmodule BlockScoutWeb.WebRouter do
as: :read_contract
)
resources(
"/token_transfers",
AddressTokenTransferController,
only: [:index],
as: :token_transfers
)
resources("/tokens", AddressTokenController, only: [:index], as: :token) do
resources(
"/token_transfers",

@ -60,13 +60,13 @@ defmodule BlockScoutWeb.Mixfile do
defp deps do
[
# GraphQL toolkit
{:absinthe, "~> 1.4"},
{:absinthe, "~> 1.5.0-rc.2"},
# Integrates Absinthe subscriptions with Phoenix
{:absinthe_phoenix, git: "https://github.com/ayrat555/absinthe_phoenix.git", branch: "ab-update-plug"},
{:absinthe_phoenix, "~> 1.5.0-rc.0"},
# Plug support for Absinthe
{:absinthe_plug, git: "https://github.com/ayrat555/absinthe_plug.git", branch: "ab-enable-default-query"},
{:absinthe_plug, "~> 1.5.0-rc.1"},
# Absinthe support for the Relay framework
{:absinthe_relay, "~> 1.4"},
{:absinthe_relay, "~> 1.5.0-rc.0"},
{:bypass, "~> 1.0", only: :test},
# To add (CORS)(https://www.w3.org/TR/cors/)
{:cors_plug, "~> 2.0"},
@ -76,7 +76,7 @@ defmodule BlockScoutWeb.Mixfile do
{:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false},
# Need until https://github.com/absinthe-graphql/absinthe_relay/pull/125 is released, then can be removed
# The current `absinthe_relay` is compatible though as shown from that PR
{:ecto, "~> 3.0", override: true},
{:ecto, "~> 3.3", override: true},
{:ex_cldr, "~> 2.7"},
{:ex_cldr_numbers, "~> 2.6"},
{:ex_cldr_units, "~> 2.5"},

@ -13,7 +13,7 @@ msgstr[0] ""
msgstr[1] ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:193
#: lib/block_scout_web/templates/transaction/overview.html.eex:194
msgid " Token Transfer"
msgstr ""
@ -72,7 +72,7 @@ msgid "(query)"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:42
#: lib/block_scout_web/templates/layout/app.html.eex:55
msgid "- We're indexing this chain right now. Some of the counts may be inaccurate."
msgstr ""
@ -87,7 +87,7 @@ msgid "A string with the name of the module to be invoked."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:147
msgid "ABI-encoded Constructor Arguments (if required by the contract)"
msgstr ""
@ -124,7 +124,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:16
#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19
#: lib/block_scout_web/views/address_view.ex:99
#: lib/block_scout_web/views/address_view.ex:100
msgid "Address"
msgstr ""
@ -135,9 +135,11 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:27
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:25
#: lib/block_scout_web/templates/address_transaction/index.html.eex:23
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:21
#: lib/block_scout_web/views/address_internal_transaction_view.ex:8
#: lib/block_scout_web/views/address_token_transfer_view.ex:8
#: lib/block_scout_web/views/address_transaction_view.ex:8
msgid "All"
msgstr ""
@ -148,7 +150,7 @@ msgid "Anything not in this list is not supported. Click on the method to be tak
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:47
#: lib/block_scout_web/templates/chain/show.html.eex:40
msgid "Average block time"
msgstr ""
@ -163,7 +165,7 @@ msgid "Balance"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:14
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:16
msgid "Balances"
msgstr ""
@ -206,7 +208,7 @@ msgid "Block Height: %{height}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:57
#: lib/block_scout_web/templates/layout/app.html.eex:27
msgid "Block Mined, awaiting import..."
msgstr ""
@ -231,14 +233,14 @@ msgid "BlockScout provides analytics data, API, and Smart Contract tools for the
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:87
#: lib/block_scout_web/templates/chain/show.html.eex:81
#: lib/block_scout_web/templates/layout/_topnav.html.eex:31
#: lib/block_scout_web/templates/layout/_topnav.html.eex:35
msgid "Blocks"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:56
#: lib/block_scout_web/templates/layout/app.html.eex:26
msgid "Blocks Indexed"
msgstr ""
@ -264,7 +266,7 @@ msgid "Call Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:296
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54
msgid "Cancel"
@ -287,7 +289,7 @@ msgid "Clear"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:62
msgid "Compiler"
msgstr ""
@ -302,7 +304,7 @@ msgid "Connection Lost"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:10
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:12
#: lib/block_scout_web/templates/block/index.html.eex:6
msgid "Connection Lost, click to load newer blocks"
msgstr ""
@ -336,14 +338,14 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:18
#: lib/block_scout_web/views/address_view.ex:97
#: lib/block_scout_web/views/address_view.ex:98
msgid "Contract Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:16
#: lib/block_scout_web/views/address_view.ex:37
#: lib/block_scout_web/views/address_view.ex:71
#: lib/block_scout_web/views/address_view.ex:38
#: lib/block_scout_web/views/address_view.ex:72
msgid "Contract Address Pending"
msgstr ""
@ -353,12 +355,12 @@ msgid "Contract Byte Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:261
#: lib/block_scout_web/views/transaction_view.ex:262
msgid "Contract Call"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:260
#: lib/block_scout_web/views/transaction_view.ex:261
msgid "Contract Creation"
msgstr ""
@ -368,7 +370,7 @@ msgid "Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:161
msgid "Contract Libraries"
msgstr ""
@ -465,7 +467,7 @@ msgid "Create2"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:94
#: lib/block_scout_web/templates/address/overview.html.eex:96
msgid "Created by"
msgstr ""
@ -497,7 +499,7 @@ msgid "Decoded"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:50
#: lib/block_scout_web/templates/address/_tabs.html.eex:56
msgid "Decompiled code"
msgstr ""
@ -577,7 +579,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:45
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:73
msgid "EVM Version"
msgstr ""
@ -597,7 +599,7 @@ msgid "Emission Reward"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:115
msgid "Enter the Solidity Contract Code"
msgstr ""
@ -629,7 +631,7 @@ msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:107
#: lib/block_scout_web/templates/address/overview.html.eex:109
msgid "Error: Could not determine contract creator."
msgstr ""
@ -641,11 +643,11 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_balance_card.html.eex:15
#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:20
#: lib/block_scout_web/templates/layout/app.html.eex:62
#: lib/block_scout_web/templates/layout/app.html.eex:32
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20
#: lib/block_scout_web/templates/transaction/_tile.html.eex:29
#: lib/block_scout_web/templates/transaction/overview.html.eex:180
#: lib/block_scout_web/templates/transaction/overview.html.eex:215
#: lib/block_scout_web/templates/transaction/overview.html.eex:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:216
#: lib/block_scout_web/views/wei_helpers.ex:78
msgid "Ether"
msgstr ""
@ -706,8 +708,10 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:42
#: lib/block_scout_web/templates/address_transaction/index.html.eex:40
#: lib/block_scout_web/views/address_internal_transaction_view.ex:7
#: lib/block_scout_web/views/address_token_transfer_view.ex:7
#: lib/block_scout_web/views/address_transaction_view.ex:7
msgid "From"
msgstr ""
@ -810,7 +814,7 @@ msgid "There are no logs for this transaction."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:15
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:60
msgid "There are no token transfers for this address."
msgstr ""
@ -847,8 +851,10 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:33
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31
#: lib/block_scout_web/templates/address_transaction/index.html.eex:29
#: lib/block_scout_web/views/address_internal_transaction_view.ex:6
#: lib/block_scout_web/views/address_token_transfer_view.ex:6
#: lib/block_scout_web/views/address_transaction_view.ex:6
msgid "To"
msgstr ""
@ -879,20 +885,22 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:5
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:259
#: lib/block_scout_web/views/transaction_view.ex:260
msgid "Token Transfer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/tokens/instance/overview/_tabs.html.eex:3
#: lib/block_scout_web/templates/tokens/instance/transfer/index.html.eex:16
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:3
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:14
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:7
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:71
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:72
#: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:313
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Token Transfers"
msgstr ""
@ -908,7 +916,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:18
#: lib/block_scout_web/views/transaction_view.ex:262
#: lib/block_scout_web/views/transaction_view.ex:263
msgid "Transaction"
msgstr ""
@ -953,30 +961,30 @@ msgid "It could still be in the TX Pool of a different node, waiting to be broad
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:79
#: lib/block_scout_web/templates/address/overview.html.eex:81
msgid "Last Balance Update: Block #"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:59
#: lib/block_scout_web/templates/layout/app.html.eex:29
msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:176
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:198
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:220
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:242
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:264
msgid "Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:166
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:188
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:210
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:232
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:254
msgid "Library Name"
msgstr ""
@ -991,7 +999,7 @@ msgid "License ID"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:243
#: lib/block_scout_web/templates/transaction/overview.html.eex:244
msgid "Limit"
msgstr ""
@ -1002,7 +1010,7 @@ msgid "Loading..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:290
msgid "Loading...."
msgstr ""
@ -1025,10 +1033,10 @@ msgid "Mainnet"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:31
#: lib/block_scout_web/templates/layout/app.html.eex:60
#: lib/block_scout_web/views/address_view.ex:125
#: lib/block_scout_web/views/address_view.ex:125
#: lib/block_scout_web/templates/chain/show.html.eex:24
#: lib/block_scout_web/templates/layout/app.html.eex:30
#: lib/block_scout_web/views/address_view.ex:126
#: lib/block_scout_web/views/address_view.ex:126
msgid "Market Cap"
msgstr ""
@ -1059,7 +1067,7 @@ msgid "More internal transactions have come in"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:148
#: lib/block_scout_web/templates/chain/show.html.eex:142
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:10
#: lib/block_scout_web/templates/transaction/index.html.eex:10
msgid "More transactions have come in"
@ -1088,7 +1096,9 @@ msgid "New Smart Contract Verification"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:46
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:89
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:132
msgid "No"
msgstr ""
@ -1105,7 +1115,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:39
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:105
msgid "Optimization runs"
msgstr ""
@ -1160,14 +1170,14 @@ msgid "Potential matches from our contract method database:"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:24
#: lib/block_scout_web/templates/layout/app.html.eex:61
#: lib/block_scout_web/templates/chain/show.html.eex:17
#: lib/block_scout_web/templates/layout/app.html.eex:31
msgid "Price"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:33
#: lib/block_scout_web/templates/address/overview.html.eex:131
#: lib/block_scout_web/templates/address/overview.html.eex:133
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:51
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:93
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:36
@ -1193,7 +1203,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:316
#: lib/block_scout_web/views/transaction_view.ex:317
msgid "Raw Trace"
msgstr ""
@ -1209,7 +1219,7 @@ msgid "Request URL"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:293
msgid "Reset"
msgstr ""
@ -1296,15 +1306,15 @@ msgid "Block Rewards"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:36
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61
#: lib/block_scout_web/templates/address_logs/index.html.eex:21
#: lib/block_scout_web/templates/address_token/index.html.eex:13
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:65
#: lib/block_scout_web/templates/address_transaction/index.html.eex:59
#: lib/block_scout_web/templates/address_validation/index.html.eex:22
#: lib/block_scout_web/templates/block_transaction/index.html.eex:23
#: lib/block_scout_web/templates/chain/show.html.eex:91
#: lib/block_scout_web/templates/chain/show.html.eex:85
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:19
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:20
#: lib/block_scout_web/templates/tokens/instance/transfer/index.html.eex:21
@ -1318,7 +1328,7 @@ msgid "Something went wrong, click to reload."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:154
#: lib/block_scout_web/templates/chain/show.html.eex:148
msgid "Something went wrong, click to retry."
msgstr ""
@ -1383,7 +1393,7 @@ msgid "There are no transactions."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:39
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:41
msgid "There is no coin history for this address."
msgstr ""
@ -1393,8 +1403,8 @@ msgid "There is no decompilded contracts for this address."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:25
#: lib/block_scout_web/templates/chain/show.html.eex:16
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:27
#: lib/block_scout_web/templates/chain/show.html.eex:9
msgid "There was a problem loading the chart."
msgstr ""
@ -1447,7 +1457,7 @@ msgid "Total Supply"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:64
#: lib/block_scout_web/templates/chain/show.html.eex:57
msgid "Total blocks"
msgstr ""
@ -1529,7 +1539,7 @@ msgid "Use the search box to find a hosted network, or select from the list of a
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:237
#: lib/block_scout_web/templates/transaction/overview.html.eex:238
msgid "Used"
msgstr ""
@ -1559,8 +1569,8 @@ msgid "Validator Info"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:180
#: lib/block_scout_web/templates/transaction/overview.html.eex:215
#: lib/block_scout_web/templates/transaction/overview.html.eex:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:216
msgid "Value"
msgstr ""
@ -1571,7 +1581,7 @@ msgid "Verify & Publish"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:292
msgid "Verify & publish"
msgstr ""
@ -1588,12 +1598,12 @@ msgid "Version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:86
#: lib/block_scout_web/templates/chain/show.html.eex:80
msgid "View All Blocks"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:144
#: lib/block_scout_web/templates/chain/show.html.eex:138
msgid "View All Transactions"
msgstr ""
@ -1635,7 +1645,7 @@ msgid "WEI"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:72
#: lib/block_scout_web/templates/chain/show.html.eex:65
msgid "Wallet addresses"
msgstr ""
@ -1645,12 +1655,14 @@ msgid "Wei"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:94
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:137
msgid "Yes"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:99
#: lib/block_scout_web/templates/address/overview.html.eex:101
msgid "at"
msgstr ""
@ -1708,8 +1720,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:37
#: lib/block_scout_web/templates/address/overview.html.eex:132
#: lib/block_scout_web/templates/address/overview.html.eex:140
#: lib/block_scout_web/templates/address/overview.html.eex:134
#: lib/block_scout_web/templates/address/overview.html.eex:142
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:94
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:102
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:106
@ -1735,7 +1747,7 @@ msgid "Decimals"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:233
#: lib/block_scout_web/templates/transaction/overview.html.eex:234
msgid "Gas"
msgstr ""
@ -1745,13 +1757,12 @@ msgid "If it still does not show up after 1 hour, please check with your sender/
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:58
#: lib/block_scout_web/templates/layout/app.html.eex:28
msgid "Indexing Tokens"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:22
#: lib/block_scout_web/templates/chain/show.html.eex:13
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:24
msgid "Loading chart"
msgstr ""
@ -1763,7 +1774,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/metadata/index.html.eex:18
#: lib/block_scout_web/templates/tokens/instance/overview/_tabs.html.eex:10
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:72
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:73
msgid "Metadata"
msgstr ""
@ -1773,7 +1784,7 @@ msgid "Module"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:56
#: lib/block_scout_web/templates/chain/show.html.eex:49
msgid "Total transactions"
msgstr ""
@ -1784,80 +1795,82 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:134
#: lib/block_scout_web/templates/transaction/overview.html.eex:147
msgid "Copy Txn Input"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:31
#: lib/block_scout_web/templates/address/_tabs.html.eex:37
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/address_view.ex:313
msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:40
#: lib/block_scout_web/templates/address/_tabs.html.eex:46
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:165
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
#: lib/block_scout_web/views/address_view.ex:307
#: lib/block_scout_web/views/address_view.ex:309
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/views/address_view.ex:310
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/views/address_view.ex:312
msgid "Coin Balance History"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/address_view.ex:310
msgid "Decompiled Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:306
#: lib/block_scout_web/views/transaction_view.ex:314
#: lib/block_scout_web/views/address_view.ex:307
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Internal Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/templates/address/_tabs.html.eex:32
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:312
#: lib/block_scout_web/views/transaction_view.ex:315
#: lib/block_scout_web/views/address_view.ex:314
#: lib/block_scout_web/views/transaction_view.ex:316
msgid "Logs"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:56
#: lib/block_scout_web/templates/address/_tabs.html.eex:62
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
#: lib/block_scout_web/views/address_view.ex:309
#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
#: lib/block_scout_web/views/address_view.ex:304
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:11
#: lib/block_scout_web/views/address_view.ex:305
msgid "Tokens"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:3
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:17
#: lib/block_scout_web/templates/address_transaction/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:10
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/chain/show.html.eex:139
#: lib/block_scout_web/templates/layout/_topnav.html.eex:50
#: lib/block_scout_web/views/address_view.ex:305
#: lib/block_scout_web/views/address_view.ex:306
msgid "Transactions"
msgstr ""

@ -13,7 +13,7 @@ msgstr[0] ""
msgstr[1] ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:193
#: lib/block_scout_web/templates/transaction/overview.html.eex:194
msgid " Token Transfer"
msgstr ""
@ -72,7 +72,7 @@ msgid "(query)"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:42
#: lib/block_scout_web/templates/layout/app.html.eex:55
msgid "- We're indexing this chain right now. Some of the counts may be inaccurate."
msgstr ""
@ -87,7 +87,7 @@ msgid "A string with the name of the module to be invoked."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:147
msgid "ABI-encoded Constructor Arguments (if required by the contract)"
msgstr ""
@ -124,7 +124,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:16
#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19
#: lib/block_scout_web/views/address_view.ex:99
#: lib/block_scout_web/views/address_view.ex:100
msgid "Address"
msgstr ""
@ -135,9 +135,11 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:27
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:25
#: lib/block_scout_web/templates/address_transaction/index.html.eex:23
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:21
#: lib/block_scout_web/views/address_internal_transaction_view.ex:8
#: lib/block_scout_web/views/address_token_transfer_view.ex:8
#: lib/block_scout_web/views/address_transaction_view.ex:8
msgid "All"
msgstr ""
@ -148,7 +150,7 @@ msgid "Anything not in this list is not supported. Click on the method to be tak
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:47
#: lib/block_scout_web/templates/chain/show.html.eex:40
msgid "Average block time"
msgstr ""
@ -163,7 +165,7 @@ msgid "Balance"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:14
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:16
msgid "Balances"
msgstr ""
@ -206,7 +208,7 @@ msgid "Block Height: %{height}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:57
#: lib/block_scout_web/templates/layout/app.html.eex:27
msgid "Block Mined, awaiting import..."
msgstr ""
@ -231,14 +233,14 @@ msgid "BlockScout provides analytics data, API, and Smart Contract tools for the
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:87
#: lib/block_scout_web/templates/chain/show.html.eex:81
#: lib/block_scout_web/templates/layout/_topnav.html.eex:31
#: lib/block_scout_web/templates/layout/_topnav.html.eex:35
msgid "Blocks"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:56
#: lib/block_scout_web/templates/layout/app.html.eex:26
msgid "Blocks Indexed"
msgstr ""
@ -264,7 +266,7 @@ msgid "Call Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:296
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54
msgid "Cancel"
@ -287,7 +289,7 @@ msgid "Clear"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:62
msgid "Compiler"
msgstr ""
@ -302,7 +304,7 @@ msgid "Connection Lost"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:10
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:12
#: lib/block_scout_web/templates/block/index.html.eex:6
msgid "Connection Lost, click to load newer blocks"
msgstr ""
@ -336,14 +338,14 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:18
#: lib/block_scout_web/views/address_view.ex:97
#: lib/block_scout_web/views/address_view.ex:98
msgid "Contract Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:16
#: lib/block_scout_web/views/address_view.ex:37
#: lib/block_scout_web/views/address_view.ex:71
#: lib/block_scout_web/views/address_view.ex:38
#: lib/block_scout_web/views/address_view.ex:72
msgid "Contract Address Pending"
msgstr ""
@ -353,12 +355,12 @@ msgid "Contract Byte Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:261
#: lib/block_scout_web/views/transaction_view.ex:262
msgid "Contract Call"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:260
#: lib/block_scout_web/views/transaction_view.ex:261
msgid "Contract Creation"
msgstr ""
@ -368,7 +370,7 @@ msgid "Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:161
msgid "Contract Libraries"
msgstr ""
@ -465,7 +467,7 @@ msgid "Create2"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:94
#: lib/block_scout_web/templates/address/overview.html.eex:96
msgid "Created by"
msgstr ""
@ -497,7 +499,7 @@ msgid "Decoded"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:50
#: lib/block_scout_web/templates/address/_tabs.html.eex:56
msgid "Decompiled code"
msgstr ""
@ -577,7 +579,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:45
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:73
msgid "EVM Version"
msgstr ""
@ -597,7 +599,7 @@ msgid "Emission Reward"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:115
msgid "Enter the Solidity Contract Code"
msgstr ""
@ -629,7 +631,7 @@ msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:107
#: lib/block_scout_web/templates/address/overview.html.eex:109
msgid "Error: Could not determine contract creator."
msgstr ""
@ -641,11 +643,11 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_balance_card.html.eex:15
#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:20
#: lib/block_scout_web/templates/layout/app.html.eex:62
#: lib/block_scout_web/templates/layout/app.html.eex:32
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20
#: lib/block_scout_web/templates/transaction/_tile.html.eex:29
#: lib/block_scout_web/templates/transaction/overview.html.eex:180
#: lib/block_scout_web/templates/transaction/overview.html.eex:215
#: lib/block_scout_web/templates/transaction/overview.html.eex:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:216
#: lib/block_scout_web/views/wei_helpers.ex:78
msgid "Ether"
msgstr ""
@ -706,8 +708,10 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:42
#: lib/block_scout_web/templates/address_transaction/index.html.eex:40
#: lib/block_scout_web/views/address_internal_transaction_view.ex:7
#: lib/block_scout_web/views/address_token_transfer_view.ex:7
#: lib/block_scout_web/views/address_transaction_view.ex:7
msgid "From"
msgstr ""
@ -810,7 +814,7 @@ msgid "There are no logs for this transaction."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:15
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:60
msgid "There are no token transfers for this address."
msgstr ""
@ -847,8 +851,10 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:33
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31
#: lib/block_scout_web/templates/address_transaction/index.html.eex:29
#: lib/block_scout_web/views/address_internal_transaction_view.ex:6
#: lib/block_scout_web/views/address_token_transfer_view.ex:6
#: lib/block_scout_web/views/address_transaction_view.ex:6
msgid "To"
msgstr ""
@ -879,20 +885,22 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:5
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:259
#: lib/block_scout_web/views/transaction_view.ex:260
msgid "Token Transfer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/tokens/instance/overview/_tabs.html.eex:3
#: lib/block_scout_web/templates/tokens/instance/transfer/index.html.eex:16
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:3
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:14
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:7
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:71
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:72
#: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:313
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Token Transfers"
msgstr ""
@ -908,7 +916,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:18
#: lib/block_scout_web/views/transaction_view.ex:262
#: lib/block_scout_web/views/transaction_view.ex:263
msgid "Transaction"
msgstr ""
@ -953,30 +961,30 @@ msgid "It could still be in the TX Pool of a different node, waiting to be broad
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:79
#: lib/block_scout_web/templates/address/overview.html.eex:81
msgid "Last Balance Update: Block #"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:59
#: lib/block_scout_web/templates/layout/app.html.eex:29
msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:176
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:198
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:220
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:242
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:264
msgid "Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:166
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:188
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:210
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:232
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:254
msgid "Library Name"
msgstr ""
@ -991,7 +999,7 @@ msgid "License ID"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:243
#: lib/block_scout_web/templates/transaction/overview.html.eex:244
msgid "Limit"
msgstr ""
@ -1002,7 +1010,7 @@ msgid "Loading..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:290
msgid "Loading...."
msgstr ""
@ -1025,10 +1033,10 @@ msgid "Mainnet"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:31
#: lib/block_scout_web/templates/layout/app.html.eex:60
#: lib/block_scout_web/views/address_view.ex:125
#: lib/block_scout_web/views/address_view.ex:125
#: lib/block_scout_web/templates/chain/show.html.eex:24
#: lib/block_scout_web/templates/layout/app.html.eex:30
#: lib/block_scout_web/views/address_view.ex:126
#: lib/block_scout_web/views/address_view.ex:126
msgid "Market Cap"
msgstr ""
@ -1059,7 +1067,7 @@ msgid "More internal transactions have come in"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:148
#: lib/block_scout_web/templates/chain/show.html.eex:142
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:10
#: lib/block_scout_web/templates/transaction/index.html.eex:10
msgid "More transactions have come in"
@ -1088,7 +1096,9 @@ msgid "New Smart Contract Verification"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:46
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:89
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:132
msgid "No"
msgstr ""
@ -1105,7 +1115,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:39
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:105
msgid "Optimization runs"
msgstr ""
@ -1160,14 +1170,14 @@ msgid "Potential matches from our contract method database:"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:24
#: lib/block_scout_web/templates/layout/app.html.eex:61
#: lib/block_scout_web/templates/chain/show.html.eex:17
#: lib/block_scout_web/templates/layout/app.html.eex:31
msgid "Price"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:33
#: lib/block_scout_web/templates/address/overview.html.eex:131
#: lib/block_scout_web/templates/address/overview.html.eex:133
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:51
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:93
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:36
@ -1193,7 +1203,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:316
#: lib/block_scout_web/views/transaction_view.ex:317
msgid "Raw Trace"
msgstr ""
@ -1209,7 +1219,7 @@ msgid "Request URL"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:293
msgid "Reset"
msgstr ""
@ -1296,15 +1306,15 @@ msgid "Block Rewards"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:36
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61
#: lib/block_scout_web/templates/address_logs/index.html.eex:21
#: lib/block_scout_web/templates/address_token/index.html.eex:13
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:65
#: lib/block_scout_web/templates/address_transaction/index.html.eex:59
#: lib/block_scout_web/templates/address_validation/index.html.eex:22
#: lib/block_scout_web/templates/block_transaction/index.html.eex:23
#: lib/block_scout_web/templates/chain/show.html.eex:91
#: lib/block_scout_web/templates/chain/show.html.eex:85
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:19
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:20
#: lib/block_scout_web/templates/tokens/instance/transfer/index.html.eex:21
@ -1318,7 +1328,7 @@ msgid "Something went wrong, click to reload."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:154
#: lib/block_scout_web/templates/chain/show.html.eex:148
msgid "Something went wrong, click to retry."
msgstr ""
@ -1383,7 +1393,7 @@ msgid "There are no transactions."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:39
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:41
msgid "There is no coin history for this address."
msgstr ""
@ -1393,8 +1403,8 @@ msgid "There is no decompilded contracts for this address."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:25
#: lib/block_scout_web/templates/chain/show.html.eex:16
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:27
#: lib/block_scout_web/templates/chain/show.html.eex:9
msgid "There was a problem loading the chart."
msgstr ""
@ -1447,7 +1457,7 @@ msgid "Total Supply"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:64
#: lib/block_scout_web/templates/chain/show.html.eex:57
msgid "Total blocks"
msgstr ""
@ -1529,7 +1539,7 @@ msgid "Use the search box to find a hosted network, or select from the list of a
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:237
#: lib/block_scout_web/templates/transaction/overview.html.eex:238
msgid "Used"
msgstr ""
@ -1559,8 +1569,8 @@ msgid "Validator Info"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:180
#: lib/block_scout_web/templates/transaction/overview.html.eex:215
#: lib/block_scout_web/templates/transaction/overview.html.eex:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:216
msgid "Value"
msgstr ""
@ -1571,7 +1581,7 @@ msgid "Verify & Publish"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:292
msgid "Verify & publish"
msgstr ""
@ -1588,12 +1598,12 @@ msgid "Version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:86
#: lib/block_scout_web/templates/chain/show.html.eex:80
msgid "View All Blocks"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:144
#: lib/block_scout_web/templates/chain/show.html.eex:138
msgid "View All Transactions"
msgstr ""
@ -1635,7 +1645,7 @@ msgid "WEI"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:72
#: lib/block_scout_web/templates/chain/show.html.eex:65
msgid "Wallet addresses"
msgstr ""
@ -1645,12 +1655,14 @@ msgid "Wei"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:94
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:137
msgid "Yes"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:99
#: lib/block_scout_web/templates/address/overview.html.eex:101
msgid "at"
msgstr ""
@ -1708,8 +1720,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:37
#: lib/block_scout_web/templates/address/overview.html.eex:132
#: lib/block_scout_web/templates/address/overview.html.eex:140
#: lib/block_scout_web/templates/address/overview.html.eex:134
#: lib/block_scout_web/templates/address/overview.html.eex:142
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:94
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:102
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:106
@ -1735,7 +1747,7 @@ msgid "Decimals"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:233
#: lib/block_scout_web/templates/transaction/overview.html.eex:234
msgid "Gas"
msgstr ""
@ -1745,13 +1757,12 @@ msgid "If it still does not show up after 1 hour, please check with your sender/
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:58
#: lib/block_scout_web/templates/layout/app.html.eex:28
msgid "Indexing Tokens"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:22
#: lib/block_scout_web/templates/chain/show.html.eex:13
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:24
msgid "Loading chart"
msgstr ""
@ -1763,7 +1774,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/metadata/index.html.eex:18
#: lib/block_scout_web/templates/tokens/instance/overview/_tabs.html.eex:10
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:72
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:73
msgid "Metadata"
msgstr ""
@ -1773,7 +1784,7 @@ msgid "Module"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:56
#: lib/block_scout_web/templates/chain/show.html.eex:49
msgid "Total transactions"
msgstr ""
@ -1784,80 +1795,82 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:134
#: lib/block_scout_web/templates/transaction/overview.html.eex:147
msgid "Copy Txn Input"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:31
#: lib/block_scout_web/templates/address/_tabs.html.eex:37
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/address_view.ex:313
msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:40
#: lib/block_scout_web/templates/address/_tabs.html.eex:46
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:165
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
#: lib/block_scout_web/views/address_view.ex:307
#: lib/block_scout_web/views/address_view.ex:309
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/views/address_view.ex:310
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/views/address_view.ex:312
msgid "Coin Balance History"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/address_view.ex:310
msgid "Decompiled Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:306
#: lib/block_scout_web/views/transaction_view.ex:314
#: lib/block_scout_web/views/address_view.ex:307
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Internal Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/templates/address/_tabs.html.eex:32
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:312
#: lib/block_scout_web/views/transaction_view.ex:315
#: lib/block_scout_web/views/address_view.ex:314
#: lib/block_scout_web/views/transaction_view.ex:316
msgid "Logs"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:56
#: lib/block_scout_web/templates/address/_tabs.html.eex:62
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
#: lib/block_scout_web/views/address_view.ex:309
#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
#: lib/block_scout_web/views/address_view.ex:304
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:11
#: lib/block_scout_web/views/address_view.ex:305
msgid "Tokens"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:3
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:17
#: lib/block_scout_web/templates/address_transaction/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:10
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/chain/show.html.eex:139
#: lib/block_scout_web/templates/layout/_topnav.html.eex:50
#: lib/block_scout_web/views/address_view.ex:305
#: lib/block_scout_web/views/address_view.ex:306
msgid "Transactions"
msgstr ""

@ -134,7 +134,15 @@ defmodule BlockScoutWeb.AddressChannelTest do
|> insert(from_address: address)
|> with_block()
internal_transaction = insert(:internal_transaction, transaction: transaction, from_address: address, index: 0)
internal_transaction =
insert(
:internal_transaction,
transaction: transaction,
from_address: address,
index: 0,
block_hash: transaction.block_hash,
block_index: 0
)
Notifier.handle_event({:chain_event, :internal_transactions, :realtime, [internal_transaction]})
@ -158,7 +166,14 @@ defmodule BlockScoutWeb.AddressChannelTest do
|> insert(to_address: address)
|> with_block()
internal_transaction = insert(:internal_transaction, transaction: transaction, to_address: address, index: 0)
internal_transaction =
insert(:internal_transaction,
transaction: transaction,
to_address: address,
index: 0,
block_hash: transaction.block_hash,
block_index: 0
)
Notifier.handle_event({:chain_event, :internal_transactions, :realtime, [internal_transaction]})
@ -186,7 +201,14 @@ defmodule BlockScoutWeb.AddressChannelTest do
|> with_block()
internal_transaction =
insert(:internal_transaction, transaction: transaction, from_address: address, to_address: address, index: 0)
insert(:internal_transaction,
transaction: transaction,
from_address: address,
to_address: address,
index: 0,
block_hash: transaction.block_hash,
block_index: 0
)
Notifier.handle_event({:chain_event, :internal_transactions, :realtime, [internal_transaction]})

@ -36,13 +36,15 @@ defmodule BlockScoutWeb.AddressContractControllerTest do
test "successfully renders the page when the address is a contract", %{conn: conn} do
address = insert(:address, contract_code: Factory.data("contract_code"), smart_contract: nil)
transaction = insert(:transaction, from_address: address)
transaction = insert(:transaction, from_address: address) |> with_block()
insert(
:internal_transaction_create,
index: 0,
transaction: transaction,
created_contract_address: address
created_contract_address: address,
block_hash: transaction.block_hash,
block_index: 0
)
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, Address.checksum(address)))

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save