Merge branch 'master' into va-add-creationMethod

pull/2950/head
varasev 5 years ago committed by GitHub
commit 333381c89d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      .circleci/config.yml
  2. 30
      CHANGELOG.md
  3. 7
      apps/block_scout_web/assets/css/theme/_ethercore_variables-non-critical.scss
  4. 84
      apps/block_scout_web/assets/css/theme/_ethercore_variables.scss
  5. 1
      apps/block_scout_web/assets/css/theme/_variables-non-critical.scss
  6. 1
      apps/block_scout_web/assets/css/theme/_variables.scss
  7. 9
      apps/block_scout_web/assets/js/lib/try_eth_api.js
  8. 40
      apps/block_scout_web/assets/js/pages/verification_form.js
  9. 7
      apps/block_scout_web/assets/js/socket.js
  10. 52
      apps/block_scout_web/assets/package-lock.json
  11. 4
      apps/block_scout_web/assets/package.json
  12. 10139
      apps/block_scout_web/assets/static/images/ethercore_logo.svg
  13. 5382
      apps/block_scout_web/assets/static/images/ethercore_testnet_logo.svg
  14. 0
      apps/block_scout_web/assets/static/manifest.webmanifest
  15. 6
      apps/block_scout_web/assets/webpack.config.js
  16. 3
      apps/block_scout_web/config/config.exs
  17. 3
      apps/block_scout_web/config/dev.exs
  18. 3
      apps/block_scout_web/config/prod.exs
  19. 4
      apps/block_scout_web/lib/block_scout_web/endpoint.ex
  20. 32
      apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex
  21. 2
      apps/block_scout_web/lib/block_scout_web/templates/layout/app.html.eex
  22. 1
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  23. 21
      apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex
  24. 2
      apps/block_scout_web/lib/block_scout_web/views/smart_contract_view.ex
  25. 5
      apps/block_scout_web/lib/block_scout_web/views/tokens/instance/overview_view.ex
  26. 10
      apps/block_scout_web/mix.exs
  27. 55
      apps/block_scout_web/priv/gettext/default.pot
  28. 55
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  29. 2
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs
  30. 2
      apps/block_scout_web/test/block_scout_web/controllers/api/v1/verified_smart_contract_controller_test.exs
  31. 6
      apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs
  32. 13
      apps/block_scout_web/test/support/fixture/smart_contract/contract_with_lib.json
  33. 2
      apps/explorer/config/config.exs
  34. 2
      apps/explorer/lib/explorer/admin/role.ex
  35. 2
      apps/explorer/lib/explorer/chain/block/range.ex
  36. 2
      apps/explorer/lib/explorer/chain/block/reward/address_type.ex
  37. 2
      apps/explorer/lib/explorer/chain/data.ex
  38. 2
      apps/explorer/lib/explorer/chain/hash/address.ex
  39. 2
      apps/explorer/lib/explorer/chain/hash/full.ex
  40. 2
      apps/explorer/lib/explorer/chain/hash/nonce.ex
  41. 4
      apps/explorer/lib/explorer/chain/import/runner/blocks.ex
  42. 6
      apps/explorer/lib/explorer/chain/import/runner/staking_pools.ex
  43. 2
      apps/explorer/lib/explorer/chain/internal_transaction/call_type.ex
  44. 2
      apps/explorer/lib/explorer/chain/internal_transaction/type.ex
  45. 2
      apps/explorer/lib/explorer/chain/method_identifier.ex
  46. 2
      apps/explorer/lib/explorer/chain/transaction/status.ex
  47. 2
      apps/explorer/lib/explorer/chain/wei.ex
  48. 45
      apps/explorer/lib/explorer/smart_contract/verifier.ex
  49. 129
      apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
  50. 6
      apps/explorer/mix.exs
  51. 204
      apps/explorer/package-lock.json
  52. 6
      apps/explorer/package.json
  53. 70
      apps/explorer/priv/repo/migrations/20191018140054_add_pending_internal_txs_operation.exs
  54. 9
      apps/explorer/priv/repo/migrations/20191128124415_remove_duplicate_indexes_token_entities.exs
  55. 66
      apps/explorer/priv/repo/migrations/scripts/20181108205650_additional_internal_transaction_constraints.sql
  56. 73
      apps/explorer/priv/repo/migrations/scripts/20191018140054_send_block_hash_block_index_dups_to_carnitine.sql
  57. 2
      apps/explorer/test/explorer/smart_contract/publisher_test.exs
  58. 559
      apps/explorer/test/explorer/smart_contract/verifier/constructor_arguments_test.exs
  59. 45
      apps/explorer/test/explorer/smart_contract/verifier_test.exs
  60. 13
      apps/explorer/test/support/fixture/smart_contract/contract_with_lib.json
  61. 6
      docker/Dockerfile
  62. 178
      docker/Makefile
  63. 22
      mix.lock
  64. 8
      rel/commands/clear_build.sh

@ -345,7 +345,7 @@ jobs:
# PGUSER: postgres # PGUSER: postgres
# ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Geth.HTTPWebSocket" # ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Geth.HTTPWebSocket"
# ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Geth" # ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Geth"
# - image: circleci/postgres:10.3-alpine # - image: circleci/postgres:10.10-alpine
# environment: # environment:
# # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database # # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
# POSTGRES_DB: explorer_test # POSTGRES_DB: explorer_test
@ -399,7 +399,7 @@ jobs:
# PGUSER: postgres # PGUSER: postgres
# ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Geth.Mox" # ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Geth.Mox"
# ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" # ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox"
# - image: circleci/postgres:10.3-alpine # - image: circleci/postgres:10.10-alpine
# environment: # environment:
# # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database # # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
# POSTGRES_DB: explorer_test # POSTGRES_DB: explorer_test
@ -453,7 +453,7 @@ jobs:
# PGUSER: postgres # PGUSER: postgres
# ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Parity.HTTPWebSocket" # ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Parity.HTTPWebSocket"
# ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Parity" # ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Parity"
# - image: circleci/postgres:10.3-alpine # - image: circleci/postgres:10.10-alpine
# environment: # environment:
# # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database # # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
# POSTGRES_DB: explorer_test # POSTGRES_DB: explorer_test
@ -507,7 +507,7 @@ jobs:
PGUSER: postgres PGUSER: postgres
ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Parity.Mox" ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Parity.Mox"
ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox"
- image: circleci/postgres:10.3-alpine - image: circleci/postgres:10.10-alpine
environment: environment:
# Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database # Match apps/explorer/config/test.exs config :explorer, Explorer.Repo, database
POSTGRES_DB: explorer_test POSTGRES_DB: explorer_test

@ -1,12 +1,32 @@
## Current ## Current
### Features ### 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) - Add "block_hash" to logs, token_transfers and internal transactions and "pending blocks operations" approach
### Fixes
- [#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
- [#2897](https://github.com/poanetwork/blockscout/pull/2897) - remove duplicate indexes
### Chore
## 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 - [#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 - [#2918](https://github.com/poanetwork/blockscout/pull/2918) - Add tokenID for tokentx API action explicitly
### Fixes ### 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
- [#2950](https://github.com/poanetwork/blockscout/pull/2950) - Add `creationMethod` to `EthereumJSONRPC.Parity.Trace.Action.entry_to_elixir` - [#2950](https://github.com/poanetwork/blockscout/pull/2950) - Add `creationMethod` to `EthereumJSONRPC.Parity.Trace.Action.entry_to_elixir`
- [#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 - [#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 - [#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 - [#2932](https://github.com/poanetwork/blockscout/pull/2932) - fix duplicate websocket connection
@ -14,6 +34,7 @@
- [#2924](https://github.com/poanetwork/blockscout/pull/2924) - Speedup address to logs 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 - [#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 - [#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 - [#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 - [#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 - [#2902](https://github.com/poanetwork/blockscout/pull/2902) - Offset in blocks retrieval for average block time
@ -21,9 +42,12 @@
- [#2899](https://github.com/poanetwork/blockscout/pull/2899) - fix empty buffered task - [#2899](https://github.com/poanetwork/blockscout/pull/2899) - fix empty buffered task
- [#2887](https://github.com/poanetwork/blockscout/pull/2887) - increase chart loading speed - [#2887](https://github.com/poanetwork/blockscout/pull/2887) - increase chart loading speed
- [2910](https://github.com/poanetwork/blockscout/pull/2910) - Reorganize queries and indexes for internal_transactions table
### Chore ### 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 - [#2896](https://github.com/poanetwork/blockscout/pull/2896) - Disable Parity websockets tests

@ -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;

@ -21,3 +21,4 @@
// @import "tobalaba_variables-non-critical"; // @import "tobalaba_variables-non-critical";
// @import "tomochain_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 "tobalaba_variables";
// @import "tomochain_variables"; // @import "tomochain_variables";
// @import "rsk_variables"; // @import "rsk_variables";
// @import "ethercore_variables";
// responsive breakpoints // responsive breakpoints
$breakpoint-xs: 320px; $breakpoint-xs: 320px;

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

@ -88,6 +88,26 @@ const elements = {
const $contractVerificationPage = $('[data-page="contract-verification"]') 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) { if ($contractVerificationPage.length) {
const store = createStore(reducer) const store = createStore(reducer)
const addressHash = $('#smart_contract_address_hash').val() const addressHash = $('#smart_contract_address_hash').val()
@ -116,6 +136,10 @@ if ($contractVerificationPage.length) {
}) })
$(function () { $(function () {
setTimeout(function () {
$('.nightly-builds-false').trigger('click')
}, 10)
$('.js-btn-add-contract-libraries').on('click', function () { $('.js-btn-add-contract-libraries').on('click', function () {
$('.js-smart-contract-libraries-wrapper').show() $('.js-smart-contract-libraries-wrapper').show()
$(this).hide() $(this).hide()
@ -129,6 +153,22 @@ if ($contractVerificationPage.length) {
if ($(this).prop('checked')) { $('.constructor-arguments').hide() } 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-smart-contract-form-reset').on('click', function () {
$('.js-contract-library-form-group').removeClass('active') $('.js-contract-library-form-group').removeClass('active')
$('.js-contract-library-form-group').first().addClass('active') $('.js-contract-library-form-group').first().addClass('active')

@ -1,7 +1,12 @@
import { Socket } from 'phoenix' import { Socket } from 'phoenix'
import { locale } from './locale' 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() socket.connect()
export default socket export default socket

@ -5883,9 +5883,9 @@
"dev": true "dev": true
}, },
"handlebars": { "handlebars": {
"version": "4.5.1", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.1.tgz", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.6.0.tgz",
"integrity": "sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA==", "integrity": "sha512-i1ZUP7Qp2JdkMaFon2a+b0m5geE8Z4ZTLaGkgrObkEd+OkUKyRbRWw4KxuFCoHfdETSY1yf9/574eVoNSiK7pw==",
"dev": true, "dev": true,
"requires": { "requires": {
"neo-async": "^2.6.0", "neo-async": "^2.6.0",
@ -11466,9 +11466,9 @@
"dev": true "dev": true
}, },
"serialize-javascript": { "serialize-javascript": {
"version": "2.1.0", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.0.tgz", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
"integrity": "sha512-a/mxFfU00QT88umAJQsNWOnUKckhNCqOl028N48e7wFmo2/EHpTo9Wso+iJJCMrQnmFvcjto5RJdAHEvVhcyUQ==", "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
"dev": true "dev": true
}, },
"set-blocking": { "set-blocking": {
@ -12672,9 +12672,9 @@
"dev": true "dev": true
}, },
"uglify-js": { "uglify-js": {
"version": "3.6.9", "version": "3.7.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.4.tgz",
"integrity": "sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw==", "integrity": "sha512-tinYWE8X1QfCHxS1lBS8yiDekyhSXOO6R66yNOCdUJeojxxw+PX2BHAz/BWyW7PQ7pkiWVxJfIEbiDxyLWvUGg==",
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
@ -13312,12 +13312,6 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true "dev": true
}, },
"serialize-javascript": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
"integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==",
"dev": true
},
"source-map": { "source-map": {
"version": "0.6.1", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -13325,20 +13319,31 @@
"dev": true "dev": true
}, },
"terser-webpack-plugin": { "terser-webpack-plugin": {
"version": "1.4.1", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
"integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
"dev": true, "dev": true,
"requires": { "requires": {
"cacache": "^12.0.2", "cacache": "^12.0.2",
"find-cache-dir": "^2.1.0", "find-cache-dir": "^2.1.0",
"is-wsl": "^1.1.0", "is-wsl": "^1.1.0",
"schema-utils": "^1.0.0", "schema-utils": "^1.0.0",
"serialize-javascript": "^1.7.0", "serialize-javascript": "^2.1.2",
"source-map": "^0.6.1", "source-map": "^0.6.1",
"terser": "^4.1.2", "terser": "^4.1.2",
"webpack-sources": "^1.4.0", "webpack-sources": "^1.4.0",
"worker-farm": "^1.7.0" "worker-farm": "^1.7.0"
},
"dependencies": {
"worker-farm": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
"integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
"dev": true,
"requires": {
"errno": "~0.1.7"
}
}
} }
} }
} }
@ -13586,15 +13591,6 @@
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
"dev": true "dev": true
}, },
"worker-farm": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
"integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
"dev": true,
"requires": {
"errno": "~0.1.7"
}
},
"wrap-ansi": { "wrap-ansi": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",

@ -8,8 +8,8 @@
"author": "POA Network", "author": "POA Network",
"license": "GPL-3.0", "license": "GPL-3.0",
"engines": { "engines": {
"node": "9.x", "node": "12.x",
"npm": "5.x" "npm": "6.x"
}, },
"scripts": { "scripts": {
"deploy": "webpack --mode production", "deploy": "webpack --mode production",

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

@ -5,6 +5,7 @@ const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin')
const { ContextReplacementPlugin } = require('webpack') const { ContextReplacementPlugin } = require('webpack')
const glob = require('glob') const glob = require('glob')
const webpack = require('webpack')
function transpileViewScript(file) { function transpileViewScript(file) {
return { return {
@ -136,7 +137,10 @@ const appJs =
filename: '../css/[name].css' filename: '../css/[name].css'
}), }),
new CopyWebpackPlugin([{ from: 'static/', to: '../' }]), 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)
})
] ]
} }

@ -41,7 +41,8 @@ config :block_scout_web, BlockScoutWeb.Endpoint,
url: [ url: [
scheme: System.get_env("BLOCKSCOUT_PROTOCOL") || "http", scheme: System.get_env("BLOCKSCOUT_PROTOCOL") || "http",
host: System.get_env("BLOCKSCOUT_HOST") || "localhost", 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)], render_errors: [view: BlockScoutWeb.ErrorView, accepts: ~w(html json)],
pubsub: [name: BlockScoutWeb.PubSub] pubsub: [name: BlockScoutWeb.PubSub]

@ -21,7 +21,8 @@ config :block_scout_web, BlockScoutWeb.Endpoint,
url: [ url: [
scheme: "http", scheme: "http",
host: System.get_env("BLOCKSCOUT_HOST") || "localhost", 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: [ https: [
port: (port && port + 1) || 4001, port: (port && port + 1) || 4001,

@ -23,7 +23,8 @@ config :block_scout_web, BlockScoutWeb.Endpoint,
scheme: System.get_env("BLOCKSCOUT_PROTOCOL") || "https", scheme: System.get_env("BLOCKSCOUT_PROTOCOL") || "https",
port: System.get_env("PORT"), port: System.get_env("PORT"),
host: System.get_env("BLOCKSCOUT_HOST") || "localhost", 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 config :block_scout_web, BlockScoutWeb.Tracer, env: "production", disabled?: true

@ -29,9 +29,9 @@ defmodule BlockScoutWeb.Endpoint do
browserconfig.xml browserconfig.xml
mstile-150x150.png mstile-150x150.png
safari-pinned-tab.svg safari-pinned-tab.svg
site.manifest
robots.txt robots.txt
) ),
only_matching: ~w(manifest)
) )
# Code reloading can be explicitly enabled under the # Code reloading can be explicitly enabled under the

@ -35,6 +35,28 @@
</div> </div>
</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">
<div class="smart-contract-form-group-inner-wrapper"> <div class="smart-contract-form-group-inner-wrapper">
<%= label f, :compiler_version, gettext("Compiler") %> <%= label f, :compiler_version, gettext("Compiler") %>
@ -62,12 +84,12 @@
<div class="center-column"> <div class="center-column">
<div class="form-radios-group"> <div class="form-radios-group">
<div class="radio-big"> <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> <div class="radio-icon"></div>
<%= label :smart_contract_optimization, :false, gettext("No"), class: "radio-text" %> <%= label :smart_contract_optimization, :false, gettext("No"), class: "radio-text" %>
</div> </div>
<div class="radio-big"> <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> <div class="radio-icon"></div>
<%= label :smart_contract_optimization, :true, gettext("Yes"), class: "radio-text" %> <%= label :smart_contract_optimization, :true, gettext("Yes"), class: "radio-text" %>
</div> </div>
@ -78,7 +100,7 @@
</div> </div>
</div> </div>
<div class="smart-contract-form-group"> <div class="smart-contract-form-group optimization-runs">
<div class="smart-contract-form-group-inner-wrapper"> <div class="smart-contract-form-group-inner-wrapper">
<%= label f, :name, gettext("Optimization runs") %> <%= label f, :name, gettext("Optimization runs") %>
<div class="center-column"> <div class="center-column">
@ -110,12 +132,12 @@
<%= label :autodetect_contructor_args, :false, gettext("No"), class: "radio-text" %> <%= label :autodetect_contructor_args, :false, gettext("No"), class: "radio-text" %>
</div> </div>
<div class="radio-big"> <div class="radio-big">
<%= radio_button f, :autodetect_contructor_args, true, class: "form-check-input autodetecttrue", "aria-describedby": "optimization-help-block" %> <%= radio_button f, :autodetect_contructor_args, true, class: "form-check-input autodetecttrue", "aria-describedby": "autodetect_contructor_args-help-block" %>
<div class="radio-icon"></div> <div class="radio-icon"></div>
<%= label :autodetect_contructor_args, :true, gettext("Yes"), class: "radio-text" %> <%= label :autodetect_contructor_args, :true, gettext("Yes"), class: "radio-text" %>
</div> </div>
</div> </div>
<%= error_tag f, :autodetect_contructor_args, id: "optimization-help-block", class: "text-danger form-error" %> <%= error_tag f, :autodetect_contructor_args, id: "autodetect_contructor_args-help-block", class: "text-danger form-error" %>
</div> </div>
</div> </div>
</div> </div>

@ -12,7 +12,7 @@
<link rel="apple-touch-icon" sizes="180x180" href="<%= static_path(@conn, "/apple-touch-icon.png") %>"> <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, "/images/favicon-32x32.png") %>"> <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="icon" type="image/png" sizes="16x16" href="<%= static_path(@conn, "/images/favicon-16x16.png") %>">
<link rel="manifest" href="<%= static_path(@conn, "/site.webmanifest") %>"> <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="mask-icon" href="<%= static_path(@conn, "/safari-pinned-tab.svg") %>" color="#5bbad5">
<link rel="shortcut icon" type='image/x-icon' href="<%= static_path(@conn, "/images/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-TileColor" content="#7dd79f">

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

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

@ -10,7 +10,7 @@ defmodule BlockScoutWeb.SmartContractView do
def named_argument?(%{"name" => _}), do: true def named_argument?(%{"name" => _}), do: true
def named_argument?(_), do: false 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 addresses
|> Enum.map(&values(&1, "address")) |> Enum.map(&values(&1, "address"))
|> Enum.join(", ") |> Enum.join(", ")

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

@ -60,13 +60,13 @@ defmodule BlockScoutWeb.Mixfile do
defp deps do defp deps do
[ [
# GraphQL toolkit # GraphQL toolkit
{:absinthe, "~> 1.4"}, {:absinthe, "~> 1.5.0-rc.2"},
# Integrates Absinthe subscriptions with Phoenix # 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 # 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 support for the Relay framework
{:absinthe_relay, "~> 1.4"}, {:absinthe_relay, "~> 1.5.0-rc.0"},
{:bypass, "~> 1.0", only: :test}, {:bypass, "~> 1.0", only: :test},
# To add (CORS)(https://www.w3.org/TR/cors/) # To add (CORS)(https://www.w3.org/TR/cors/)
{:cors_plug, "~> 2.0"}, {:cors_plug, "~> 2.0"},
@ -76,7 +76,7 @@ defmodule BlockScoutWeb.Mixfile do
{:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false}, {: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 # 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 # 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, "~> 2.7"},
{:ex_cldr_numbers, "~> 2.6"}, {:ex_cldr_numbers, "~> 2.6"},
{:ex_cldr_units, "~> 2.5"}, {:ex_cldr_units, "~> 2.5"},

@ -13,7 +13,7 @@ msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#, elixir-format #, 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" msgid " Token Transfer"
msgstr "" msgstr ""
@ -87,7 +87,7 @@ msgid "A string with the name of the module to be invoked."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:125 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:147
msgid "ABI-encoded Constructor Arguments (if required by the contract)" msgid "ABI-encoded Constructor Arguments (if required by the contract)"
msgstr "" msgstr ""
@ -266,7 +266,7 @@ msgid "Call Code"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:274 #: 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/_action_tile.html.eex:47
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54 #: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54
msgid "Cancel" msgid "Cancel"
@ -289,7 +289,7 @@ msgid "Clear"
msgstr "" msgstr ""
#, elixir-format #, 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" msgid "Compiler"
msgstr "" msgstr ""
@ -370,7 +370,7 @@ msgid "Contract Creation Code"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:139 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:161
msgid "Contract Libraries" msgid "Contract Libraries"
msgstr "" msgstr ""
@ -579,7 +579,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:45 #: 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" msgid "EVM Version"
msgstr "" msgstr ""
@ -599,7 +599,7 @@ msgid "Emission Reward"
msgstr "" msgstr ""
#, elixir-format #, 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" msgid "Enter the Solidity Contract Code"
msgstr "" msgstr ""
@ -646,8 +646,8 @@ msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:32 #: 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/_pending_tile.html.eex:20
#: lib/block_scout_web/templates/transaction/_tile.html.eex:29 #: 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:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:215 #: lib/block_scout_web/templates/transaction/overview.html.eex:216
#: lib/block_scout_web/views/wei_helpers.ex:78 #: lib/block_scout_web/views/wei_helpers.ex:78
msgid "Ether" msgid "Ether"
msgstr "" msgstr ""
@ -898,7 +898,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:4 #: 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/templates/transaction_token_transfer/index.html.eex:7
#: lib/block_scout_web/views/address_view.ex:308 #: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:71 #: 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/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:314 #: lib/block_scout_web/views/transaction_view.ex:314
msgid "Token Transfers" msgid "Token Transfers"
@ -971,20 +971,20 @@ msgid "Less than"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:154
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:176 #: 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:198
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:220 #: 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:242
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:264
msgid "Library Address" msgid "Library Address"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:144
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:166 #: 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:188
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:210 #: 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:232
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:254
msgid "Library Name" msgid "Library Name"
msgstr "" msgstr ""
@ -999,7 +999,7 @@ msgid "License ID"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:243 #: lib/block_scout_web/templates/transaction/overview.html.eex:244
msgid "Limit" msgid "Limit"
msgstr "" msgstr ""
@ -1010,7 +1010,7 @@ msgid "Loading..."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:268 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:290
msgid "Loading...." msgid "Loading...."
msgstr "" msgstr ""
@ -1096,8 +1096,9 @@ msgid "New Smart Contract Verification"
msgstr "" msgstr ""
#, elixir-format #, 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:110 #: 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" msgid "No"
msgstr "" msgstr ""
@ -1114,7 +1115,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:39 #: 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" msgid "Optimization runs"
msgstr "" msgstr ""
@ -1218,7 +1219,7 @@ msgid "Request URL"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:271 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:293
msgid "Reset" msgid "Reset"
msgstr "" msgstr ""
@ -1538,7 +1539,7 @@ msgid "Use the search box to find a hosted network, or select from the list of a
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:237 #: lib/block_scout_web/templates/transaction/overview.html.eex:238
msgid "Used" msgid "Used"
msgstr "" msgstr ""
@ -1568,8 +1569,8 @@ msgid "Validator Info"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:180 #: lib/block_scout_web/templates/transaction/overview.html.eex:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:215 #: lib/block_scout_web/templates/transaction/overview.html.eex:216
msgid "Value" msgid "Value"
msgstr "" msgstr ""
@ -1580,7 +1581,7 @@ msgid "Verify & Publish"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:270 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:292
msgid "Verify & publish" msgid "Verify & publish"
msgstr "" msgstr ""
@ -1654,8 +1655,9 @@ msgid "Wei"
msgstr "" msgstr ""
#, elixir-format #, 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:115 #: 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" msgid "Yes"
msgstr "" msgstr ""
@ -1745,7 +1747,7 @@ msgid "Decimals"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:233 #: lib/block_scout_web/templates/transaction/overview.html.eex:234
msgid "Gas" msgid "Gas"
msgstr "" msgstr ""
@ -1772,7 +1774,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/instance/metadata/index.html.eex:18 #: 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/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" msgid "Metadata"
msgstr "" msgstr ""
@ -1793,6 +1795,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:134 #: lib/block_scout_web/templates/transaction/overview.html.eex:134
#: lib/block_scout_web/templates/transaction/overview.html.eex:147
msgid "Copy Txn Input" msgid "Copy Txn Input"
msgstr "" msgstr ""

@ -13,7 +13,7 @@ msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#, elixir-format #, 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" msgid " Token Transfer"
msgstr "" msgstr ""
@ -87,7 +87,7 @@ msgid "A string with the name of the module to be invoked."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:125 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:147
msgid "ABI-encoded Constructor Arguments (if required by the contract)" msgid "ABI-encoded Constructor Arguments (if required by the contract)"
msgstr "" msgstr ""
@ -266,7 +266,7 @@ msgid "Call Code"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:274 #: 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/_action_tile.html.eex:47
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54 #: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54
msgid "Cancel" msgid "Cancel"
@ -289,7 +289,7 @@ msgid "Clear"
msgstr "" msgstr ""
#, elixir-format #, 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" msgid "Compiler"
msgstr "" msgstr ""
@ -370,7 +370,7 @@ msgid "Contract Creation Code"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:139 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:161
msgid "Contract Libraries" msgid "Contract Libraries"
msgstr "" msgstr ""
@ -579,7 +579,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:45 #: 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" msgid "EVM Version"
msgstr "" msgstr ""
@ -599,7 +599,7 @@ msgid "Emission Reward"
msgstr "" msgstr ""
#, elixir-format #, 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" msgid "Enter the Solidity Contract Code"
msgstr "" msgstr ""
@ -646,8 +646,8 @@ msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:32 #: 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/_pending_tile.html.eex:20
#: lib/block_scout_web/templates/transaction/_tile.html.eex:29 #: 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:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:215 #: lib/block_scout_web/templates/transaction/overview.html.eex:216
#: lib/block_scout_web/views/wei_helpers.ex:78 #: lib/block_scout_web/views/wei_helpers.ex:78
msgid "Ether" msgid "Ether"
msgstr "" msgstr ""
@ -898,7 +898,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:4 #: 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/templates/transaction_token_transfer/index.html.eex:7
#: lib/block_scout_web/views/address_view.ex:308 #: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:71 #: 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/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:314 #: lib/block_scout_web/views/transaction_view.ex:314
msgid "Token Transfers" msgid "Token Transfers"
@ -971,20 +971,20 @@ msgid "Less than"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:154
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:176 #: 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:198
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:220 #: 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:242
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:264
msgid "Library Address" msgid "Library Address"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:144
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:166 #: 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:188
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:210 #: 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:232
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:254
msgid "Library Name" msgid "Library Name"
msgstr "" msgstr ""
@ -999,7 +999,7 @@ msgid "License ID"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:243 #: lib/block_scout_web/templates/transaction/overview.html.eex:244
msgid "Limit" msgid "Limit"
msgstr "" msgstr ""
@ -1010,7 +1010,7 @@ msgid "Loading..."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:268 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:290
msgid "Loading...." msgid "Loading...."
msgstr "" msgstr ""
@ -1096,8 +1096,9 @@ msgid "New Smart Contract Verification"
msgstr "" msgstr ""
#, elixir-format #, 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:110 #: 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" msgid "No"
msgstr "" msgstr ""
@ -1114,7 +1115,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:39 #: 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" msgid "Optimization runs"
msgstr "" msgstr ""
@ -1218,7 +1219,7 @@ msgid "Request URL"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:271 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:293
msgid "Reset" msgid "Reset"
msgstr "" msgstr ""
@ -1538,7 +1539,7 @@ msgid "Use the search box to find a hosted network, or select from the list of a
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:237 #: lib/block_scout_web/templates/transaction/overview.html.eex:238
msgid "Used" msgid "Used"
msgstr "" msgstr ""
@ -1568,8 +1569,8 @@ msgid "Validator Info"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:180 #: lib/block_scout_web/templates/transaction/overview.html.eex:181
#: lib/block_scout_web/templates/transaction/overview.html.eex:215 #: lib/block_scout_web/templates/transaction/overview.html.eex:216
msgid "Value" msgid "Value"
msgstr "" msgstr ""
@ -1580,7 +1581,7 @@ msgid "Verify & Publish"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:270 #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:292
msgid "Verify & publish" msgid "Verify & publish"
msgstr "" msgstr ""
@ -1654,8 +1655,9 @@ msgid "Wei"
msgstr "" msgstr ""
#, elixir-format #, 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:115 #: 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" msgid "Yes"
msgstr "" msgstr ""
@ -1745,7 +1747,7 @@ msgid "Decimals"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:233 #: lib/block_scout_web/templates/transaction/overview.html.eex:234
msgid "Gas" msgid "Gas"
msgstr "" msgstr ""
@ -1772,7 +1774,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/instance/metadata/index.html.eex:18 #: 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/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" msgid "Metadata"
msgstr "" msgstr ""
@ -1793,6 +1795,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:134 #: lib/block_scout_web/templates/transaction/overview.html.eex:134
#: lib/block_scout_web/templates/transaction/overview.html.eex:147
msgid "Copy Txn Input" msgid "Copy Txn Input"
msgstr "" msgstr ""

@ -647,7 +647,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
test "with external libraries", %{conn: conn} do test "with external libraries", %{conn: conn} do
contract_data = contract_data =
"#{File.cwd!()}/test/support/fixture/smart_contract/compiler_tests.json" "#{File.cwd!()}/test/support/fixture/smart_contract/contract_with_lib.json"
|> File.read!() |> File.read!()
|> Jason.decode!() |> Jason.decode!()
|> List.first() |> List.first()

@ -28,7 +28,7 @@ defmodule BlockScoutWeb.API.V1.VerifiedControllerTest do
test "verifying a smart contract with external libraries", %{conn: conn} do test "verifying a smart contract with external libraries", %{conn: conn} do
contract_data = contract_data =
"#{File.cwd!()}/test/support/fixture/smart_contract/compiler_tests.json" "#{File.cwd!()}/test/support/fixture/smart_contract/contract_with_lib.json"
|> File.read!() |> File.read!()
|> Jason.decode!() |> Jason.decode!()
|> List.first() |> List.first()

@ -14,7 +14,7 @@ defmodule BlockScoutWeb.ApiDocsViewTest do
test "adds slash before path" do test "adds slash before path" do
Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint,
url: [scheme: "https", host: "blockscout.com", port: 9999, path: "/chain/dog"] url: [scheme: "https", host: "blockscout.com", port: 9999, api_path: "/chain/dog"]
) )
assert APIDocsView.api_url() == "https://blockscout.com/chain/dog/api" assert APIDocsView.api_url() == "https://blockscout.com/chain/dog/api"
@ -22,7 +22,7 @@ defmodule BlockScoutWeb.ApiDocsViewTest do
test "does not add slash to empty path" do test "does not add slash to empty path" do
Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint,
url: [scheme: "https", host: "blockscout.com", port: 9999, path: ""] url: [scheme: "https", host: "blockscout.com", port: 9999, api_path: ""]
) )
assert APIDocsView.api_url() == "https://blockscout.com/api" assert APIDocsView.api_url() == "https://blockscout.com/api"
@ -49,7 +49,7 @@ defmodule BlockScoutWeb.ApiDocsViewTest do
test "adds slash before path" do test "adds slash before path" do
Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint,
url: [scheme: "https", host: "blockscout.com", port: 9999, path: "/chain/dog"] url: [scheme: "https", host: "blockscout.com", port: 9999, api_path: "/chain/dog"]
) )
assert APIDocsView.eth_rpc_api_url() == "https://blockscout.com/chain/dog/api/eth_rpc" assert APIDocsView.eth_rpc_api_url() == "https://blockscout.com/chain/dog/api/eth_rpc"

@ -0,0 +1,13 @@
[
{
"compiler_version": "v0.5.11+commit.c082d0b4",
"contract": "pragma solidity 0.5.11;library BadSafeMath { function add(uint256 a, uint256 b) public pure returns (uint256) { uint256 c = a + 2 * b; require(c >= a, \"SafeMath: addition overflow\"); return c; }}contract SimpleStorage { uint256 storedData = 10; using BadSafeMath for uint256; function increment(uint256 x) public { storedData = storedData.add(x); } function set(uint256 x) public { storedData = x; } function get() public view returns (uint256) { return storedData; }}",
"expected_bytecode": "608060405234801561001057600080fd5b50600436106100415760003560e01c806360fe47b1146100465780636d4ce63c146100655780637cf5dab01461007f575b600080fd5b6100636004803603602081101561005c57600080fd5b503561009c565b005b61006d6100a1565b60408051918252519081900360200190f35b6100636004803603602081101561009557600080fd5b50356100a7565b600055565b60005490565b600054733662e222908fa35f013bee37695d0510098b6d7363771602f79091836040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561010257600080fd5b505af4158015610116573d6000803e3d6000fd5b505050506040513d602081101561012c57600080fd5b50516000555056fea265627a7a723158203e59bfb9a5a2e55d38231922c86d8b2ec9b66cb2f6595613674bc4e15290b60764736f6c634300050b0032",
"external_libraries": {
"BadSafeMath": "0x3662e222908fa35f013bee37695d0510098b6d73"
},
"name": "SimpleStorage",
"optimize": true
}
]

@ -12,7 +12,7 @@ config :explorer,
token_functions_reader_max_retries: 3, token_functions_reader_max_retries: 3,
allowed_evm_versions: allowed_evm_versions:
System.get_env("ALLOWED_EVM_VERSIONS") || System.get_env("ALLOWED_EVM_VERSIONS") ||
"homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople,petersburg,default", "homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople,petersburg,istanbul,default",
include_uncles_in_average_block_time: include_uncles_in_average_block_time:
if(System.get_env("UNCLES_IN_AVERAGE_BLOCK_TIME") == "true", do: true, else: false), if(System.get_env("UNCLES_IN_AVERAGE_BLOCK_TIME") == "true", do: true, else: false),
healthy_blocks_period: System.get_env("HEALTHY_BLOCKS_PERIOD") || :timer.minutes(5), healthy_blocks_period: System.get_env("HEALTHY_BLOCKS_PERIOD") || :timer.minutes(5),

@ -3,7 +3,7 @@ defmodule Explorer.Admin.Administrator.Role do
Supported roles for an administrator. Supported roles for an administrator.
""" """
@behaviour Ecto.Type use Ecto.Type
@typedoc """ @typedoc """
Supported role atoms for an administrator. Supported role atoms for an administrator.

@ -19,7 +19,7 @@ defmodule Explorer.Chain.Block.Range do
to: integer() | :infinity to: integer() | :infinity
} }
@behaviour Ecto.Type use Ecto.Type
@doc """ @doc """
The underlying Postgres type, `int8range`. The underlying Postgres type, `int8range`.

@ -3,7 +3,7 @@ defmodule Explorer.Chain.Block.Reward.AddressType do
Block reward address types Block reward address types
""" """
@behaviour Ecto.Type use Ecto.Type
@typedoc """ @typedoc """
* `:emission_funds` * `:emission_funds`

@ -9,7 +9,7 @@ defmodule Explorer.Chain.Data do
alias Explorer.Chain.Data alias Explorer.Chain.Data
alias Poison.Encoder.BitString alias Poison.Encoder.BitString
@behaviour Ecto.Type use Ecto.Type
@typedoc """ @typedoc """
A variable-byte-length binary, wrapped in a struct, so that it can use protocols. A variable-byte-length binary, wrapped in a struct, so that it can use protocols.

@ -8,7 +8,7 @@ defmodule Explorer.Chain.Hash.Address do
alias Explorer.Chain.Hash alias Explorer.Chain.Hash
@behaviour Ecto.Type use Ecto.Type
@behaviour Hash @behaviour Hash
@byte_count 20 @byte_count 20

@ -5,7 +5,7 @@ defmodule Explorer.Chain.Hash.Full do
alias Explorer.Chain.Hash alias Explorer.Chain.Hash
@behaviour Ecto.Type use Ecto.Type
@behaviour Hash @behaviour Hash
@byte_count 32 @byte_count 32

@ -5,7 +5,7 @@ defmodule Explorer.Chain.Hash.Nonce do
alias Explorer.Chain.Hash alias Explorer.Chain.Hash
@behaviour Ecto.Type use Ecto.Type
@behaviour Hash @behaviour Hash
@byte_count 8 @byte_count 8

@ -310,6 +310,9 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
end end
defp new_pending_operations(repo, nonconsensus_hashes, hashes, %{timeout: timeout, timestamps: timestamps}) do defp new_pending_operations(repo, nonconsensus_hashes, hashes, %{timeout: timeout, timestamps: timestamps}) do
if Application.get_env(:explorer, :json_rpc_named_arguments)[:variant] == EthereumJSONRPC.RSK do
{:ok, []}
else
sorted_pending_ops = sorted_pending_ops =
nonconsensus_hashes nonconsensus_hashes
|> MapSet.new() |> MapSet.new()
@ -330,6 +333,7 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
timestamps: timestamps timestamps: timestamps
) )
end end
end
defp delete_address_token_balances(_, [], _), do: {:ok, []} defp delete_address_token_balances(_, [], _), do: {:ok, []}

@ -154,7 +154,7 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do
total = repo.one!(total_query) total = repo.one!(total_query)
if total > Decimal.new(0) do if total.value > Decimal.new(0) do
update_query = update_query =
from( from(
p in StakingPool, p in StakingPool,
@ -162,8 +162,8 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do
# ShareLocks order already enforced by `acquire_all_staking_pools` (see docs: sharelocks.md) # ShareLocks order already enforced by `acquire_all_staking_pools` (see docs: sharelocks.md)
update: [ update: [
set: [ set: [
staked_ratio: p.staked_amount / ^total * 100, staked_ratio: p.staked_amount / ^total.value * 100,
likelihood: p.staked_amount / ^total * 100 likelihood: p.staked_amount / ^total.value * 100
] ]
] ]
) )

@ -3,7 +3,7 @@ defmodule Explorer.Chain.InternalTransaction.CallType do
Internal transaction types Internal transaction types
""" """
@behaviour Ecto.Type use Ecto.Type
@typedoc """ @typedoc """
* `:call` - call a function in a contract by jumping into the contract's context * `:call` - call a function in a contract by jumping into the contract's context

@ -3,7 +3,7 @@ defmodule Explorer.Chain.InternalTransaction.Type do
Internal transaction types Internal transaction types
""" """
@behaviour Ecto.Type use Ecto.Type
@typedoc """ @typedoc """
* `:call` * `:call`

@ -5,7 +5,7 @@ defmodule Explorer.Chain.MethodIdentifier do
Represented in the database as a 4 byte integer, decodes into a 4 byte bitstring Represented in the database as a 4 byte integer, decodes into a 4 byte bitstring
""" """
@behaviour Ecto.Type use Ecto.Type
@type t :: binary @type t :: binary

@ -8,7 +8,7 @@ defmodule Explorer.Chain.Transaction.Status do
for failure. for failure.
""" """
@behaviour Ecto.Type use Ecto.Type
@typedoc """ @typedoc """
* `:ok` - transaction succeeded * `:ok` - transaction succeeded

@ -24,7 +24,7 @@ defmodule Explorer.Chain.Wei do
defstruct ~w(value)a defstruct ~w(value)a
@behaviour Ecto.Type use Ecto.Type
@impl Ecto.Type @impl Ecto.Type
def type, do: :decimal def type, do: :decimal

@ -54,17 +54,25 @@ defmodule Explorer.SmartContract.Verifier do
external_libs: external_libraries external_libs: external_libraries
) )
compare_bytecodes(solc_output, address_hash, constructor_arguments, autodetect_contructor_arguments) compare_bytecodes(
solc_output,
address_hash,
constructor_arguments,
autodetect_contructor_arguments,
contract_source_code
)
end end
defp compare_bytecodes({:error, :name}, _, _, _), do: {:error, :name} defp compare_bytecodes({:error, :name}, _, _, _, _), do: {:error, :name}
defp compare_bytecodes({:error, _}, _, _, _), do: {:error, :compilation} defp compare_bytecodes({:error, _}, _, _, _, _), do: {:error, :compilation}
# credo:disable-for-next-line /Complexity/
defp compare_bytecodes( defp compare_bytecodes(
{:ok, %{"abi" => abi, "bytecode" => bytecode}}, {:ok, %{"abi" => abi, "bytecode" => bytecode}},
address_hash, address_hash,
arguments_data, arguments_data,
autodetect_contructor_arguments autodetect_contructor_arguments,
contract_source_code
) do ) do
generated_bytecode = extract_bytecode(bytecode) generated_bytecode = extract_bytecode(bytecode)
@ -73,6 +81,7 @@ defmodule Explorer.SmartContract.Verifier do
|> Chain.smart_contract_bytecode() |> Chain.smart_contract_bytecode()
blockchain_bytecode_without_whisper = extract_bytecode(blockchain_bytecode) blockchain_bytecode_without_whisper = extract_bytecode(blockchain_bytecode)
empty_constructor_arguments = arguments_data == "" or arguments_data == nil
cond do cond do
generated_bytecode != blockchain_bytecode_without_whisper && generated_bytecode != blockchain_bytecode_without_whisper &&
@ -80,7 +89,7 @@ defmodule Explorer.SmartContract.Verifier do
{:error, :generated_bytecode} {:error, :generated_bytecode}
has_constructor_with_params?(abi) && autodetect_contructor_arguments -> has_constructor_with_params?(abi) && autodetect_contructor_arguments ->
result = ConstructorArguments.find_constructor_arguments(address_hash, abi) result = ConstructorArguments.find_constructor_arguments(address_hash, abi, contract_source_code)
if result do if result do
{:ok, %{abi: abi, contructor_arguments: result}} {:ok, %{abi: abi, contructor_arguments: result}}
@ -88,8 +97,16 @@ defmodule Explorer.SmartContract.Verifier do
{:error, :constructor_arguments} {:error, :constructor_arguments}
end end
has_constructor_with_params?(abi) && empty_constructor_arguments ->
{:error, :constructor_arguments}
has_constructor_with_params?(abi) && has_constructor_with_params?(abi) &&
!ConstructorArguments.verify(address_hash, blockchain_bytecode_without_whisper, arguments_data) -> !ConstructorArguments.verify(
address_hash,
blockchain_bytecode_without_whisper,
arguments_data,
contract_source_code
) ->
{:error, :constructor_arguments} {:error, :constructor_arguments}
true -> true ->
@ -151,6 +168,22 @@ defmodule Explorer.SmartContract.Verifier do
|> Enum.reverse() |> Enum.reverse()
|> :binary.list_to_bin() |> :binary.list_to_bin()
# Solidity >= 0.6.0 https://github.com/ethereum/solidity/blob/develop/Changelog.md#060-2019-12-17
# https://github.com/ethereum/solidity/blob/26b700771e9cc9c956f0503a05de69a1be427963/docs/metadata.rst#encoding-of-the-metadata-hash-in-the-bytecode
# IPFS is used instead of Swarm
# The current version of the Solidity compiler usually adds the following to the end of the deployed bytecode:
# 0xa2
# 0x64 'i' 'p' 'f' 's' 0x58 0x22 <34 bytes IPFS hash>
# 0x64 's' 'o' 'l' 'c' 0x43 <3 byte version encoding>
# 0x00 0x32
# Note: there is a bug in the docs. Instead of 0x32, 0x33 should be used.
# Fixing PR has been created https://github.com/ethereum/solidity/pull/8174
"a264697066735822" <>
<<_::binary-size(68)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0033" <> _constructor_arguments ->
extracted
|> Enum.reverse()
|> :binary.list_to_bin()
<<next::binary-size(2)>> <> rest -> <<next::binary-size(2)>> <> rest ->
do_extract_bytecode([next | extracted], rest) do_extract_bytecode([next | extracted], rest)
end end

@ -5,7 +5,7 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
alias ABI.{FunctionSelector, TypeDecoder} alias ABI.{FunctionSelector, TypeDecoder}
alias Explorer.Chain alias Explorer.Chain
def verify(address_hash, contract_code, arguments_data) do def verify(address_hash, contract_code, arguments_data, contract_source_code) do
arguments_data = arguments_data |> String.trim_trailing() |> String.trim_leading("0x") arguments_data = arguments_data |> String.trim_trailing() |> String.trim_leading("0x")
creation_code = creation_code =
@ -18,7 +18,7 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
if verify_older_version(creation_code, contract_code, check_func) do if verify_older_version(creation_code, contract_code, check_func) do
true true
else else
extract_constructor_arguments(creation_code, check_func) extract_constructor_arguments(creation_code, check_func, contract_source_code)
end end
end end
@ -31,50 +31,76 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
|> check_func.() |> check_func.()
end end
defp extract_constructor_arguments(code, check_func) do defp extract_constructor_arguments(code, check_func, contract_source_code) do
case code do case code do
# Solidity ~ 4.23 # https://solidity.readthedocs.io/en/v0.4.23/metadata.html # Solidity ~ 4.23 # https://solidity.readthedocs.io/en/v0.4.23/metadata.html
"a165627a7a72305820" <> <<_::binary-size(64)>> <> "0029" <> constructor_arguments -> "a165627a7a72305820" <> <<_::binary-size(64)>> <> "0029" <> constructor_arguments ->
check_func_result = check_func.(constructor_arguments) extract_constructor_arguments_check_func(constructor_arguments, check_func, contract_source_code)
if check_func_result do
check_func_result
else
extract_constructor_arguments(constructor_arguments, check_func)
end
# Solidity >= 0.5.10 https://solidity.readthedocs.io/en/v0.5.10/metadata.html # Solidity >= 0.5.10 https://solidity.readthedocs.io/en/v0.5.10/metadata.html
"a265627a7a72305820" <> "a265627a7a72305820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments -> <<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments ->
check_func_result = check_func.(constructor_arguments) extract_constructor_arguments_check_func(constructor_arguments, check_func, contract_source_code)
if check_func_result do
check_func_result
else
extract_constructor_arguments(constructor_arguments, check_func)
end
# Solidity >= 0.5.11 https://github.com/ethereum/solidity/blob/develop/Changelog.md#0511-2019-08-12 # Solidity >= 0.5.11 https://github.com/ethereum/solidity/blob/develop/Changelog.md#0511-2019-08-12
# Metadata: Update the swarm hash to the current specification, changes bzzr0 to bzzr1 and urls to use bzz-raw:// # Metadata: Update the swarm hash to the current specification, changes bzzr0 to bzzr1 and urls to use bzz-raw://
"a265627a7a72315820" <> "a265627a7a72315820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments -> <<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments ->
extract_constructor_arguments_check_func(constructor_arguments, check_func, contract_source_code)
# Solidity >= 0.6.0 https://github.com/ethereum/solidity/blob/develop/Changelog.md#060-2019-12-17
# https://github.com/ethereum/solidity/blob/26b700771e9cc9c956f0503a05de69a1be427963/docs/metadata.rst#encoding-of-the-metadata-hash-in-the-bytecode
# IPFS is used instead of Swarm
# The current version of the Solidity compiler usually adds the following to the end of the deployed bytecode:
# 0xa2
# 0x64 'i' 'p' 'f' 's' 0x58 0x22 <34 bytes IPFS hash>
# 0x64 's' 'o' 'l' 'c' 0x43 <3 byte version encoding>
# 0x00 0x32
# Note: there is a bug in the docs. Instead of 0x32, 0x33 should be used.
# Fixing PR has been created https://github.com/ethereum/solidity/pull/8174
"a264697066735822" <>
<<_::binary-size(68)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0033" <> constructor_arguments ->
extract_constructor_arguments_check_func(constructor_arguments, check_func, contract_source_code)
<<>> ->
check_func.("")
<<_::binary-size(2)>> <> rest ->
extract_constructor_arguments(rest, check_func, contract_source_code)
end
end
defp extract_constructor_arguments_check_func(constructor_arguments, check_func, contract_source_code) do
constructor_arguments =
remove_require_messages_from_constructor_arguments(contract_source_code, constructor_arguments)
check_func_result = check_func.(constructor_arguments) check_func_result = check_func.(constructor_arguments)
if check_func_result do if check_func_result do
check_func_result check_func_result
else else
extract_constructor_arguments(constructor_arguments, check_func) extract_constructor_arguments(constructor_arguments, check_func, contract_source_code)
end
end end
<<>> -> def remove_require_messages_from_constructor_arguments(contract_source_code, constructor_arguments) do
check_func.("") msgs_list =
contract_source_code
|> extract_require_messages_from_constructor()
|> Enum.reverse()
<<_::binary-size(2)>> <> rest -> Enum.reduce(msgs_list, constructor_arguments, fn msg, pure_constructor_arguments ->
extract_constructor_arguments(rest, check_func) case String.split(pure_constructor_arguments, msg, parts: 2) do
[_, constructor_arguments_part] ->
constructor_arguments_part
[_] ->
pure_constructor_arguments
end end
end)
end end
def find_constructor_arguments(address_hash, abi) do def find_constructor_arguments(address_hash, abi, contract_source_code) do
creation_code = creation_code =
address_hash address_hash
|> Chain.contract_creation_input_data() |> Chain.contract_creation_input_data()
@ -97,6 +123,61 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
end end
end end
extract_constructor_arguments(creation_code, check_func) extract_constructor_arguments(creation_code, check_func, contract_source_code)
end
def extract_require_messages_from_constructor(contract_source_code) do
constructor = find_constructor_content(contract_source_code)
require_contents = find_require_in_constructor(constructor)
messages_list =
Enum.reduce(require_contents, [], fn require_content, msgs ->
msg = get_require_message_hex(require_content)
if msg, do: [msg | msgs]
end)
if messages_list, do: messages_list, else: []
end
def find_constructor_content(contract_source_code) do
case String.split(contract_source_code, "constructor", parts: 2) do
[_, right_from_contstructor] ->
[_, right_from_contstructor_inside] = String.split(right_from_contstructor, "{", parts: 2)
[constructor, _] = String.split(right_from_contstructor_inside, "}", parts: 2)
constructor
[_] ->
nil
end
end
def find_require_in_constructor(constructor) do
if constructor do
[_ | requires] = String.split(constructor, "require")
Enum.reduce(requires, [], fn right_from_require, requires_list ->
[_ | [right_from_require_inside]] = String.split(right_from_require, "(", parts: 2)
[require_content | _] = String.split(right_from_require_inside, ");", parts: 2)
[require_content | requires_list]
end)
else
[]
end
end
def get_require_message_hex(require_content) do
case String.split(require_content, ",", parts: 2) do
[_ | [msg]] ->
msg
|> String.trim()
|> String.trim_leading("\"")
|> String.trim_trailing("\"")
|> String.trim_leading("'")
|> String.trim_trailing("'")
|> Base.encode16(case: :lower)
[_] ->
nil
end
end end
end end

@ -74,9 +74,9 @@ defmodule Explorer.Mixfile do
{:decimal, "~> 1.0"}, {:decimal, "~> 1.0"},
{:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false}, {:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false},
# `override: true` for `ex_machina` compatibility # `override: true` for `ex_machina` compatibility
{:ecto, "~> 3.1", override: true}, {:ecto, "~> 3.3", override: true},
# Storing blockchain data and derived data in PostgreSQL. # Storing blockchain data and derived data in PostgreSQL.
{:ecto_sql, "~> 3.1"}, {:ecto_sql, "~> 3.3"},
# JSONRPC access to query smart contracts # JSONRPC access to query smart contracts
{:ethereum_jsonrpc, in_umbrella: true}, {:ethereum_jsonrpc, in_umbrella: true},
# Data factory for testing # Data factory for testing
@ -110,7 +110,7 @@ defmodule Explorer.Mixfile do
# `:spandex` tracing of `:ecto` # `:spandex` tracing of `:ecto`
{:spandex_ecto, "~> 0.4.0"}, {:spandex_ecto, "~> 0.4.0"},
# Attach `:prometheus_ecto` to `:ecto` # Attach `:prometheus_ecto` to `:ecto`
{:telemetry, "~> 0.4.0"}, {:telemetry, "~> 0.4.1"},
# `Timex.Duration` for `Explorer.Counters.AverageBlockTime.average_block_time/0` # `Timex.Duration` for `Explorer.Counters.AverageBlockTime.average_block_time/0`
{:timex, "~> 3.6"}, {:timex, "~> 3.6"},
{:con_cache, "~> 0.13"} {:con_cache, "~> 0.13"}

@ -3,19 +3,6 @@
"requires": true, "requires": true,
"lockfileVersion": 1, "lockfileVersion": 1,
"dependencies": { "dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -38,67 +25,26 @@
"concat-map": "0.0.1" "concat-map": "0.0.1"
} }
}, },
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"requires": {
"string-width": "^3.1.0",
"strip-ansi": "^5.2.0",
"wrap-ansi": "^5.1.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"command-exists": { "command-exists": {
"version": "1.2.8", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz",
"integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw=="
}, },
"commander": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
"integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow=="
},
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
}, },
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
},
"file-uri-to-path": { "file-uri-to-path": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
}, },
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"requires": {
"locate-path": "^3.0.0"
}
},
"fs-extra": { "fs-extra": {
"version": "0.30.0", "version": "0.30.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
@ -116,15 +62,10 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
}, },
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"glob": { "glob": {
"version": "7.1.5", "version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"requires": { "requires": {
"fs.realpath": "^1.0.0", "fs.realpath": "^1.0.0",
"inflight": "^1.0.4", "inflight": "^1.0.4",
@ -153,11 +94,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
}, },
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"js-sha3": { "js-sha3": {
"version": "0.8.0", "version": "0.8.0",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
@ -190,15 +126,6 @@
"graceful-fs": "^4.1.9" "graceful-fs": "^4.1.9"
} }
}, },
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"memorystream": { "memorystream": {
"version": "0.3.1", "version": "0.3.1",
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
@ -230,52 +157,16 @@
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
}, },
"p-limit": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
"integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"requires": {
"p-limit": "^2.0.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
},
"path-is-absolute": { "path-is-absolute": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
}, },
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
"require-from-string": { "require-from-string": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
}, },
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"rimraf": { "rimraf": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@ -294,42 +185,19 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}, },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"solc": { "solc": {
"version": "0.5.12", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/solc/-/solc-0.5.12.tgz", "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.1.tgz",
"integrity": "sha512-OX/AGZT04tuUsagoVXSZBiBZYJReA02hdwZOfRkB03/eeYP9Dl3pr+M+au+1MhssgiuWBlFPN7sRXFiqwkAW2g==", "integrity": "sha512-iKqNYps2p++x8L9sBg7JeAJb7EmW8VJ/2asAzwlLYcUhj86AzuWLe94UTSQHv1SSCCj/x6lya8twvXkZtlTbIQ==",
"requires": { "requires": {
"command-exists": "^1.2.8", "command-exists": "^1.2.8",
"commander": "3.0.2",
"fs-extra": "^0.30.0", "fs-extra": "^0.30.0",
"js-sha3": "0.8.0", "js-sha3": "0.8.0",
"memorystream": "^0.3.1", "memorystream": "^0.3.1",
"require-from-string": "^2.0.0", "require-from-string": "^2.0.0",
"semver": "^5.5.0", "semver": "^5.5.0",
"tmp": "0.0.33", "tmp": "0.0.33"
"yargs": "^13.2.0"
}
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"requires": {
"ansi-regex": "^4.1.0"
} }
}, },
"tmp": { "tmp": {
@ -340,56 +208,10 @@
"os-tmpdir": "~1.0.2" "os-tmpdir": "~1.0.2"
} }
}, },
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"wrap-ansi": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"requires": {
"ansi-styles": "^3.2.0",
"string-width": "^3.0.0",
"strip-ansi": "^5.0.0"
}
},
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
},
"yargs": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
"integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
"requires": {
"cliui": "^5.0.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^13.1.1"
}
},
"yargs-parser": {
"version": "13.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
} }
} }
} }

@ -8,12 +8,12 @@
"author": "POA Network", "author": "POA Network",
"license": "GPL-3.0", "license": "GPL-3.0",
"engines": { "engines": {
"node": "9.x", "node": "12.x",
"npm": "5.x" "npm": "6.x"
}, },
"scripts": {}, "scripts": {},
"dependencies": { "dependencies": {
"keccak": "^2.0.0", "keccak": "^2.0.0",
"solc": "^0.5.12" "solc": "^0.6.1"
} }
} }

@ -55,76 +55,6 @@ defmodule Explorer.Repo.Migrations.AddPendingInternalTxsOperation do
DELETE FROM internal_transactions WHERE block_hash IS NULL; DELETE FROM internal_transactions WHERE block_hash IS NULL;
""") """)
execute("""
DO $$
DECLARE
duplicates_count INTEGER := 0;
blocks_scanned INTEGER := 0;
int_txs_count INTEGER := 0;
temprow RECORD;
BEGIN
SELECT COUNT(*) INTO int_txs_count FROM internal_transactions;
IF int_txs_count < 10000000 THEN
FOR temprow IN
SELECT block_hash FROM internal_transactions
GROUP BY block_hash, block_index HAVING COUNT(*) > 1
LOOP
duplicates_count := duplicates_count + 1;
RAISE NOTICE '% duplicates, blocks scanned %, block #%, block hash is %', duplicates_count, blocks_scanned, temprow.number , temprow.hash;
IF NOT EXISTS (
SELECT 1 FROM pending_block_operations
WHERE block_hash = temprow.block_hash
) THEN
INSERT INTO pending_block_operations
(block_hash, inserted_at, updated_at, fetch_internal_transactions)
SELECT b.hash, now(), now(), TRUE FROM blocks b
WHERE b.hash = temprow.block_hash;
END IF;
DELETE FROM internal_transactions
WHERE block_hash = temprow.block_hash;
RAISE NOTICE 'DELETED';
END LOOP;
ELSE
FOR temprow IN SELECT number, hash FROM blocks LOOP
blocks_scanned := blocks_scanned + 1;
IF EXISTS (
SELECT 1 FROM transactions WHERE block_hash = temprow.hash
) THEN
IF EXISTS (
SELECT block_hash, block_index FROM internal_transactions
WHERE block_hash = temprow.hash
GROUP BY block_hash, block_index HAVING COUNT(*) > 1
) THEN
duplicates_count := duplicates_count + 1;
RAISE NOTICE '% duplicates, blocks scanned %, block #%, block hash is %', duplicates_count, blocks_scanned, temprow.number , temprow.hash;
IF NOT EXISTS (
SELECT 1 FROM pending_block_operations
WHERE block_hash = temprow.hash
) THEN
INSERT INTO pending_block_operations
(block_hash, inserted_at, updated_at, fetch_internal_transactions)
SELECT b.hash, now(), now(), TRUE FROM blocks b
WHERE b.hash = temprow.hash;
END IF;
DELETE FROM internal_transactions
WHERE block_hash = temprow.hash;
RAISE NOTICE 'DELETED';
END IF;
END IF;
END LOOP;
END IF;
RAISE NOTICE 'SCRIPT FINISHED';
END $$;
""")
execute(""" execute("""
ALTER table internal_transactions ALTER table internal_transactions
DROP CONSTRAINT internal_transactions_pkey, DROP CONSTRAINT internal_transactions_pkey,

@ -0,0 +1,9 @@
defmodule Explorer.Repo.Migrations.RemoveDuplicateIndexesTokenEntities do
use Ecto.Migration
def change do
drop_if_exists(index(:address_token_balances, [:block_number], name: "address_token_balances_block_number_index"))
drop_if_exists(index(:token_instances, [:token_id], name: "token_instances_token_id_index"))
end
end

@ -1,69 +1,77 @@
-- UPDATE (2020-08-01): use pending_block_operations table
DO $$ DO $$
DECLARE DECLARE
row_count integer := 1; row_count integer := 1;
batch_size integer := 50000; -- HOW MANY ITEMS WILL BE UPDATED AT TIME batch_size integer := 500; -- HOW MANY ITEMS WILL BE UPDATED AT TIME
iterator integer := batch_size; iterator integer := batch_size;
max_row_number integer; max_row_number integer;
next_iterator integer; next_iterator integer;
updated_transaction_count integer; updated_blocks_count integer;
deleted_internal_transaction_count integer; deleted_internal_transaction_count integer;
deleted_row_count integer; deleted_row_count integer;
BEGIN BEGIN
DROP TABLE IF EXISTS transactions_with_deprecated_internal_transactions; DROP TABLE IF EXISTS blocks_with_deprecated_internal_transactions;
-- CREATES TEMP TABLE TO STORE DATA TO BE UPDATED -- CREATES TEMP TABLE TO STORE DATA TO BE UPDATED
CREATE TEMP TABLE transactions_with_deprecated_internal_transactions( CREATE TEMP TABLE blocks_with_deprecated_internal_transactions(
hash bytea NOT NULL, block_number integer NOT NULL,
row_number integer row_number integer
); );
INSERT INTO transactions_with_deprecated_internal_transactions INSERT INTO blocks_with_deprecated_internal_transactions
SELECT DISTINCT ON (transaction_hash) SELECT DISTINCT ON (a.block_number)
transaction_hash, a.block_number,
ROW_NUMBER () OVER () ROW_NUMBER () OVER ()
FROM internal_transactions FROM (
SELECT DISTINCT i.block_number, i.transaction_index
FROM internal_transactions i
WHERE WHERE
i.block_number IS NOT NULL
AND
-- call_has_call_type CONSTRAINT -- call_has_call_type CONSTRAINT
(type = 'call' AND call_type IS NULL) OR ((i.type = 'call' AND i.call_type IS NULL) OR
-- call_has_input CONSTRAINT -- call_has_input CONSTRAINT
(type = 'call' AND input IS NULL) OR (i.type = 'call' AND i.input IS NULL) OR
-- create_has_init CONSTRAINT -- create_has_init CONSTRAINT
(type = 'create' AND init is NULL) (i.type = 'create' AND i.init is NULL))
ORDER BY transaction_hash DESC; ORDER BY i.block_number DESC, i.transaction_index
) a;
max_row_number := (SELECT MAX(row_number) FROM transactions_with_deprecated_internal_transactions); max_row_number := (SELECT MAX(row_number) FROM blocks_with_deprecated_internal_transactions);
RAISE NOTICE '% transactions to be updated', max_row_number + 1; RAISE NOTICE '% blocks to be updated', max_row_number + 1;
-- ITERATES THROUGH THE ITEMS UNTIL THE TEMP TABLE IS EMPTY -- ITERATES THROUGH THE ITEMS UNTIL THE TEMP TABLE IS EMPTY
WHILE iterator <= max_row_number LOOP WHILE iterator <= max_row_number LOOP
next_iterator := iterator + batch_size; next_iterator := iterator + batch_size;
RAISE NOTICE '-> transactions with deprecated internal transactions % to % to be updated', iterator, next_iterator - 1; RAISE NOTICE '-> blocks with deprecated internal transactions % to % to be updated', iterator, next_iterator - 1;
UPDATE transactions INSERT INTO pending_block_operations (block_hash, inserted_at, updated_at, fetch_internal_transactions)
SET internal_transactions_indexed_at = NULL, SELECT b.hash, NOW(), NOW(), true
error = NULL FROM blocks_with_deprecated_internal_transactions bd, blocks b
FROM transactions_with_deprecated_internal_transactions WHERE bd.block_number = b.number
WHERE transactions.hash = transactions_with_deprecated_internal_transactions.hash AND AND bd.row_number < next_iterator
transactions_with_deprecated_internal_transactions.row_number < next_iterator; AND b.consensus = true
ON CONFLICT (block_hash)
DO NOTHING;
GET DIAGNOSTICS updated_transaction_count = ROW_COUNT; GET DIAGNOSTICS updated_blocks_count = ROW_COUNT;
RAISE NOTICE '-> % transactions updated to refetch internal transactions', updated_transaction_count; RAISE NOTICE '-> % blocks updated to refetch internal transactions', updated_blocks_count;
DELETE FROM internal_transactions DELETE FROM internal_transactions
USING transactions_with_deprecated_internal_transactions USING blocks_with_deprecated_internal_transactions
WHERE internal_transactions.transaction_hash = transactions_with_deprecated_internal_transactions.hash AND WHERE internal_transactions.block_number = blocks_with_deprecated_internal_transactions.block_number AND
transactions_with_deprecated_internal_transactions.row_number < next_iterator; blocks_with_deprecated_internal_transactions.row_number < next_iterator;
GET DIAGNOSTICS deleted_internal_transaction_count = ROW_COUNT; GET DIAGNOSTICS deleted_internal_transaction_count = ROW_COUNT;
RAISE NOTICE '-> % internal transactions deleted', deleted_internal_transaction_count; RAISE NOTICE '-> % internal transactions deleted', deleted_internal_transaction_count;
DELETE FROM transactions_with_deprecated_internal_transactions DELETE FROM blocks_with_deprecated_internal_transactions
WHERE row_number < next_iterator; WHERE row_number < next_iterator;
GET DIAGNOSTICS deleted_row_count = ROW_COUNT; GET DIAGNOSTICS deleted_row_count = ROW_COUNT;
ASSERT updated_transaction_count = deleted_row_count; ASSERT updated_blocks_count = deleted_row_count;
-- COMMITS THE BATCH UPDATES -- COMMITS THE BATCH UPDATES
CHECKPOINT; CHECKPOINT;

@ -0,0 +1,73 @@
-- This script should be a part of migration to "pennding_block_operations" internal transactions indexing approach
-- if 20191018140054_add_pending_internal_txs_operation.exs migration failed due to occasional duplicates of
-- {block_hash, block_index} pair in the DB, that could exist due to bugs in previous versions of the application
--, before setting a primary key on those columns. If so, this script should be inserted at line 57 of that migration
-- just before changing of a primary key.
DO $$
DECLARE
duplicates_count INTEGER := 0;
blocks_scanned INTEGER := 0;
int_txs_count INTEGER := 0;
temprow RECORD;
BEGIN
SELECT COUNT(*) INTO int_txs_count FROM internal_transactions;
IF int_txs_count < 10000000 THEN
FOR temprow IN
SELECT block_hash FROM internal_transactions
GROUP BY block_hash, block_index HAVING COUNT(*) > 1
LOOP
duplicates_count := duplicates_count + 1;
RAISE NOTICE '% duplicates, blocks scanned %, block #%, block hash is %', duplicates_count, blocks_scanned, temprow.number , temprow.hash;
IF NOT EXISTS (
SELECT 1 FROM pending_block_operations
WHERE block_hash = temprow.block_hash
) THEN
INSERT INTO pending_block_operations
(block_hash, inserted_at, updated_at, fetch_internal_transactions)
SELECT b.hash, now(), now(), TRUE FROM blocks b
WHERE b.hash = temprow.block_hash;
END IF;
DELETE FROM internal_transactions
WHERE block_hash = temprow.block_hash;
RAISE NOTICE 'DELETED';
END LOOP;
ELSE
FOR temprow IN SELECT number, hash FROM blocks LOOP
blocks_scanned := blocks_scanned + 1;
IF EXISTS (
SELECT 1 FROM transactions WHERE block_hash = temprow.hash
) THEN
IF EXISTS (
SELECT block_hash, block_index FROM internal_transactions
WHERE block_hash = temprow.hash
GROUP BY block_hash, block_index HAVING COUNT(*) > 1
) THEN
duplicates_count := duplicates_count + 1;
RAISE NOTICE '% duplicates, blocks scanned %, block #%, block hash is %', duplicates_count, blocks_scanned, temprow.number , temprow.hash;
IF NOT EXISTS (
SELECT 1 FROM pending_block_operations
WHERE block_hash = temprow.hash
) THEN
INSERT INTO pending_block_operations
(block_hash, inserted_at, updated_at, fetch_internal_transactions)
SELECT b.hash, now(), now(), TRUE FROM blocks b
WHERE b.hash = temprow.hash;
END IF;
DELETE FROM internal_transactions
WHERE block_hash = temprow.hash;
RAISE NOTICE 'DELETED';
END IF;
END IF;
END LOOP;
END IF;
RAISE NOTICE 'SCRIPT FINISHED';
END $$;

@ -131,7 +131,7 @@ defmodule Explorer.SmartContract.PublisherTest do
test "validates and creates smart contract with external libraries" do test "validates and creates smart contract with external libraries" do
contract_data = contract_data =
"#{File.cwd!()}/test/support/fixture/smart_contract/compiler_tests.json" "#{File.cwd!()}/test/support/fixture/smart_contract/contract_with_lib.json"
|> File.read!() |> File.read!()
|> Jason.decode!() |> Jason.decode!()
|> List.first() |> List.first()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,13 @@
[
{
"compiler_version": "v0.5.11+commit.c082d0b4",
"contract": "pragma solidity 0.5.11;library BadSafeMath { function add(uint256 a, uint256 b) public pure returns (uint256) { uint256 c = a + 2 * b; require(c >= a, \"SafeMath: addition overflow\"); return c; }}contract SimpleStorage { uint256 storedData = 10; using BadSafeMath for uint256; function increment(uint256 x) public { storedData = storedData.add(x); } function set(uint256 x) public { storedData = x; } function get() public view returns (uint256) { return storedData; }}",
"expected_bytecode": "608060405234801561001057600080fd5b50600436106100415760003560e01c806360fe47b1146100465780636d4ce63c146100655780637cf5dab01461007f575b600080fd5b6100636004803603602081101561005c57600080fd5b503561009c565b005b61006d6100a1565b60408051918252519081900360200190f35b6100636004803603602081101561009557600080fd5b50356100a7565b600055565b60005490565b600054733662e222908fa35f013bee37695d0510098b6d7363771602f79091836040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561010257600080fd5b505af4158015610116573d6000803e3d6000fd5b505050506040513d602081101561012c57600080fd5b50516000555056fea265627a7a723158203e59bfb9a5a2e55d38231922c86d8b2ec9b66cb2f6595613674bc4e15290b60764736f6c634300050b0032",
"external_libraries": {
"BadSafeMath": "0x3662e222908fa35f013bee37695d0510098b6d73"
},
"name": "SimpleStorage",
"optimize": true
}
]

@ -1,4 +1,4 @@
FROM bitwalker/alpine-elixir-phoenix:1.9.0 FROM bitwalker/alpine-elixir-phoenix:1.9.1
RUN apk --no-cache --update add alpine-sdk gmp-dev automake libtool inotify-tools autoconf python RUN apk --no-cache --update add alpine-sdk gmp-dev automake libtool inotify-tools autoconf python
@ -15,7 +15,7 @@ ADD apps/explorer/mix.exs ./apps/explorer/
ADD apps/ethereum_jsonrpc/mix.exs ./apps/ethereum_jsonrpc/ ADD apps/ethereum_jsonrpc/mix.exs ./apps/ethereum_jsonrpc/
ADD apps/indexer/mix.exs ./apps/indexer/ ADD apps/indexer/mix.exs ./apps/indexer/
RUN mix do deps.get, deps.compile RUN mix do deps.get, local.rebar --force, deps.compile
ADD . . ADD . .
@ -37,6 +37,8 @@ RUN cd apps/explorer/ && \
# RUN mix do ecto.drop --force, ecto.create, ecto.migrate # RUN mix do ecto.drop --force, ecto.create, ecto.migrate
RUN mix phx.digest
# USER default # USER default
# CMD ["mix", "phx.server"] # CMD ["mix", "phx.server"]

@ -3,7 +3,7 @@ HOST = host.docker.internal
DOCKER_IMAGE = blockscout_prod DOCKER_IMAGE = blockscout_prod
BS_CONTAINER_NAME = blockscout BS_CONTAINER_NAME = blockscout
PG_CONTAINER_NAME = postgres PG_CONTAINER_NAME = postgres
PG_CONTAINER_IMAGE = postgres:10.6 PG_CONTAINER_IMAGE = postgres:10.10
THIS_FILE = $(lastword $(MAKEFILE_LIST)) THIS_FILE = $(lastword $(MAKEFILE_LIST))
ifeq ($(SYSTEM), Linux) ifeq ($(SYSTEM), Linux)
@ -16,35 +16,185 @@ BLOCKSCOUT_CONTAINNER_PARAMS = -e 'MIX_ENV=prod' \
ifeq ($(SYSTEM), Linux) ifeq ($(SYSTEM), Linux)
BLOCKSCOUT_CONTAINNER_PARAMS += --network=host BLOCKSCOUT_CONTAINNER_PARAMS += --network=host
endif endif
ifdef NETWORK
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK=$(NETWORK)'
endif
ifdef SUBNETWORK
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SUBNETWORK=$(SUBNETWORK)'
endif
ifdef NETWORK_ICON
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK_ICON=$(NETWORK_ICON)'
endif
ifdef LOGO
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'LOGO=$(LOGO)'
endif
ifdef LOGO_FOOTER
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'LOGO_FOOTER=$(LOGO_FOOTER)'
endif
ifdef ETHEREUM_JSONRPC_VARIANT ifdef ETHEREUM_JSONRPC_VARIANT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_VARIANT=$(ETHEREUM_JSONRPC_VARIANT)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_VARIANT=$(ETHEREUM_JSONRPC_VARIANT)'
endif endif
ifdef ETHEREUM_JSONRPC_HTTP_URL ifdef ETHEREUM_JSONRPC_HTTP_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_HTTP_URL=$(ETHEREUM_JSONRPC_HTTP_URL)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_HTTP_URL=$(ETHEREUM_JSONRPC_HTTP_URL)'
endif endif
ifdef ETHEREUM_JSONRPC_TRACE_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_TRACE_URL=$(ETHEREUM_JSONRPC_TRACE_URL)'
endif
ifdef ETHEREUM_JSONRPC_WS_URL ifdef ETHEREUM_JSONRPC_WS_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_WS_URL=$(ETHEREUM_JSONRPC_WS_URL)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_WS_URL=$(ETHEREUM_JSONRPC_WS_URL)'
endif endif
ifdef ETHEREUM_JSONRPC_TRACE_URL ifdef ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_TRACE_URL=$(ETHEREUM_JSONRPC_TRACE_URL)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT=$(ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT)'
endif
ifdef IPC_PATH
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'IPC_PATH=$(IPC_PATH)'
endif
ifdef NETWORK_PATH
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK_PATH=$(NETWORK_PATH)'
endif
ifdef CHECK_ORIGIN
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'CHECK_ORIGIN=$(CHECK_ORIGIN)'
endif endif
ifdef COIN ifdef COIN
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'COIN=$(COIN)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'COIN=$(COIN)'
endif endif
ifdef LOGO ifdef METADATA_CONTRACT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'LOGO=$(LOGO)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'METADATA_CONTRACT=$(METADATA_CONTRACT)'
endif endif
ifdef NETWORK ifdef VALIDATORS_CONTRACT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK=$(NETWORK)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'VALIDATORS_CONTRACT=$(VALIDATORS_CONTRACT)'
endif endif
ifdef SUBNETWORK ifdef SUPPLY_MODULE
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SUBNETWORK=$(SUBNETWORK)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SUPPLY_MODULE=$(SUPPLY_MODULE)'
endif endif
ifdef NETWORK_ICON ifdef SOURCE_MODULE
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK_ICON=$(NETWORK_ICON)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SOURCE_MODULE=$(SOURCE_MODULE)'
endif endif
ifdef NETWORK_PATH ifdef POOL_SIZE
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK_PATH=$(NETWORK_PATH)' BLOCKSCOUT_CONTAINNER_PARAMS += -e 'POOL_SIZE=$(POOL_SIZE)'
endif
ifdef ECTO_USE_SSL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ECTO_USE_SSL=$(ECTO_USE_SSL)'
endif
ifdef DATADOG_HOST
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'DATADOG_HOST=$(DATADOG_HOST)'
endif
ifdef DATADOG_PORT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'DATADOG_PORT=$(DATADOG_PORT)'
endif
ifdef SPANDEX_BATCH_SIZE
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SPANDEX_BATCH_SIZE=$(SPANDEX_BATCH_SIZE)'
endif
ifdef SPANDEX_SYNC_THRESHOLD
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SPANDEX_SYNC_THRESHOLD=$(SPANDEX_SYNC_THRESHOLD)'
endif
ifdef HEART_BEAT_TIMEOUT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'HEART_BEAT_TIMEOUT=$(HEART_BEAT_TIMEOUT)'
endif
ifdef HEART_COMMAND
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'HEART_COMMAND=$(HEART_COMMAND)'
endif
ifdef BLOCKSCOUT_VERSION
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'BLOCKSCOUT_VERSION=$(BLOCKSCOUT_VERSION)'
endif
ifdef RELEASE_LINK
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'RELEASE_LINK=$(RELEASE_LINK)'
endif
ifdef ELIXIR_VERSION
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ELIXIR_VERSION=$(ELIXIR_VERSION)'
endif
ifdef BLOCK_TRANSFORMER
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'BLOCK_TRANSFORMER=$(BLOCK_TRANSFORMER)'
endif
ifdef GRAPHIQL_TRANSACTION
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'GRAPHIQL_TRANSACTION=$(GRAPHIQL_TRANSACTION)'
endif
ifdef FIRST_BLOCK
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'FIRST_BLOCK=$(FIRST_BLOCK)'
endif
ifdef LAST_BLOCK
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'LAST_BLOCK=$(LAST_BLOCK)'
endif
ifdef TXS_COUNT_CACHE_PERIOD
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'TXS_COUNT_CACHE_PERIOD=$(TXS_COUNT_CACHE_PERIOD)'
endif
ifdef ADDRESS_WITH_BALANCES_UPDATE_INTERVAL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ADDRESS_WITH_BALANCES_UPDATE_INTERVAL=$(ADDRESS_WITH_BALANCES_UPDATE_INTERVAL)'
endif
ifdef LINK_TO_OTHER_EXPLORERS
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'LINK_TO_OTHER_EXPLORERS=$(LINK_TO_OTHER_EXPLORERS)'
endif
ifdef COINMARKETCAP_PAGES
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'COINMARKETCAP_PAGES=$(COINMARKETCAP_PAGES)'
endif
ifdef SUPPORTED_CHAINS
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SUPPORTED_CHAINS=$(SUPPORTED_CHAINS)'
endif
ifdef BLOCK_COUNT_CACHE_PERIOD
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'BLOCK_COUNT_CACHE_PERIOD=$(BLOCK_COUNT_CACHE_PERIOD)'
endif
ifdef ADDRESS_SUM_CACHE_PERIOD
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ADDRESS_SUM_CACHE_PERIOD=$(ADDRESS_SUM_CACHE_PERIOD)'
endif
ifdef ADDRESS_COUNT_CACHE_PERIOD
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ADDRESS_COUNT_CACHE_PERIOD=$(ADDRESS_COUNT_CACHE_PERIOD)'
endif
ifdef ALLOWED_EVM_VERSIONS
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ALLOWED_EVM_VERSIONS=$(ALLOWED_EVM_VERSIONS)'
endif
ifdef UNCLES_IN_AVERAGE_BLOCK_TIME
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'UNCLES_IN_AVERAGE_BLOCK_TIME=$(UNCLES_IN_AVERAGE_BLOCK_TIME)'
endif
ifdef AVERAGE_BLOCK_CACHE_PERIOD
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'AVERAGE_BLOCK_CACHE_PERIOD=$(AVERAGE_BLOCK_CACHE_PERIOD)'
endif
ifdef MARKET_HISTORY_CACHE_PERIOD
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'MARKET_HISTORY_CACHE_PERIOD=$(MARKET_HISTORY_CACHE_PERIOD)'
endif
ifdef DISABLE_WEBAPP
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'DISABLE_WEBAPP=$(DISABLE_WEBAPP)'
endif
ifdef DISABLE_READ_API
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'DISABLE_READ_API=$(DISABLE_READ_API)'
endif
ifdef DISABLE_WRITE_API
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'DISABLE_WRITE_API=$(DISABLE_WRITE_API)'
endif
ifdef DISABLE_INDEXER
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'DISABLE_INDEXER=$(DISABLE_INDEXER)'
endif
ifdef WEBAPP_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'WEBAPP_URL=$(WEBAPP_URL)'
endif
ifdef API_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'API_URL=$(API_URL)'
endif
ifdef CHAIN_SPEC_PATH
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'CHAIN_SPEC_PATH=$(CHAIN_SPEC_PATH)'
endif
ifdef COIN_GECKO_ID
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'COIN_GECKO_ID=$(COIN_GECKO_ID)'
endif
ifdef EMISSION_FORMAT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'EMISSION_FORMAT=$(EMISSION_FORMAT)'
endif
ifdef REWARDS_CONTRACT_ADDRESS
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'REWARDS_CONTRACT_ADDRESS=$(REWARDS_CONTRACT_ADDRESS)'
endif
ifdef SHOW_ADDRESS_MARKETCAP_PERCENTAGE
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SHOW_ADDRESS_MARKETCAP_PERCENTAGE=$(SHOW_ADDRESS_MARKETCAP_PERCENTAGE)'
endif
ifdef BLOCKSCOUT_PROTOCOL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'BLOCKSCOUT_PROTOCOL=$(BLOCKSCOUT_PROTOCOL)'
endif
ifdef BLOCKSCOUT_HOST
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'BLOCKSCOUT_HOST=$(BLOCKSCOUT_HOST)'
endif
ifdef DECOMPILED_SMART_CONTRACT_TOKEN
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'DECOMPILED_SMART_CONTRACT_TOKEN=$(DECOMPILED_SMART_CONTRACT_TOKEN)'
endif
ifdef SOCKET_ROOT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SOCKET_ROOT=$(SOCKET_ROOT)'
endif endif
HAS_BLOCKSCOUT_IMAGE := $(shell docker images | grep ${DOCKER_IMAGE}) HAS_BLOCKSCOUT_IMAGE := $(shell docker images | grep ${DOCKER_IMAGE})
@ -61,7 +211,7 @@ migrate: build postgres
@echo "==> Running migrations" @echo "==> Running migrations"
@docker run --rm \ @docker run --rm \
$(BLOCKSCOUT_CONTAINNER_PARAMS) \ $(BLOCKSCOUT_CONTAINNER_PARAMS) \
$(DOCKER_IMAGE) /bin/sh -c "echo $$MIX_ENV && mix do ecto.drop --force, ecto.create, ecto.migrate" $(DOCKER_IMAGE) /bin/sh -c "echo $$MIX_ENV && mix do ecto.create, ecto.migrate"
PG_EXIST := $(shell docker ps -a --filter name=${PG_CONTAINER_NAME} | grep ${PG_CONTAINER_NAME}) PG_EXIST := $(shell docker ps -a --filter name=${PG_CONTAINER_NAME} | grep ${PG_CONTAINER_NAME})

@ -1,8 +1,8 @@
%{ %{
"absinthe": {:hex, :absinthe, "1.4.16", "0933e4d9f12652b12115d5709c0293a1bf78a22578032e9ad0dad4efee6b9eb1", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "absinthe": {:hex, :absinthe, "1.5.0-rc.2", "132ceb90783a39454cba1a043e833add5385036ed1e6fe8e889b85fc2b7cd89f", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"absinthe_phoenix": {:git, "https://github.com/ayrat555/absinthe_phoenix.git", "4dbb73a25a0935a4d292e63876698e18534d835f", [branch: "ab-update-plug"]}, "absinthe_phoenix": {:hex, :absinthe_phoenix, "1.5.0-rc.0", "63558295f77f09c9e412fa0a4ef92a66003eaf539821a810fd928c1c67a6005d", [:mix], [{:absinthe, "~> 1.5.0-rc.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5.0-rc.0", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm"},
"absinthe_plug": {:git, "https://github.com/ayrat555/absinthe_plug.git", "cbe1c170e11e60b3b0146b925a1ce6ec562840ce", [branch: "ab-enable-default-query"]}, "absinthe_plug": {:hex, :absinthe_plug, "1.5.0-rc.1", "f6d8a7a74c42cb1547f9d62cf728b8aab960c5246b8415deb0cb1f5aac1fb671", [:mix], [{:absinthe, "~> 1.5.0-rc.2", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"absinthe_relay": {:hex, :absinthe_relay, "1.4.6", "ec0e2288994b388556247cf9601245abec785cdf206d6e844f2992d29de21624", [:mix], [{:absinthe, "~> 1.4.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "absinthe_relay": {:hex, :absinthe_relay, "1.5.0-rc.0", "99048f5a8239dbcecf6c600f6a2410e1b157832df01d3f4859bc804565ddf1bc", [:mix], [{:absinthe, "~> 1.5.0-rc.1", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm"}, "accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm"},
"bcrypt_elixir": {:hex, :bcrypt_elixir, "1.1.1", "6b5560e47a02196ce5f0ab3f1d8265db79a23868c137e973b27afef928ed8006", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, "bcrypt_elixir": {:hex, :bcrypt_elixir, "1.1.1", "6b5560e47a02196ce5f0ab3f1d8265db79a23868c137e973b27afef928ed8006", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"benchee": {:hex, :benchee, "0.13.2", "30cd4ff5f593fdd218a9b26f3c24d580274f297d88ad43383afe525b1543b165", [:mix], [{:deep_merge, "~> 0.1", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"}, "benchee": {:hex, :benchee, "0.13.2", "30cd4ff5f593fdd218a9b26f3c24d580274f297d88ad43383afe525b1543b165", [:mix], [{:deep_merge, "~> 0.1", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"},
@ -22,15 +22,15 @@
"cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm"}, "cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm"},
"credo": {:hex, :credo, "1.1.2", "02b6422f3e659eb74b05aca3c20c1d8da0119a05ee82577a82e6c2938bf29f81", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "1.1.2", "02b6422f3e659eb74b05aca3c20c1d8da0119a05ee82577a82e6c2938bf29f81", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"csv": {:hex, :csv, "2.3.1", "9ce11eff5a74a07baf3787b2b19dd798724d29a9c3a492a41df39f6af686da0e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, "csv": {:hex, :csv, "2.3.1", "9ce11eff5a74a07baf3787b2b19dd798724d29a9c3a492a41df39f6af686da0e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"},
"dataloader": {:hex, :dataloader, "1.0.6", "fb724d6d3fb6acb87d27e3b32dea3a307936ad2d245faf9cf5221d1323d6a4ba", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "dataloader": {:hex, :dataloader, "1.0.7", "58351b335673cf40601429bfed6c11fece6ce7ad169b2ac0f0fe83e716587391", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"db_connection": {:hex, :db_connection, "2.1.1", "a51e8a2ee54ef2ae6ec41a668c85787ed40cb8944928c191280fe34c15b76ae5", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, "db_connection": {:hex, :db_connection, "2.2.0", "e923e88887cd60f9891fd324ac5e0290954511d090553c415fbf54be4c57ee63", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
"decimal": {:hex, :decimal, "1.8.0", "ca462e0d885f09a1c5a342dbd7c1dcf27ea63548c65a65e67334f4b61803822e", [:mix], [], "hexpm"}, "decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm"},
"decorator": {:hex, :decorator, "1.3.0", "6203dbd6e4e519a21a079e2a74e50fddaf03e80be22711b92eb4cd410173abea", [:mix], [], "hexpm"}, "decorator": {:hex, :decorator, "1.3.0", "6203dbd6e4e519a21a079e2a74e50fddaf03e80be22711b92eb4cd410173abea", [:mix], [], "hexpm"},
"deep_merge": {:hex, :deep_merge, "0.2.0", "c1050fa2edf4848b9f556fba1b75afc66608a4219659e3311d9c9427b5b680b3", [:mix], [], "hexpm"}, "deep_merge": {:hex, :deep_merge, "0.2.0", "c1050fa2edf4848b9f556fba1b75afc66608a4219659e3311d9c9427b5b680b3", [:mix], [], "hexpm"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.1.7", "fa21d06ef56cdc2fdaa62574e8c3ba34a2751d44ea34c30bc65f0728421043e5", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, "ecto": {:hex, :ecto, "3.3.1", "82ab74298065bf0c64ca299f6c6785e68ea5d6b980883ee80b044499df35aba1", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_sql": {:hex, :ecto_sql, "3.1.6", "1e80e30d16138a729c717f73dcb938590bcdb3a4502f3012414d0cbb261045d8", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0 or ~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "ecto_sql": {:hex, :ecto_sql, "3.3.2", "92804e0de69bb63e621273c3492252cb08a29475c05d40eeb6f41ad2d483cfd3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm"}, "elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm"},
"ex_abi": {:hex, :ex_abi, "0.1.18", "19db9bffdd201edbdff97d7dd5849291218b17beda045c1b76bff5248964f37d", [:mix], [{:exth_crypto, "~> 0.1.4", [hex: :exth_crypto, repo: "hexpm", optional: false]}], "hexpm"}, "ex_abi": {:hex, :ex_abi, "0.1.18", "19db9bffdd201edbdff97d7dd5849291218b17beda045c1b76bff5248964f37d", [:mix], [{:exth_crypto, "~> 0.1.4", [hex: :exth_crypto, repo: "hexpm", optional: false]}], "hexpm"},
"ex_cldr": {:hex, :ex_cldr, "2.7.2", "d79a1af6ed12630a15175d2b88d4381b22db5d6f835c5da8de132f0cf712b233", [:mix], [{:cldr_utils, "~> 2.1", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"}, "ex_cldr": {:hex, :ex_cldr, "2.7.2", "d79a1af6ed12630a15175d2b88d4381b22db5d6f835c5da8de132f0cf712b233", [:mix], [{:cldr_utils, "~> 2.1", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
@ -92,7 +92,7 @@
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.15.0", "dd5349161019caeea93efa42f9b22f9d79995c3a86bdffb796427b4c9863b0f0", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, "postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"prometheus": {:hex, :prometheus, "4.4.1", "1e96073b3ed7788053768fea779cbc896ddc3bdd9ba60687f2ad50b252ac87d6", [:mix, :rebar3], [], "hexpm"}, "prometheus": {:hex, :prometheus, "4.4.1", "1e96073b3ed7788053768fea779cbc896ddc3bdd9ba60687f2ad50b252ac87d6", [:mix, :rebar3], [], "hexpm"},
"prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm"}, "prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm"},
"prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"}, "prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"},
@ -108,7 +108,7 @@
"spandex_ecto": {:hex, :spandex_ecto, "0.4.0", "deaeaddc11a35f1c551206c53d09bb93a0da5808dbef751430e465c8c7de01d3", [:mix], [{:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm"}, "spandex_ecto": {:hex, :spandex_ecto, "0.4.0", "deaeaddc11a35f1c551206c53d09bb93a0da5808dbef751430e465c8c7de01d3", [:mix], [{:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm"},
"spandex_phoenix": {:hex, :spandex_phoenix, "0.3.2", "e81889d80852a895cf62ce2e25181b15766d21e8647962e0a4458414b935feb3", [:mix], [{:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}, {:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm"}, "spandex_phoenix": {:hex, :spandex_phoenix, "0.3.2", "e81889d80852a895cf62ce2e25181b15766d21e8647962e0a4458414b935feb3", [:mix], [{:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}, {:spandex, "~> 2.2", [hex: :spandex, repo: "hexpm", optional: false]}], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm"},
"telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm"}, "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm"},
"timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, "timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"tzdata": {:hex, :tzdata, "1.0.1", "f6027a331af7d837471248e62733c6ebee86a72e57c613aa071ebb1f750fc71a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "tzdata": {:hex, :tzdata, "1.0.1", "f6027a331af7d837471248e62733c6ebee86a72e57c613aa071ebb1f750fc71a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},

@ -4,8 +4,12 @@ rm -rf ./_build
rm -rf ./deps rm -rf ./deps
logs=$(find . -not -path '*/\.*' -name "logs" -type d) logs=$(find . -not -path '*/\.*' -name "logs" -type d)
dev=$(find ${logs} -name "dev") dev=$(find ${logs} -name "dev")
files_and_dirs_in_logs=$(ls -d ${dev}/*) files_and_dirs_in_logs_dev=$(ls -d ${dev}/*)
rm -rf $files_and_dirs_in_logs rm -rf $files_and_dirs_in_logs_dev
test=$(find ${logs} -name "test")
files_and_dirs_in_logs_test=$(ls -d ${test}/*)
rm -rf $files_and_dirs_in_logs_test
find . -name "node_modules" -type d -exec rm -rf '{}' + find . -name "node_modules" -type d -exec rm -rf '{}' +

Loading…
Cancel
Save