Merge branch 'master' of github.com:poanetwork/blockscout into vb-estimated-address-count

pull/2822/head
Victor Baranov 5 years ago
commit 46230dd22f
  1. 4
      .circleci/config.yml
  2. 2
      CHANGELOG.md
  3. 44
      apps/block_scout_web/assets/js/pages/address.js
  4. 239
      apps/block_scout_web/assets/package-lock.json
  5. 2
      apps/block_scout_web/assets/package.json
  6. 8
      apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex
  7. 8
      apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex
  8. 42
      apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex
  9. 7
      apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex
  10. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex
  11. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex
  12. 7
      apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex
  13. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex
  14. 7
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex
  15. 9
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex
  16. 7
      apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex
  17. 14
      apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex
  18. 29
      apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex
  19. 6
      apps/block_scout_web/lib/block_scout_web/views/address_view.ex
  20. 2
      apps/block_scout_web/lib/block_scout_web/web_router.ex
  21. 182
      apps/block_scout_web/priv/gettext/default.pot
  22. 182
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  23. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_contract_controller_test.exs
  24. 13
      apps/block_scout_web/test/block_scout_web/controllers/address_controller_test.exs
  25. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs
  26. 2
      apps/explorer/lib/explorer/chain.ex
  27. 43
      apps/explorer/package-lock.json
  28. 1
      apps/explorer/package.json

@ -229,7 +229,7 @@ jobs:
eslint:
docker:
# Ensure .tool-versions matches
- image: circleci/node:9.10.1
- image: circleci/node:12.13.0-browsers-legacy
working_directory: ~/app
@ -271,7 +271,7 @@ jobs:
jest:
docker:
# Ensure .tool-versions matches
- image: circleci/node:9.10.1
- image: circleci/node:12.13.0-browsers-legacy
working_directory: ~/app

@ -1,6 +1,7 @@
## Current
### Features
- [#2787](https://github.com/poanetwork/blockscout/pull/2787) - async fetching of address counters
- [#2791](https://github.com/poanetwork/blockscout/pull/2791) - add ipc client
- [#2449](https://github.com/poanetwork/blockscout/pull/2449) - add ability to send notification events through postgres notify
- [#2822](https://github.com/poanetwork/blockscout/pull/2822) - Estimated address count on the main page, if cache is empty
@ -11,6 +12,7 @@
- [#2803](https://github.com/poanetwork/blockscout/pull/2803) - Fix block validator custom tooltip
### Chore
- [#2827](https://github.com/poanetwork/blockscout/pull/2827) - Node js 12.13.0 (latest LTS release) support
- [#2817](https://github.com/poanetwork/blockscout/pull/2817) - move docker integration documentation to blockscout docs
- [#2808](https://github.com/poanetwork/blockscout/pull/2808) - Add tooltip for tx input
- [#2807](https://github.com/poanetwork/blockscout/pull/2807) - 422 page

@ -18,7 +18,8 @@ export const initialState = {
balanceCard: null,
fetchedCoinBalanceBlockNumber: null,
transactionCount: null,
validationCount: null
validationCount: null,
countersFetched: false
}
export function reducer (state = initialState, action) {
@ -34,6 +35,13 @@ export function reducer (state = initialState, action) {
channelDisconnected: true
})
}
case 'COUNTERS_FETCHED': {
return Object.assign({}, state, {
transactionCount: action.transactionCount,
validationCount: action.validationCount,
countersFetched: true
})
}
case 'RECEIVED_NEW_BLOCK': {
if (state.channelDisconnected) return state
@ -81,8 +89,15 @@ const elements = {
return { transactionCount: numeral($el.text()).value() }
},
render ($el, state, oldState) {
if (oldState.transactionCount === state.transactionCount) return
$el.empty().append(numeral(state.transactionCount).format())
if (state.countersFetched && state.transactionCount) {
if (oldState.transactionCount === state.transactionCount) return
$el.empty().append('>= ' + numeral(state.transactionCount).format() + ' Transactions')
$el.show()
$el.parent('.address-detail-item').removeAttr('style')
} else {
$el.hide()
$el.parent('.address-detail-item').css('display', 'none')
}
}
},
'[data-selector="fetched-coin-balance-block-number"]': {
@ -99,12 +114,29 @@ const elements = {
return { validationCount: numeral($el.text()).value() }
},
render ($el, state, oldState) {
if (oldState.validationCount === state.validationCount) return
$el.empty().append(numeral(state.validationCount).format())
if (state.countersFetched && state.validationCount) {
if (oldState.validationCount === state.validationCount) return
$el.empty().append(numeral(state.validationCount).format() + ' Blocks Validated')
$el.show()
} else {
$el.hide()
}
}
}
}
function loadCounters (store) {
const $element = $('[data-async-counters]')
const path = $element.data().asyncCounters
function fetchCounters () {
$.getJSON(path)
.done(response => store.dispatch(Object.assign({type: 'COUNTERS_FETCHED'}, humps.camelizeKeys(response))))
}
fetchCounters()
}
const $addressDetailsPage = $('[data-page="address-details"]')
if ($addressDetailsPage.length) {
const store = createStore(reducer)
@ -149,4 +181,6 @@ if ($addressDetailsPage.length) {
type: 'RECEIVED_UPDATED_BALANCE',
msg: humps.camelizeKeys(msg)
}))
loadCounters(store)
}

@ -1976,6 +1976,39 @@
"tiny-emitter": "^2.0.0"
}
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wrap-ansi": "^2.0.0"
},
"dependencies": {
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
}
}
},
"clone-deep": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
@ -6725,9 +6758,9 @@
"integrity": "sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ=="
},
"js-base64": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.5.tgz",
"integrity": "sha512-aUnNwqMOXw3yvErjMPSQu6qIIzUmT1e5KcU1OZxRDU1g/am6mzBvcrmLAYwzmB59BHPrh5/tKaiF4OPhqRWESQ==",
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
"integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==",
"dev": true
},
"js-tokens": {
@ -6962,18 +6995,6 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"lodash.assign": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
"dev": true
},
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
"dev": true
},
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@ -6986,12 +7007,6 @@
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
"dev": true
},
"lodash.mergewith": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"dev": true
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@ -7523,7 +7538,8 @@
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
"dev": true
"dev": true,
"optional": true
},
"nanoassert": {
"version": "1.1.0",
@ -7618,20 +7634,6 @@
"block-stream": "*",
"fstream": "^1.0.12",
"inherits": "2"
},
"dependencies": {
"fstream": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
"mkdirp": ">=0.5 0",
"rimraf": "2"
}
}
}
}
}
@ -7691,9 +7693,9 @@
}
},
"node-sass": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.3.tgz",
"integrity": "sha512-XzXyGjO+84wxyH7fV6IwBOTrEBe2f0a6SBze9QWWYR/cL74AcQUks2AsqcCZenl/Fp/JVbuEaLpgrLtocwBUww==",
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz",
"integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==",
"dev": true,
"requires": {
"async-foreach": "^0.1.3",
@ -7703,26 +7705,42 @@
"get-stdin": "^4.0.1",
"glob": "^7.0.3",
"in-publish": "^2.0.0",
"lodash.assign": "^4.2.0",
"lodash.clonedeep": "^4.3.2",
"lodash.mergewith": "^4.6.0",
"lodash": "^4.17.11",
"meow": "^3.7.0",
"mkdirp": "^0.5.1",
"nan": "^2.10.0",
"nan": "^2.13.2",
"node-gyp": "^3.8.0",
"npmlog": "^4.0.0",
"request": "2.87.0",
"request": "^2.88.0",
"sass-graph": "^2.2.4",
"stdout-stream": "^1.4.0",
"true-case-path": "^1.0.2"
},
"dependencies": {
"ajv": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"aws4": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
@ -7746,11 +7764,104 @@
"which": "^1.2.9"
}
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true
},
"har-validator": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"dev": true,
"requires": {
"ajv": "^6.5.5",
"har-schema": "^2.0.0"
}
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
"dev": true
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
"dev": true,
"requires": {
"mime-db": "1.40.0"
}
},
"nan": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
"dev": true
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
"dev": true
},
"request": {
"version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"dev": true,
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
}
}
}
},
@ -9788,17 +9899,6 @@
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
"dev": true
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wrap-ansi": "^2.0.0"
}
},
"find-up": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
@ -10463,9 +10563,9 @@
}
},
"stdout-stream": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
"integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
"integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
"dev": true,
"requires": {
"readable-stream": "^2.0.1"
@ -11433,27 +11533,12 @@
"dev": true
},
"true-case-path": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz",
"integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
"integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
"dev": true,
"requires": {
"glob": "^6.0.4"
},
"dependencies": {
"glob": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
"integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
"dev": true,
"requires": {
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "2 || 3",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
}
"glob": "^7.1.2"
}
},
"tslib": {

@ -59,7 +59,7 @@
"file-loader": "^1.1.11",
"jest": "^23.2.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.9.3",
"node-sass": "^4.12.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^2.1.4",
"sass-loader": "^7.1.0",

@ -5,7 +5,6 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.AddressCoinBalanceView
@ -60,15 +59,12 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do
def index(conn, %{"address_id" => address_hash_string}) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(conn, "index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count,
validation_count: validation_count,
current_path: current_path(conn)
current_path: current_path(conn),
counters_path: address_path(conn, :address_counters, %{"id" => to_string(address_hash)})
)
else
:error ->

@ -1,8 +1,7 @@
# credo:disable-for-this-file
defmodule BlockScoutWeb.AddressContractController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand
@ -20,16 +19,13 @@ defmodule BlockScoutWeb.AddressContractController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count,
validation_count: validation_count
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string})
)
else
:error ->

@ -5,7 +5,6 @@ defmodule BlockScoutWeb.AddressController do
alias BlockScoutWeb.AddressView
alias Explorer.{Chain, Market}
alias Explorer.Chain.Hash
alias Explorer.ExchangeRates.Token
alias Phoenix.View
@ -68,19 +67,30 @@ defmodule BlockScoutWeb.AddressController do
redirect(conn, to: address_transaction_path(conn, :index, id))
end
def transaction_and_validation_count(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do
def address_counters(conn, %{"id" => address_hash_string}) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address)
json(conn, %{transaction_count: transaction_count, validation_count: validation_count})
else
_ -> not_found(conn)
end
end
defp transaction_and_validation_count(address) do
transaction_count_task =
Task.async(fn ->
transaction_count(address_hash)
transaction_count(address)
end)
validation_count_task =
Task.async(fn ->
validation_count(address_hash)
validation_count(address)
end)
[transaction_count_task, validation_count_task]
|> Task.yield_many(:timer.seconds(30))
|> Task.yield_many(:timer.seconds(60))
|> Enum.map(fn {_task, res} ->
case res do
{:ok, result} ->
@ -96,11 +106,25 @@ defmodule BlockScoutWeb.AddressController do
|> List.to_tuple()
end
def transaction_count(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do
Chain.total_transactions_sent_by_address(address_hash)
defp transaction_count(address) do
if contract?(address) do
incoming_transaction_count = Chain.address_to_incoming_transaction_count(address.hash)
if incoming_transaction_count == 0 do
Chain.total_transactions_sent_by_address(address.hash)
else
incoming_transaction_count
end
else
Chain.total_transactions_sent_by_address(address.hash)
end
end
def validation_count(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do
Chain.address_to_validation_count(address_hash)
defp validation_count(address) do
Chain.address_to_validation_count(address.hash)
end
defp contract?(%{contract_code: nil}), do: false
defp contract?(%{contract_code: _}), do: true
end

@ -1,8 +1,6 @@
defmodule BlockScoutWeb.AddressDecompiledContractController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand
@ -10,16 +8,13 @@ defmodule BlockScoutWeb.AddressDecompiledContractController do
def index(conn, %{"address_id" => address_hash_string}) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_decompiled_contract_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count,
validation_count: validation_count
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string})
)
else
:error ->

@ -5,7 +5,6 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.InternalTransactionView
@ -63,8 +62,6 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
@ -73,8 +70,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
current_path: current_path(conn),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
filter: params["filter"],
transaction_count: transaction_count,
validation_count: validation_count
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string})
)
else
:error ->

@ -3,7 +3,6 @@ defmodule BlockScoutWeb.AddressLogsController do
Manages events logs tab.
"""
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.AddressLogsView
@ -56,8 +55,6 @@ defmodule BlockScoutWeb.AddressLogsController do
def index(conn, %{"address_id" => address_hash_string}) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
@ -65,8 +62,7 @@ defmodule BlockScoutWeb.AddressLogsController do
current_path: current_path(conn),
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count,
validation_count: validation_count
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string})
)
else
_ ->

@ -12,8 +12,6 @@ defmodule BlockScoutWeb.AddressReadContractController do
alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
def index(conn, %{"address_id" => address_hash_string}) do
address_options = [
necessity_by_association: %{
@ -28,16 +26,13 @@ defmodule BlockScoutWeb.AddressReadContractController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true),
false <- is_nil(address.smart_contract) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count,
validation_count: validation_count
counters_path: address_path(conn, :address_counters, %{"id" => to_string(address_hash)})
)
else
_ ->

@ -1,7 +1,6 @@
defmodule BlockScoutWeb.AddressTokenController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain, only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1]
alias BlockScoutWeb.AddressTokenView
@ -57,8 +56,6 @@ defmodule BlockScoutWeb.AddressTokenController do
def index(conn, %{"address_id" => address_hash_string} = _params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
@ -66,8 +63,7 @@ defmodule BlockScoutWeb.AddressTokenController do
current_path: current_path(conn),
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count,
validation_count: validation_count
counters_path: address_path(conn, :address_counters, %{"id" => to_string(address_hash)})
)
else
:error ->

@ -7,8 +7,6 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
alias Indexer.Fetcher.CoinBalanceOnDemand
alias Phoenix.View
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain,
only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1]
@ -77,8 +75,6 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
{:ok, token_hash} <- Chain.string_to_address_hash(token_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, token} <- Chain.token_from_address_hash(token_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
@ -87,8 +83,7 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
current_path: current_path(conn),
token: token,
transaction_count: transaction_count,
validation_count: validation_count
counters_path: address_path(conn, :address_counters, %{"id" => to_string(address_hash)})
)
else
:error ->

@ -5,7 +5,6 @@ defmodule BlockScoutWeb.AddressTransactionController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.TransactionView
@ -98,8 +97,6 @@ defmodule BlockScoutWeb.AddressTransactionController do
def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
@ -107,8 +104,7 @@ defmodule BlockScoutWeb.AddressTransactionController do
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
filter: params["filter"],
transaction_count: transaction_count,
validation_count: validation_count,
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string}),
current_path: current_path(conn)
)
else
@ -128,8 +124,7 @@ defmodule BlockScoutWeb.AddressTransactionController do
coin_balance_status: nil,
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
filter: params["filter"],
transaction_count: 0,
validation_count: 0,
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string}),
current_path: current_path(conn)
)

@ -4,8 +4,6 @@ defmodule BlockScoutWeb.AddressValidationController do
"""
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain,
only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
@ -69,16 +67,13 @@ defmodule BlockScoutWeb.AddressValidationController do
def index(conn, %{"address_id" => address_hash_string}) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_or_insert_address_from_hash(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
current_path: current_path(conn),
transaction_count: transaction_count,
validation_count: validation_count,
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string}),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null()
)
else

@ -27,14 +27,12 @@
class: "card-tab #{tab_status("logs", @conn.request_path)}",
to: address_logs_path(@conn, :index, @address.hash)
) %>
<%= if BlockScoutWeb.AddressView.validator?(@validation_count) do %>
<%= link(
gettext("Blocks Validated"),
class: "card-tab #{tab_status("validations", @conn.request_path)}",
"data-test": "validations_tab_link",
to: address_validation_path(@conn, :index, @address.hash)
) %>
<% end %>
<%= link(
gettext("Blocks Validated"),
class: "card-tab #{tab_status("validations", @conn.request_path)}",
"data-test": "validations_tab_link",
to: address_validation_path(@conn, :index, @address.hash)
) %>
<%= if contract?(@address) do %>
<%= link(
to: address_contract_path(@conn, :index, @address.hash),

@ -1,4 +1,4 @@
<section class="address-overview" data-page="address-details" data-page-address-hash="<%= @address.hash %>">
<section class="address-overview" data-page="address-details" data-page-address-hash="<%= @address.hash %>" data-async-counters="<%= @counters_path %>">
<div class="row">
<!-- Address details -->
<div class="card-section col-md-12 col-lg-8 pr-0-md">
@ -70,33 +70,20 @@
</span>
<% end %>
<span>
<span class="address-detail-item">
<%= if contract?(@address) do %>
<%= gettext(">=") %>
<span data-selector="transaction-count">
<%= incoming_transaction_count(@address.hash) %>
</span>
<%= gettext("Incoming Transactions") %>
<% else %>
<span data-selector="transaction-count">
<%= BlockScoutWeb.Cldr.Number.to_string!(@transaction_count, format: "#,###") %>
</span>
<%= gettext("Transactions Sent") %>
<% end %>
<span class="address-detail-item" style="display: none">
<span data-selector="transaction-count">
</span>
</span>
<%= if @address.fetched_coin_balance_block_number do %>
<span class="address-detail-item">
<%= gettext("Last Balance Update: Block #") %><span data-selector="fetched-coin-balance-block-number"><%= @address.fetched_coin_balance_block_number %></span>
</span>
<% end %>
<%= if validator?(@validation_count) do %>
<span class="address-detail-item">
<span data-selector="validation-count">
<%= BlockScoutWeb.Cldr.Number.to_string!(@validation_count, format: "#,###") %>
</span>
<%= gettext("Blocks Validated") %>
<span class="address-detail-item">
<span data-selector="validation-count">
</span>
<% end %>
</span>
</span>
</div>
<% from_address_hash = from_address_hash(@address) %>

@ -219,12 +219,6 @@ defmodule BlockScoutWeb.AddressView do
def token_title(%Token{name: name, symbol: symbol}), do: "#{name} (#{symbol})"
def incoming_transaction_count(address_hash) do
address_hash
|> Chain.address_to_incoming_transaction_count()
|> BlockScoutWeb.Cldr.Number.to_string!(format: "#,###")
end
def trimmed_hash(%Hash{} = hash) do
string_hash = to_string(hash)
"#{String.slice(string_hash, 0..5)}#{String.slice(string_hash, -6..-1)}"

@ -208,6 +208,8 @@ defmodule BlockScoutWeb.WebRouter do
as: :smart_contract
)
get("/address_counters", AddressController, :address_counters)
get("/search", ChainController, :search)
get("/search_logs", AddressLogsController, :search_logs)

@ -76,11 +76,6 @@ msgstr ""
msgid "- We're indexing this chain right now. Some of the counts may be inaccurate."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:75
msgid ">="
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:73
msgid "A string with the name of the action to be invoked."
@ -247,14 +242,6 @@ msgstr ""
msgid "Blocks Indexed"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:32
#: lib/block_scout_web/templates/address/overview.html.eex:97
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
#: lib/block_scout_web/views/address_view.ex:313
msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_footer.html.eex:17
msgid "Blockscout is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Ethereum Networks."
@ -299,22 +286,6 @@ msgstr ""
msgid "Clear"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:42
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:165
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
#: lib/block_scout_web/views/address_view.ex:309
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/views/address_view.ex:312
msgid "Coin Balance History"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40
msgid "Compiler"
@ -494,7 +465,7 @@ msgid "Create2"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:107
#: lib/block_scout_web/templates/address/overview.html.eex:94
msgid "Created by"
msgstr ""
@ -526,12 +497,7 @@ msgid "Decoded"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/address_view.ex:310
msgid "Decompiled Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:52
#: lib/block_scout_web/templates/address/_tabs.html.eex:50
msgid "Decompiled code"
msgstr ""
@ -663,7 +629,7 @@ msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:120
#: lib/block_scout_web/templates/address/overview.html.eex:107
msgid "Error: Could not determine contract creator."
msgstr ""
@ -930,14 +896,6 @@ msgstr ""
msgid "Token Transfers"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
#: lib/block_scout_web/views/address_view.ex:306
msgid "Tokens"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_metatags.html.eex:13
msgid "Top Accounts - %{subnetwork} Explorer"
@ -959,11 +917,6 @@ msgstr ""
msgid "If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:79
msgid "Incoming Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:55
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:108
@ -982,16 +935,6 @@ msgstr ""
msgid "Internal Transaction"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Internal Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/invalid.html.eex:6
msgid "Invalid Transaction Hash"
@ -1010,7 +953,7 @@ msgid "It could still be in the TX Pool of a different node, waiting to be broad
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:89
#: lib/block_scout_web/templates/address/overview.html.eex:79
msgid "Last Balance Update: Block #"
msgstr ""
@ -1071,16 +1014,6 @@ msgstr ""
msgid "Log Data"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:314
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Logs"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_footer.html.eex:44
msgid "Main Networks"
@ -1234,7 +1167,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:33
#: lib/block_scout_web/templates/address/overview.html.eex:144
#: lib/block_scout_web/templates/address/overview.html.eex:131
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:51
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:93
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:36
@ -1264,14 +1197,6 @@ msgstr ""
msgid "Raw Trace"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:58
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
#, elixir-format
#:
#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:11
@ -1552,22 +1477,6 @@ msgstr ""
msgid "Transaction Speed"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:3
#: lib/block_scout_web/templates/address_transaction/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:10
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/layout/_topnav.html.eex:50
#: lib/block_scout_web/views/address_view.ex:307
msgid "Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:84
msgid "Transactions Sent"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tile.html.eex:31
msgid "Transactions sent"
@ -1741,7 +1650,7 @@ msgid "Yes"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:112
#: lib/block_scout_web/templates/address/overview.html.eex:99
msgid "at"
msgstr ""
@ -1799,8 +1708,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:37
#: lib/block_scout_web/templates/address/overview.html.eex:145
#: lib/block_scout_web/templates/address/overview.html.eex:153
#: lib/block_scout_web/templates/address/overview.html.eex:132
#: lib/block_scout_web/templates/address/overview.html.eex:140
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:94
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:102
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:106
@ -1877,3 +1786,78 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:134
msgid "Copy Txn Input"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:31
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
#: lib/block_scout_web/views/address_view.ex:307
msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:40
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:165
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
#: lib/block_scout_web/views/address_view.ex:303
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/views/address_view.ex:306
msgid "Coin Balance History"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/address_view.ex:304
msgid "Decompiled Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:302
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Internal Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Logs"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:56
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
#: lib/block_scout_web/views/address_view.ex:305
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
#: lib/block_scout_web/views/address_view.ex:300
msgid "Tokens"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:3
#: lib/block_scout_web/templates/address_transaction/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:10
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/layout/_topnav.html.eex:50
#: lib/block_scout_web/views/address_view.ex:301
msgid "Transactions"
msgstr ""

@ -76,11 +76,6 @@ msgstr ""
msgid "- We're indexing this chain right now. Some of the counts may be inaccurate."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:75
msgid ">="
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:73
msgid "A string with the name of the action to be invoked."
@ -247,14 +242,6 @@ msgstr ""
msgid "Blocks Indexed"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:32
#: lib/block_scout_web/templates/address/overview.html.eex:97
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
#: lib/block_scout_web/views/address_view.ex:313
msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_footer.html.eex:17
msgid "Blockscout is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Ethereum Networks."
@ -299,22 +286,6 @@ msgstr ""
msgid "Clear"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:42
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:165
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
#: lib/block_scout_web/views/address_view.ex:309
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/views/address_view.ex:312
msgid "Coin Balance History"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40
msgid "Compiler"
@ -494,7 +465,7 @@ msgid "Create2"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:107
#: lib/block_scout_web/templates/address/overview.html.eex:94
msgid "Created by"
msgstr ""
@ -526,12 +497,7 @@ msgid "Decoded"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/address_view.ex:310
msgid "Decompiled Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:52
#: lib/block_scout_web/templates/address/_tabs.html.eex:50
msgid "Decompiled code"
msgstr ""
@ -663,7 +629,7 @@ msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:120
#: lib/block_scout_web/templates/address/overview.html.eex:107
msgid "Error: Could not determine contract creator."
msgstr ""
@ -930,14 +896,6 @@ msgstr ""
msgid "Token Transfers"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
#: lib/block_scout_web/views/address_view.ex:306
msgid "Tokens"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_metatags.html.eex:13
msgid "Top Accounts - %{subnetwork} Explorer"
@ -959,11 +917,6 @@ msgstr ""
msgid "If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:79
msgid "Incoming Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:55
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:108
@ -982,16 +935,6 @@ msgstr ""
msgid "Internal Transaction"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Internal Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/invalid.html.eex:6
msgid "Invalid Transaction Hash"
@ -1010,7 +953,7 @@ msgid "It could still be in the TX Pool of a different node, waiting to be broad
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:89
#: lib/block_scout_web/templates/address/overview.html.eex:79
msgid "Last Balance Update: Block #"
msgstr ""
@ -1071,16 +1014,6 @@ msgstr ""
msgid "Log Data"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:314
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Logs"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_footer.html.eex:44
msgid "Main Networks"
@ -1234,7 +1167,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:33
#: lib/block_scout_web/templates/address/overview.html.eex:144
#: lib/block_scout_web/templates/address/overview.html.eex:131
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:51
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:93
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:36
@ -1264,14 +1197,6 @@ msgstr ""
msgid "Raw Trace"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:58
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
#: lib/block_scout_web/views/address_view.ex:311
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
#, elixir-format
#:
#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:11
@ -1552,22 +1477,6 @@ msgstr ""
msgid "Transaction Speed"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:3
#: lib/block_scout_web/templates/address_transaction/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:10
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/layout/_topnav.html.eex:50
#: lib/block_scout_web/views/address_view.ex:307
msgid "Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:84
msgid "Transactions Sent"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tile.html.eex:31
msgid "Transactions sent"
@ -1741,7 +1650,7 @@ msgid "Yes"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:112
#: lib/block_scout_web/templates/address/overview.html.eex:99
msgid "at"
msgstr ""
@ -1799,8 +1708,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:37
#: lib/block_scout_web/templates/address/overview.html.eex:145
#: lib/block_scout_web/templates/address/overview.html.eex:153
#: lib/block_scout_web/templates/address/overview.html.eex:132
#: lib/block_scout_web/templates/address/overview.html.eex:140
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:94
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:102
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:106
@ -1877,3 +1786,78 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:134
msgid "Copy Txn Input"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/address/_tabs.html.eex:31
#: lib/block_scout_web/templates/address_validation/index.html.eex:13
#: lib/block_scout_web/views/address_view.ex:307
msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:40
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:165
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:187
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:126
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:149
#: lib/block_scout_web/views/address_view.ex:303
msgid "Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:20
#: lib/block_scout_web/views/address_view.ex:306
msgid "Coin Balance History"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/views/address_view.ex:304
msgid "Decompiled Code"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/address/_tabs.html.eex:14
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:19
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:302
#: lib/block_scout_web/views/transaction_view.ex:314
msgid "Internal Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:26
#: lib/block_scout_web/templates/address_logs/index.html.eex:8
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:308
#: lib/block_scout_web/views/transaction_view.ex:315
msgid "Logs"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/address/_tabs.html.eex:56
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:25
#: lib/block_scout_web/views/address_view.ex:305
#: lib/block_scout_web/views/tokens/overview_view.ex:37
msgid "Read Contract"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/address/_tabs.html.eex:8
#: lib/block_scout_web/templates/address_token/index.html.eex:8
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:9
#: lib/block_scout_web/views/address_view.ex:300
msgid "Tokens"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/address/_tabs.html.eex:3
#: lib/block_scout_web/templates/address_transaction/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:10
#: lib/block_scout_web/templates/block_transaction/index.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:145
#: lib/block_scout_web/templates/layout/_topnav.html.eex:50
#: lib/block_scout_web/views/address_view.ex:301
msgid "Transactions"
msgstr ""

@ -49,7 +49,6 @@ defmodule BlockScoutWeb.AddressContractControllerTest do
assert html_response(conn, 200)
assert address.hash == conn.assigns.address.hash
assert %Token{} = conn.assigns.exchange_rate
assert conn.assigns.transaction_count
end
end
end

@ -37,4 +37,17 @@ defmodule BlockScoutWeb.AddressControllerTest do
assert redirected_to(conn) =~ "/address/0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed/transactions"
end
end
describe "GET address_counters/2" do
test "returns address counters" do
address = insert(:address)
conn = get(conn, "/address_counters", %{"id" => to_string(address.hash)})
assert conn.status == 200
{:ok, response} = Jason.decode(conn.resp_body)
assert %{"transaction_count" => 0, "validation_count" => 0} == response
end
end
end

@ -37,7 +37,6 @@ defmodule BlockScoutWeb.AddressReadContractControllerTest do
assert html_response(conn, 200)
assert contract_address.hash == conn.assigns.address.hash
assert %Token{} = conn.assigns.exchange_rate
assert conn.assigns.transaction_count
end
test "returns not found for an unverified contract", %{conn: conn} do

@ -204,7 +204,7 @@ defmodule Explorer.Chain do
last_nonce =
address_hash
|> Transaction.last_nonce_by_address_query()
|> Repo.one()
|> Repo.one(timeout: :infinity)
case last_nonce do
nil -> 0

@ -14,9 +14,12 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"bindings": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz",
"integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew=="
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"brace-expansion": {
"version": "1.1.11",
@ -71,6 +74,11 @@
"strip-eof": "^1.0.0"
}
},
"file-uri-to-path": {
"version": "1.0.0",
"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=="
},
"fs-extra": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
@ -162,9 +170,9 @@
}
},
"keccak": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz",
"integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-2.0.0.tgz",
"integrity": "sha512-rKe/lRr0KGhjoz97cwg+oeT1Rj/Y4cjae6glArioUC8JBF9ROGZctwIaaruM7d7naovME4Q8WcQSO908A8qcyQ==",
"requires": {
"bindings": "^1.2.1",
"inherits": "^2.0.3",
@ -240,9 +248,9 @@
}
},
"nan": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.12.0.tgz",
"integrity": "sha512-zT5nC0JhbljmyEf+Z456nvm7iO7XgRV2hYxoBtPpnyp+0Q4aCoP6uWNn76v/I6k2kCYNLWqWbwBWQcjsNI/bjw=="
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
},
"npm-run-path": {
"version": "2.0.2",
@ -330,9 +338,9 @@
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
},
"semver": {
"version": "5.5.0",
@ -410,6 +418,17 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"keccak": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz",
"integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
"requires": {
"bindings": "^1.2.1",
"inherits": "^2.0.3",
"nan": "^2.2.1",
"safe-buffer": "^5.1.0"
}
},
"os-locale": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",

@ -13,6 +13,7 @@
},
"scripts": {},
"dependencies": {
"keccak": "^2.0.0",
"solc": "^0.5"
}
}

Loading…
Cancel
Save