diff --git a/CHANGELOG.md b/CHANGELOG.md index 8199bc9cd3..343301eb65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ ## Current ### Features -- [#2671](https://github.com/poanetwork/blockscout/pull/2671) - fixed buttons color at smart contract section +- [#2679](https://github.com/poanetwork/blockscout/pull/2679) - added fixed height for card chain blocks and card chain transactions +- [#2678](https://github.com/poanetwork/blockscout/pull/2678) - fixed dashboard banner height bug - [#2672](https://github.com/poanetwork/blockscout/pull/2672) - added new theme for xUSDT +- [#2663](https://github.com/poanetwork/blockscout/pull/2663) - Fetch address counters in parallel ### Fixes +- [#2682](https://github.com/poanetwork/blockscout/pull/2682) - Use Task.start instead of Task.async in caches ### Chore diff --git a/README.md b/README.md index 3c95a5d125..138ddf18d8 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ BlockScout provides a comprehensive, easy-to-use interface for users to view, co See our [project documentation](https://poanetwork.github.io/blockscout) for detailed information and setup instructions. -Visit the [POA BlockScout forum](https://forum.poa.network/c/blockscout) for FAQs, troubleshooting, and other BlockScout related items. You can also post and answer questions here. +Visit the [POA BlockScout forum](https://forum.poa.network/c/blockscout) for FAQs, troubleshooting, and other BlockScout related items. You can also post and answer questions here. -You can also access the dev chatroom on our [Gitter Channel](https://gitter.im/poanetwork/blockscout). +You can also access the dev chatroom on our [Gitter Channel](https://gitter.im/poanetwork/blockscout). ## About BlockScout @@ -28,23 +28,24 @@ Currently available full-featured block explorers (Etherscan, Etherchain, Blockc ## Supported Projects -| **Hosted Mainnets** | **Hosted Testnets** | **Additional Chains using BlockScout** | -|--------------------------------------------------------|-------------------------------------------------------|----------------------------------------------------| -| [Aerum](https://blockscout.com/aerum/mainnet) | [Goerli Testnet](https://blockscout.com/eth/goerli) | [ARTIS](https://explorer.sigma1.artis.network) | -| [Callisto](https://blockscout.com/callisto/mainnet) | [Kovan Testnet](https://blockscout.com/eth/kovan) | [Ether-1](https://blocks.ether1.wattpool.net/) | -| [Ethereum Classic](https://blockscout.com/etc/mainnet) | [POA Sokol Testnet](https://blockscout.com/poa/sokol) | [Fuse Network](https://explorer.fuse.io/) | -| [Ethereum Mainnet](https://blockscout.com/eth/mainnet) | [Rinkeby Testnet](https://blockscout.com/eth/rinkeby) | [Oasis Labs](https://blockexplorer.oasiscloud.io/) | -| [POA Core Network](https://blockscout.com/poa/core) | [Ropsten Testnet](https://blockscout.com/eth/ropsten) | [Petrichor](https://explorer.petrachor.com/) | -| [RSK](https://blockscout.com/rsk/mainnet) | | [PIRL](http://pirl.es/) | -| [xDai Chain](https://blockscout.com/poa/dai) | | [SafeChain](https://explorer.safechain.io) | -| | | [SpringChain](https://explorer.springrole.com/) | -| | | [Kotti Testnet](https://kottiexplorer.ethernode.io/) | -| | | [Loom](http://plasma-blockexplorer.dappchains.com/) | -| | | [Tenda](https://tenda.network) | -| | | [GoJoy Chain](https://gojoychain.com/) | - - -Current BlockScout versions for hosted projects are available [on the forum](https://forum.poa.network/t/deployed-instances-on-blockscout-com/1938). +| **Hosted Mainnets** | **Hosted Testnets** | **Additional Chains using BlockScout** | **Additional Chains using BlockScout** | +|--------------------------------------------------------|-------------------------------------------------------|------------------------------------------------------|----------------------------------------------------------------| +| [Callisto](https://blockscout.com/callisto/mainnet) | [Goerli Testnet](https://blockscout.com/eth/goerli) | [ARTIS](https://explorer.sigma1.artis.network) | [Celo Testnet](https://alfajores-blockscout.celo-testnet.org/) | +| [Ethereum Classic](https://blockscout.com/etc/mainnet) | [Kovan Testnet](https://blockscout.com/eth/kovan) | [Ether-1](https://blocks.ether1.wattpool.net/) | [Matic Testnet](https://explorer.testnet2.matic.network/) | +| [Ethereum Mainnet](https://blockscout.com/eth/mainnet) | [LUKSO L14 Testnet](https://blockscout.com/lukso/l14) | [Kotti Testnet](https://kottiexplorer.ethernode.io/) | | +| [POA Core Network](https://blockscout.com/poa/core) | [POA Sokol Testnet](https://blockscout.com/poa/sokol) | [Fuse Network](https://explorer.fuse.io/) | | +| [RSK](https://blockscout.com/rsk/mainnet) | [Rinkeby Testnet](https://blockscout.com/eth/rinkeby) | [Oasis Labs](https://blockexplorer.oasiscloud.io/) | | +| [xDai Chain](https://blockscout.com/poa/dai) | [Ropsten Testnet](https://blockscout.com/eth/ropsten) | [Petrichor](https://explorer.petrachor.com/) | | +| | | [PIRL](http://pirl.es/) | | +| | | [SafeChain](https://explorer.safechain.io) | | +| | | [SpringChain](https://explorer.springrole.com/) | | +| | | [Tenda](https://tenda.network) | | +| | | [Loom](http://plasma-blockexplorer.dappchains.com/) | | +| | | [GoJoy Chain](https://gojoychain.com/) | | +| | | [Xerom](https://blocks.xerom.org/) | | + + +Current BlockScout versions for hosted projects are available [on the forum](https://forum.poa.network/t/deployed-instances-on-blockscout-com/1938). ## Getting Started diff --git a/apps/block_scout_web/assets/css/_images-preload.scss b/apps/block_scout_web/assets/css/_images-preload.scss index 95f4633a56..031cf20888 100644 --- a/apps/block_scout_web/assets/css/_images-preload.scss +++ b/apps/block_scout_web/assets/css/_images-preload.scss @@ -13,4 +13,5 @@ body:after { url(/images/network-selector-icons/ropsten-testnet.svg) url(/images/network-selector-icons/xdai-chain.svg) url(/images/network-selector-icons/lukso-l14-testnet.svg) + url(/images/network-selector-icons/circle-xusdt.svg) }; \ No newline at end of file diff --git a/apps/block_scout_web/assets/css/app.scss b/apps/block_scout_web/assets/css/app.scss index c5d07c2ae2..4563ec33d5 100644 --- a/apps/block_scout_web/assets/css/app.scss +++ b/apps/block_scout_web/assets/css/app.scss @@ -1,12 +1,10 @@ @import "./mixins"; /* Phoenix flash messages */ - .alert:empty { - display: none; + display: none; } - /* This file is for your main application css. */ // Font Awesome @@ -15,10 +13,13 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts"; @import "fa-brands"; @import "fa-regular"; @import "fa-solid"; + // Bootstrap Core CSS @import "node_modules/bootstrap/scss/functions"; @import "node_modules/bootstrap/scss/mixins"; + @import "theme/variables"; + @import "node_modules/bootstrap/scss/root"; @import "node_modules/bootstrap/scss/reboot"; @import "node_modules/bootstrap/scss/grid"; @@ -37,6 +38,7 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts"; @import "node_modules/bootstrap/scss/utilities/position"; @import "node_modules/bootstrap/scss/utilities/borders"; @import "node_modules/bootstrap/scss/progress"; + // Bootstrap Components @import "node_modules/bootstrap/scss/alert"; @import "node_modules/bootstrap/scss/badge"; @@ -48,10 +50,13 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts"; @import "node_modules/bootstrap/scss/pagination"; @import "node_modules/bootstrap/scss/tables"; @import "node_modules/bootstrap/scss/transitions"; + // Code highlight @import "node_modules/highlight.js/styles/default"; + //Custom theme @import "theme/fonts"; + // Custom SCSS @import "layout"; @import "typography"; @@ -109,18 +114,15 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts"; @import "components/radio_big"; @import "components/btn_no_border"; @import "components/custom_tooltips_block_details"; -@import "components/_erc721_token_image_container"; @import "theme/dark-theme"; :export { - dashboardBannerChartAxisFontColor: $dashboard-banner-chart-axis-font-color; - dashboardLineColorMarket: $dashboard-line-color-market; - dashboardLineColorPrice: $dashboard-line-color-price; - primary: $primary; - secondary: $secondary; - darkprimary: $dark-primary; - darksecondary: $dark-secondary; + dashboardBannerChartAxisFontColor: $dashboard-banner-chart-axis-font-color; + dashboardLineColorMarket: $dashboard-line-color-market; + dashboardLineColorPrice: $dashboard-line-color-price; + primary: $primary; + secondary: $secondary; + darkprimary: $dark-primary; + darksecondary: $dark-secondary; } - - diff --git a/apps/block_scout_web/assets/css/components/_card.scss b/apps/block_scout_web/assets/css/components/_card.scss index 80d97305b5..8fff120deb 100644 --- a/apps/block_scout_web/assets/css/components/_card.scss +++ b/apps/block_scout_web/assets/css/components/_card.scss @@ -7,214 +7,245 @@ $card-background-1: $primary !default; $card-background-1-text-color: #fff !default; $card-tab-icon-color: #20b760 !default; $card-tab-icon-color-active: #fff !default; + .card { - background-color: $card-background-color; - border-radius: $card-default-border-radius; - border: none; - box-shadow: 0 0 30px 0 rgba(202, 199, 226, 0.5); - margin-bottom: $common-container-margin; - .block-details-row { - flex-direction: row; + background-color: $card-background-color; + border-radius: $card-default-border-radius; + border: none; + box-shadow: 0 0 30px 0 rgba(202, 199, 226, 0.5); + margin-bottom: $common-container-margin; + + .block-details-row { + flex-direction: row; + @include media-breakpoint-down(sm) { + flex-direction: column; + } + + .block-detail-el { + & + .block-detail-el { @include media-breakpoint-down(sm) { - flex-direction: column; - } - .block-detail-el { - &+.block-detail-el { - @include media-breakpoint-down(sm) { - margin-top: 6px; - } - } + margin-top: 6px; } + } } + } } .card-background-1 { - background-color: $card-background-1; + background-color: $card-background-1; + color: $card-background-1-text-color; + + a:not(.dropdown-item), + a:not(.dropdown-item):hover { color: $card-background-1-text-color; - a:not(.dropdown-item), - a:not(.dropdown-item):hover { - color: $card-background-1-text-color; - } + } } .card-header { - background: transparent; - border-bottom: 1px solid $base-border-color; - padding: $card-vertical-padding $card-horizontal-padding; - &-tabs { - margin: (-$card-spacer-y) (-$card-spacer-x); - } + background: transparent; + border-bottom: 1px solid $base-border-color; + padding: $card-vertical-padding $card-horizontal-padding; + + &-tabs { + margin: (-$card-spacer-y) (-$card-spacer-x); + } } .card-title { - font-size: 18px; - font-weight: normal; - line-height: 1.2rem; - margin-bottom: 2rem; - &.lg-card-title { - @media (max-width: 374px) { - font-size: 13px; - } - } - &.margin-bottom-md { - margin-bottom: 25px; - } - &.margin-bottom-sm { - margin-bottom: 15px; - } - &.margin-bottom-xs { - margin-bottom: 10px; - } - &.margin-bottom-0 { - margin-bottom: 0; + font-size: 18px; + font-weight: normal; + line-height: 1.2rem; + margin-bottom: 2rem; + + &.lg-card-title { + @media (max-width: 374px) { + font-size: 13px; } - .card-title-container & { - line-height: 1.2; - margin: 0; - @include media-breakpoint-down(sm) { - margin-bottom: 25px; - } + } + + &.margin-bottom-md { + margin-bottom: 25px; + } + + &.margin-bottom-sm { + margin-bottom: 15px; + } + + &.margin-bottom-xs { + margin-bottom: 10px; + } + + &.margin-bottom-0 { + margin-bottom: 0; + } + + .card-title-container & { + line-height: 1.2; + margin: 0; + + @include media-breakpoint-down(sm) { + margin-bottom: 25px; } + } } .card-subtitle { - color: #333; - font-size: 12px; - font-weight: normal; - line-height: 1.2; - margin: 0 0 30px; - &.margin-bottom-0 { - margin-bottom: 0; - } + color: #333; + font-size: 12px; + font-weight: normal; + line-height: 1.2; + margin: 0 0 30px; + + &.margin-bottom-0 { + margin-bottom: 0; + } } .card-title-container { - align-items: center; - display: flex; - justify-content: space-between; - padding: 25px $card-horizontal-padding; - @include media-breakpoint-down(sm) { - flex-direction: column; - } + align-items: center; + display: flex; + justify-content: space-between; + padding: 25px $card-horizontal-padding; + + @include media-breakpoint-down(sm) { + flex-direction: column; + } } .card-title-controls { - align-items: center; - display: flex; - justify-content: flex-end; - @include media-breakpoint-down(sm) { - flex-direction: column; + align-items: center; + display: flex; + justify-content: flex-end; + + @include media-breakpoint-down(sm) { + flex-direction: column; + } + + .card-title-control { + margin-right: 20px; + + &:last-child { + margin-right: 0; } - .card-title-control { - margin-right: 20px; - &:last-child { - margin-right: 0; - } - @include media-breakpoint-down(sm) { - margin-bottom: 20px; - margin-right: 0; - &:last-child { - margin-bottom: 0; - } - } + + @include media-breakpoint-down(sm) { + margin-bottom: 20px; + margin-right: 0; + + &:last-child { + margin-bottom: 0; + } } + } } .card-body { - padding: $card-horizontal-padding; + padding: $card-horizontal-padding; } .card-body-flex-column-space-between { - display: flex; - flex-direction: column; - justify-content: space-between; + display: flex; + flex-direction: column; + justify-content: space-between; } .card-server-response-body { - max-height: 400px; - overflow-y: auto; + max-height: 400px; + overflow-y: auto; } .card-chain-blocks { - height: auto; - [class*="col-"]:last-child { - .tile { - margin-bottom: 0; - } + min-height: 233px; + max-height: auto; + [class*="col-"]:last-child { + .tile { + margin-bottom: 0; } + } } .card-chain-transactions { - height: auto; - .tile { - margin-bottom: 0; - } + min-height: 664px; + max-height: auto; + + .tile { + margin-bottom: 0; + } } .card-tabs { - align-items: center; - border-top-left-radius: $card-default-border-radius; - border-top-right-radius: $card-default-border-radius; - border-bottom: 1px solid $base-border-color; - display: flex; - justify-content: flex-start; - overflow: hidden; - @include media-breakpoint-down(md) { - flex-direction: column; - } + align-items: center; + border-top-left-radius: $card-default-border-radius; + border-top-right-radius: $card-default-border-radius; + border-bottom: 1px solid $base-border-color; + display: flex; + justify-content: flex-start; + overflow: hidden; + + @include media-breakpoint-down(md) { + flex-direction: column; + } } .card-tab { - align-items: center; - background-color: $card-background-color; - color: #333; - cursor: pointer; - display: flex; - font-size: 14px; - font-weight: normal; - height: 70px; - padding: 0 25px; - text-align: center; - transition: $transition-cont; - &:hover { - background-color: rgba($card-tab-active, .15); - color: $card-tab-active; - text-decoration: none; + align-items: center; + background-color: $card-background-color; + color: #333; + cursor: pointer; + display: flex; + font-size: 14px; + font-weight: normal; + height: 70px; + padding: 0 25px; + text-align: center; + transition: $transition-cont; + + &:hover { + background-color: rgba($card-tab-active, .15); + color: $card-tab-active; + text-decoration: none; + } + + @include media-breakpoint-down(md) { + display: none; + width: 100%; + } + + .fa-check-circle { + color: $card-tab-icon-color; + margin-left: 6px; + } + + &.active { + background-color: $card-tab-active; + color: #fff; + cursor: default; + text-decoration: none; + + .fa-check-circle { + color: $card-tab-icon-color-active; } + @include media-breakpoint-down(md) { + cursor: pointer; + display: flex; + order: -1; + + &::after { + border-bottom: 0; + border-left: 0.3em solid transparent; + border-right: 0.3em solid transparent; + border-top: 0.3em solid; + content: ""; + display: inline-block; + height: 0; + margin-left: 10px; + width: 0; + } + + &.noCaret::after { display: none; - width: 100%; - } - .fa-check-circle { - color: $card-tab-icon-color; - margin-left: 6px; + } } - &.active { - background-color: $card-tab-active; - color: #fff; - cursor: default; - text-decoration: none; - .fa-check-circle { - color: $card-tab-icon-color-active; - } - @include media-breakpoint-down(md) { - cursor: pointer; - display: flex; - order: -1; - &::after { - border-bottom: 0; - border-left: 0.3em solid transparent; - border-right: 0.3em solid transparent; - border-top: 0.3em solid; - content: ""; - display: inline-block; - height: 0; - margin-left: 10px; - width: 0; - } - &.noCaret::after { - display: none; - } - } - } -} \ No newline at end of file + } +} diff --git a/apps/block_scout_web/assets/css/components/_custom_tooltips_block_details.scss b/apps/block_scout_web/assets/css/components/_custom_tooltips_block_details.scss index 883b699cab..91eb3ad01a 100644 --- a/apps/block_scout_web/assets/css/components/_custom_tooltips_block_details.scss +++ b/apps/block_scout_web/assets/css/components/_custom_tooltips_block_details.scss @@ -10,7 +10,7 @@ position: absolute; width: 50%; background-color: white; - color: #5c34a2; + color: black; text-align: center; border-radius: 6px; left: 25%; @@ -22,7 +22,7 @@ margin-bottom: 15px; opacity: 0; transition: opacity 0.5s; - @include media-breakpoint-down(sm) { + @include media-breakpoint-down(lg) { left: 60%; } } @@ -60,9 +60,9 @@ margin-bottom: 15px; opacity: 0; transition: opacity 0.5s; - @include media-breakpoint-down(sm) { - padding: 9px 10px; + @include media-breakpoint-down(lg) { bottom: 100%; + padding: 9px 10px; } } diff --git a/apps/block_scout_web/assets/css/components/_dashboard-banner.scss b/apps/block_scout_web/assets/css/components/_dashboard-banner.scss index 5a6dcc46bd..0cf8071caf 100644 --- a/apps/block_scout_web/assets/css/components/_dashboard-banner.scss +++ b/apps/block_scout_web/assets/css/components/_dashboard-banner.scss @@ -1,7 +1,10 @@ $dashboard-banner-gradient-start: $primary !default; -$dashboard-banner-gradient-end: lighten( $dashboard-banner-gradient-start, 5%) !default; -$dashboard-banner-network-plain-container-background-color: lighten( $dashboard-banner-gradient-end, 5%) !default; -$dashboard-line-color-price: lighten( $dashboard-banner-gradient-end, 5%) !default; +$dashboard-banner-gradient-end: lighten( + $dashboard-banner-gradient-start, + 5% +) !default; +$dashboard-banner-network-plain-container-background-color: lighten($dashboard-banner-gradient-end, 5%) !default; +$dashboard-line-color-price: lighten($dashboard-banner-gradient-end, 5%) !default; $dashboard-line-color-market: $secondary !default; $dashboard-stats-item-label-color: #fff !default; $dashboard-stats-item-value-color: rgba(#fff, 0.8) !default; @@ -10,192 +13,218 @@ $dashboard-banner-chart-legend-value-color: $dashboard-stats-item-value-color !d $dashboard-stats-item-border-color: $primary !default; $dashboard-banner-network-plain-container-height: 205px; $dashboard-banner-chart-axis-font-color: $dashboard-stats-item-value-color !default; + .dashboard-banner-container { - @include gradient-container(); - margin-bottom: 3rem; - overflow: hidden; - padding: 0; - position: relative; - height: 249px; - @include media-breakpoint-down(sm) { - height: auto; - } - @include media-breakpoint-down(md) { - height: auto; - } + @include gradient-container(); + margin-bottom: 3rem; + overflow: hidden; + padding: 0; + position: relative; + height: 249px; + @include media-breakpoint-down(sm) { + height: auto; + } + @include media-breakpoint-down(md) { + height: auto; + } } .dashboard-banner { - display: flex; - justify-content: space-between; - position: relative; - z-index: 9; - @include media-breakpoint-down(sm) { - flex-direction: column; - } + display: flex; + justify-content: space-between; + position: relative; + z-index: 9; + + @include media-breakpoint-down(sm) { + flex-direction: column; + } } .dashboard-banner-network-graph { - flex-grow: 1; - padding: 15px 0 0 0; - @include media-breakpoint-down(md) { - display: flex; - flex-direction: column; - padding-top: 20px; - } + flex-grow: 1; + padding: 15px 0 0 0; + + @include media-breakpoint-down(md) { + display: flex; + flex-direction: column; + padding-top: 20px; + } } .dashboard-banner-chart { - flex-grow: 1; - margin: 0 0 35px 0; - max-width: 350px; + flex-grow: 1; + margin: 0 0 35px 0; + max-width: 350px; + position: relative; + + @include media-breakpoint-down(md) { + flex-grow: 0; + margin-bottom: 20px; + margin-top: auto; + max-width: 100%; + } + + > canvas { + max-height: 100%; + max-width: 100%; + width: 100%; + } +} + +.dashboard-banner-chart-legend { + display: flex; + grid-template-columns: 1fr 1fr; + padding-bottom: 12px; + + .dashboard-banner-chart-legend-item { + padding-bottom: 3px; + padding-left: 12px; + padding-top: 3px; position: relative; + padding-right: 60px; + @include media-breakpoint-down(md) { - flex-grow: 0; - margin-bottom: 20px; - margin-top: auto; - max-width: 100%; + display: flex; + flex-direction: row; } - >canvas { - max-height: 100%; - max-width: 100%; - width: 100%; + + @media (max-width: 599px) { + padding-top: 0; + padding-bottom: 0; + flex-direction: column; } -} -.dashboard-banner-chart-legend { - display: flex; - /* grid-template-columns: 1fr 1fr; */ - padding-bottom: 12px; - .dashboard-banner-chart-legend-item { - padding-bottom: 3px; - padding-left: 12px; - padding-top: 3px; - position: relative; - padding-right: 60px; - @include media-breakpoint-down(md) { - display: flex; - flex-direction: row; - } - @media (max-width: 599px) { - padding-top: 0; - padding-bottom: 0; - flex-direction: column; - } - &::before { - border-radius: 2px; - content: ""; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 4px; - } - &:nth-child(1)::before { - background-color: $dashboard-line-color-price; - } - &:nth-child(2)::before { - background-color: $dashboard-line-color-market; - } + &::before { + border-radius: 2px; + content: ""; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 4px; } - .dashboard-banner-chart-legend-label { - color: $dashboard-banner-chart-legend-label-color; - display: block; - font-size: 12px; - font-weight: 600; - line-height: 1.2; - margin: 0 0 5px; - @media (max-width: 374px) { - position: relative; - top: -2px; - } - @include media-breakpoint-down(md) { - margin: 0 5px 0 0; - } + + &:nth-child(1)::before { + background-color: $dashboard-line-color-price; } - .dashboard-banner-chart-legend-value { - color: $dashboard-banner-chart-legend-value-color; - display: block; - font-size: 12px; - font-weight: normal; - line-height: 1.2; + + &:nth-child(2)::before { + background-color: $dashboard-line-color-market; } + } + + .dashboard-banner-chart-legend-label { + color: $dashboard-banner-chart-legend-label-color; + display: block; + font-size: 12px; + font-weight: 600; + line-height: 1.2; + margin: 0 0 5px; + + @media (max-width: 374px) { + position: relative; + top: -2px; + } + + @include media-breakpoint-down(md) { + margin: 0 5px 0 0; + } + } + + .dashboard-banner-chart-legend-value { + color: $dashboard-banner-chart-legend-value-color; + display: block; + font-size: 12px; + font-weight: normal; + line-height: 1.2; + } } .dashboard-banner-network-plain-container { - align-items: center; - align-self: flex-end; + align-items: center; + align-self: flex-end; + background-color: $dashboard-banner-network-plain-container-background-color; + border-top-left-radius: 10px; + display: flex; + height: $dashboard-banner-network-plain-container-height; + justify-content: center; + margin: 45px 0 0 30px; + max-width: 100%; + padding: 30px 0 30px 60px; + width: 750px; + position: relative; + + @include media-breakpoint-down(lg) { + margin-top: 15px; + width: 550px; + } + + @include media-breakpoint-down(md) { + border-top-right-radius: 10px; + height: auto; + justify-content: flex-start; + margin-left: 0; + max-width: 100%; + padding: 20px 0 20px 20px; + width: 250px; + box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.2); + } + + @include media-breakpoint-down(sm) { + width: 100%; + } + + &::after { background-color: $dashboard-banner-network-plain-container-background-color; - border-top-left-radius: 10px; - display: flex; + bottom: 0; + content: ""; + display: block; height: $dashboard-banner-network-plain-container-height; - justify-content: center; - margin: 45px 0 0 30px; - max-width: 100%; - padding: 30px 0 30px 60px; - width: 750px; - position: relative; - @include media-breakpoint-down(lg) { - margin-top: 50px; - width: 550px; - } + left: 0; + position: absolute; + width: 9999px; + z-index: -1; + box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.2); + border-top-left-radius: 10px; + @include media-breakpoint-down(md) { - border-top-right-radius: 10px; - height: auto; - justify-content: flex-start; - margin-left: 0; - max-width: 100%; - padding: 20px 0 20px 20px; - width: 250px; - box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.2); - } - @include media-breakpoint-down(sm) { - width: 100%; - } - &::after { - background-color: $dashboard-banner-network-plain-container-background-color; - bottom: 0; - content: ""; - display: block; - height: $dashboard-banner-network-plain-container-height; - left: 0; - position: absolute; - width: 9999px; - z-index: -1; - box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.2); - border-top-left-radius: 10px; - @include media-breakpoint-down(md) { - display: none; - } + display: none; } + } } .dashboard-banner-network-stats { - column-gap: 25px; - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - @include media-breakpoint-down(lg) { - grid-template-columns: 1fr 1fr; - row-gap: 20px; - } - @include media-breakpoint-down(md) { - grid-template-columns: 1fr; - row-gap: 20px; - } - @include media-breakpoint-down(sm) { - column-gap: 10px; - grid-template-columns: 1fr 1fr; - } - @include stats-item( $dashboard-stats-item-border-color, $dashboard-stats-item-label-color, $dashboard-stats-item-value-color); - .dashboard-banner-network-stats-item { - @media (max-width: 374px) { - padding-left: calc(0.6rem + 4px); - padding-right: 0.5rem; - } + column-gap: 25px; + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + + @include media-breakpoint-down(lg) { + grid-template-columns: 1fr 1fr; + row-gap: 20px; + } + + @include media-breakpoint-down(md) { + grid-template-columns: 1fr; + row-gap: 20px; + } + + @include media-breakpoint-down(sm) { + column-gap: 10px; + grid-template-columns: 1fr 1fr; + } + + @include stats-item($dashboard-stats-item-border-color, $dashboard-stats-item-label-color, $dashboard-stats-item-value-color); + + .dashboard-banner-network-stats-item { + @media (max-width: 374px) { + padding-left: calc(0.6rem + 4px); + padding-right: 0.5rem; } - .dashboard-banner-network-stats-value { - @media (max-width: 374px) { - font-size: 0.9rem; - } + } + + .dashboard-banner-network-stats-value { + @media (max-width: 374px) { + font-size: 0.9rem; } + } } \ No newline at end of file diff --git a/apps/block_scout_web/assets/css/components/_erc721_token_image_container.scss b/apps/block_scout_web/assets/css/components/_erc721_token_image_container.scss deleted file mode 100644 index b5f9cb6a92..0000000000 --- a/apps/block_scout_web/assets/css/components/_erc721_token_image_container.scss +++ /dev/null @@ -1,10 +0,0 @@ -/* ERC721 image block */ -.erc721-image { - display: flex; - justify-content: center; -} - -.erc721-image img { - height: 80px; -} -/* ERC721 image block end */ diff --git a/apps/block_scout_web/assets/css/components/_network-selector.scss b/apps/block_scout_web/assets/css/components/_network-selector.scss index 9df2d22164..e3ffea33de 100644 --- a/apps/block_scout_web/assets/css/components/_network-selector.scss +++ b/apps/block_scout_web/assets/css/components/_network-selector.scss @@ -280,6 +280,9 @@ $network-selector-item-icon-dimensions: 30px !default; &-lukso-l14-testnet { background-image: url(/images/network-selector-icons/lukso-l14-testnet.svg) } + &-xusdt-chain { + background-image: url(/images/network-selector-icons/circle-xusdt.svg) + } } .network-selector-item-title { diff --git a/apps/block_scout_web/assets/css/components/_tile.scss b/apps/block_scout_web/assets/css/components/_tile.scss index e621e4fd6d..79441d0722 100644 --- a/apps/block_scout_web/assets/css/components/_tile.scss +++ b/apps/block_scout_web/assets/css/components/_tile.scss @@ -562,3 +562,15 @@ $cube-quantity: 5; transform: scale(0); } } + +.dark-block-loader { + width: auto; + height: 15px; + background-color: #e2e5ec; + margin-bottom: 5px; + border-radius: 4px; +} + +.dark-theme-applied .dark-block-loader { + background-color: #313355; +} diff --git a/apps/block_scout_web/assets/css/components/_transaction.scss b/apps/block_scout_web/assets/css/components/_transaction.scss index b8d7b82e39..35cb0d59c0 100644 --- a/apps/block_scout_web/assets/css/components/_transaction.scss +++ b/apps/block_scout_web/assets/css/components/_transaction.scss @@ -43,4 +43,11 @@ text-decoration: underline; } } +} + +.block-detail-number { + width: 25%; + @include media-breakpoint-down(sm) { + width: 60%; + } } \ No newline at end of file diff --git a/apps/block_scout_web/assets/css/theme/_dai_variables.scss b/apps/block_scout_web/assets/css/theme/_dai_variables.scss index 6722369c7f..edfc1a26fd 100644 --- a/apps/block_scout_web/assets/css/theme/_dai_variables.scss +++ b/apps/block_scout_web/assets/css/theme/_dai_variables.scss @@ -1,23 +1,23 @@ // general -$primary: #17314f; -$secondary: #15bba6; -$tertiary: #93d7ff; +$primary: #233174; +$secondary: #15f9bb; +$tertiary: #5a77ff; $additional-font: #fff; // footer -$footer-background-color: $primary; +$footer-background-color:#202d6a; $footer-title-color: #fff; -$footer-text-color: #96bde8; +$footer-text-color: #b5c2ff; $footer-item-disc-color: $secondary; .footer-logo { filter: brightness(0) invert(1); } - +.footer-social-icon { color: $secondary!important; } // dashboard $dashboard-line-color-price: $tertiary; // price left border $dashboard-line-color-market: $secondary; $dashboard-banner-chart-legend-label-color: $footer-text-color; -$dashboard-stats-item-label-color: $footer-text-color; +$dashboard-stats-item-label-color: #b4c1ff; $dashboard-banner-chart-legend-value-color: #fff; // chart labels $dashboard-stats-item-value-color: #fff; // stat values @@ -25,9 +25,11 @@ $dashboard-stats-item-border-color: $secondary; // stat border $dashboard-banner-gradient-start: $primary; // gradient begin -$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end +$dashboard-banner-gradient-end: #1e2a63; +// gradient end -$dashboard-banner-network-plain-container-background-color: #20446e; // stats bg +$dashboard-banner-network-plain-container-background-color: #273781 +; // stats bg // navigation @@ -35,20 +37,20 @@ $dashboard-banner-network-plain-container-background-color: #20446e; // stats bg // buttons $btn-line-bg: #fff; // button bg -$btn-line-color: $secondary; // button border and font color && hover bg color -$btn-copy-color: $secondary; // btn copy -$btn-qr-color: $secondary; // btn qr-code +$btn-line-color: $primary; // button border and font color && hover bg color +$btn-copy-color: $primary; // btn copy +$btn-qr-color: $primary; // btn qr-code $btn-address-card-icon-color: $secondary; // btn address color //links & tile -$tile-body-a-color: $secondary; -$tile-type-block-color: $secondary; -$tile-type-progress-bar-color: $secondary; -a.tile-title { color: $secondary !important; } +$tile-body-a-color: $tertiary; +$tile-type-block-color: $primary; +$tile-type-progress-bar-color: $primary; +a.tile-title { color: $primary !important; } // card -$card-background-1: $secondary; -$card-tab-active: $secondary; +$card-background-1: $primary; +$card-tab-active: $primary; .layout-container { .dashboard-banner-container { @@ -66,6 +68,20 @@ $badge-neutral-background-color: rgba(#20446e, .1); $api-text-monospace-color: #20446e; // Dark theme -$dark-primary: #15bba6; -$dark-secondary: #93d7ff; -$dark-primary-alternate: #15bba6; \ No newline at end of file +$dark-primary: #233174; +$dark-secondary:#15f9bb; +$dark-tertiary: #5a77ff; + +.dark-theme-applied .tile .tile-body a, .dark-theme-applied .tile span[data-address-hash] { + color: $dark-tertiary!important; +} + +.dark-theme-applied .btn-line { + background-color: transparent!important; + border-color: $dark-tertiary!important; + color: $dark-tertiary!important; +} + +.dark-theme-applied .btn-line:hover { + color: $additional-font!important; +} \ No newline at end of file diff --git a/apps/block_scout_web/assets/css/theme/_variables-non-critical.scss b/apps/block_scout_web/assets/css/theme/_variables-non-critical.scss index 232b9cc647..39762ec68a 100644 --- a/apps/block_scout_web/assets/css/theme/_variables-non-critical.scss +++ b/apps/block_scout_web/assets/css/theme/_variables-non-critical.scss @@ -1,5 +1,6 @@ @import "theme/base_variables"; @import "neutral_variables-non-critical"; +// @import "xusdt_variables-non-critical"; // @import "dai_variables-non-critical"; // @import "ethereum_classic_variables-non-critical"; // @import "ethereum_variables-non-critical"; diff --git a/apps/block_scout_web/assets/css/theme/_variables.scss b/apps/block_scout_web/assets/css/theme/_variables.scss index bff54cc6bf..15571b454b 100644 --- a/apps/block_scout_web/assets/css/theme/_variables.scss +++ b/apps/block_scout_web/assets/css/theme/_variables.scss @@ -1,5 +1,6 @@ @import "theme/base_variables"; @import "neutral_variables"; +// @import "xusdt_variables"; // @import "dai_variables"; // @import "ethereum_classic_variables"; // @import "ethereum_variables"; diff --git a/apps/block_scout_web/assets/css/theme/_xusdt_variables-non-critical.scss b/apps/block_scout_web/assets/css/theme/_xusdt_variables-non-critical.scss new file mode 100644 index 0000000000..7f337f9bf5 --- /dev/null +++ b/apps/block_scout_web/assets/css/theme/_xusdt_variables-non-critical.scss @@ -0,0 +1,7 @@ +// general +$primary: #2b9f7a; +$secondary: #20745a; +$tertiary: #fff; +$additional-font: #fff; + +$btn-line-color: $secondary; // button border and font color && hover bg color \ No newline at end of file diff --git a/apps/block_scout_web/assets/css/theme/_xusdt_variables.scss b/apps/block_scout_web/assets/css/theme/_xusdt_variables.scss new file mode 100644 index 0000000000..ac3b2fa4e0 --- /dev/null +++ b/apps/block_scout_web/assets/css/theme/_xusdt_variables.scss @@ -0,0 +1,97 @@ +// general +$primary: #2b9f7a; +$secondary: #20745a; +$tertiary: #fff; +$additional-font: #fff; + +$tile-body-a-color: $primary; +$tile-type-block-color: $primary; +$tile-type-progress-bar-color: $primary; +a.tile-title { color: $primary !important; } + +// footer +$footer-background-color: #282d31; +$footer-title-color: #fff; +$footer-text-color: $additional-font; +$footer-item-disc-color: $secondary; +$footer-social-icon-color: $secondary; + +// dashboard +$dashboard-line-color-price: #fff; // price left border + +$dashboard-banner-chart-legend-label-color: #fff; +$dashboard-stats-item-label-color: $dashboard-banner-chart-legend-label-color; +$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-gradient-start: $primary; // gradient begin + +$dashboard-banner-gradient-end: #289371; // gradient end + +$dashboard-banner-network-plain-container-background-color: #2ea780; // stats bg + + +// navigation +.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow +$dropdown-menu-item-hover-color: $primary !default; +$dropdown-menu-item-hover-background: rgba($primary, .1) !default; +$header-icon-color-hover: $primary; +$header-icon-border-color-hover: $primary; + +// buttons +$btn-line-bg: #fff; // button bg +$btn-line-color: $primary; // button border and font color && hover bg color +$btn-copy-color: $primary; // btn copy +$btn-qr-color: $primary; // btn qr-code +$btn-address-card-icon-color: $primary; // btn address color + +//links & tile +$tile-body-a-color: $primary; +$tile-type-block-color: $primary; +$tile-type-progress-bar-color: $primary; +a.tile-title { color: $primary !important; } + +// card +$card-background-1: $primary; +$card-tab-active: $primary; + +.layout-container { + .dashboard-banner-container { + background-image: linear-gradient( + to bottom, + $dashboard-banner-gradient-start, + $dashboard-banner-gradient-end + ); + } +} + +// Badges +$badge-neutral-color: $primary; +$badge-neutral-background-color: rgba($primary, .1); +$api-text-monospace-color: $primary; + +// Tokens dropdown +.token-balance-dropdown[aria-labelledby="dropdown-tokens"] { + .dropdown-items .dropdown-item:hover { + color: $primary !important; + } +} + +// Dark theme +$dark-primary: #2b9f7a; +$dark-secondary: #20745a; +$dark-primary-alternate: #2b9f7a; + +.dark-theme-applied .dashboard-banner-chart-legend .dashboard-banner-chart-legend-item:nth-child(1)::before { + background-color: white!important; +} + +.dark-theme-applied .dashboard-banner-chart-legend .dashboard-banner-chart-legend-item:nth-child(2)::before { + background-color: $primary!important; +} + +.dark-theme-applied .tile .tile-body a, .dark-theme-applied .tile span[data-address-hash] { + color: #2b9f7a; +} \ No newline at end of file diff --git a/apps/block_scout_web/assets/js/lib/try_api.js b/apps/block_scout_web/assets/js/lib/try_api.js index c0eb8cd5e3..6c33779f30 100644 --- a/apps/block_scout_web/assets/js/lib/try_api.js +++ b/apps/block_scout_web/assets/js/lib/try_api.js @@ -55,6 +55,10 @@ function handleSuccess (query, xhr, clickedButton) { clickedButton.prop('disabled', false) } +function dropDomain (url) { + return new URL(url).pathname +} + // Show 'Try it out' UI for a module/action. $('button[data-selector*="btn-try-api"]').click(event => { const clickedButton = $(event.target) @@ -124,7 +128,7 @@ $('button[data-try-api-ui-button-type="execute"]').click(event => { } $.ajax({ - url: `/api${query}`, + url: dropDomain(composeRequestUrl(query)), success: (_data, _status, xhr) => { handleSuccess(query, xhr, clickedButton) }, diff --git a/apps/block_scout_web/assets/js/lib/try_eth_api.js b/apps/block_scout_web/assets/js/lib/try_eth_api.js index a3dd7b6f4e..30299431be 100644 --- a/apps/block_scout_web/assets/js/lib/try_eth_api.js +++ b/apps/block_scout_web/assets/js/lib/try_eth_api.js @@ -1,7 +1,8 @@ import $ from 'jquery' function composeCurlCommand (data) { - return `curl -H "content-type: application/json" -X POST --data '${JSON.stringify(data)}'` + const url = $('[data-endpoint-url]').attr('data-endpoint-url') + return `curl -H "content-type: application/json" -X POST --data '${JSON.stringify(data)}' ${url}` } function handleResponse (data, xhr, clickedButton) { @@ -43,6 +44,10 @@ function parseInput (input) { } } +function dropDomain (url) { + return new URL(url).pathname +} + $('button[data-try-eth-api-ui-button-type="execute"]').click(event => { const clickedButton = $(event.target) const module = clickedButton.attr('data-module') @@ -50,7 +55,6 @@ $('button[data-try-eth-api-ui-button-type="execute"]').click(event => { const inputs = $(`input[data-selector="${module}-${action}-try-api-ui"]`) const params = $.map(inputs, parseInput) const formData = wrapJsonRpc(action, params) - console.log(formData) const loadingText = ' Loading...' clickedButton.prop('disabled', true) @@ -60,8 +64,10 @@ $('button[data-try-eth-api-ui-button-type="execute"]').click(event => { clickedButton.html(loadingText) } + const url = $('[data-endpoint-url]').attr('data-endpoint-url') + $.ajax({ - url: '/api/eth_rpc', + url: dropDomain(url), type: 'POST', data: JSON.stringify(formData), dataType: 'json', diff --git a/apps/block_scout_web/assets/package-lock.json b/apps/block_scout_web/assets/package-lock.json index d00f148391..6aff90670b 100644 --- a/apps/block_scout_web/assets/package-lock.json +++ b/apps/block_scout_web/assets/package-lock.json @@ -6958,9 +6958,9 @@ } }, "lodash": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.assign": { "version": "4.2.0", diff --git a/apps/block_scout_web/assets/package.json b/apps/block_scout_web/assets/package.json index 1169e22859..a081a7e46b 100644 --- a/apps/block_scout_web/assets/package.json +++ b/apps/block_scout_web/assets/package.json @@ -30,7 +30,7 @@ "highlightjs-solidity": "^1.0.6", "humps": "^2.0.1", "jquery": "^3.4.0", - "lodash": "^4.17.13", + "lodash": "^4.17.15", "moment": "^2.22.1", "nanomorph": "^5.1.3", "numeral": "^2.0.6", diff --git a/apps/block_scout_web/assets/static/images/dai_logo.svg b/apps/block_scout_web/assets/static/images/dai_logo.svg index 3ce9609c84..538f3bc4c3 100644 --- a/apps/block_scout_web/assets/static/images/dai_logo.svg +++ b/apps/block_scout_web/assets/static/images/dai_logo.svg @@ -1,11 +1,5 @@ - - - - - - - - - - + + + + diff --git a/apps/block_scout_web/assets/static/images/network-selector-icons/circle-xusdt.svg b/apps/block_scout_web/assets/static/images/network-selector-icons/circle-xusdt.svg new file mode 100644 index 0000000000..de660df5d8 --- /dev/null +++ b/apps/block_scout_web/assets/static/images/network-selector-icons/circle-xusdt.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/block_scout_web/assets/static/images/network-selector-icons/xdai-chain.svg b/apps/block_scout_web/assets/static/images/network-selector-icons/xdai-chain.svg index e6f660410a..ac045d3112 100644 --- a/apps/block_scout_web/assets/static/images/network-selector-icons/xdai-chain.svg +++ b/apps/block_scout_web/assets/static/images/network-selector-icons/xdai-chain.svg @@ -1,4 +1,4 @@ - - + + diff --git a/apps/block_scout_web/assets/static/images/xusdt-logo-footer.svg b/apps/block_scout_web/assets/static/images/xusdt-logo-footer.svg new file mode 100644 index 0000000000..53763fdec4 --- /dev/null +++ b/apps/block_scout_web/assets/static/images/xusdt-logo-footer.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/block_scout_web/assets/static/images/xusdt-logo-top.svg b/apps/block_scout_web/assets/static/images/xusdt-logo-top.svg new file mode 100644 index 0000000000..1e0ac1b3c8 --- /dev/null +++ b/apps/block_scout_web/assets/static/images/xusdt-logo-top.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex index 8b39de91a7..97ab7c8490 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex @@ -5,7 +5,7 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do use BlockScoutWeb, :controller - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + 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,12 +60,14 @@ 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(address_hash), - validation_count: validation_count(address_hash), + transaction_count: transaction_count, + validation_count: validation_count, current_path: current_path(conn) ) else diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex index 5db900b12b..4ff45fe101 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.AddressContractController do use BlockScoutWeb, :controller - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1] alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token @@ -20,14 +20,16 @@ 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(address_hash), - validation_count: validation_count(address_hash) + transaction_count: transaction_count, + validation_count: validation_count ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex index 9f955fa672..5916359281 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex @@ -69,6 +69,34 @@ 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 + transaction_count_task = + Task.async(fn -> + transaction_count(address_hash) + end) + + validation_count_task = + Task.async(fn -> + validation_count(address_hash) + end) + + [transaction_count_task, validation_count_task] + |> Task.yield_many(:timer.seconds(30)) + |> Enum.map(fn {_task, res} -> + case res do + {:ok, result} -> + result + + {:exit, reason} -> + raise "Query fetching address counters terminated: #{inspect(reason)}" + + nil -> + raise "Query fetching address counters timed out." + end + end) + |> 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) end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex index be591ce384..e9f5cbe62e 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.AddressDecompiledContractController do use BlockScoutWeb, :controller - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1] alias Explorer.{Chain, Market} alias Explorer.ExchangeRates.Token @@ -10,14 +10,16 @@ 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(address_hash), - validation_count: validation_count(address_hash) + transaction_count: transaction_count, + validation_count: validation_count ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex index 15aa87e69a..ee3a66aab2 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex @@ -5,7 +5,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do use BlockScoutWeb, :controller - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + 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,6 +63,8 @@ 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", @@ -71,8 +73,8 @@ 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(address_hash), - validation_count: validation_count(address_hash) + transaction_count: transaction_count, + validation_count: validation_count ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex index d3ea4e5303..f08378e980 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex @@ -3,7 +3,7 @@ defmodule BlockScoutWeb.AddressLogsController do Manages events logs tab. """ - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + 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,6 +56,8 @@ 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", @@ -63,8 +65,8 @@ 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(address_hash), - validation_count: validation_count(address_hash) + transaction_count: transaction_count, + validation_count: validation_count ) else _ -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex index 0849689dce..2625dbd47f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex @@ -12,7 +12,7 @@ defmodule BlockScoutWeb.AddressReadContractController do alias Explorer.ExchangeRates.Token alias Indexer.Fetcher.CoinBalanceOnDemand - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1] def index(conn, %{"address_id" => address_hash_string}) do address_options = [ @@ -27,14 +27,16 @@ 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) 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(address_hash), - validation_count: validation_count(address_hash) + transaction_count: transaction_count, + validation_count: validation_count ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex index d77baa605a..f8a3a9f750 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.AddressTokenController do use BlockScoutWeb, :controller - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + 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,6 +57,8 @@ 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", @@ -64,8 +66,8 @@ 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(address_hash), - validation_count: validation_count(address_hash) + transaction_count: transaction_count, + validation_count: validation_count ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex index 4e0023b067..7d0c8c1284 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex @@ -7,7 +7,7 @@ defmodule BlockScoutWeb.AddressTokenTransferController do alias Indexer.Fetcher.CoinBalanceOnDemand alias Phoenix.View - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + 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,6 +77,8 @@ 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", @@ -85,8 +87,8 @@ 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(address_hash), - validation_count: validation_count(address_hash) + transaction_count: transaction_count, + validation_count: validation_count ) else :error -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex index f30c3cb0cd..9236c433a7 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex @@ -5,7 +5,7 @@ defmodule BlockScoutWeb.AddressTransactionController do use BlockScoutWeb, :controller - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + 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 @@ -96,6 +96,8 @@ 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", @@ -103,8 +105,8 @@ 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(address_hash), - validation_count: validation_count(address_hash), + transaction_count: transaction_count, + validation_count: validation_count, current_path: current_path(conn) ) else diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex index 7226dffcf8..d8d558d5fb 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex @@ -4,7 +4,7 @@ defmodule BlockScoutWeb.AddressValidationController do """ use BlockScoutWeb, :controller - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + 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,14 +69,16 @@ 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(address.hash), - validation_count: validation_count(address.hash), + transaction_count: transaction_count, + validation_count: validation_count, exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null() ) else diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex index 835e19bf3e..2b9bdc0dd6 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/block_controller.ex @@ -26,7 +26,7 @@ defmodule BlockScoutWeb.API.RPC.BlockController do def eth_block_number(conn, params) do id = Map.get(params, "id", 1) - max_block_number = BlockNumber.max_number() + max_block_number = BlockNumber.get_max() render(conn, :eth_block_number, number: max_block_number, id: id) end diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index 73f1bbe591..f246349de6 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -66,7 +66,7 @@
-
<%= for {line, number} <- contract_lines_with_index(@address.smart_contract.contract_source_code) do %>
<%= line %>
<% end %>
+
<%= for {line, number} <- contract_lines_with_index(@address.smart_contract.contract_source_code, @address.smart_contract.inserted_at) do %>
<%= line %>
<% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex index 7f342b4a16..f464533c7e 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex @@ -4,9 +4,9 @@

<%= @action %>

<%= raw @info.notes %>

- curl -X POST --data '{"id":0,"jsonrpc":"2.0","method": "<%= @action %>", params: []}' + curl -X POST --data '{"id":0,"jsonrpc":"2.0","method": "<%= @action %>", "params": []}'

diff --git a/apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex index 26fa5ba725..752fd314e3 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex @@ -4,24 +4,18 @@
-

+

<%= gettext("%{block_type} Details", block_type: block_type(@block)) %>

- - -

- +

<%= if block_type(@block) == "Block" do %> - <%= gettext("Block Height: %{height}", height: @block.number) %> <%= if @block.number == 0, do: "- " <> gettext("Genesis Block")%> <% else %> <%= gettext("%{block_type} Height:", block_type: block_type(@block)) %> <%= link(@block, to: block_path(BlockScoutWeb.Endpoint, :show, @block.number)) %> <% end %> -

-
<%= gettext "%{count} Transactions", count: @block_transaction_count %> @@ -36,18 +30,13 @@

-
-
<%= gettext "Hash" %>
-
<%= to_string(@block.hash) %>
-
- <%= unless @block.number == 0 do %> @@ -68,7 +57,7 @@
<%= gettext "Difficulty" %>
-
+
<%= @block.difficulty |> BlockScoutWeb.Cldr.Number.to_string! %>
@@ -95,6 +84,9 @@ <%= link( gettext("Position %{index}", index: index), class: "transaction__link", + "data-toggle": "tooltip", + "data-placement": "top" , + "data-original-title": "Index position(s) of referenced stale blocks." , "data-test": "uncle_link", "data-uncle-hash": to_string(relation.uncle_hash), to: block_path(@conn, :show, relation.uncle_hash) @@ -106,11 +98,11 @@ <%= if show_reward?(@block.rewards) do %> -
+
<%= gettext "Gas Used" %>
- <%= @block.gas_used |> BlockScoutWeb.Cldr.Number.to_string! %> - (<%= (Decimal.to_integer(@block.gas_used) / Decimal.to_integer(@block.gas_limit)) |> BlockScoutWeb.Cldr.Number.to_string!(format: "#.#%") %>) + <%= @block.gas_used |> BlockScoutWeb.Cldr.Number.to_string! %> + (<%= (Decimal.to_integer(@block.gas_used) / Decimal.to_integer(@block.gas_limit)) |> BlockScoutWeb.Cldr.Number.to_string!(format: "#.#%") %>)
@@ -148,17 +140,13 @@
-
+
- <%= if show_reward?(@block.rewards) do %>

<%= gettext "Block Rewards" %>

-
- Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees. +
<%= for block_reward <- @block.rewards do %> - -

<%= block_reward_text(block_reward) %> <%= format_wei_value(block_reward.reward, :ether) %>

- +

<%= block_reward_text(block_reward) %> <%= format_wei_value(block_reward.reward, :ether) %>

<% end %>
<% else %> @@ -169,7 +157,6 @@ (<%= (Decimal.to_integer(@block.gas_used) / Decimal.to_integer(@block.gas_limit)) |> BlockScoutWeb.Cldr.Number.to_string!(format: "#.#%") %>)

<%= @block.gas_limit |> BlockScoutWeb.Cldr.Number.to_string! %><%= gettext "Gas Limit" %>

-
<% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex index 8285d429e0..cb42c2c338 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex @@ -91,13 +91,50 @@ <%= gettext "Something went wrong, click to reload." %> -
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/common_components/_tile-loader.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/common_components/_tile-loader.html.eex index 6607baaeae..91195d51db 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/common_components/_tile-loader.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/common_components/_tile-loader.html.eex @@ -46,6 +46,54 @@
+
+
+
+ + + + + + +
+
+ + +
+
+ + + + + + +
+
+
+
+
+
+ + + + + + +
+
+ + +
+
+ + + + + + +
+
+
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_details.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_details.html.eex index c362d18d43..c4fbdc2af2 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_details.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_details.html.eex @@ -71,7 +71,7 @@ <%= if total_supply?(@token) do %>
-
+

<%= gettext "Total Supply" %>

diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex index 7b112377f3..70162a3be8 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex @@ -23,10 +23,4 @@ <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>

- - - - - - \ No newline at end of file diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex index 57c6e11da7..f9128dfb11 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex @@ -2,7 +2,7 @@ defmodule BlockScoutWeb.AddressContractView do use BlockScoutWeb, :view alias ABI.{FunctionSelector, TypeDecoder} - alias Explorer.Chain.{Address, Data, InternalTransaction} + alias Explorer.Chain.{Address, Data, InternalTransaction, SmartContract} def render("scripts.html", %{conn: conn}) do render_scripts(conn, "address_contract/code_highlighting.js") @@ -63,8 +63,11 @@ defmodule BlockScoutWeb.AddressContractView do end) end - def contract_lines_with_index(contract_source_code) do - contract_lines = String.split(contract_source_code, "\n") + def contract_lines_with_index(source_code, inserted_at \\ nil) do + contract_lines = + source_code + |> String.split("\n") + |> SmartContract.add_submitted_comment(inserted_at) max_digits = contract_lines diff --git a/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex b/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex index ac7d4d55ee..363a4a0179 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.APIDocsView do use BlockScoutWeb, :view - alias BlockScoutWeb.{Endpoint, LayoutView} + alias BlockScoutWeb.LayoutView def action_tile_id(module, action) do "#{module}-#{action}" @@ -34,30 +34,27 @@ defmodule BlockScoutWeb.APIDocsView do end) end - def blockscout_url do + defp blockscout_url do url_params = Application.get_env(:block_scout_web, BlockScoutWeb.Endpoint)[:url] host = url_params[:host] path = url_params[:path] - scheme = url_params[:scheme] + scheme = Keyword.get(url_params, :scheme, "http") if host != "localhost" do - scheme <> "://" <> host <> path + "#{scheme}://#{host}#{path}" else - Endpoint.url() + port = Application.get_env(:block_scout_web, BlockScoutWeb.Endpoint)[:http][:port] + "#{scheme}://#{host}:#{to_string(port)}" end end def api_url do - handle_slash("api") + blockscout_url() + |> Path.join("api") end def eth_rpc_api_url do - handle_slash("api/eth_rpc") - end - - defp handle_slash(path) do - base_url = blockscout_url() - - Path.join(base_url, path) + blockscout_url() + |> Path.join("api/eth_rpc") end end diff --git a/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex b/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex index 506d6ff3c8..a5f0ebef50 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex @@ -3,6 +3,15 @@ defmodule BlockScoutWeb.ChainView do alias BlockScoutWeb.LayoutView + defp market_cap(:standard, %{available_supply: available_supply, usd_value: usd_value}) + when is_nil(available_supply) or is_nil(usd_value) do + Decimal.new(0) + end + + defp market_cap(:standard, %{available_supply: available_supply, usd_value: usd_value}) do + Decimal.mult(available_supply, usd_value) + end + defp market_cap(:standard, exchange_rate) do exchange_rate.market_cap_usd end diff --git a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex index 7ac564fae3..121bd6ad5e 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex @@ -135,12 +135,12 @@ defmodule BlockScoutWeb.TransactionView do def confirmations(%Transaction{block: block}, named_arguments) when is_list(named_arguments) do case block do - nil -> - 0 - %Block{consensus: true} -> {:ok, confirmations} = Chain.confirmations(block, named_arguments) BlockScoutWeb.Cldr.Number.to_string!(confirmations, format: "#,###") + + _ -> + 0 end end diff --git a/apps/block_scout_web/lib/block_scout_web/views/wei_helpers.ex b/apps/block_scout_web/lib/block_scout_web/views/wei_helpers.ex index c9dfefa7b7..992909524a 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/wei_helpers.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/wei_helpers.ex @@ -35,7 +35,7 @@ defmodule BlockScoutWeb.WeiHelpers do "10,000 Gwei" iex> format_wei_value(%Wei{value: Decimal.new(1, 10, 21)}, :ether) - "10,000 POA" + "10,000 Ether" # With formatting options @@ -43,7 +43,7 @@ defmodule BlockScoutWeb.WeiHelpers do ...> %Wei{value: Decimal.new(1000500000000000000)}, ...> :ether ...> ) - "1.0005 POA" + "1.0005 Ether" iex> format_wei_value( ...> %Wei{value: Decimal.new(10)}, diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index c2c324f51e..9aec6fbce9 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -12,6 +12,16 @@ msgid_plural "%{count} transactions" msgstr[0] "" msgstr[1] "" +#, elixir-format +#: lib/block_scout_web/templates/transaction/overview.html.eex:192 +msgid " Token Transfer" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:14 +msgid " is recommended." +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address/_metatags.html.eex:3 msgid "%{address} - %{subnetwork} Explorer" @@ -23,7 +33,7 @@ msgid "%{block_type} Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:19 +#: lib/block_scout_web/templates/block/overview.html.eex:15 msgid "%{block_type} Height:" msgstr "" @@ -33,7 +43,7 @@ msgid "%{block_type}s" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:27 +#: lib/block_scout_web/templates/block/overview.html.eex:21 #: lib/block_scout_web/templates/chain/_block.html.eex:11 msgid "%{count} Transactions" msgstr "" @@ -66,6 +76,11 @@ 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." @@ -76,6 +91,16 @@ msgstr "" msgid "A string with the name of the module to be invoked." msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104 +msgid "ABI-encoded Constructor Arguments (if required by the contract)" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/api_docs/index.html.eex:4 +msgid "API Documentation" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/api_docs/_metatags.html.eex:4 msgid "API endpoints for the %{subnetwork}" @@ -86,6 +111,11 @@ msgstr "" msgid "API for the %{subnetwork} - BlockScout" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/layout/_topnav.html.eex:81 +msgid "APIs" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/layout/_topnav.html.eex:71 msgid "Accounts" @@ -118,22 +148,42 @@ msgstr "" msgid "All" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15 +msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences." +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/chain/show.html.eex:47 msgid "Average block time" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/transaction/not_found.html.eex:30 +msgid "Back Home" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address/_balance_card.html.eex:3 msgid "Balance" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:14 +msgid "Balances" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:5 #: lib/block_scout_web/templates/api_docs/index.html.eex:5 msgid "Base URL:" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_coin_balance/_coin_balances.html.eex:8 +msgid "Block" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/block/_link.html.eex:2 #: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:28 @@ -152,7 +202,12 @@ msgid "Block Confirmations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:17 +#: lib/block_scout_web/templates/block_transaction/404.html.eex:7 +msgid "Block Details" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/block/overview.html.eex:13 msgid "Block Height: %{height}" msgstr "" @@ -171,6 +226,11 @@ msgstr "" msgid "Block Pending" msgstr "" +#, elixir-format +#: lib/block_scout_web/views/block_transaction_view.ex:15 +msgid "Block not found, please try again later." +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/chain/_metatags.html.eex:4 msgid "BlockScout provides analytics data, API, and Smart Contract tools for the %{subnetwork}" @@ -196,6 +256,27 @@ msgstr "" 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." +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_token/index.html.eex:28 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:74 +msgid "CSV" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/views/internal_transaction_view.ex:21 +msgid "Call" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/views/internal_transaction_view.ex:22 +msgid "Call Code" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47 @@ -203,6 +284,16 @@ msgstr "" msgid "Cancel" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11 +msgid "Change Network" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_footer.html.eex:36 +msgid "Chat" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:137 #: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:106 @@ -228,6 +319,12 @@ msgstr "" msgid "Code" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address/_tabs.html.eex:20 +#: lib/block_scout_web/views/address_view.ex:310 +msgid "Coin Balance History" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40 msgid "Compiler" @@ -238,6 +335,11 @@ msgstr "" msgid "Compiler version" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:4 +msgid "Connection Lost" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:10 #: lib/block_scout_web/templates/block/index.html.eex:6 @@ -261,6 +363,11 @@ msgstr "" msgid "Connection Lost, click to load newer validations" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:53 +msgid "Constructor Arguments" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract/index.html.eex:75 msgid "Contract ABI" @@ -279,6 +386,11 @@ msgstr "" msgid "Contract Address Pending" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:105 +msgid "Contract Byte Code" +msgstr "" + #, elixir-format #: lib/block_scout_web/views/transaction_view.ex:261 msgid "Contract Call" @@ -289,6 +401,16 @@ msgstr "" msgid "Contract Creation" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:91 +msgid "Contract Creation Code" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118 +msgid "Contract Libraries" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:29 msgid "Contract Name" @@ -304,6 +426,21 @@ msgstr "" msgid "Contract source code" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:97 +msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified." +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_footer.html.eex:35 +msgid "Contribute" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:77 +msgid "Copy ABI" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:13 #: lib/block_scout_web/templates/address/overview.html.eex:17 @@ -313,394 +450,383 @@ msgid "Copy Address" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:16 -msgid "Copy Transaction Hash" +#: lib/block_scout_web/templates/address_contract/index.html.eex:107 +msgid "Copy Contract Byte Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:20 -msgid "Copy Txn Hash" +#: lib/block_scout_web/templates/address_contract/index.html.eex:93 +msgid "Copy Contract Creation Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:107 -msgid "Created by" +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:17 +msgid "Copy Decompiled Contract Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:146 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:116 -msgid "Curl" +#: lib/block_scout_web/templates/address_contract/index.html.eex:65 +msgid "Copy Source Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:53 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:188 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:60 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:150 -msgid "Description" +#: lib/block_scout_web/templates/transaction/overview.html.eex:16 +msgid "Copy Transaction Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:8 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:166 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:127 -msgid "Details" +#: lib/block_scout_web/templates/transaction/overview.html.eex:20 +msgid "Copy Txn Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:70 +#: lib/block_scout_web/templates/block/overview.html.eex:59 msgid "Difficulty" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:50 -msgid "ETH" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:66 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:119 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:31 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:69 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:122 +msgid "Copy Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_balance_card.html.eex:32 -msgid "Error trying to fetch balances." +#: lib/block_scout_web/views/internal_transaction_view.ex:25 +msgid "Create" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:188 -msgid "Error: %{reason}" +#: lib/block_scout_web/views/internal_transaction_view.ex:26 +msgid "Create2" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:186 -msgid "Error: (Awaiting internal transactions for reason)" +#: lib/block_scout_web/templates/address/overview.html.eex:107 +msgid "Created by" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_balance_card.html.eex:15 -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:20 -#: lib/block_scout_web/templates/layout/app.html.eex:62 -#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20 -#: lib/block_scout_web/templates/transaction/_tile.html.eex:29 -#: lib/block_scout_web/templates/transaction/overview.html.eex:179 -#: lib/block_scout_web/templates/transaction/overview.html.eex:209 -#: lib/block_scout_web/views/wei_helpers.ex:78 -msgid "Ether" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:146 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:116 +msgid "Curl" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:211 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:164 -msgid "Example Value" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:56 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:109 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:175 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:21 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:59 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:112 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:179 +msgid "Data" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:128 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:99 -msgid "Execute" +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:63 +msgid "Decimals" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_balance_card.html.eex:29 -msgid "Fetching tokens..." +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:37 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:90 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:32 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:40 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:93 +msgid "Decoded" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:41 -msgid "Forked Blocks (Reorgs)" +#: lib/block_scout_web/views/address_view.ex:308 +msgid "Decompiled Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:40 -#: lib/block_scout_web/views/address_internal_transaction_view.ex:7 -#: lib/block_scout_web/views/address_transaction_view.ex:7 -msgid "From" +#: lib/block_scout_web/templates/address/_tabs.html.eex:52 +msgid "Decompiled code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:18 -msgid "GET" +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:15 +msgid "Decompiled contract code" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:8 +msgid "Decompiler version" msgstr "" #, elixir-format #: lib/block_scout_web/templates/block/_tile.html.eex:56 -#: lib/block_scout_web/templates/block/overview.html.eex:117 -#: lib/block_scout_web/templates/block/overview.html.eex:171 +#: lib/block_scout_web/templates/block/overview.html.eex:109 +#: lib/block_scout_web/templates/block/overview.html.eex:159 msgid "Gas Limit" msgstr "" #, elixir-format #: lib/block_scout_web/templates/block/_tile.html.eex:61 -#: lib/block_scout_web/templates/block/overview.html.eex:110 -#: lib/block_scout_web/templates/block/overview.html.eex:165 +#: lib/block_scout_web/templates/block/overview.html.eex:102 +#: lib/block_scout_web/templates/block/overview.html.eex:153 msgid "Gas Used" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:19 -msgid "Github" +#: lib/block_scout_web/views/internal_transaction_view.ex:23 +msgid "Delegate Call" msgstr "" #, elixir-format -#: lib/block_scout_web/views/block_view.ex:20 -#: lib/block_scout_web/views/wei_helpers.ex:77 -msgid "Gwei" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:53 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:188 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:60 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:150 +msgid "Description" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:45 -msgid "Hash" +#: lib/block_scout_web/templates/address/overview.html.eex:8 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:166 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:127 +msgid "Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:38 -#: lib/block_scout_web/templates/transaction/_tile.html.eex:72 -msgid "IN" +#: lib/block_scout_web/templates/address_contract/index.html.eex:98 +msgid "Displaying the init data provided of the creating transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/app.html.eex:58 -msgid "Indexing Tokens" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:22 +msgid "During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:3 -msgid "Input" +#: lib/block_scout_web/views/transaction_view.ex:84 +msgid "ERC-20 " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:6 -msgid "Internal Transaction" +#: lib/block_scout_web/views/transaction_view.ex:85 +msgid "ERC-721 " 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:306 -#: lib/block_scout_web/views/transaction_view.ex:314 -msgid "Internal Transactions" +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:50 +msgid "ETH" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16 -#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:17 -#: lib/block_scout_web/views/tokens/overview_view.ex:38 -msgid "Inventory" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:4 +msgid "ETH RPC API Documentation" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/app.html.eex:59 -msgid "Less than" +#: lib/block_scout_web/templates/address_contract/index.html.eex:45 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51 +msgid "EVM Version" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:237 -msgid "Limit" +#: lib/block_scout_web/views/block_transaction_view.ex:7 +msgid "Easy Cowboy! This block does not exist yet!" 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:312 -#: lib/block_scout_web/views/transaction_view.ex:315 -msgid "Logs" +#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:5 +msgid "Emission Contract" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:31 -#: lib/block_scout_web/templates/layout/app.html.eex:60 -#: lib/block_scout_web/views/address_view.ex:121 -#: lib/block_scout_web/views/address_view.ex:121 -msgid "Market Cap" +#: lib/block_scout_web/views/block_view.ex:60 +msgid "Emission Reward" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:169 -#: lib/block_scout_web/views/transaction_view.ex:169 -msgid "Max of" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93 +msgid "Enter the Solidity Contract Code" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:49 +msgid "Error rendering value" msgstr "" #, elixir-format #: lib/block_scout_web/templates/block/_tile.html.eex:38 -#: lib/block_scout_web/templates/block/overview.html.eex:133 +#: lib/block_scout_web/templates/block/overview.html.eex:125 #: lib/block_scout_web/templates/chain/_block.html.eex:15 msgid "Miner" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:223 -msgid "Model" +#: lib/block_scout_web/templates/address/_balance_card.html.eex:32 +msgid "Error trying to fetch balances." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 -msgid "Module" +#: lib/block_scout_web/views/transaction_view.ex:188 +msgid "Error: %{reason}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:10 -msgid "More internal transactions have come in" +#: lib/block_scout_web/views/transaction_view.ex:186 +msgid "Error: (Awaiting internal transactions for reason)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:111 -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:10 -#: lib/block_scout_web/templates/transaction/index.html.eex:10 -msgid "More transactions have come in" +#: lib/block_scout_web/templates/address/overview.html.eex:120 +msgid "Error: Could not determine contract creator." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:63 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:74 -msgid "Must be set to:" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:95 +msgid "Eth RPC" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:106 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:59 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:19 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:56 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:109 -msgid "Name" +#: lib/block_scout_web/templates/address/_balance_card.html.eex:15 +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:20 +#: lib/block_scout_web/templates/layout/app.html.eex:62 +#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20 +#: lib/block_scout_web/templates/transaction/_tile.html.eex:29 +#: lib/block_scout_web/templates/transaction/overview.html.eex:179 +#: lib/block_scout_web/templates/transaction/overview.html.eex:209 +#: lib/block_scout_web/views/wei_helpers.ex:78 +msgid "Ether" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67 -msgid "No" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:211 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:164 +msgid "Example Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:85 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:128 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:99 +msgid "Execute" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/block/overview.html.eex:74 #: lib/block_scout_web/templates/transaction/overview.html.eex:79 msgid "Nonce" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:36 -#: lib/block_scout_web/templates/transaction/_tile.html.eex:68 -msgid "OUT" +#: lib/block_scout_web/templates/address_contract/index.html.eex:120 +msgid "External libraries" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:30 -msgid "Optimization enabled" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32 +msgid "Failed to decode input data." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:18 -msgid "Owner Address" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:35 +msgid "Failed to decode log data." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:19 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:26 -msgid "POST" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:24 +msgid "Favorites" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:33 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:40 -msgid "Parameters" +#: lib/block_scout_web/templates/address/_balance_card.html.eex:29 +msgid "Fetching tokens..." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:55 -msgid "Parent Hash" +#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:16 +msgid "For any existing contracts in the database, insert all ABI entries into the contract_methods table. Use this in case you have verified smart contracts before early March 2019 and you want other contracts with the same functions to show those ABI's as candidate matches." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:59 -#: lib/block_scout_web/views/transaction_view.ex:183 -#: lib/block_scout_web/views/transaction_view.ex:217 -msgid "Pending" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:41 +msgid "Forked Blocks (Reorgs)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:4 -msgid "Pending Transactions" +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:40 +#: lib/block_scout_web/views/address_internal_transaction_view.ex:7 +#: lib/block_scout_web/views/address_transaction_view.ex:7 +msgid "From" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:96 -msgid "Position %{index}" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:18 +msgid "GET" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:24 -#: lib/block_scout_web/templates/layout/app.html.eex:61 -msgid "Price" +#: lib/block_scout_web/templates/block/overview.html.eex:85 +msgid "Position %{index}" 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/tokens/overview/_details.html.eex:36 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:105 -msgid "QR Code" +#: lib/block_scout_web/templates/transaction/overview.html.eex:227 +msgid "Gas" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:22 -msgid "Query" +#: lib/block_scout_web/templates/block/overview.html.eex:13 +msgid "Genesis Block" 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:309 -#: lib/block_scout_web/views/tokens/overview_view.ex:37 -msgid "Read Contract" +#: lib/block_scout_web/templates/layout/_footer.html.eex:19 +msgid "Github" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:155 -msgid "Request URL" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:85 +msgid "GraphQL" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250 -msgid "Reset" +#: lib/block_scout_web/views/block_view.ex:20 +#: lib/block_scout_web/views/wei_helpers.ex:77 +msgid "Gwei" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:173 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:134 -msgid "Response Body" +#: lib/block_scout_web/templates/block/overview.html.eex:37 +msgid "Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:185 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:147 -msgid "Responses" +#: lib/block_scout_web/templates/transaction/overview.html.eex:115 +#: lib/block_scout_web/templates/transaction/overview.html.eex:119 +msgid "Hex (Default)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:14 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:127 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:144 -msgid "Search" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:11 +msgid "However, in general, the" msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:30 -msgid "Search tokens" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18 +msgid "IMPORTANT: This information is a best guess based on similar functions from other verified contracts." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:163 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:124 -msgid "Server Response" +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:38 +#: lib/block_scout_web/templates/transaction/_tile.html.eex:72 +msgid "IN" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:34 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:37 -msgid "Show QR Code" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:26 +msgid "If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information." msgstr "" #, elixir-format @@ -838,7 +964,7 @@ msgid "Top Accounts - %{subnetwork} Explorer" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:79 +#: lib/block_scout_web/templates/block/overview.html.eex:68 msgid "Total Difficulty" msgstr "" @@ -854,207 +980,116 @@ msgid "Transaction" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_metatags.html.eex:3 -msgid "Transaction %{transaction} - %{subnetwork} Explorer" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:12 +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/transaction/_metatags.html.eex:11 -msgid "Transaction %{transaction}, %{subnetwork} %{transaction}" +#: lib/block_scout_web/templates/address/overview.html.eex:79 +msgid "Incoming Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:11 -msgid "Transaction Details" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:55 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:108 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:111 +msgid "Indexed?" 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:108 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:50 -#: lib/block_scout_web/views/address_view.ex:305 -msgid "Transactions" +#: lib/block_scout_web/templates/layout/app.html.eex:58 +msgid "Indexing Tokens" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_tile.html.eex:31 -msgid "Transactions sent" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:61 -msgid "Transfers" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:40 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:47 -msgid "Try it out" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:22 -msgid "Twitter" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:92 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:38 -msgid "Uncles" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:6 -msgid "Unique Token" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:231 -msgid "Used" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:54 -msgid "Validated" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/index.html.eex:4 -msgid "Validated Transactions" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address/_tile.html.eex:35 -msgid "Validations" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:179 -#: lib/block_scout_web/templates/transaction/overview.html.eex:209 -msgid "Value" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:11 -#: lib/block_scout_web/templates/address_contract/index.html.eex:16 -msgid "Verify & Publish" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249 -msgid "Verify & publish" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:55 -msgid "View Contract" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_tile.html.eex:53 -msgid "View Less Transfers" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_tile.html.eex:52 -msgid "View More Transfers" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address/_metatags.html.eex:9 -msgid "View the account balance, transactions, and other data for %{address} on the %{network}" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/block/_metatags.html.eex:10 -msgid "View the transactions, token transfers, and uncles for block number %{block_number}" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_metatags.html.eex:10 -msgid "View transaction %{transaction} on %{subnetwork}" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:49 -msgid "WEI" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:3 +msgid "Input" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:72 -msgid "Wallet addresses" +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:6 +msgid "Internal Transaction" msgstr "" #, elixir-format -#: lib/block_scout_web/views/wei_helpers.ex:76 -msgid "Wei" +#: 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:306 +#: lib/block_scout_web/views/transaction_view.ex:314 +msgid "Internal Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72 -msgid "Yes" +#: lib/block_scout_web/templates/transaction/invalid.html.eex:6 +msgid "Invalid Transaction Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:112 -msgid "at" +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16 +#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:17 +#: lib/block_scout_web/views/tokens/overview_view.ex:38 +msgid "Inventory" msgstr "" #, elixir-format -#: lib/block_scout_web/views/address_contract_view.ex:23 -msgid "false" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:16 +msgid "It could still be in the TX Pool of a different node, waiting to be broadcasted." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:69 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:81 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:70 -msgid "required" +#: lib/block_scout_web/templates/address/overview.html.eex:89 +msgid "Last Balance Update: Block #" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:59 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:70 -msgid "string" +#: lib/block_scout_web/templates/layout/app.html.eex:59 +msgid "Less than" msgstr "" #, elixir-format -#: lib/block_scout_web/views/address_contract_view.ex:22 -msgid "true" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221 +msgid "Library Address" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:21 -msgid "Call" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211 +msgid "Library Name" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:25 -msgid "Create" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:24 +msgid "License Expires" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:23 -msgid "Delegate Call" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:10 +msgid "License ID" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:27 -msgid "Self-Destruct" +#: lib/block_scout_web/templates/transaction/overview.html.eex:237 +msgid "Limit" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:63 -msgid "Decimals" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:22 +#: lib/block_scout_web/templates/chain/show.html.eex:13 +msgid "Loading chart" msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_read_contract/index.html.eex:14 -#: lib/block_scout_web/templates/chain/show.html.eex:99 #: lib/block_scout_web/templates/tokens/read_contract/index.html.eex:21 msgid "Loading..." msgstr "" @@ -1065,73 +1100,45 @@ msgid "Loading...." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:81 -msgid "APIs" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:85 -msgid "GraphQL" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:90 -msgid "RPC" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/api_docs/index.html.eex:6 -msgid "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:109 -msgid "Raw Input" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/views/block_transaction_view.ex:15 -msgid "Block not found, please try again later." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/views/block_transaction_view.ex:7 -msgid "Easy Cowboy! This block does not exist yet!" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/views/block_transaction_view.ex:11 -msgid "This block has not been processed yet." +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:103 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:106 +msgid "Log Data" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/invalid.html.eex:6 -msgid "Invalid Transaction Hash" +#: 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:312 +#: lib/block_scout_web/views/transaction_view.ex:315 +msgid "Logs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/invalid.html.eex:8 -msgid "is not a valid transaction hash" +#: lib/block_scout_web/templates/layout/_footer.html.eex:44 +msgid "Main Networks" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:22 -msgid "Call Code" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22 +msgid "Mainnet" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:24 -msgid "Static Call" +#: lib/block_scout_web/templates/chain/show.html.eex:31 +#: lib/block_scout_web/templates/layout/app.html.eex:60 +#: lib/block_scout_web/views/address_view.ex:121 +#: lib/block_scout_web/views/address_view.ex:121 +msgid "Market Cap" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:37 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:90 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:32 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:40 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:93 -msgid "Decoded" +#: lib/block_scout_web/views/transaction_view.ex:169 +#: lib/block_scout_web/views/transaction_view.ex:169 +msgid "Max of" msgstr "" #, elixir-format @@ -1140,705 +1147,697 @@ msgid "Method Id" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:2 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16 -msgid "Transaction Inputs" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 -msgid "Verify the contract " -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 -msgid "here" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32 -msgid "Failed to decode input data." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:49 -msgid "Error rendering value" +#: lib/block_scout_web/views/block_view.ex:56 +msgid "Miner Reward" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34 -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 -#: lib/block_scout_web/templates/address_logs/index.html.eex:21 -#: lib/block_scout_web/templates/address_token/index.html.eex:13 -#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:59 -#: lib/block_scout_web/templates/address_validation/index.html.eex:22 -#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 -#: lib/block_scout_web/templates/chain/show.html.eex:91 -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:19 -#: lib/block_scout_web/templates/tokens/holder/index.html.eex:21 -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:21 -#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:20 -#: lib/block_scout_web/templates/transaction/index.html.eex:20 -#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:13 -#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:12 -msgid "Something went wrong, click to reload." +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:223 +msgid "Model" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_validation/index.html.eex:18 -msgid "There are no blocks validated by this address." +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 +msgid "Module" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/index.html.eex:26 -msgid "There are no transactions." +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:10 +msgid "More internal transactions have come in" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:14 -msgid "Balances" +#: lib/block_scout_web/templates/chain/show.html.eex:148 +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:10 +#: lib/block_scout_web/templates/transaction/index.html.eex:10 +msgid "More transactions have come in" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/_coin_balances.html.eex:8 -msgid "Block" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:63 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:74 +msgid "Must be set to:" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_tabs.html.eex:20 -#: lib/block_scout_web/views/address_view.ex:310 -msgid "Coin Balance History" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:106 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:59 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:19 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:56 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:109 +msgid "Name" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:22 -#: lib/block_scout_web/templates/chain/show.html.eex:13 -msgid "Loading chart" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:9 +msgid "New Smart Contract Verification" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:39 -msgid "There is no coin history for this address." +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67 +msgid "No" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:25 -#: lib/block_scout_web/templates/chain/show.html.eex:16 -msgid "There was a problem loading the chart." +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:36 +#: lib/block_scout_web/templates/transaction/_tile.html.eex:68 +msgid "OUT" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:23 -msgid "There are no pending transactions." +#: lib/block_scout_web/templates/address_contract/index.html.eex:30 +msgid "Optimization enabled" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/index.html.eex:18 -msgid "There are no blocks." +#: lib/block_scout_web/templates/address_contract/index.html.eex:39 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83 +msgid "Optimization runs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:24 -msgid "License Expires" +#: lib/block_scout_web/templates/layout/_footer.html.eex:68 +msgid "Other Explorers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:10 -msgid "License ID" +#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:18 +msgid "Owner Address" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:48 -msgid "Show Validator Info" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:19 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:26 +msgid "POST" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:30 -msgid "Validator Creation Date" +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 +msgid "Page" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:5 -msgid "Validator Data" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:33 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:40 +msgid "Parameters" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:52 -msgid "Validator Info" +#: lib/block_scout_web/templates/block/overview.html.eex:44 +msgid "Parent Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:155 -msgid "Block Rewards" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:59 +#: lib/block_scout_web/views/transaction_view.ex:183 +#: lib/block_scout_web/views/transaction_view.ex:217 +msgid "Pending" msgstr "" #, elixir-format -#: lib/block_scout_web/views/block_view.ex:60 -msgid "Emission Reward" +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:4 +msgid "Pending Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/views/block_view.ex:56 -msgid "Miner Reward" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:17 +msgid "Potential matches from our contract method database:" msgstr "" #, elixir-format -#: lib/block_scout_web/views/block_view.ex:64 -msgid "Uncle Reward" +#: lib/block_scout_web/templates/chain/show.html.eex:24 +#: lib/block_scout_web/templates/layout/app.html.eex:61 +msgid "Price" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18 -msgid "IMPORTANT: This information is a best guess based on similar functions from other verified contracts." +#: 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/tokens/overview/_details.html.eex:36 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:105 +msgid "QR Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:17 -msgid "Potential matches from our contract method database:" +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:22 +msgid "Query" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:19 -msgid "To have guaranteed accuracy, use the link above to verify the contract's source code." +#: lib/block_scout_web/templates/layout/_topnav.html.eex:90 +msgid "RPC" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:6 -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:8 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:6 -msgid "To see accurate decoded input data, the contract must be verified." +#: lib/block_scout_web/templates/transaction/overview.html.eex:109 +msgid "Raw Input" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:5 -msgid "Emission Contract" +#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24 +#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7 +#: lib/block_scout_web/views/transaction_view.ex:316 +msgid "Raw Trace" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:117 -msgid "Something went wrong, click to retry." +#: 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:309 +#: lib/block_scout_web/views/tokens/overview_view.ex:37 +msgid "Read Contract" 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." +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:11 +msgid "Records" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:36 -msgid "Chat" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:155 +msgid "Request URL" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:35 -msgid "Contribute" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250 +msgid "Reset" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:44 -msgid "Main Networks" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:173 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:134 +msgid "Response Body" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:68 -msgid "Other Explorers" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:185 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:147 +msgid "Responses" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:34 -msgid "Submit an Issue" +#: lib/block_scout_web/templates/block/_tile.html.eex:47 +#: lib/block_scout_web/templates/chain/_block.html.eex:23 +#: lib/block_scout_web/views/internal_transaction_view.ex:28 +msgid "Reward" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:57 -msgid "Test Networks" +#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:21 +msgid "Run" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:83 -msgid "Version" +#: lib/block_scout_web/templates/address_logs/index.html.eex:14 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:127 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:144 +msgid "Search" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:37 -msgid "Support" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:121 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:125 +msgid "Search by address, token symbol name, transaction hash, or block number" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:77 -msgid "Copy ABI" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:18 +msgid "Search network" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:93 -msgid "Copy Contract Creation Code" +#: +#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:30 +msgid "Search tokens" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:65 -msgid "Copy Source Code" +#: lib/block_scout_web/views/internal_transaction_view.ex:27 +msgid "Self-Destruct" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:17 -msgid "Genesis Block" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:163 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:124 +msgid "Server Response" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118 -msgid "Contract Libraries" +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:5 +msgid "Show" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:89 -msgid "Last Balance Update: Block #" +#: lib/block_scout_web/templates/address/overview.html.eex:34 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:37 +msgid "Show QR Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:84 -msgid "Transactions Sent" +#: lib/block_scout_web/templates/address/overview.html.eex:48 +msgid "Show Validator Info" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:101 -msgid "Transaction Speed" +#: lib/block_scout_web/templates/block/overview.html.eex:146 +msgid "Block Rewards" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:115 -#: lib/block_scout_web/templates/transaction/overview.html.eex:119 -msgid "Hex (Default)" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 +#: lib/block_scout_web/templates/address_logs/index.html.eex:21 +#: lib/block_scout_web/templates/address_token/index.html.eex:13 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:59 +#: lib/block_scout_web/templates/address_validation/index.html.eex:22 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 +#: lib/block_scout_web/templates/chain/show.html.eex:91 +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:19 +#: lib/block_scout_web/templates/tokens/holder/index.html.eex:21 +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:21 +#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:20 +#: lib/block_scout_web/templates/transaction/index.html.eex:20 +#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/index.html.eex:13 +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:12 +msgid "Something went wrong, click to reload." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:122 -msgid "UTF-8" +#: lib/block_scout_web/templates/chain/show.html.eex:154 +msgid "Something went wrong, click to retry." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:16 -msgid "For any existing contracts in the database, insert all ABI entries into the contract_methods table. Use this in case you have verified smart contracts before early March 2019 and you want other contracts with the same functions to show those ABI's as candidate matches." +#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 +msgid "Sorry, We are unable to locate this transaction Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:21 -msgid "Run" +#: lib/block_scout_web/views/internal_transaction_view.ex:24 +msgid "Static Call" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:75 -msgid ">=" +#: lib/block_scout_web/templates/layout/_footer.html.eex:34 +msgid "Submit an Issue" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:79 -msgid "Incoming Transactions" +#: lib/block_scout_web/templates/layout/_footer.html.eex:37 +msgid "Support" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:120 -msgid "Error: Could not determine contract creator." +#: lib/block_scout_web/templates/layout/_footer.html.eex:57 +msgid "Test Networks" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:121 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:125 -msgid "Search by address, token symbol name, transaction hash, or block number" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23 +msgid "Testnet" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:45 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51 -msgid "EVM Version" +#: lib/block_scout_web/templates/address_validation/index.html.eex:18 +msgid "There are no blocks validated by this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:17 -msgid "Copy Decompiled Contract Code" +#: lib/block_scout_web/templates/block/index.html.eex:18 +msgid "There are no blocks." msgstr "" #, elixir-format -#: lib/block_scout_web/views/address_view.ex:308 -msgid "Decompiled Code" +#: lib/block_scout_web/templates/address_logs/index.html.eex:26 +msgid "There are no logs for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_tabs.html.eex:52 -msgid "Decompiled code" +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:23 +msgid "There are no pending transactions." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:15 -msgid "Decompiled contract code" +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:17 +msgid "There are no token transfers for this transaction" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:8 -msgid "Decompiler version" +#: lib/block_scout_web/templates/transaction/index.html.eex:26 +msgid "There are no transactions." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:39 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83 -msgid "Optimization runs" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:39 +msgid "There is no coin history for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/index.html.eex:4 -msgid "API Documentation" +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:27 +msgid "There is no decompilded contracts for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:86 -msgid "View All Blocks" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:25 +#: lib/block_scout_web/templates/chain/show.html.eex:16 +msgid "There was a problem loading the chart." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:107 -msgid "View All Transactions" +#: lib/block_scout_web/templates/api_docs/index.html.eex:6 +msgid "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:227 -msgid "Gas" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:7 +msgid "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24 -#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7 -#: lib/block_scout_web/views/transaction_view.ex:316 -msgid "Raw Trace" +#: lib/block_scout_web/views/block_transaction_view.ex:11 +msgid "This block has not been processed yet." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:64 -msgid "Total blocks" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:10 +msgid "This is useful to allow sending requests to blockscout without having to change anything about the request." msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 -msgid "Page" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:19 +msgid "To have guaranteed accuracy, use the link above to verify the contract's source code." msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:11 -msgid "Records" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:6 +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:8 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:6 +msgid "To see accurate decoded input data, the contract must be verified." msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:5 -msgid "Show" +#: lib/block_scout_web/templates/address_logs/index.html.eex:12 +msgid "Topic" msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 -msgid "of" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:145 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:149 +msgid "Topics" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block_transaction/404.html.eex:7 -msgid "Block Details" +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75 +msgid "Total Supply" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:105 -msgid "Contract Byte Code" +#: lib/block_scout_web/templates/chain/show.html.eex:64 +msgid "Total blocks" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:91 -msgid "Contract Creation Code" +#: lib/block_scout_web/templates/transaction/_metatags.html.eex:3 +msgid "Transaction %{transaction} - %{subnetwork} Explorer" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:97 -msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified." +#: lib/block_scout_web/templates/transaction/_metatags.html.eex:11 +msgid "Transaction %{transaction}, %{subnetwork} %{transaction}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:107 -msgid "Copy Contract Byte Code" +#: lib/block_scout_web/templates/transaction/overview.html.eex:11 +msgid "Transaction Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:98 -msgid "Displaying the init data provided of the creating transaction." +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:2 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16 +msgid "Transaction Inputs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:26 -msgid "There are no logs for this address." +#: lib/block_scout_web/templates/transaction/overview.html.eex:101 +msgid "Transaction Speed" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:12 -msgid "If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page." +#: 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:305 +msgid "Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:30 -msgid "Back Home" +#: lib/block_scout_web/templates/address/overview.html.eex:84 +msgid "Transactions Sent" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:22 -msgid "During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it." +#: lib/block_scout_web/templates/address/_tile.html.eex:31 +msgid "Transactions sent" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:26 -msgid "If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information." +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:61 +msgid "Transfers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:16 -msgid "It could still be in the TX Pool of a different node, waiting to be broadcasted." +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:40 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:47 +msgid "Try it out" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 -msgid "Sorry, We are unable to locate this transaction Hash" +#: lib/block_scout_web/templates/layout/_footer.html.eex:22 +msgid "Twitter" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:17 -msgid "There are no token transfers for this transaction" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:54 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:107 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:20 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:57 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:110 +msgid "Type" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:12 -msgid "Topic" +#: lib/block_scout_web/templates/transaction/overview.html.eex:122 +msgid "UTF-8" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104 -msgid "ABI-encoded Constructor Arguments (if required by the contract)" +#: lib/block_scout_web/views/block_view.ex:64 +msgid "Uncle Reward" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93 -msgid "Enter the Solidity Contract Code" +#: lib/block_scout_web/templates/block/overview.html.eex:81 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:38 +msgid "Uncles" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221 -msgid "Library Address" +#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:6 +msgid "Unique Token" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211 -msgid "Library Name" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:12 +msgid "Use the search box to find a hosted network, or select from the list of available networks below." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:9 -msgid "New Smart Contract Verification" +#: lib/block_scout_web/templates/transaction/overview.html.eex:231 +msgid "Used" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:192 -msgid " Token Transfer" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:54 +msgid "Validated" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:14 -msgid " is recommended." +#: lib/block_scout_web/templates/transaction/index.html.eex:4 +msgid "Validated Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15 -msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences." +#: lib/block_scout_web/templates/address/_tile.html.eex:35 +msgid "Validations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:4 -msgid "ETH RPC API Documentation" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:30 +msgid "Validator Creation Date" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:95 -msgid "Eth RPC" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:5 +msgid "Validator Data" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:11 -msgid "However, in general, the" +#: lib/block_scout_web/templates/address/overview.html.eex:52 +msgid "Validator Info" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:27 -msgid "There is no decompilded contracts for this address." +#: lib/block_scout_web/templates/transaction/overview.html.eex:179 +#: lib/block_scout_web/templates/transaction/overview.html.eex:209 +msgid "Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:7 -msgid "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found " +#: lib/block_scout_web/templates/address_contract/index.html.eex:11 +#: lib/block_scout_web/templates/address_contract/index.html.eex:16 +msgid "Verify & Publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:10 -msgid "This is useful to allow sending requests to blockscout without having to change anything about the request." +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249 +msgid "Verify & publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:12 -msgid "custom RPC" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 +msgid "Verify the contract " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:9 -msgid "here." +#: lib/block_scout_web/templates/layout/_footer.html.eex:83 +msgid "Version" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_token/index.html.eex:28 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:74 -msgid "CSV" +#: lib/block_scout_web/templates/chain/show.html.eex:86 +msgid "View All Blocks" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11 -msgid "Change Network" +#: lib/block_scout_web/templates/chain/show.html.eex:144 +msgid "View All Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:84 -msgid "ERC-20 " +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:55 +msgid "View Contract" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:85 -msgid "ERC-721 " +#: lib/block_scout_web/templates/transaction/_tile.html.eex:53 +msgid "View Less Transfers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:120 -msgid "External libraries" +#: lib/block_scout_web/templates/transaction/_tile.html.eex:52 +msgid "View More Transfers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:24 -msgid "Favorites" +#: lib/block_scout_web/templates/address/_metatags.html.eex:9 +msgid "View the account balance, transactions, and other data for %{address} on the %{network}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22 -msgid "Mainnet" +#: lib/block_scout_web/templates/block/_metatags.html.eex:10 +msgid "View the transactions, token transfers, and uncles for block number %{block_number}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:18 -msgid "Search network" +#: lib/block_scout_web/templates/transaction/_metatags.html.eex:10 +msgid "View transaction %{transaction} on %{subnetwork}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23 -msgid "Testnet" +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:49 +msgid "WEI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:12 -msgid "Use the search box to find a hosted network, or select from the list of available networks below." +#: lib/block_scout_web/templates/chain/show.html.eex:72 +msgid "Wallet addresses" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:4 -msgid "Connection Lost" +#: lib/block_scout_web/views/wei_helpers.ex:76 +msgid "Wei" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:53 -msgid "Constructor Arguments" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72 +msgid "Yes" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:66 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:119 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:31 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:69 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:122 -msgid "Copy Value" +#: lib/block_scout_web/templates/address/overview.html.eex:112 +msgid "at" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:26 -msgid "Create2" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:12 +msgid "custom RPC" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:56 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:109 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:175 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:21 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:59 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:112 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:179 -msgid "Data" +#: lib/block_scout_web/views/address_contract_view.ex:23 +msgid "false" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:35 -msgid "Failed to decode log data." +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 +msgid "here" 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 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:111 -msgid "Indexed?" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:9 +msgid "here." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:103 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:106 -msgid "Log Data" +#: lib/block_scout_web/templates/transaction/invalid.html.eex:8 +msgid "is not a valid transaction hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/_tile.html.eex:47 -#: lib/block_scout_web/templates/chain/_block.html.eex:23 -#: lib/block_scout_web/views/internal_transaction_view.ex:28 -msgid "Reward" +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 +msgid "of" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:145 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:149 -msgid "Topics" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:69 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:81 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:70 +msgid "required" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:54 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:107 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:20 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:57 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:110 -msgid "Type" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:59 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:70 +msgid "string" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75 -msgid "Total Supply" +#: lib/block_scout_web/views/address_contract_view.ex:22 +msgid "true" msgstr "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index dd60e9394d..9aec6fbce9 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -12,6 +12,16 @@ msgid_plural "%{count} transactions" msgstr[0] "" msgstr[1] "" +#, elixir-format +#: lib/block_scout_web/templates/transaction/overview.html.eex:192 +msgid " Token Transfer" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:14 +msgid " is recommended." +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address/_metatags.html.eex:3 msgid "%{address} - %{subnetwork} Explorer" @@ -23,7 +33,7 @@ msgid "%{block_type} Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:19 +#: lib/block_scout_web/templates/block/overview.html.eex:15 msgid "%{block_type} Height:" msgstr "" @@ -33,7 +43,7 @@ msgid "%{block_type}s" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:27 +#: lib/block_scout_web/templates/block/overview.html.eex:21 #: lib/block_scout_web/templates/chain/_block.html.eex:11 msgid "%{count} Transactions" msgstr "" @@ -66,6 +76,11 @@ 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." @@ -76,6 +91,16 @@ msgstr "" msgid "A string with the name of the module to be invoked." msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104 +msgid "ABI-encoded Constructor Arguments (if required by the contract)" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/api_docs/index.html.eex:4 +msgid "API Documentation" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/api_docs/_metatags.html.eex:4 msgid "API endpoints for the %{subnetwork}" @@ -86,6 +111,11 @@ msgstr "" msgid "API for the %{subnetwork} - BlockScout" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/layout/_topnav.html.eex:81 +msgid "APIs" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/layout/_topnav.html.eex:71 msgid "Accounts" @@ -118,22 +148,42 @@ msgstr "" msgid "All" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15 +msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences." +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/chain/show.html.eex:47 msgid "Average block time" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/transaction/not_found.html.eex:30 +msgid "Back Home" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address/_balance_card.html.eex:3 msgid "Balance" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:14 +msgid "Balances" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:5 #: lib/block_scout_web/templates/api_docs/index.html.eex:5 msgid "Base URL:" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_coin_balance/_coin_balances.html.eex:8 +msgid "Block" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/block/_link.html.eex:2 #: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:28 @@ -152,7 +202,12 @@ msgid "Block Confirmations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:17 +#: lib/block_scout_web/templates/block_transaction/404.html.eex:7 +msgid "Block Details" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/block/overview.html.eex:13 msgid "Block Height: %{height}" msgstr "" @@ -171,6 +226,11 @@ msgstr "" msgid "Block Pending" msgstr "" +#, elixir-format +#: lib/block_scout_web/views/block_transaction_view.ex:15 +msgid "Block not found, please try again later." +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/chain/_metatags.html.eex:4 msgid "BlockScout provides analytics data, API, and Smart Contract tools for the %{subnetwork}" @@ -196,6 +256,27 @@ msgstr "" 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." +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_token/index.html.eex:28 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:74 +msgid "CSV" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/views/internal_transaction_view.ex:21 +msgid "Call" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/views/internal_transaction_view.ex:22 +msgid "Call Code" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47 @@ -203,6 +284,16 @@ msgstr "" msgid "Cancel" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11 +msgid "Change Network" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_footer.html.eex:36 +msgid "Chat" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:137 #: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:106 @@ -228,6 +319,12 @@ msgstr "" msgid "Code" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address/_tabs.html.eex:20 +#: lib/block_scout_web/views/address_view.ex:310 +msgid "Coin Balance History" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:40 msgid "Compiler" @@ -238,6 +335,11 @@ msgstr "" msgid "Compiler version" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:4 +msgid "Connection Lost" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:10 #: lib/block_scout_web/templates/block/index.html.eex:6 @@ -261,6 +363,11 @@ msgstr "" msgid "Connection Lost, click to load newer validations" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:53 +msgid "Constructor Arguments" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract/index.html.eex:75 msgid "Contract ABI" @@ -279,6 +386,11 @@ msgstr "" msgid "Contract Address Pending" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:105 +msgid "Contract Byte Code" +msgstr "" + #, elixir-format #: lib/block_scout_web/views/transaction_view.ex:261 msgid "Contract Call" @@ -289,6 +401,16 @@ msgstr "" msgid "Contract Creation" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:91 +msgid "Contract Creation Code" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118 +msgid "Contract Libraries" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address_contract_verification/new.html.eex:29 msgid "Contract Name" @@ -304,6 +426,21 @@ msgstr "" msgid "Contract source code" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:97 +msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified." +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_footer.html.eex:35 +msgid "Contribute" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_contract/index.html.eex:77 +msgid "Copy ABI" +msgstr "" + #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:13 #: lib/block_scout_web/templates/address/overview.html.eex:17 @@ -313,394 +450,383 @@ msgid "Copy Address" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:16 -msgid "Copy Transaction Hash" +#: lib/block_scout_web/templates/address_contract/index.html.eex:107 +msgid "Copy Contract Byte Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:20 -msgid "Copy Txn Hash" +#: lib/block_scout_web/templates/address_contract/index.html.eex:93 +msgid "Copy Contract Creation Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:107 -msgid "Created by" +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:17 +msgid "Copy Decompiled Contract Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:146 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:116 -msgid "Curl" +#: lib/block_scout_web/templates/address_contract/index.html.eex:65 +msgid "Copy Source Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:53 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:188 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:60 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:150 -msgid "Description" +#: lib/block_scout_web/templates/transaction/overview.html.eex:16 +msgid "Copy Transaction Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:8 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:166 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:127 -msgid "Details" +#: lib/block_scout_web/templates/transaction/overview.html.eex:20 +msgid "Copy Txn Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:70 +#: lib/block_scout_web/templates/block/overview.html.eex:59 msgid "Difficulty" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:50 -msgid "ETH" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:66 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:119 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:31 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:69 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:122 +msgid "Copy Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_balance_card.html.eex:32 -msgid "Error trying to fetch balances." +#: lib/block_scout_web/views/internal_transaction_view.ex:25 +msgid "Create" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:188 -msgid "Error: %{reason}" +#: lib/block_scout_web/views/internal_transaction_view.ex:26 +msgid "Create2" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:186 -msgid "Error: (Awaiting internal transactions for reason)" +#: lib/block_scout_web/templates/address/overview.html.eex:107 +msgid "Created by" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_balance_card.html.eex:15 -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:20 -#: lib/block_scout_web/templates/layout/app.html.eex:62 -#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20 -#: lib/block_scout_web/templates/transaction/_tile.html.eex:29 -#: lib/block_scout_web/templates/transaction/overview.html.eex:179 -#: lib/block_scout_web/templates/transaction/overview.html.eex:209 -#: lib/block_scout_web/views/wei_helpers.ex:78 -msgid "Ether" -msgstr "POA" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:146 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:116 +msgid "Curl" +msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:211 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:164 -msgid "Example Value" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:56 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:109 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:175 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:21 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:59 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:112 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:179 +msgid "Data" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:128 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:99 -msgid "Execute" +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:63 +msgid "Decimals" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_balance_card.html.eex:29 -msgid "Fetching tokens..." +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:37 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:90 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:32 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:40 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:93 +msgid "Decoded" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:41 -msgid "Forked Blocks (Reorgs)" +#: lib/block_scout_web/views/address_view.ex:308 +msgid "Decompiled Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:40 -#: lib/block_scout_web/views/address_internal_transaction_view.ex:7 -#: lib/block_scout_web/views/address_transaction_view.ex:7 -msgid "From" +#: lib/block_scout_web/templates/address/_tabs.html.eex:52 +msgid "Decompiled code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:18 -msgid "GET" +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:15 +msgid "Decompiled contract code" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:8 +msgid "Decompiler version" msgstr "" #, elixir-format #: lib/block_scout_web/templates/block/_tile.html.eex:56 -#: lib/block_scout_web/templates/block/overview.html.eex:117 -#: lib/block_scout_web/templates/block/overview.html.eex:171 +#: lib/block_scout_web/templates/block/overview.html.eex:109 +#: lib/block_scout_web/templates/block/overview.html.eex:159 msgid "Gas Limit" msgstr "" #, elixir-format #: lib/block_scout_web/templates/block/_tile.html.eex:61 -#: lib/block_scout_web/templates/block/overview.html.eex:110 -#: lib/block_scout_web/templates/block/overview.html.eex:165 +#: lib/block_scout_web/templates/block/overview.html.eex:102 +#: lib/block_scout_web/templates/block/overview.html.eex:153 msgid "Gas Used" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:19 -msgid "Github" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/views/block_view.ex:20 -#: lib/block_scout_web/views/wei_helpers.ex:77 -msgid "Gwei" +#: lib/block_scout_web/views/internal_transaction_view.ex:23 +msgid "Delegate Call" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:45 -msgid "Hash" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:53 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:188 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:60 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:150 +msgid "Description" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:38 -#: lib/block_scout_web/templates/transaction/_tile.html.eex:72 -msgid "IN" +#: lib/block_scout_web/templates/address/overview.html.eex:8 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:166 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:127 +msgid "Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/app.html.eex:58 -msgid "Indexing Tokens" +#: lib/block_scout_web/templates/address_contract/index.html.eex:98 +msgid "Displaying the init data provided of the creating transaction." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:3 -msgid "Input" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:22 +msgid "During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:6 -msgid "Internal Transaction" +#: lib/block_scout_web/views/transaction_view.ex:84 +msgid "ERC-20 " 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:306 -#: lib/block_scout_web/views/transaction_view.ex:314 -msgid "Internal Transactions" +#: lib/block_scout_web/views/transaction_view.ex:85 +msgid "ERC-721 " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16 -#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:17 -#: lib/block_scout_web/views/tokens/overview_view.ex:38 -msgid "Inventory" +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:50 +msgid "ETH" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/app.html.eex:59 -msgid "Less than" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:4 +msgid "ETH RPC API Documentation" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:237 -msgid "Limit" +#: lib/block_scout_web/templates/address_contract/index.html.eex:45 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51 +msgid "EVM Version" 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:312 -#: lib/block_scout_web/views/transaction_view.ex:315 -msgid "Logs" +#: lib/block_scout_web/views/block_transaction_view.ex:7 +msgid "Easy Cowboy! This block does not exist yet!" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:31 -#: lib/block_scout_web/templates/layout/app.html.eex:60 -#: lib/block_scout_web/views/address_view.ex:121 -#: lib/block_scout_web/views/address_view.ex:121 -msgid "Market Cap" +#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:5 +msgid "Emission Contract" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:169 -#: lib/block_scout_web/views/transaction_view.ex:169 -msgid "Max of" +#: lib/block_scout_web/views/block_view.ex:60 +msgid "Emission Reward" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93 +msgid "Enter the Solidity Contract Code" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:49 +msgid "Error rendering value" msgstr "" #, elixir-format #: lib/block_scout_web/templates/block/_tile.html.eex:38 -#: lib/block_scout_web/templates/block/overview.html.eex:133 +#: lib/block_scout_web/templates/block/overview.html.eex:125 #: lib/block_scout_web/templates/chain/_block.html.eex:15 msgid "Miner" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:223 -msgid "Model" +#: lib/block_scout_web/templates/address/_balance_card.html.eex:32 +msgid "Error trying to fetch balances." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 -msgid "Module" +#: lib/block_scout_web/views/transaction_view.ex:188 +msgid "Error: %{reason}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:10 -msgid "More internal transactions have come in" +#: lib/block_scout_web/views/transaction_view.ex:186 +msgid "Error: (Awaiting internal transactions for reason)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:111 -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:10 -#: lib/block_scout_web/templates/transaction/index.html.eex:10 -msgid "More transactions have come in" +#: lib/block_scout_web/templates/address/overview.html.eex:120 +msgid "Error: Could not determine contract creator." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:63 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:74 -msgid "Must be set to:" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:95 +msgid "Eth RPC" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:106 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:59 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:19 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:56 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:109 -msgid "Name" +#: lib/block_scout_web/templates/address/_balance_card.html.eex:15 +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:20 +#: lib/block_scout_web/templates/layout/app.html.eex:62 +#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20 +#: lib/block_scout_web/templates/transaction/_tile.html.eex:29 +#: lib/block_scout_web/templates/transaction/overview.html.eex:179 +#: lib/block_scout_web/templates/transaction/overview.html.eex:209 +#: lib/block_scout_web/views/wei_helpers.ex:78 +msgid "Ether" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67 -msgid "No" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:211 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:164 +msgid "Example Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:85 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:128 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:99 +msgid "Execute" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/block/overview.html.eex:74 #: lib/block_scout_web/templates/transaction/overview.html.eex:79 msgid "Nonce" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:36 -#: lib/block_scout_web/templates/transaction/_tile.html.eex:68 -msgid "OUT" +#: lib/block_scout_web/templates/address_contract/index.html.eex:120 +msgid "External libraries" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:30 -msgid "Optimization enabled" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32 +msgid "Failed to decode input data." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:18 -msgid "Owner Address" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:35 +msgid "Failed to decode log data." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:19 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:26 -msgid "POST" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:24 +msgid "Favorites" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:33 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:40 -msgid "Parameters" +#: lib/block_scout_web/templates/address/_balance_card.html.eex:29 +msgid "Fetching tokens..." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:55 -msgid "Parent Hash" +#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:16 +msgid "For any existing contracts in the database, insert all ABI entries into the contract_methods table. Use this in case you have verified smart contracts before early March 2019 and you want other contracts with the same functions to show those ABI's as candidate matches." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:59 -#: lib/block_scout_web/views/transaction_view.ex:183 -#: lib/block_scout_web/views/transaction_view.ex:217 -msgid "Pending" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:41 +msgid "Forked Blocks (Reorgs)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:4 -msgid "Pending Transactions" +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:40 +#: lib/block_scout_web/views/address_internal_transaction_view.ex:7 +#: lib/block_scout_web/views/address_transaction_view.ex:7 +msgid "From" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:96 -msgid "Position %{index}" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:18 +msgid "GET" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:24 -#: lib/block_scout_web/templates/layout/app.html.eex:61 -msgid "Price" +#: lib/block_scout_web/templates/block/overview.html.eex:85 +msgid "Position %{index}" 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/tokens/overview/_details.html.eex:36 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:105 -msgid "QR Code" +#: lib/block_scout_web/templates/transaction/overview.html.eex:227 +msgid "Gas" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:22 -msgid "Query" +#: lib/block_scout_web/templates/block/overview.html.eex:13 +msgid "Genesis Block" 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:309 -#: lib/block_scout_web/views/tokens/overview_view.ex:37 -msgid "Read Contract" +#: lib/block_scout_web/templates/layout/_footer.html.eex:19 +msgid "Github" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:155 -msgid "Request URL" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:85 +msgid "GraphQL" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250 -msgid "Reset" +#: lib/block_scout_web/views/block_view.ex:20 +#: lib/block_scout_web/views/wei_helpers.ex:77 +msgid "Gwei" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:173 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:134 -msgid "Response Body" +#: lib/block_scout_web/templates/block/overview.html.eex:37 +msgid "Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:185 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:147 -msgid "Responses" +#: lib/block_scout_web/templates/transaction/overview.html.eex:115 +#: lib/block_scout_web/templates/transaction/overview.html.eex:119 +msgid "Hex (Default)" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:14 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:127 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:144 -msgid "Search" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:11 +msgid "However, in general, the" msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:30 -msgid "Search tokens" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18 +msgid "IMPORTANT: This information is a best guess based on similar functions from other verified contracts." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:163 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:124 -msgid "Server Response" +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:38 +#: lib/block_scout_web/templates/transaction/_tile.html.eex:72 +msgid "IN" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:34 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:37 -msgid "Show QR Code" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:26 +msgid "If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information." msgstr "" #, elixir-format @@ -838,7 +964,7 @@ msgid "Top Accounts - %{subnetwork} Explorer" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:79 +#: lib/block_scout_web/templates/block/overview.html.eex:68 msgid "Total Difficulty" msgstr "" @@ -854,207 +980,116 @@ msgid "Transaction" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_metatags.html.eex:3 -msgid "Transaction %{transaction} - %{subnetwork} Explorer" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:12 +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/transaction/_metatags.html.eex:11 -msgid "Transaction %{transaction}, %{subnetwork} %{transaction}" +#: lib/block_scout_web/templates/address/overview.html.eex:79 +msgid "Incoming Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:11 -msgid "Transaction Details" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:55 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:108 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:111 +msgid "Indexed?" 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:108 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:50 -#: lib/block_scout_web/views/address_view.ex:305 -msgid "Transactions" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address/_tile.html.eex:31 -msgid "Transactions sent" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:61 -msgid "Transfers" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:40 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:47 -msgid "Try it out" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:22 -msgid "Twitter" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:92 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:38 -msgid "Uncles" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:6 -msgid "Unique Token" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:231 -msgid "Used" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:54 -msgid "Validated" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/index.html.eex:4 -msgid "Validated Transactions" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address/_tile.html.eex:35 -msgid "Validations" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:179 -#: lib/block_scout_web/templates/transaction/overview.html.eex:209 -msgid "Value" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:11 -#: lib/block_scout_web/templates/address_contract/index.html.eex:16 -msgid "Verify & Publish" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249 -msgid "Verify & publish" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:55 -msgid "View Contract" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_tile.html.eex:53 -msgid "View Less Transfers" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_tile.html.eex:52 -msgid "View More Transfers" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address/_metatags.html.eex:9 -msgid "View the account balance, transactions, and other data for %{address} on the %{network}" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/block/_metatags.html.eex:10 -msgid "View the transactions, token transfers, and uncles for block number %{block_number}" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_metatags.html.eex:10 -msgid "View transaction %{transaction} on %{subnetwork}" +#: lib/block_scout_web/templates/layout/app.html.eex:58 +msgid "Indexing Tokens" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:49 -msgid "WEI" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:3 +msgid "Input" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:72 -msgid "Wallet addresses" +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:6 +msgid "Internal Transaction" msgstr "" #, elixir-format -#: lib/block_scout_web/views/wei_helpers.ex:76 -msgid "Wei" +#: 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:306 +#: lib/block_scout_web/views/transaction_view.ex:314 +msgid "Internal Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72 -msgid "Yes" +#: lib/block_scout_web/templates/transaction/invalid.html.eex:6 +msgid "Invalid Transaction Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:112 -msgid "at" +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16 +#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:17 +#: lib/block_scout_web/views/tokens/overview_view.ex:38 +msgid "Inventory" msgstr "" #, elixir-format -#: lib/block_scout_web/views/address_contract_view.ex:23 -msgid "false" +#: lib/block_scout_web/templates/transaction/not_found.html.eex:16 +msgid "It could still be in the TX Pool of a different node, waiting to be broadcasted." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:69 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:81 -#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:70 -msgid "required" +#: lib/block_scout_web/templates/address/overview.html.eex:89 +msgid "Last Balance Update: Block #" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:59 -#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:70 -msgid "string" +#: lib/block_scout_web/templates/layout/app.html.eex:59 +msgid "Less than" msgstr "" #, elixir-format -#: lib/block_scout_web/views/address_contract_view.ex:22 -msgid "true" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221 +msgid "Library Address" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:21 -msgid "Call" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211 +msgid "Library Name" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:25 -msgid "Create" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:24 +msgid "License Expires" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:23 -msgid "Delegate Call" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:10 +msgid "License ID" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:27 -msgid "Self-Destruct" +#: lib/block_scout_web/templates/transaction/overview.html.eex:237 +msgid "Limit" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:63 -msgid "Decimals" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:22 +#: lib/block_scout_web/templates/chain/show.html.eex:13 +msgid "Loading chart" msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_read_contract/index.html.eex:14 -#: lib/block_scout_web/templates/chain/show.html.eex:99 #: lib/block_scout_web/templates/tokens/read_contract/index.html.eex:21 msgid "Loading..." msgstr "" @@ -1065,73 +1100,45 @@ msgid "Loading...." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:81 -msgid "APIs" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:85 -msgid "GraphQL" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:90 -msgid "RPC" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/api_docs/index.html.eex:6 -msgid "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:109 -msgid "Raw Input" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/views/block_transaction_view.ex:15 -msgid "Block not found, please try again later." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/views/block_transaction_view.ex:7 -msgid "Easy Cowboy! This block does not exist yet!" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/views/block_transaction_view.ex:11 -msgid "This block has not been processed yet." +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:103 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:106 +msgid "Log Data" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/invalid.html.eex:6 -msgid "Invalid Transaction Hash" +#: 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:312 +#: lib/block_scout_web/views/transaction_view.ex:315 +msgid "Logs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/invalid.html.eex:8 -msgid "is not a valid transaction hash" +#: lib/block_scout_web/templates/layout/_footer.html.eex:44 +msgid "Main Networks" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:22 -msgid "Call Code" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22 +msgid "Mainnet" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:24 -msgid "Static Call" +#: lib/block_scout_web/templates/chain/show.html.eex:31 +#: lib/block_scout_web/templates/layout/app.html.eex:60 +#: lib/block_scout_web/views/address_view.ex:121 +#: lib/block_scout_web/views/address_view.ex:121 +msgid "Market Cap" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:37 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:90 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:32 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:40 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:93 -msgid "Decoded" +#: lib/block_scout_web/views/transaction_view.ex:169 +#: lib/block_scout_web/views/transaction_view.ex:169 +msgid "Max of" msgstr "" #, elixir-format @@ -1140,706 +1147,697 @@ msgid "Method Id" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:2 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16 -msgid "Transaction Inputs" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 -msgid "Verify the contract " -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 -msgid "here" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32 -msgid "Failed to decode input data." -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:49 -msgid "Error rendering value" +#: lib/block_scout_web/views/block_view.ex:56 +msgid "Miner Reward" msgstr "" -"" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34 -#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 -#: lib/block_scout_web/templates/address_logs/index.html.eex:21 -#: lib/block_scout_web/templates/address_token/index.html.eex:13 -#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:59 -#: lib/block_scout_web/templates/address_validation/index.html.eex:22 -#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 -#: lib/block_scout_web/templates/chain/show.html.eex:91 -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:19 -#: lib/block_scout_web/templates/tokens/holder/index.html.eex:21 -#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:21 -#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:20 -#: lib/block_scout_web/templates/transaction/index.html.eex:20 -#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:11 -#: lib/block_scout_web/templates/transaction_log/index.html.eex:13 -#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:12 -msgid "Something went wrong, click to reload." +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:223 +msgid "Model" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_validation/index.html.eex:18 -msgid "There are no blocks validated by this address." +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 +msgid "Module" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/index.html.eex:26 -msgid "There are no transactions." +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:10 +msgid "More internal transactions have come in" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:14 -msgid "Balances" +#: lib/block_scout_web/templates/chain/show.html.eex:148 +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:10 +#: lib/block_scout_web/templates/transaction/index.html.eex:10 +msgid "More transactions have come in" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/_coin_balances.html.eex:8 -msgid "Block" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:63 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:74 +msgid "Must be set to:" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_tabs.html.eex:20 -#: lib/block_scout_web/views/address_view.ex:310 -msgid "Coin Balance History" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:106 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:59 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:19 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:56 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:109 +msgid "Name" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:22 -#: lib/block_scout_web/templates/chain/show.html.eex:13 -msgid "Loading chart" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:9 +msgid "New Smart Contract Verification" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:39 -msgid "There is no coin history for this address." +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67 +msgid "No" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:25 -#: lib/block_scout_web/templates/chain/show.html.eex:16 -msgid "There was a problem loading the chart." +#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:36 +#: lib/block_scout_web/templates/transaction/_tile.html.eex:68 +msgid "OUT" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/pending_transaction/index.html.eex:23 -msgid "There are no pending transactions." +#: lib/block_scout_web/templates/address_contract/index.html.eex:30 +msgid "Optimization enabled" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/index.html.eex:18 -msgid "There are no blocks." +#: lib/block_scout_web/templates/address_contract/index.html.eex:39 +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83 +msgid "Optimization runs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:24 -msgid "License Expires" +#: lib/block_scout_web/templates/layout/_footer.html.eex:68 +msgid "Other Explorers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:10 -msgid "License ID" +#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:18 +msgid "Owner Address" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:48 -msgid "Show Validator Info" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:19 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:26 +msgid "POST" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:30 -msgid "Validator Creation Date" +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 +msgid "Page" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:5 -msgid "Validator Data" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:33 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:40 +msgid "Parameters" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:52 -msgid "Validator Info" +#: lib/block_scout_web/templates/block/overview.html.eex:44 +msgid "Parent Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:155 -msgid "Block Rewards" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:59 +#: lib/block_scout_web/views/transaction_view.ex:183 +#: lib/block_scout_web/views/transaction_view.ex:217 +msgid "Pending" msgstr "" #, elixir-format -#: lib/block_scout_web/views/block_view.ex:60 -msgid "Emission Reward" +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:4 +msgid "Pending Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/views/block_view.ex:56 -msgid "Miner Reward" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:17 +msgid "Potential matches from our contract method database:" msgstr "" #, elixir-format -#: lib/block_scout_web/views/block_view.ex:64 -msgid "Uncle Reward" +#: lib/block_scout_web/templates/chain/show.html.eex:24 +#: lib/block_scout_web/templates/layout/app.html.eex:61 +msgid "Price" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18 -msgid "IMPORTANT: This information is a best guess based on similar functions from other verified contracts." +#: 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/tokens/overview/_details.html.eex:36 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:105 +msgid "QR Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:17 -msgid "Potential matches from our contract method database:" +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:22 +msgid "Query" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:19 -msgid "To have guaranteed accuracy, use the link above to verify the contract's source code." +#: lib/block_scout_web/templates/layout/_topnav.html.eex:90 +msgid "RPC" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:6 -#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:8 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:6 -msgid "To see accurate decoded input data, the contract must be verified." +#: lib/block_scout_web/templates/transaction/overview.html.eex:109 +msgid "Raw Input" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:5 -msgid "Emission Contract" +#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24 +#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7 +#: lib/block_scout_web/views/transaction_view.ex:316 +msgid "Raw Trace" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:117 -msgid "Something went wrong, click to retry." +#: 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:309 +#: lib/block_scout_web/views/tokens/overview_view.ex:37 +msgid "Read Contract" 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." +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:11 +msgid "Records" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:36 -msgid "Chat" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:155 +msgid "Request URL" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:35 -msgid "Contribute" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250 +msgid "Reset" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:44 -msgid "Main Networks" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:173 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:134 +msgid "Response Body" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:68 -msgid "Other Explorers" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:185 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:147 +msgid "Responses" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:34 -msgid "Submit an Issue" +#: lib/block_scout_web/templates/block/_tile.html.eex:47 +#: lib/block_scout_web/templates/chain/_block.html.eex:23 +#: lib/block_scout_web/views/internal_transaction_view.ex:28 +msgid "Reward" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:57 -msgid "Test Networks" +#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:21 +msgid "Run" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:83 -msgid "Version" +#: lib/block_scout_web/templates/address_logs/index.html.eex:14 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:127 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:144 +msgid "Search" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_footer.html.eex:37 -msgid "Support" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:121 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:125 +msgid "Search by address, token symbol name, transaction hash, or block number" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:77 -msgid "Copy ABI" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:18 +msgid "Search network" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:93 -msgid "Copy Contract Creation Code" +#: +#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:30 +msgid "Search tokens" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:65 -msgid "Copy Source Code" +#: lib/block_scout_web/views/internal_transaction_view.ex:27 +msgid "Self-Destruct" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/overview.html.eex:17 -msgid "Genesis Block" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:163 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:124 +msgid "Server Response" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118 -msgid "Contract Libraries" +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:5 +msgid "Show" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:89 -msgid "Last Balance Update: Block #" +#: lib/block_scout_web/templates/address/overview.html.eex:34 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:37 +msgid "Show QR Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:84 -msgid "Transactions Sent" +#: lib/block_scout_web/templates/address/overview.html.eex:48 +msgid "Show Validator Info" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:101 -msgid "Transaction Speed" +#: lib/block_scout_web/templates/block/overview.html.eex:146 +msgid "Block Rewards" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:115 -#: lib/block_scout_web/templates/transaction/overview.html.eex:119 -msgid "Hex (Default)" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:34 +#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 +#: lib/block_scout_web/templates/address_logs/index.html.eex:21 +#: lib/block_scout_web/templates/address_token/index.html.eex:13 +#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:20 +#: lib/block_scout_web/templates/address_transaction/index.html.eex:59 +#: lib/block_scout_web/templates/address_validation/index.html.eex:22 +#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 +#: lib/block_scout_web/templates/chain/show.html.eex:91 +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:19 +#: lib/block_scout_web/templates/tokens/holder/index.html.eex:21 +#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:21 +#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:20 +#: lib/block_scout_web/templates/transaction/index.html.eex:20 +#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/index.html.eex:13 +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:12 +msgid "Something went wrong, click to reload." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:122 -msgid "UTF-8" +#: lib/block_scout_web/templates/chain/show.html.eex:154 +msgid "Something went wrong, click to retry." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:16 -msgid "For any existing contracts in the database, insert all ABI entries into the contract_methods table. Use this in case you have verified smart contracts before early March 2019 and you want other contracts with the same functions to show those ABI's as candidate matches." +#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 +msgid "Sorry, We are unable to locate this transaction Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:21 -msgid "Run" +#: lib/block_scout_web/views/internal_transaction_view.ex:24 +msgid "Static Call" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:75 -msgid ">=" +#: lib/block_scout_web/templates/layout/_footer.html.eex:34 +msgid "Submit an Issue" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:79 -msgid "Incoming Transactions" +#: lib/block_scout_web/templates/layout/_footer.html.eex:37 +msgid "Support" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:120 -msgid "Error: Could not determine contract creator." +#: lib/block_scout_web/templates/layout/_footer.html.eex:57 +msgid "Test Networks" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:121 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:125 -msgid "Search by address, token symbol name, transaction hash, or block number" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23 +msgid "Testnet" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:45 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:51 -msgid "EVM Version" +#: lib/block_scout_web/templates/address_validation/index.html.eex:18 +msgid "There are no blocks validated by this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:17 -msgid "Copy Decompiled Contract Code" +#: lib/block_scout_web/templates/block/index.html.eex:18 +msgid "There are no blocks." msgstr "" #, elixir-format -#: lib/block_scout_web/views/address_view.ex:308 -msgid "Decompiled Code" +#: lib/block_scout_web/templates/address_logs/index.html.eex:26 +msgid "There are no logs for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/_tabs.html.eex:52 -msgid "Decompiled code" +#: lib/block_scout_web/templates/pending_transaction/index.html.eex:23 +msgid "There are no pending transactions." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:15 -msgid "Decompiled contract code" +#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:17 +msgid "There are no token transfers for this transaction" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:8 -msgid "Decompiler version" +#: lib/block_scout_web/templates/transaction/index.html.eex:26 +msgid "There are no transactions." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:39 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:83 -msgid "Optimization runs" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:39 +msgid "There is no coin history for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/index.html.eex:4 -msgid "API Documentation" +#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:27 +msgid "There is no decompilded contracts for this address." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:86 -msgid "View All Blocks" +#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:25 +#: lib/block_scout_web/templates/chain/show.html.eex:16 +msgid "There was a problem loading the chart." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:107 -msgid "View All Transactions" +#: lib/block_scout_web/templates/api_docs/index.html.eex:6 +msgid "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:227 -msgid "Gas" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:7 +msgid "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24 -#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7 -#: lib/block_scout_web/views/transaction_view.ex:316 -msgid "Raw Trace" +#: lib/block_scout_web/views/block_transaction_view.ex:11 +msgid "This block has not been processed yet." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:64 -msgid "Total blocks" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:10 +msgid "This is useful to allow sending requests to blockscout without having to change anything about the request." msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 -msgid "Page" +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:19 +msgid "To have guaranteed accuracy, use the link above to verify the contract's source code." msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:11 -msgid "Records" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:6 +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:8 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:6 +msgid "To see accurate decoded input data, the contract must be verified." msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:5 -msgid "Show" +#: lib/block_scout_web/templates/address_logs/index.html.eex:12 +msgid "Topic" msgstr "" #, elixir-format -#: -#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 -msgid "of" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:145 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:149 +msgid "Topics" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block_transaction/404.html.eex:7 -msgid "Block Details" +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75 +msgid "Total Supply" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:105 -msgid "Contract Byte Code" +#: lib/block_scout_web/templates/chain/show.html.eex:64 +msgid "Total blocks" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:91 -msgid "Contract Creation Code" +#: lib/block_scout_web/templates/transaction/_metatags.html.eex:3 +msgid "Transaction %{transaction} - %{subnetwork} Explorer" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:97 -msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified." +#: lib/block_scout_web/templates/transaction/_metatags.html.eex:11 +msgid "Transaction %{transaction}, %{subnetwork} %{transaction}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:107 -msgid "Copy Contract Byte Code" +#: lib/block_scout_web/templates/transaction/overview.html.eex:11 +msgid "Transaction Details" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:98 -msgid "Displaying the init data provided of the creating transaction." +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:2 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16 +msgid "Transaction Inputs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:26 -msgid "There are no logs for this address." +#: lib/block_scout_web/templates/transaction/overview.html.eex:101 +msgid "Transaction Speed" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:12 -msgid "If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page." +#: 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:305 +msgid "Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:30 -msgid "Back Home" +#: lib/block_scout_web/templates/address/overview.html.eex:84 +msgid "Transactions Sent" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:22 -msgid "During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it." +#: lib/block_scout_web/templates/address/_tile.html.eex:31 +msgid "Transactions sent" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:26 -msgid "If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information." +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:61 +msgid "Transfers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:16 -msgid "It could still be in the TX Pool of a different node, waiting to be broadcasted." +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:40 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:47 +msgid "Try it out" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/not_found.html.eex:7 -msgid "Sorry, We are unable to locate this transaction Hash" +#: lib/block_scout_web/templates/layout/_footer.html.eex:22 +msgid "Twitter" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:17 -msgid "There are no token transfers for this transaction" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:54 +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:107 +#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:20 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:57 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:110 +msgid "Type" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/index.html.eex:12 -msgid "Topic" +#: lib/block_scout_web/templates/transaction/overview.html.eex:122 +msgid "UTF-8" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104 -msgid "ABI-encoded Constructor Arguments (if required by the contract)" +#: lib/block_scout_web/views/block_view.ex:64 +msgid "Uncle Reward" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:93 -msgid "Enter the Solidity Contract Code" +#: lib/block_scout_web/templates/block/overview.html.eex:81 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:38 +msgid "Uncles" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221 -msgid "Library Address" +#: lib/block_scout_web/templates/tokens/inventory/_token.html.eex:6 +msgid "Unique Token" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189 -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211 -msgid "Library Name" +#: lib/block_scout_web/templates/layout/_network_selector.html.eex:12 +msgid "Use the search box to find a hosted network, or select from the list of available networks below." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:9 -msgid "New Smart Contract Verification" +#: lib/block_scout_web/templates/transaction/overview.html.eex:231 +msgid "Used" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:192 -msgid " Token Transfer" +#: lib/block_scout_web/templates/layout/_topnav.html.eex:54 +msgid "Validated" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:14 -msgid " is recommended." +#: lib/block_scout_web/templates/transaction/index.html.eex:4 +msgid "Validated Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15 -msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences." +#: lib/block_scout_web/templates/address/_tile.html.eex:35 +msgid "Validations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:4 -msgid "ETH RPC API Documentation" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:30 +msgid "Validator Creation Date" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:95 -msgid "Eth RPC" +#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:5 +msgid "Validator Data" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:11 -msgid "However, in general, the" +#: lib/block_scout_web/templates/address/overview.html.eex:52 +msgid "Validator Info" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:27 -msgid "There is no decompilded contracts for this address." +#: lib/block_scout_web/templates/transaction/overview.html.eex:179 +#: lib/block_scout_web/templates/transaction/overview.html.eex:209 +msgid "Value" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:7 -msgid "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found " +#: lib/block_scout_web/templates/address_contract/index.html.eex:11 +#: lib/block_scout_web/templates/address_contract/index.html.eex:16 +msgid "Verify & Publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:10 -msgid "This is useful to allow sending requests to blockscout without having to change anything about the request." +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249 +msgid "Verify & publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:12 -msgid "custom RPC" +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 +msgid "Verify the contract " msgstr "" #, elixir-format -#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:9 -msgid "here." +#: lib/block_scout_web/templates/layout/_footer.html.eex:83 +msgid "Version" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_token/index.html.eex:28 -#: lib/block_scout_web/templates/address_transaction/index.html.eex:74 -msgid "CSV" +#: lib/block_scout_web/templates/chain/show.html.eex:86 +msgid "View All Blocks" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11 -msgid "Change Network" +#: lib/block_scout_web/templates/chain/show.html.eex:144 +msgid "View All Transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:84 -msgid "ERC-20 " +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:55 +msgid "View Contract" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:85 -msgid "ERC-721 " +#: lib/block_scout_web/templates/transaction/_tile.html.eex:53 +msgid "View Less Transfers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:120 -msgid "External libraries" +#: lib/block_scout_web/templates/transaction/_tile.html.eex:52 +msgid "View More Transfers" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:24 -msgid "Favorites" +#: lib/block_scout_web/templates/address/_metatags.html.eex:9 +msgid "View the account balance, transactions, and other data for %{address} on the %{network}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22 -msgid "Mainnet" +#: lib/block_scout_web/templates/block/_metatags.html.eex:10 +msgid "View the transactions, token transfers, and uncles for block number %{block_number}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:18 -msgid "Search network" +#: lib/block_scout_web/templates/transaction/_metatags.html.eex:10 +msgid "View transaction %{transaction} on %{subnetwork}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23 -msgid "Testnet" +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:49 +msgid "WEI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_network_selector.html.eex:12 -msgid "Use the search box to find a hosted network, or select from the list of available networks below." +#: lib/block_scout_web/templates/chain/show.html.eex:72 +msgid "Wallet addresses" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:4 -msgid "Connection Lost" +#: lib/block_scout_web/views/wei_helpers.ex:76 +msgid "Wei" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_contract/index.html.eex:53 -msgid "Constructor Arguments" +#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72 +msgid "Yes" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:66 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:119 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:31 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:69 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:122 -msgid "Copy Value" +#: lib/block_scout_web/templates/address/overview.html.eex:112 +msgid "at" msgstr "" #, elixir-format -#: lib/block_scout_web/views/internal_transaction_view.ex:26 -msgid "Create2" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:12 +msgid "custom RPC" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:56 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:109 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:175 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:21 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:59 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:112 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:179 -msgid "Data" +#: lib/block_scout_web/views/address_contract_view.ex:23 +msgid "false" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:35 -msgid "Failed to decode log data." +#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9 +#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11 +#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9 +msgid "here" 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 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:111 -msgid "Indexed?" +#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:9 +msgid "here." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:103 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:106 -msgid "Log Data" +#: lib/block_scout_web/templates/transaction/invalid.html.eex:8 +msgid "is not a valid transaction hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/block/_tile.html.eex:47 -#: lib/block_scout_web/templates/chain/_block.html.eex:23 -#: lib/block_scout_web/views/internal_transaction_view.ex:28 -msgid "Reward" +#: +#: lib/block_scout_web/templates/common_components/_pagination_container.html.eex:39 +msgid "of" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:145 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:149 -msgid "Topics" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:58 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:69 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:81 +#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:70 +msgid "required" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:54 -#: lib/block_scout_web/templates/address_logs/_logs.html.eex:107 -#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:20 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:57 -#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:110 -msgid "Type" +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:59 +#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:70 +msgid "string" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75 -msgid "Total Supply" +#: lib/block_scout_web/views/address_contract_view.ex:22 +msgid "true" msgstr "" diff --git a/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs index 3fbd1713bb..37ce57f508 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs @@ -1,6 +1,6 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do use BlockScoutWeb.ConnCase - alias Explorer.Factory + alias Explorer.{Chain, Factory} describe "listcontracts" do setup do @@ -450,7 +450,9 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do expected_result = [ %{ "Address" => to_string(contract.address_hash), - "SourceCode" => contract.contract_source_code, + "SourceCode" => + "/**\n* Submitted for verification at blockscout.com on #{contract.inserted_at}\n*/\n" <> + contract.contract_source_code, "ABI" => Jason.encode!(contract.abi), "ContractName" => contract.name, "CompilerVersion" => contract.compiler_version, @@ -496,9 +498,13 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do |> get("/api", params) |> json_response(200) + verified_contract = Chain.address_hash_to_smart_contract(contract_address.hash) + expected_result = %{ "Address" => to_string(contract_address.hash), - "SourceCode" => contract_code_info.source_code, + "SourceCode" => + "/**\n* Submitted for verification at blockscout.com on #{verified_contract.inserted_at}\n*/\n" <> + contract_code_info.source_code, "ABI" => Jason.encode!(contract_code_info.abi), "ContractName" => contract_code_info.name, "CompilerVersion" => contract_code_info.version, @@ -563,8 +569,14 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do result = response["result"] + verified_contract = Chain.address_hash_to_smart_contract(contract_address.hash) + assert result["Address"] == to_string(contract_address.hash) - assert result["SourceCode"] == contract_source_code + + assert result["SourceCode"] == + "/**\n* Submitted for verification at blockscout.com on #{verified_contract.inserted_at}\n*/\n" <> + contract_source_code + assert result["ContractName"] == name assert result["DecompiledSourceCode"] == "Contract source code not decompiled." assert result["DecompilerVersion"] == "" diff --git a/apps/block_scout_web/test/block_scout_web/controllers/block_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/block_controller_test.exs index e8c4af7de8..6c0bfabfa0 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/block_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/block_controller_test.exs @@ -3,8 +3,8 @@ defmodule BlockScoutWeb.BlockControllerTest do alias Explorer.Chain.Block setup do - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, :blocks}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, :blocks}) + Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) + Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) :ok end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs index 00a53689c8..fa82bb5bab 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs @@ -9,8 +9,8 @@ defmodule BlockScoutWeb.ChainControllerTest do alias Explorer.Counters.AddressesWithBalanceCounter setup do - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, :blocks}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, :blocks}) + Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) + Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) start_supervised!(AddressesWithBalanceCounter) AddressesWithBalanceCounter.consolidate() diff --git a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs index 7f42b4cbcc..b5f17afc49 100644 --- a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs +++ b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs @@ -73,7 +73,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do session |> AddressPage.visit_page(address) - |> assert_text(AddressPage.balance(), "0.0000000000000005 POA") + |> assert_text(AddressPage.balance(), "0.0000000000000005 Ether") end describe "viewing contract creator" do diff --git a/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs b/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs index a32e4f5da3..27b4dbb329 100644 --- a/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs +++ b/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs @@ -10,8 +10,8 @@ defmodule BlockScoutWeb.ViewingChainTest do alias Explorer.Counters.AddressesWithBalanceCounter setup do - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, :blocks}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, :blocks}) + Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) + Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) Enum.map(401..404, &insert(:block, number: &1)) diff --git a/apps/block_scout_web/test/block_scout_web/views/address_coin_balance_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_coin_balance_view_test.exs index e7b56ff560..348dc96f6c 100644 --- a/apps/block_scout_web/test/block_scout_web/views/address_coin_balance_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/address_coin_balance_view_test.exs @@ -8,13 +8,13 @@ defmodule BlockScoutWeb.AddressCoinBalanceViewTest do test "format the wei value in ether" do wei = Wei.from(Decimal.new(1_340_000_000), :gwei) - assert AddressCoinBalanceView.format(wei) == "1.34 POA" + assert AddressCoinBalanceView.format(wei) == "1.34 Ether" end test "format negative values" do wei = Wei.from(Decimal.new(-1_340_000_000), :gwei) - assert AddressCoinBalanceView.format(wei) == "-1.34 POA" + assert AddressCoinBalanceView.format(wei) == "-1.34 Ether" end end @@ -50,13 +50,13 @@ defmodule BlockScoutWeb.AddressCoinBalanceViewTest do test "format positive values" do value = Decimal.new(1_340_000_000_000_000_000) - assert AddressCoinBalanceView.format_delta(value) == "1.34 POA" + assert AddressCoinBalanceView.format_delta(value) == "1.34 Ether" end test "format negative values" do value = Decimal.new(-1_340_000_000_000_000_000) - assert AddressCoinBalanceView.format_delta(value) == "1.34 POA" + assert AddressCoinBalanceView.format_delta(value) == "1.34 Ether" end end end diff --git a/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs index 4bcb1eb2bf..9f0314fb88 100644 --- a/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs @@ -38,22 +38,25 @@ defmodule BlockScoutWeb.AddressContractViewTest do result = AddressContractView.contract_lines_with_index(code) assert result == [ - {"pragma solidity >=0.4.22 <0.6.0;", " 1"}, - {"", " 2"}, - {"struct Proposal {", " 3"}, - {" uint voteCount;", " 4"}, - {"}", " 5"}, - {"", " 6"}, - {"address chairperson;", " 7"}, - {"mapping(address => Voter) voters;", " 8"}, - {"Proposal[] proposals;", " 9"}, - {"", "10"}, - {"constructor(uint8 _numProposals) public {", "11"}, - {" chairperson = msg.sender;", "12"}, - {" voters[chairperson].weight = 1;", "13"}, - {" proposals.length = _numProposals;", "14"}, - {"}", "15"}, - {"", "16"} + {"/**", " 1"}, + {"* Submitted for verification at blockscout.com on ", " 2"}, + {"*/", " 3"}, + {"pragma solidity >=0.4.22 <0.6.0;", " 4"}, + {"", " 5"}, + {"struct Proposal {", " 6"}, + {" uint voteCount;", " 7"}, + {"}", " 8"}, + {"", " 9"}, + {"address chairperson;", "10"}, + {"mapping(address => Voter) voters;", "11"}, + {"Proposal[] proposals;", "12"}, + {"", "13"}, + {"constructor(uint8 _numProposals) public {", "14"}, + {" chairperson = msg.sender;", "15"}, + {" voters[chairperson].weight = 1;", "16"}, + {" proposals.length = _numProposals;", "17"}, + {"}", "18"}, + {"", "19"} ] end @@ -66,7 +69,17 @@ defmodule BlockScoutWeb.AddressContractViewTest do test "returns a list of tuples and the first element is just a line from the original string" do result = AddressContractView.contract_lines_with_index("a\nb\nc\nd\ne") - assert Enum.map(result, fn {line, _number} -> line end) == ["a", "b", "c", "d", "e"] + + assert Enum.map(result, fn {line, _number} -> line end) == [ + "/**", + "* Submitted for verification at blockscout.com on ", + "*/", + "a", + "b", + "c", + "d", + "e" + ] end end end diff --git a/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs index 7583aeaa4f..31922b4486 100644 --- a/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs @@ -3,32 +3,6 @@ defmodule BlockScoutWeb.ApiDocsViewTest do alias BlockScoutWeb.APIDocsView - describe "blockscout_url/0" do - setup do - original = Application.get_env(:block_scout_web, BlockScoutWeb.Endpoint) - - on_exit(fn -> Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, original) end) - - :ok - end - - test "returns url with scheme and host without port" do - Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, - url: [scheme: "https", host: "blockscout.com", port: 9999, path: "/"] - ) - - assert APIDocsView.blockscout_url() == "https://blockscout.com/" - end - - test "returns url with scheme and host with path" do - Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, - url: [scheme: "https", host: "blockscout.com", port: 9999, path: "/chain/dog"] - ) - - assert APIDocsView.blockscout_url() == "https://blockscout.com/chain/dog" - end - end - describe "api_url/1" do setup do original = Application.get_env(:block_scout_web, BlockScoutWeb.Endpoint) @@ -53,6 +27,15 @@ defmodule BlockScoutWeb.ApiDocsViewTest do assert APIDocsView.api_url() == "https://blockscout.com/api" end + + test "localhost return with port" do + Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, + url: [scheme: "http", host: "localhost"], + http: [port: 9999] + ) + + assert APIDocsView.api_url() == "http://localhost:9999/api" + end end describe "eth_rpc_api_url/1" do @@ -79,5 +62,14 @@ defmodule BlockScoutWeb.ApiDocsViewTest do assert APIDocsView.eth_rpc_api_url() == "https://blockscout.com/api/eth_rpc" end + + test "localhost return with port" do + Application.put_env(:block_scout_web, BlockScoutWeb.Endpoint, + url: [scheme: "http", host: "localhost"], + http: [port: 9999] + ) + + assert APIDocsView.eth_rpc_api_url() == "http://localhost:9999/api/eth_rpc" + end end end diff --git a/apps/block_scout_web/test/block_scout_web/views/block_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/block_view_test.exs index a25922cd07..d707404628 100644 --- a/apps/block_scout_web/test/block_scout_web/views/block_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/block_view_test.exs @@ -91,7 +91,7 @@ defmodule BlockScoutWeb.BlockViewTest do block = Repo.preload(block, :rewards) - assert BlockView.combined_rewards_value(block) == "3.000042 POA" + assert BlockView.combined_rewards_value(block) == "3.000042 Ether" end end end diff --git a/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs index 69cca69f41..e8505b144e 100644 --- a/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs @@ -136,7 +136,7 @@ defmodule BlockScoutWeb.TransactionViewTest do gas_used: nil ) - expected_value = "Max of 0.009 POA" + expected_value = "Max of 0.009 Ether" assert expected_value == TransactionView.formatted_fee(transaction, denomination: :ether) end @@ -144,12 +144,9 @@ defmodule BlockScoutWeb.TransactionViewTest do {:ok, gas_price} = Wei.cast(3_000_000_000) transaction = build(:transaction, gas_price: gas_price, gas_used: Decimal.from_float(1_034_234.0)) - expected_value = "0.003102702 POA" + expected_value = "0.003102702 Ether" assert expected_value == TransactionView.formatted_fee(transaction, denomination: :ether) end - - test "with fee but no available exchange_rate" do - end end describe "formatted_status/1" do diff --git a/apps/explorer/config/config.exs b/apps/explorer/config/config.exs index 93298073e0..056c3a991c 100644 --- a/apps/explorer/config/config.exs +++ b/apps/explorer/config/config.exs @@ -27,12 +27,18 @@ config :explorer, Explorer.Counters.AverageBlockTime, enabled: true, period: average_block_period -config :explorer, Explorer.ChainSpec.GenesisData, enabled: false, chain_spec_path: System.get_env("CHAIN_SPEC_PATH") +config :explorer, Explorer.ChainSpec.GenesisData, + enabled: true, + chain_spec_path: System.get_env("CHAIN_SPEC_PATH"), + emission_format: System.get_env("EMISSION_FORMAT", "DEFAULT"), + rewards_contract_address: System.get_env("REWARDS_CONTRACT_ADDRESS", "0xeca443e8e1ab29971a45a9c57a6a9875701698a5") -config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: true +config :explorer, Explorer.Chain.Cache.BlockNumber, + enabled: true, + ttl_check_interval: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(1), else: false), + global_ttl: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(5)) -config :explorer, Explorer.ExchangeRates.Source.CoinMarketCap, - pages: String.to_integer(System.get_env("COINMARKETCAP_PAGES") || "10") +config :explorer, Explorer.ExchangeRates.Source.CoinGecko, coin_id: System.get_env("COIN_GECKO_ID", "poa-network") balances_update_interval = if System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL") do @@ -124,6 +130,14 @@ market_history_cache_period = config :explorer, Explorer.Market.MarketHistoryCache, period: market_history_cache_period +config :explorer, Explorer.Chain.Cache.Blocks, + ttl_check_interval: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(1), else: false), + global_ttl: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(5)) + +config :explorer, Explorer.Chain.Cache.Transactions, + ttl_check_interval: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(1), else: false), + global_ttl: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(5)) + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --git a/apps/explorer/lib/explorer/application.ex b/apps/explorer/lib/explorer/application.ex index c28469c340..7c55d28f76 100644 --- a/apps/explorer/lib/explorer/application.ex +++ b/apps/explorer/lib/explorer/application.ex @@ -42,10 +42,11 @@ defmodule Explorer.Application do Explorer.SmartContract.SolcDownloader, {Registry, keys: :duplicate, name: Registry.ChainEvents, id: Registry.ChainEvents}, {Admin.Recovery, [[], [name: Admin.Recovery]]}, - {TransactionCount, [[], []]}, - {BlockCount, []}, + TransactionCount, + BlockCount, Blocks, - con_cache_child_spec(NetVersion.cache_name()), + NetVersion, + BlockNumber, con_cache_child_spec(MarketHistoryCache.cache_name()), con_cache_child_spec(RSK.cache_name(), ttl_check_interval: :timer.minutes(1), global_ttl: :timer.minutes(30)), Transactions @@ -55,11 +56,7 @@ defmodule Explorer.Application do opts = [strategy: :one_for_one, name: Explorer.Supervisor] - res = Supervisor.start_link(children, opts) - - BlockNumber.setup() - - res + Supervisor.start_link(children, opts) end defp configurable_children do diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index b2c18e8a50..15f6644f25 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -230,9 +230,8 @@ defmodule Explorer.Chain do Reward.fetch_emission_rewards_tuples(address_hash, paging_options) end) - address_hash - |> address_to_transactions_without_rewards(paging_options, options) - |> Enum.concat(Task.await(rewards_task, :timer.seconds(20))) + [rewards_task | address_to_transactions_tasks(address_hash, options)] + |> wait_for_address_transactions() |> Enum.sort_by(fn item -> case item do {%Reward{} = emission_reward, _} -> @@ -242,32 +241,83 @@ defmodule Explorer.Chain do {-item.block_number, -item.index} end end) + |> Enum.dedup_by(fn item -> + case item do + {%Reward{} = emission_reward, _} -> + {emission_reward.block_hash, emission_reward.address_hash, emission_reward.address_type} + + transaction -> + transaction.hash + end + end) |> Enum.take(paging_options.page_size) else - address_to_transactions_without_rewards(address_hash, paging_options, options) + address_to_transactions_without_rewards(address_hash, options) end end - def address_to_transactions_without_rewards(address_hash, paging_options, options) do + def address_to_transactions_without_rewards(address_hash, options) do + paging_options = Keyword.get(options, :paging_options, @default_paging_options) + + address_hash + |> address_to_transactions_tasks(options) + |> wait_for_address_transactions() + |> Enum.sort_by(&{&1.block_number, &1.index}, &>=/2) + |> Enum.dedup_by(& &1.hash) + |> Enum.take(paging_options.page_size) + end + + defp address_to_transactions_tasks(address_hash, options) do + paging_options = Keyword.get(options, :paging_options, @default_paging_options) direction = Keyword.get(options, :direction) necessity_by_association = Keyword.get(options, :necessity_by_association, %{}) - transaction_hashes_from_token_transfers = - TokenTransfer.where_any_address_fields_match(direction, address_hash, paging_options) + base_query = + paging_options + |> fetch_transactions() + |> join_associations(necessity_by_association) + |> Transaction.preload_token_transfers(address_hash) + + direction_tasks = + base_query + |> Transaction.matching_address_queries_list(direction, address_hash) + |> Enum.map(fn query -> Task.async(fn -> Repo.all(query) end) end) - paging_options - |> fetch_transactions() - |> Transaction.where_transaction_matches(transaction_hashes_from_token_transfers, direction, address_hash) - |> join_associations(necessity_by_association) - |> Transaction.preload_token_transfers(address_hash) - |> Repo.all() + token_transfers_task = + Task.async(fn -> + transaction_hashes_from_token_transfers = + TokenTransfer.where_any_address_fields_match(direction, address_hash, paging_options) + + final_query = where(base_query, [t], t.hash in ^transaction_hashes_from_token_transfers) + + Repo.all(final_query) + end) + + [token_transfers_task | direction_tasks] + end + + defp wait_for_address_transactions(tasks) do + tasks + |> Task.yield_many(:timer.seconds(20)) + |> Enum.flat_map(fn {_task, res} -> + case res do + {:ok, result} -> + result + + {:exit, reason} -> + raise "Query fetching address transactions terminated: #{inspect(reason)}" + + nil -> + raise "Query fetching address transactions timed out." + end + end) end @spec address_to_logs(Hash.Address.t(), Keyword.t()) :: [Log.t()] def address_to_logs(address_hash, options \\ []) when is_list(options) do paging_options = Keyword.get(options, :paging_options) || %PagingOptions{page_size: 50} - {block_number, transaction_index, log_index} = paging_options.key || {BlockNumber.max_number(), 0, 0} + {block_number, transaction_index, log_index} = paging_options.key || {BlockNumber.get_max(), 0, 0} base_query = from(log in Log, @@ -1176,7 +1226,7 @@ defmodule Explorer.Chain do """ @spec indexed_ratio() :: Decimal.t() def indexed_ratio do - {min, max} = BlockNumber.min_and_max_numbers() + %{min: min, max: max} = BlockNumber.get_all() case {min, max} do {0, 0} -> @@ -1189,20 +1239,30 @@ defmodule Explorer.Chain do end end - @spec fetch_min_and_max_block_numbers() :: {non_neg_integer, non_neg_integer} - def fetch_min_and_max_block_numbers do + @spec fetch_min_block_number() :: non_neg_integer + def fetch_min_block_number do query = from(block in Block, - select: {min(block.number), max(block.number)}, - where: block.consensus == true + select: block.number, + where: block.consensus == true, + order_by: [asc: block.number], + limit: 1 ) - result = Repo.one!(query) + Repo.one(query) || 0 + end - case result do - {nil, nil} -> {0, 0} - _ -> result - end + @spec fetch_max_block_number() :: non_neg_integer + def fetch_max_block_number do + query = + from(block in Block, + select: block.number, + where: block.consensus == true, + order_by: [desc: block.number], + limit: 1 + ) + + Repo.one(query) || 0 end @spec fetch_count_consensus_block() :: non_neg_integer @@ -2195,7 +2255,7 @@ defmodule Explorer.Chain do """ @spec transaction_estimated_count() :: non_neg_integer() def transaction_estimated_count do - cached_value = TransactionCount.value() + cached_value = TransactionCount.get_count() if is_nil(cached_value) do %Postgrex.Result{rows: [[rows]]} = @@ -2214,7 +2274,7 @@ defmodule Explorer.Chain do """ @spec block_estimated_count() :: non_neg_integer() def block_estimated_count do - cached_value = BlockCount.count() + cached_value = BlockCount.get_count() if is_nil(cached_value) do %Postgrex.Result{rows: [[count]]} = Repo.query!("SELECT reltuples FROM pg_class WHERE relname = 'blocks';") @@ -2532,8 +2592,26 @@ defmodule Explorer.Chain do @spec address_hash_to_address_with_source_code(Hash.Address.t()) :: Address.t() | nil def address_hash_to_address_with_source_code(address_hash) do case Repo.get(Address, address_hash) do - nil -> nil - address -> Repo.preload(address, [:smart_contract, :decompiled_smart_contracts]) + nil -> + nil + + address -> + address_with_smart_contract = Repo.preload(address, [:smart_contract, :decompiled_smart_contracts]) + + if address_with_smart_contract.smart_contract do + formatted_code = + SmartContract.add_submitted_comment( + address_with_smart_contract.smart_contract.contract_source_code, + address_with_smart_contract.smart_contract.inserted_at + ) + + %{ + address_with_smart_contract + | smart_contract: %{address_with_smart_contract.smart_contract | contract_source_code: formatted_code} + } + else + address_with_smart_contract + end end end @@ -2717,7 +2795,7 @@ defmodule Explorer.Chain do end defp supply_module do - Application.get_env(:explorer, :supply, Explorer.Chain.Supply.CoinMarketCap) + Application.get_env(:explorer, :supply, Explorer.Chain.Supply.ExchangeRate) end @doc """ diff --git a/apps/explorer/lib/explorer/chain/address.ex b/apps/explorer/lib/explorer/chain/address.ex index 478c35deb1..96d4dc7ab4 100644 --- a/apps/explorer/lib/explorer/chain/address.ex +++ b/apps/explorer/lib/explorer/chain/address.ex @@ -170,7 +170,7 @@ defmodule Explorer.Chain.Address do end def rsk_checksum(hash) do - chain_id = NetVersion.version() + chain_id = NetVersion.get_version() string_hash = hash diff --git a/apps/explorer/lib/explorer/chain/address_transaction_csv_exporter.ex b/apps/explorer/lib/explorer/chain/address_transaction_csv_exporter.ex index 0196de3bc0..d608cc55e3 100644 --- a/apps/explorer/lib/explorer/chain/address_transaction_csv_exporter.ex +++ b/apps/explorer/lib/explorer/chain/address_transaction_csv_exporter.ex @@ -42,8 +42,9 @@ defmodule Explorer.Chain.AddressTransactionCsvExporter do end defp fetch_all_transactions(address_hash, paging_options, acc \\ []) do - transactions = - Chain.address_to_transactions_without_rewards(address_hash, paging_options, @necessity_by_association) + options = Keyword.put(@necessity_by_association, :paging_options, paging_options) + + transactions = Chain.address_to_transactions_without_rewards(address_hash, options) new_acc = transactions ++ acc diff --git a/apps/explorer/lib/explorer/chain/cache/block_count.ex b/apps/explorer/lib/explorer/chain/cache/block_count.ex index 8ba09cc86f..ef1e587dfe 100644 --- a/apps/explorer/lib/explorer/chain/cache/block_count.ex +++ b/apps/explorer/lib/explorer/chain/cache/block_count.ex @@ -5,143 +5,61 @@ defmodule Explorer.Chain.Cache.BlockCount do require Logger - use GenServer + @default_cache_period :timer.minutes(10) - alias Explorer.Chain - - # 10 minutes - @cache_period 1_000 * 60 * 10 - @key "count" - @default_value nil - @name __MODULE__ - - def start_link(params) do - name = params[:name] || @name - params_with_name = Keyword.put(params, :name, name) - - GenServer.start_link(__MODULE__, params_with_name, name: name) - end - - def init(params) do - cache_period = period_from_env_var() || params[:cache_period] || @cache_period - current_value = params[:default_value] || @default_value - name = params[:name] - - init_ets_table(name) - - {:ok, {{cache_period, current_value, name}, nil}} - end - - def count(process_name \\ __MODULE__) do - GenServer.call(process_name, :count) - end - - def handle_call(:count, _, {{cache_period, default_value, name}, task}) do - {count, task} = - case cached_values(name) do - nil -> - {default_value, update_cache(task, name)} - - {cached_value, timestamp} -> - task = - if current_time() - timestamp > cache_period do - update_cache(task, name) - end - - {cached_value, task} - end - - {:reply, count, {{cache_period, default_value, name}, task}} - end - - def update_cache(nil, name) do - async_update_cache(name) - end - - def update_cache(task, _) do - task - end + use Explorer.Chain.MapCache, + name: :block_count, + key: :count, + key: :async_task, + global_ttl: cache_period(), + ttl_check_interval: :timer.minutes(1), + callback: &async_task_on_deletion(&1) - def handle_cast({:update_cache, value}, {{cache_period, default_value, name}, _}) do - current_time = current_time() - tuple = {value, current_time} - - table_name = table_name(name) - - :ets.insert(table_name, {@key, tuple}) - - {:noreply, {{cache_period, default_value, name}, nil}} - end - - def handle_info({:DOWN, _, _, _, _}, {{cache_period, default_value, name}, _}) do - {:noreply, {{cache_period, default_value, name}, nil}} - end - - def handle_info(_, {{cache_period, default_value, name}, _}) do - {:noreply, {{cache_period, default_value, name}, nil}} - end - - # sobelow_skip ["DOS"] - defp table_name(name) do - name - |> Atom.to_string() - |> Macro.underscore() - |> String.to_atom() - end + alias Explorer.Chain - def async_update_cache(name) do - Task.async(fn -> - try do - result = Chain.fetch_count_consensus_block() + defp handle_fallback(:count) do + # This will get the task PID if one exists and launch a new task if not + # See next `handle_fallback` definition + get_async_task() - GenServer.cast(name, {:update_cache, result}) - rescue - e -> - Logger.debug([ - "Coudn't update block count test #{inspect(e)}" - ]) - end - end) + {:return, nil} end - defp init_ets_table(name) do - table_name = table_name(name) - - if :ets.whereis(table_name) == :undefined do - :ets.new(table_name, [ - :set, - :named_table, - :public, - write_concurrency: true - ]) - end - end + defp handle_fallback(:async_task) do + # If this gets called it means an async task was requested, but none exists + # so a new one needs to be launched + {:ok, task} = + Task.start(fn -> + try do + result = Chain.fetch_count_consensus_block() + + set_count(result) + rescue + e -> + Logger.debug([ + "Coudn't update block count test #{inspect(e)}" + ]) + end - defp cached_values(name) do - table_name = table_name(name) + set_async_task(nil) + end) - case :ets.lookup(table_name, @key) do - [{_, cached_values}] -> cached_values - _ -> nil - end + {:update, task} end - defp current_time do - utc_now = DateTime.utc_now() - - DateTime.to_unix(utc_now, :millisecond) - end + # By setting this as a `callback` an async task will be started each time the + # `count` expires (unless there is one already running) + defp async_task_on_deletion({:delete, _, :count}), do: get_async_task() - defp period_from_env_var do - case System.get_env("BLOCK_COUNT_CACHE_PERIOD") do - value when is_binary(value) -> - case Integer.parse(value) do - {integer, ""} -> integer * 1_000 - _ -> nil - end + defp async_task_on_deletion(_data), do: nil - _ -> - nil + defp cache_period do + "BLOCK_COUNT_CACHE_PERIOD" + |> System.get_env("") + |> Integer.parse() + |> case do + {integer, ""} -> :timer.seconds(integer) + _ -> @default_cache_period end end end diff --git a/apps/explorer/lib/explorer/chain/cache/block_number.ex b/apps/explorer/lib/explorer/chain/cache/block_number.ex index 5212117793..fb5f1b515a 100644 --- a/apps/explorer/lib/explorer/chain/cache/block_number.ex +++ b/apps/explorer/lib/explorer/chain/cache/block_number.ex @@ -3,89 +3,38 @@ defmodule Explorer.Chain.Cache.BlockNumber do Cache for max and min block numbers. """ - alias Explorer.Chain - - @tab :block_number_cache - @key "min_max" + @type value :: non_neg_integer() - @spec setup() :: :ok - def setup do - if :ets.whereis(@tab) == :undefined do - :ets.new(@tab, [ - :set, - :named_table, - :public, - write_concurrency: true - ]) - end + use Explorer.Chain.MapCache, + name: :block_number, + keys: [:min, :max], + ttl_check_interval: Application.get_env(:explorer, __MODULE__)[:ttl_check_interval], + global_ttl: Application.get_env(:explorer, __MODULE__)[:global_ttl] - update_cache() - - :ok - end + alias Explorer.Chain - def max_number do - value(:max) - end + defp handle_update(_key, nil, value), do: {:ok, value} - def min_number do - value(:min) - end + defp handle_update(:min, old_value, new_value), do: {:ok, min(new_value, old_value)} - def min_and_max_numbers do - value(:all) - end + defp handle_update(:max, old_value, new_value), do: {:ok, max(new_value, old_value)} - defp value(type) do - {min, max} = - if Application.get_env(:explorer, __MODULE__)[:enabled] do - cached_values() - else - min_and_max_from_db() - end + defp handle_fallback(key) do + result = fetch_from_db(key) - case type do - :max -> max - :min -> min - :all -> {min, max} + if Application.get_env(:explorer, __MODULE__)[:enabled] do + {:update, result} + else + {:return, result} end end - @spec update(non_neg_integer()) :: boolean() - def update(number) do - {old_min, old_max} = cached_values() - - cond do - number > old_max -> - tuple = {old_min, number} - :ets.insert(@tab, {@key, tuple}) - - number < old_min -> - tuple = {number, old_max} - :ets.insert(@tab, {@key, tuple}) - - true -> - false + defp fetch_from_db(key) do + case key do + :min -> Chain.fetch_min_block_number() + :max -> Chain.fetch_max_block_number() end - end - - defp update_cache do - {min, max} = min_and_max_from_db() - tuple = {min, max} - - :ets.insert(@tab, {@key, tuple}) - end - - defp cached_values do - [{_, cached_values}] = :ets.lookup(@tab, @key) - - cached_values - end - - defp min_and_max_from_db do - Chain.fetch_min_and_max_block_numbers() rescue - _e -> - {0, 0} + _e -> 0 end end diff --git a/apps/explorer/lib/explorer/chain/cache/blocks.ex b/apps/explorer/lib/explorer/chain/cache/blocks.ex index 4a18646d37..d2a5b47061 100644 --- a/apps/explorer/lib/explorer/chain/cache/blocks.ex +++ b/apps/explorer/lib/explorer/chain/cache/blocks.ex @@ -11,7 +11,9 @@ defmodule Explorer.Chain.Cache.Blocks do ids_list_key: "block_numbers", preload: :transactions, preload: [miner: :names], - preload: :rewards + preload: :rewards, + ttl_check_interval: Application.get_env(:explorer, __MODULE__)[:ttl_check_interval], + global_ttl: Application.get_env(:explorer, __MODULE__)[:global_ttl] @type element :: Block.t() diff --git a/apps/explorer/lib/explorer/chain/cache/net_version.ex b/apps/explorer/lib/explorer/chain/cache/net_version.ex index ac33ca8f45..4a5c0cd144 100644 --- a/apps/explorer/lib/explorer/chain/cache/net_version.ex +++ b/apps/explorer/lib/explorer/chain/cache/net_version.ex @@ -3,42 +3,27 @@ defmodule Explorer.Chain.Cache.NetVersion do Caches chain version. """ - @cache_name :net_version - @key :version + @json_rpc_named_arguments Application.get_env(:explorer, :json_rpc_named_arguments) - @spec version() :: non_neg_integer() | {:error, any()} - def version do - cached_value = fetch_from_cache() + require Logger - if is_nil(cached_value) do - fetch_from_node() - else - cached_value - end - end - - def cache_name do - @cache_name - end - - defp fetch_from_cache do - ConCache.get(@cache_name, @key) - end + use Explorer.Chain.MapCache, + name: :net_version, + key: :version - defp cache_value(value) do - ConCache.put(@cache_name, @key, value) - end - - defp fetch_from_node do - json_rpc_named_arguments = Application.get_env(:explorer, :json_rpc_named_arguments) - - case EthereumJSONRPC.fetch_net_version(json_rpc_named_arguments) do + defp handle_fallback(:version) do + case EthereumJSONRPC.fetch_net_version(@json_rpc_named_arguments) do {:ok, value} -> - cache_value(value) - value + {:update, value} - other -> - other + {:error, reason} -> + Logger.debug([ + "Coudn't fetch net_version, reason: #{inspect(reason)}" + ]) + + {:return, nil} end end + + defp handle_fallback(_key), do: {:return, nil} end diff --git a/apps/explorer/lib/explorer/chain/cache/transaction_count.ex b/apps/explorer/lib/explorer/chain/cache/transaction_count.ex index e1fe2dad82..d6b2f7ae0d 100644 --- a/apps/explorer/lib/explorer/chain/cache/transaction_count.ex +++ b/apps/explorer/lib/explorer/chain/cache/transaction_count.ex @@ -3,152 +3,64 @@ defmodule Explorer.Chain.Cache.TransactionCount do Cache for estimated transaction count. """ - require Logger + @default_cache_period :timer.hours(2) + + use Explorer.Chain.MapCache, + name: :transaction_count, + key: :count, + key: :async_task, + global_ttl: cache_period(), + ttl_check_interval: :timer.minutes(10), + callback: &async_task_on_deletion(&1) - use GenServer + require Logger alias Explorer.Chain.Transaction alias Explorer.Repo - # 2 hours - @cache_period 1_000 * 60 * 60 * 2 - @default_value nil - @key "count" - @name __MODULE__ - - def start_link([params, gen_server_options]) do - name = gen_server_options[:name] || @name - params_with_name = Keyword.put(params, :name, name) - - GenServer.start_link(__MODULE__, params_with_name, name: name) - end - - def init(params) do - cache_period = period_from_env_var() || params[:cache_period] || @cache_period - current_value = params[:default_value] || @default_value - name = params[:name] - - init_ets_table(name) - - schedule_cache_update() - - {:ok, {{cache_period, current_value, name}, nil}} - end - - def value(process_name \\ __MODULE__) do - GenServer.call(process_name, :value) - end - - def handle_call(:value, _, {{cache_period, default_value, name}, task}) do - {value, task} = - case cached_values(name) do - nil -> - {default_value, update_cache(task, name)} + defp handle_fallback(:count) do + # This will get the task PID if one exists and launch a new task if not + # See next `handle_fallback` definition + get_async_task() - {cached_value, timestamp} -> - task = - if current_time() - timestamp > cache_period do - update_cache(task, name) - end - - {cached_value, task} - end - - {:reply, value, {{cache_period, default_value, name}, task}} + {:return, nil} end - def update_cache(nil, name) do - async_update_cache(name) - end - - def update_cache(task, _) do - task - end - - def handle_cast({:update_cache, value}, {{cache_period, default_value, name}, _}) do - current_time = current_time() - tuple = {value, current_time} - - table_name = table_name(name) - - :ets.insert(table_name, {@key, tuple}) + defp handle_fallback(:async_task) do + # If this gets called it means an async task was requested, but none exists + # so a new one needs to be launched + {:ok, task} = + Task.start(fn -> + try do + result = Repo.aggregate(Transaction, :count, :hash, timeout: :infinity) - {:noreply, {{cache_period, default_value, name}, nil}} - end - - def handle_info({:DOWN, _, _, _, _}, {{cache_period, default_value, name}, _}) do - {:noreply, {{cache_period, default_value, name}, nil}} - end - - def handle_info(_, {{cache_period, default_value, name}, _}) do - {:noreply, {{cache_period, default_value, name}, nil}} - end - - # sobelow_skip ["DOS"] - defp table_name(name) do - name - |> Atom.to_string() - |> Macro.underscore() - |> String.to_atom() - end - - def async_update_cache(name) do - Task.async(fn -> - try do - result = Repo.aggregate(Transaction, :count, :hash, timeout: :infinity) - - GenServer.cast(name, {:update_cache, result}) - rescue - e -> - Logger.debug([ - "Coudn't update transaction count test #{inspect(e)}" - ]) - end - end) - end - - defp init_ets_table(name) do - table_name = table_name(name) - - if :ets.whereis(table_name) == :undefined do - :ets.new(table_name, [ - :set, - :named_table, - :public, - write_concurrency: true - ]) - end - end - - defp cached_values(name) do - table_name = table_name(name) + set_count(result) + rescue + e -> + Logger.debug([ + "Coudn't update transaction count test #{inspect(e)}" + ]) + end - case :ets.lookup(table_name, @key) do - [{_, cached_values}] -> cached_values - _ -> nil - end - end + set_async_task(nil) + end) - defp schedule_cache_update do - Process.send_after(self(), :update_cache, 2_000) + {:update, task} end - defp current_time do - utc_now = DateTime.utc_now() + # By setting this as a `callback` an async task will be started each time the + # `count` expires (unless there is one already running) + defp async_task_on_deletion({:delete, _, :count}), do: get_async_task() - DateTime.to_unix(utc_now, :millisecond) - end - - defp period_from_env_var do - case System.get_env("TXS_COUNT_CACHE_PERIOD") do - value when is_binary(value) -> - case Integer.parse(value) do - {integer, ""} -> integer * 1_000 - _ -> nil - end + defp async_task_on_deletion(_data), do: nil - _ -> - nil + defp cache_period do + "TXS_COUNT_CACHE_PERIOD" + |> System.get_env("") + |> Integer.parse() + |> case do + {integer, ""} -> :timer.seconds(integer) + _ -> @default_cache_period end end end diff --git a/apps/explorer/lib/explorer/chain/cache/transactions.ex b/apps/explorer/lib/explorer/chain/cache/transactions.ex index 7dee7ec87d..e9b8a40a9e 100644 --- a/apps/explorer/lib/explorer/chain/cache/transactions.ex +++ b/apps/explorer/lib/explorer/chain/cache/transactions.ex @@ -16,7 +16,9 @@ defmodule Explorer.Chain.Cache.Transactions do token_transfers: :token, token_transfers: :from_address, token_transfers: :to_address - ] + ], + ttl_check_interval: Application.get_env(:explorer, __MODULE__)[:ttl_check_interval], + global_ttl: Application.get_env(:explorer, __MODULE__)[:global_ttl] @type element :: Transaction.t() diff --git a/apps/explorer/lib/explorer/chain/map_cache.ex b/apps/explorer/lib/explorer/chain/map_cache.ex new file mode 100644 index 0000000000..d50a4c5e44 --- /dev/null +++ b/apps/explorer/lib/explorer/chain/map_cache.ex @@ -0,0 +1,217 @@ +defmodule Explorer.Chain.MapCache do + @moduledoc """ + Behaviour for a map-like cache of elements. + + A macro based on `ConCache` is provided as well, at its minimum it can be used as; + ``` + use Explorer.Chain.MapCache, + name: :name, + keys: [:fst, :snd] + ``` + Note: `keys` can also be set singularly with the option `key`, e.g.: + ``` + use Explorer.Chain.MapCache, + name: :cache, + key: :fst, + key: :snd + ``` + Additionally all of the options accepted by `ConCache.start_link/1` can be + provided as well. By default only `ttl_check_interval:` is set (to `false`). + + ## Named functions + Apart from the functions defined in the behaviour, the macro will also create + 3 named function for each key, for instance for the key `:fst`: + - `get_fst` + - `set_fst` + - `update_fst` + These all work as their respective counterparts with the `t:key/0` parameter. + + ## Callbacks + Apart from the `callback` that can be set as part of the `ConCache` options, + two callbacks esist and can be overridden: + + `c:handle_update/3` will be called whenever an update is issued. It will receive + the `t:key/0` that is going to be updated, the current `t:value/0` that is + stored for said key and the new `t:value/0` to evaluate. + This allows to select what value to keep and do additional processing. + By default this just stores the new `t:value/0`. + + `c:handle_fallback/1` will be called whenever a get is performed and there is no + stored value for the given `t:key/0` (or when the value is `nil`). + It can return 2 different tuples: + - `{:update, value}` that will cause the value to be returned and the `t:key/0` + to be `c:update/2`d + - `{:return, value}` that will cause the value to be returned but not stored + This allows to define of a default value or perform some actions. + By default it will simply `{:return, nil}` + """ + + @type key :: atom() + + @type value :: term() + + @doc """ + An atom that identifies this cache + """ + @callback cache_name :: atom() + + @doc """ + List of `t:key/0`s that the cache contains + """ + @callback cache_keys :: [key()] + + @doc """ + Gets everything in a map + """ + @callback get_all :: map() + + @doc """ + Gets the stored `t:value/0` for a given `t:key/0` + """ + @callback get(atom()) :: value() + + @doc """ + Stores the same `t:value/0` for every `t:key/0` + """ + @callback set_all(value()) :: :ok + + @doc """ + Stores the given `t:value/0` for the given `t:key/0` + """ + @callback set(key(), value()) :: :ok + + @doc """ + Updates every `t:key/0` with the given `t:value/0` + """ + @callback update_all(value()) :: :ok + + @doc """ + Updates the given `t:key/0` (or every `t:key/0` in a list) using the given `t:value/0` + """ + @callback update(key() | [key()], value()) :: :ok + + @doc """ + Gets called during an update for the given `t:key/0` + """ + @callback handle_update(key(), value(), value()) :: {:ok, value()} | {:error, term()} + + @doc """ + Gets called when a `c:get/1` finds no `t:value/0` + """ + @callback handle_fallback(key()) :: {:update, value()} | {:return, value()} + + # credo:disable-for-next-line /Complexity/ + defmacro __using__(opts) when is_list(opts) do + # name is necessary + name = Keyword.fetch!(opts, :name) + keys = Keyword.get(opts, :keys) || Keyword.get_values(opts, :key) + + concache_params = + opts + |> Keyword.drop([:keys, :key]) + |> Keyword.put_new(:ttl_check_interval, false) + + # credo:disable-for-next-line Credo.Check.Refactor.LongQuoteBlocks + quote do + alias Explorer.Chain.MapCache + + @behaviour MapCache + + @dialyzer {:nowarn_function, handle_fallback: 1} + + @impl MapCache + def cache_name, do: unquote(name) + + @impl MapCache + def cache_keys, do: unquote(keys) + + @impl MapCache + def get_all do + Map.new(cache_keys(), fn key -> {key, get(key)} end) + end + + @impl MapCache + def get(key) do + case ConCache.get(cache_name(), key) do + nil -> + case handle_fallback(key) do + {:update, new_value} -> + update(key, new_value) + new_value + + {:return, new_value} -> + new_value + end + + value -> + value + end + end + + @impl MapCache + def set_all(value) do + Enum.each(cache_keys(), &set(&1, value)) + end + + @impl MapCache + def set(key, value) do + ConCache.put(cache_name(), key, value) + end + + @impl MapCache + def update_all(value), do: update(cache_keys(), value) + + @impl MapCache + def update(keys, value) when is_list(keys) do + Enum.each(keys, &update(&1, value)) + end + + @impl MapCache + def update(key, value) do + ConCache.update(cache_name(), key, fn old_val -> handle_update(key, old_val, value) end) + end + + ### Autogenerated named functions + + unquote(Enum.map(keys, &named_functions(&1))) + + ### Overridable callback functions + + @impl MapCache + def handle_update(_key, _old_value, new_value), do: {:ok, new_value} + + @impl MapCache + def handle_fallback(_key), do: {:return, nil} + + defoverridable handle_update: 3, handle_fallback: 1 + + ### Supervisor's child specification + + @doc """ + The child specification for a Supervisor. Note that all the `params` + provided to this function will override the ones set by using the macro + """ + def child_spec(params \\ []) do + params = Keyword.merge(unquote(concache_params), params) + + Supervisor.child_spec({ConCache, params}, id: child_id()) + end + + def child_id, do: {ConCache, cache_name()} + end + end + + # sobelow_skip ["DOS"] + defp named_functions(key) do + quote do + # sobelow_skip ["DOS"] + def unquote(:"get_#{key}")(), do: get(unquote(key)) + + # sobelow_skip ["DOS"] + def unquote(:"set_#{key}")(value), do: set(unquote(key), value) + + # sobelow_skip ["DOS"] + def unquote(:"update_#{key}")(value), do: update(unquote(key), value) + end + end +end diff --git a/apps/explorer/lib/explorer/chain/ordered_cache.ex b/apps/explorer/lib/explorer/chain/ordered_cache.ex index 2a1c0fc689..5365fe0f76 100644 --- a/apps/explorer/lib/explorer/chain/ordered_cache.ex +++ b/apps/explorer/lib/explorer/chain/ordered_cache.ex @@ -26,7 +26,10 @@ defmodule Explorer.Chain.OrderedCache do preload: [transaction: :hash] ``` Additionally all of the options accepted by `ConCache.start_link/1` can be - provided as well. By default only `ttl_check_interval:` is set (to `false`). + provided as well. Unless specified, only these values have defaults: + - `:ttl_check_interval` is set (to `false`). + - `:callback` is only set if `:ttl_check_interval` is not `false` to call the + `remove_deleted_from_index` function, that removes expired values from the index. It's also possible, and advised, to override the implementation of the `c:prevails?/2` and `c:element_to_id/1` callbacks. @@ -131,10 +134,7 @@ defmodule Explorer.Chain.OrderedCache do max_size = Keyword.get(opts, :max_size, 100) preloads = Keyword.get(opts, :preloads) || Keyword.get_values(opts, :preload) - concache_params = - opts - |> Keyword.drop([:ids_list_key, :max_size, :preloads, :preload]) - |> Keyword.put_new(:ttl_check_interval, false) + concache_params = Keyword.drop(opts, [:ids_list_key, :max_size, :preloads, :preload]) # credo:disable-for-next-line Credo.Check.Refactor.LongQuoteBlocks quote do @@ -206,6 +206,19 @@ defmodule Explorer.Chain.OrderedCache do ### Updating function + def remove_deleted_from_index({:delete, _cache_pid, id}) do + # simply check with `ConCache.get` because it is faster + if Enum.member?(ids_list(), id) do + ConCache.update(cache_name(), ids_list_key(), fn ids -> + updated_list = List.delete(ids || [], id) + # ids_list is set to never expire + {:ok, %ConCache.Item{value: updated_list, ttl: :infinity}} + end) + end + end + + def remove_deleted_from_index(_), do: nil + @impl OrderedCache def update(elements) when is_nil(elements), do: :ok @@ -217,7 +230,8 @@ defmodule Explorer.Chain.OrderedCache do |> Enum.sort(&prevails?(&1, &2)) |> merge_and_update(ids || [], max_size()) - {:ok, updated_list} + # ids_list is set to never expire + {:ok, %ConCache.Item{value: updated_list, ttl: :infinity}} end) end @@ -308,7 +322,21 @@ defmodule Explorer.Chain.OrderedCache do provided to this function will override the ones set by using the macro """ def child_spec(params) do - params = Keyword.merge(unquote(concache_params), params) + # params specified in `use` + merged_params = + unquote(concache_params) + # params specified in `child_spec` + |> Keyword.merge(params) + # `:ttl_check_interval` needs to be specified, defaults to `false` + |> Keyword.put_new(:ttl_check_interval, false) + + # if `:ttl_check_interval` is not `false` the expired values need to be + # removed from the cache's index + params = + case merged_params[:ttl_check_interval] do + false -> merged_params + _ -> Keyword.put_new(merged_params, :callback, &remove_deleted_from_index/1) + end Supervisor.child_spec({ConCache, params}, id: child_id()) end diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index ed579e8e00..0db7d7e613 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -271,6 +271,45 @@ defmodule Explorer.Chain.SmartContract do |> add_error(:contract_source_code, error_message(error)) end + def add_submitted_comment(code, inserted_at) when is_binary(code) do + code + |> String.split("\n") + |> add_submitted_comment(inserted_at) + |> Enum.join("\n") + end + + def add_submitted_comment(contract_lines, inserted_at) when is_list(contract_lines) do + etherscan_index = + Enum.find_index(contract_lines, fn line -> + String.contains?(line, "Submitted for verification at Etherscan.io") + end) + + blockscout_index = + Enum.find_index(contract_lines, fn line -> + String.contains?(line, "Submitted for verification at blockscout.com") + end) + + cond do + etherscan_index && blockscout_index -> + List.replace_at(contract_lines, etherscan_index, "*") + + etherscan_index && !blockscout_index -> + List.replace_at( + contract_lines, + etherscan_index, + "* Submitted for verification at blockscout.com on #{inserted_at}" + ) + + !etherscan_index && !blockscout_index -> + header = ["/**", "* Submitted for verification at blockscout.com on #{inserted_at}", "*/"] + + header ++ contract_lines + + true -> + contract_lines + end + end + defp upsert_contract_methods(%Ecto.Changeset{changes: %{abi: abi}} = changeset) do ContractMethod.upsert_from_abi(abi, get_field(changeset, :address_hash)) diff --git a/apps/explorer/lib/explorer/chain/supply/coin_market_cap.ex b/apps/explorer/lib/explorer/chain/supply/exchange_rate.ex similarity index 72% rename from apps/explorer/lib/explorer/chain/supply/coin_market_cap.ex rename to apps/explorer/lib/explorer/chain/supply/exchange_rate.ex index ebaadb3c47..d45a8edc02 100644 --- a/apps/explorer/lib/explorer/chain/supply/coin_market_cap.ex +++ b/apps/explorer/lib/explorer/chain/supply/exchange_rate.ex @@ -1,6 +1,6 @@ -defmodule Explorer.Chain.Supply.CoinMarketCap do +defmodule Explorer.Chain.Supply.ExchangeRate do @moduledoc """ - Defines the supply API for calculating supply for coins from coinmarketcap. + Defines the supply API for calculating supply for coins from exchange_rate.. """ use Explorer.Chain.Supply diff --git a/apps/explorer/lib/explorer/chain/supply/rsk.ex b/apps/explorer/lib/explorer/chain/supply/rsk.ex index eb7c4571cd..c34cf62d49 100644 --- a/apps/explorer/lib/explorer/chain/supply/rsk.ex +++ b/apps/explorer/lib/explorer/chain/supply/rsk.ex @@ -102,7 +102,7 @@ defmodule Explorer.Chain.Supply.RSK do def cache_name, do: @cache_name defp fetch_circulating_value do - max_number = BlockNumber.max_number() + max_number = BlockNumber.get_max() params = [ %{block_quantity: integer_to_quantity(max_number), hash_data: "0x0000000000000000000000000000000001000006"} diff --git a/apps/explorer/lib/explorer/chain/transaction.ex b/apps/explorer/lib/explorer/chain/transaction.ex index 78d162fa4e..1274202bd5 100644 --- a/apps/explorer/lib/explorer/chain/transaction.ex +++ b/apps/explorer/lib/explorer/chain/transaction.ex @@ -484,40 +484,26 @@ defmodule Explorer.Chain.Transaction do end @doc """ - Modifies a query to filter for transactions whose hash is in a list or that are - linked to the given address_hash through a direction. - - Be careful to not pass a large list, because this will lead to performance - problems. + Produces a list of queries starting from the given one and adding filters for + transactions that are linked to the given address_hash through a direction. """ - def where_transaction_matches(query, transaction_hashes, :from, address_hash) do - where( - query, - [t], - t.hash in ^transaction_hashes or - t.from_address_hash == ^address_hash - ) + def matching_address_queries_list(query, :from, address_hash) do + [where(query, [t], t.from_address_hash == ^address_hash)] end - def where_transaction_matches(query, transaction_hashes, :to, address_hash) do - where( - query, - [t], - t.hash in ^transaction_hashes or - t.to_address_hash == ^address_hash or - t.created_contract_address_hash == ^address_hash - ) + def matching_address_queries_list(query, :to, address_hash) do + [ + where(query, [t], t.to_address_hash == ^address_hash), + where(query, [t], t.created_contract_address_hash == ^address_hash) + ] end - def where_transaction_matches(query, transaction_hashes, _direction, address_hash) do - where( - query, - [t], - t.hash in ^transaction_hashes or - t.from_address_hash == ^address_hash or - t.to_address_hash == ^address_hash or - t.created_contract_address_hash == ^address_hash - ) + def matching_address_queries_list(query, _direction, address_hash) do + [ + where(query, [t], t.from_address_hash == ^address_hash), + where(query, [t], t.to_address_hash == ^address_hash), + where(query, [t], t.created_contract_address_hash == ^address_hash) + ] end @collated_fields ~w(block_number cumulative_gas_used gas_used index)a diff --git a/apps/explorer/lib/explorer/chain_spec/parity/importer.ex b/apps/explorer/lib/explorer/chain_spec/parity/importer.ex index 6b560bf530..fa16ee0739 100644 --- a/apps/explorer/lib/explorer/chain_spec/parity/importer.ex +++ b/apps/explorer/lib/explorer/chain_spec/parity/importer.ex @@ -3,18 +3,23 @@ defmodule Explorer.ChainSpec.Parity.Importer do Imports data from parity chain spec. """ + require Logger + alias Explorer.{Chain, Repo} alias Explorer.Chain.Block.{EmissionReward, Range} alias Explorer.Chain.Hash.Address, as: AddressHash alias Explorer.Chain.Wei + alias Explorer.ChainSpec.GenesisData + alias Explorer.ChainSpec.POA.Importer, as: PoaEmissionImporter @max_block_number :infinity def import_emission_rewards(chain_spec) do - rewards = emission_rewards(chain_spec) - - {_, nil} = Repo.delete_all(EmissionReward) - {_, nil} = Repo.insert_all(EmissionReward, rewards) + if Application.get_env(:explorer, GenesisData)[:emission_format] == "POA" do + PoaEmissionImporter.import_emission_rewards() + else + import_rewards_from_chain_spec(chain_spec) + end end def import_genesis_coin_balances(chain_spec) do @@ -38,18 +43,37 @@ defmodule Explorer.ChainSpec.Parity.Importer do Chain.import(params) end + defp import_rewards_from_chain_spec(chain_spec) do + rewards = emission_rewards(chain_spec) + + {_, nil} = Repo.delete_all(EmissionReward) + {_, nil} = Repo.insert_all(EmissionReward, rewards) + end + def genesis_coin_balances(chain_spec) do accounts = chain_spec["accounts"] - parse_accounts(accounts) + if accounts do + parse_accounts(accounts) + else + Logger.warn(fn -> "No accounts are defined in chain spec" end) + + [] + end end def emission_rewards(chain_spec) do rewards = chain_spec["engine"]["Ethash"]["params"]["blockReward"] - rewards - |> parse_hex_numbers() - |> format_ranges() + if rewards do + rewards + |> parse_hex_numbers() + |> format_ranges() + else + Logger.warn(fn -> "No rewards are defined in chain spec" end) + + [] + end end defp parse_accounts(accounts) do @@ -59,7 +83,7 @@ defmodule Explorer.ChainSpec.Parity.Importer do end) |> Stream.map(fn {address, %{"balance" => value}} -> {:ok, address_hash} = AddressHash.cast(address) - balance = parse_hex_number(value) + balance = parse_number(value) %{address_hash: address_hash, value: balance} end) @@ -92,16 +116,22 @@ defmodule Explorer.ChainSpec.Parity.Importer do defp parse_hex_numbers(rewards) do Enum.map(rewards, fn {hex_block_number, hex_reward} -> - block_number = parse_hex_number(hex_block_number) - {:ok, reward} = hex_reward |> parse_hex_number() |> Wei.cast() + block_number = parse_number(hex_block_number) + {:ok, reward} = hex_reward |> parse_number() |> Wei.cast() {block_number, reward} end) end - defp parse_hex_number("0x" <> hex_number) do + defp parse_number("0x" <> hex_number) do {number, ""} = Integer.parse(hex_number, 16) number end + + defp parse_number(string_number) do + {number, ""} = Integer.parse(string_number, 10) + + number + end end diff --git a/apps/explorer/lib/explorer/chain_spec/poa/importer.ex b/apps/explorer/lib/explorer/chain_spec/poa/importer.ex new file mode 100644 index 0000000000..03935d85b2 --- /dev/null +++ b/apps/explorer/lib/explorer/chain_spec/poa/importer.ex @@ -0,0 +1,89 @@ +defmodule Explorer.ChainSpec.POA.Importer do + @moduledoc """ + Imports emission reward range for POA chain. + """ + + require Logger + + alias Explorer.Chain.Wei + alias Explorer.Repo + alias Explorer.SmartContract.Reader + alias Explorer.Chain.Block.{EmissionReward, Range} + alias Explorer.ChainSpec.GenesisData + + @block_reward_amount_abi %{ + "type" => "function", + "stateMutability" => "view", + "payable" => false, + "outputs" => [%{"type" => "uint256", "name" => ""}], + "name" => "blockRewardAmount", + "inputs" => [], + "constant" => true + } + @block_reward_amount_params %{"blockRewardAmount" => []} + @emission_funds_amount_abi %{ + "type" => "function", + "stateMutability" => "view", + "payable" => false, + "outputs" => [%{"type" => "uint256", "name" => ""}], + "name" => "emissionFundsAmount", + "inputs" => [], + "constant" => true + } + @emission_funds_amount_params %{"emissionFundsAmount" => []} + @emission_funds_block_start 5_098_087 + + def import_emission_rewards do + if is_nil(rewards_contract_address()) do + Logger.warn(fn -> "No rewards contract address is defined" end) + else + block_reward = block_reward_amount() + emission_funds = emission_funds_amount() + + rewards = [ + %{ + block_range: %Range{from: 0, to: @emission_funds_block_start}, + reward: %Wei{value: block_reward} + }, + %{ + block_range: %Range{from: @emission_funds_block_start + 1, to: :infinity}, + reward: %Wei{value: Decimal.add(block_reward, emission_funds)} + } + ] + + {_, nil} = Repo.delete_all(EmissionReward) + {_, nil} = Repo.insert_all(EmissionReward, rewards) + end + end + + def block_reward_amount do + call_contract(rewards_contract_address(), @block_reward_amount_abi, @block_reward_amount_params) + end + + def emission_funds_amount do + call_contract(rewards_contract_address(), @emission_funds_amount_abi, @emission_funds_amount_params) + end + + defp rewards_contract_address do + Application.get_env(:explorer, GenesisData)[:rewards_contract_address] + end + + defp call_contract(address, abi, params) do + abi = [abi] + + method_name = + params + |> Enum.map(fn {key, _value} -> key end) + |> List.first() + + Reader.query_contract(address, abi, params) + + value = + case Reader.query_contract(address, abi, params) do + %{^method_name => {:ok, [result]}} -> result + _ -> 0 + end + + Decimal.new(value) + end +end diff --git a/apps/explorer/lib/explorer/exchange_rates/source.ex b/apps/explorer/lib/explorer/exchange_rates/source.ex index 41b87c1e29..fdb0e06fc3 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source.ex @@ -2,8 +2,6 @@ defmodule Explorer.ExchangeRates.Source do @moduledoc """ Behaviour for fetching exchange rates from external sources. """ - - alias Explorer.ExchangeRates.Source.CoinMarketCap alias Explorer.ExchangeRates.Token alias HTTPoison.{Error, Response} @@ -12,34 +10,18 @@ defmodule Explorer.ExchangeRates.Source do """ @spec fetch_exchange_rates(module) :: {:ok, [Token.t()]} | {:error, any} def fetch_exchange_rates(source \\ exchange_rates_source()) do - if(source == CoinMarketCap) do - fetch_exchange_rates_from_paginable_source(source) - else - fetch_exchange_rates_request(source) - end - end - - defp fetch_exchange_rates_from_paginable_source(source, page \\ 1) do - case HTTPoison.get(source.source_url(page), headers()) do - {:ok, %Response{body: body, status_code: 200}} -> - cond do - body =~ Explorer.coin() -> {:ok, source.format_data(body)} - page == source.max_page_number -> {:error, "exchange rates not found for this network"} - true -> fetch_exchange_rates_from_paginable_source(source, page + 1) - end - - {:ok, %Response{body: body, status_code: status_code}} when status_code in 400..502 -> - {:error, decode_json(body)["error"]} - - {:error, %Error{reason: reason}} -> - {:error, reason} - end + fetch_exchange_rates_request(source) end defp fetch_exchange_rates_request(source) do case HTTPoison.get(source.source_url(), headers()) do {:ok, %Response{body: body, status_code: 200}} -> - {:ok, source.format_data(body)} + result = + body + |> decode_json() + |> source.format_data() + + {:ok, result} {:ok, %Response{body: body, status_code: status_code}} when status_code in 400..499 -> {:error, decode_json(body)["error"]} @@ -83,7 +65,7 @@ defmodule Explorer.ExchangeRates.Source do @spec exchange_rates_source() :: module() defp exchange_rates_source do - config(:source) || Explorer.ExchangeRates.Source.CoinMarketCap + config(:source) || Explorer.ExchangeRates.Source.CoinGecko end @spec config(atom()) :: term diff --git a/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex b/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex index 4e59537bf6..95ecafb046 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex @@ -11,43 +11,50 @@ defmodule Explorer.ExchangeRates.Source.CoinGecko do @behaviour Source @impl Source - def format_data(data) do + def format_data(%{"market_data" => _} = json_data) do {:ok, price} = get_btc_price() btc_price = to_decimal(price) - for item <- decode_json(data), - not is_nil(item["total_supply"]) and not is_nil(item["current_price"]) do - {:ok, last_updated, 0} = DateTime.from_iso8601(item["last_updated"]) + market_data = json_data["market_data"] + {:ok, last_updated, 0} = DateTime.from_iso8601(market_data["last_updated"]) - current_price = to_decimal(item["current_price"]) + current_price = to_decimal(market_data["current_price"]["usd"]) - id = item["id"] - btc_value = if id != "btc", do: Decimal.div(current_price, btc_price), else: 1 + id = json_data["id"] + btc_value = if id != "btc", do: Decimal.div(current_price, btc_price), else: 1 + [ %Token{ - available_supply: to_decimal(item["total_supply"]), - total_supply: to_decimal(item["total_supply"]), + available_supply: to_decimal(market_data["circulating_supply"]), + total_supply: to_decimal(market_data["total_supply"]), btc_value: btc_value, - id: id, + id: json_data["id"], last_updated: last_updated, - market_cap_usd: to_decimal(item["market_cap"]), - name: item["name"], - symbol: item["symbol"], + market_cap_usd: to_decimal(market_data["market_cap"]["usd"]), + name: json_data["name"], + symbol: String.upcase(json_data["symbol"]), usd_value: current_price, - volume_24h_usd: to_decimal(item["total_volume"]) + volume_24h_usd: to_decimal(market_data["total_volume"]["usd"]) } - end + ] end @impl Source - def source_url(currency \\ "usd") do - "#{base_url()}/coins/markets?vs_currency=#{currency}" + def format_data(_), do: [] + + @impl Source + def source_url do + "#{base_url()}/coins/#{coin_id()}" end defp base_url do config(:base_url) || "https://api.coingecko.com/api/v3" end + defp coin_id do + Application.get_env(:explorer, __MODULE__)[:coin_id] + end + defp get_btc_price(currency \\ "usd") do url = "#{base_url()}/exchange_rates" diff --git a/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex b/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex deleted file mode 100644 index efe592e0fa..0000000000 --- a/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex +++ /dev/null @@ -1,52 +0,0 @@ -defmodule Explorer.ExchangeRates.Source.CoinMarketCap do - @moduledoc """ - Adapter for fetching exchange rates from https://coinmarketcap.com. - """ - - alias Explorer.ExchangeRates.{Source, Token} - - import Source, only: [decode_json: 1, to_decimal: 1] - - @behaviour Source - - @impl Source - def format_data(data) do - for item <- decode_json(data), not is_nil(item["last_updated"]) do - {last_updated_as_unix, _} = Integer.parse(item["last_updated"]) - last_updated = DateTime.from_unix!(last_updated_as_unix) - - %Token{ - available_supply: to_decimal(item["available_supply"]), - total_supply: to_decimal(item["total_supply"]), - btc_value: to_decimal(item["price_btc"]), - id: item["id"], - last_updated: last_updated, - market_cap_usd: to_decimal(item["market_cap_usd"]), - name: item["name"], - symbol: item["symbol"], - usd_value: to_decimal(item["price_usd"]), - volume_24h_usd: to_decimal(item["24h_volume_usd"]) - } - end - end - - @impl Source - def source_url do - source_url(1) - end - - def source_url(page) do - "#{base_url()}/v1/ticker/?start=#{page - 1}00" - end - - def max_page_number, do: config(:pages) - - defp base_url do - config(:base_url) || "https://api.coinmarketcap.com" - end - - @spec config(atom()) :: term - defp config(key) do - Application.get_env(:explorer, __MODULE__, [])[key] - end -end diff --git a/apps/explorer/lib/explorer/exchange_rates/source/token_bridge.ex b/apps/explorer/lib/explorer/exchange_rates/source/token_bridge.ex index 03234ff649..aa2b849a11 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source/token_bridge.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source/token_bridge.ex @@ -30,7 +30,7 @@ defmodule Explorer.ExchangeRates.Source.TokenBridge do btc_value: original_token.btc_value, id: original_token.id, last_updated: original_token.last_updated, - market_cap_usd: Decimal.mult(to_decimal(Chain.circulating_supply()), original_token.usd_value), + market_cap_usd: market_cap_usd(Chain.circulating_supply(), original_token), name: original_token.name, symbol: original_token.symbol, usd_value: original_token.usd_value, @@ -38,6 +38,14 @@ defmodule Explorer.ExchangeRates.Source.TokenBridge do } end + defp market_cap_usd(nil, _original_token), do: Decimal.new(0) + + defp market_cap_usd(supply, original_token) do + supply + |> to_decimal() + |> Decimal.mult(original_token.usd_value) + end + @impl Source def source_url do secondary_source().source_url() @@ -45,7 +53,7 @@ defmodule Explorer.ExchangeRates.Source.TokenBridge do @spec secondary_source() :: module() defp secondary_source do - config(:secondary_source) || Explorer.ExchangeRates.Source.CoinMarketCap + config(:secondary_source) || Explorer.ExchangeRates.Source.CoinGecko end @spec config(atom()) :: term diff --git a/apps/explorer/test/explorer/chain/cache/block_count_test.exs b/apps/explorer/test/explorer/chain/cache/block_count_test.exs index 646af8de43..108c929a75 100644 --- a/apps/explorer/test/explorer/chain/cache/block_count_test.exs +++ b/apps/explorer/test/explorer/chain/cache/block_count_test.exs @@ -3,53 +3,53 @@ defmodule Explorer.Chain.Cache.BlockCountTest do alias Explorer.Chain.Cache.BlockCount - test "returns default transaction count" do - BlockCount.start_link(name: BlockTestCache) + setup do + Supervisor.terminate_child(Explorer.Supervisor, BlockCount.child_id()) + Supervisor.restart_child(Explorer.Supervisor, BlockCount.child_id()) + :ok + end - result = BlockCount.count(BlockTestCache) + test "returns default transaction count" do + result = BlockCount.get_count() assert is_nil(result) end test "updates cache if initial value is zero" do - BlockCount.start_link(name: BlockTestCache) - insert(:block, consensus: true) insert(:block, consensus: true) insert(:block, consensus: false) - _result = BlockCount.count(BlockTestCache) + _result = BlockCount.get_count() Process.sleep(1000) - updated_value = BlockCount.count(BlockTestCache) + updated_value = BlockCount.get_count() assert updated_value == 2 end test "does not update cache if cache period did not pass" do - BlockCount.start_link(name: BlockTestCache) - insert(:block, consensus: true) insert(:block, consensus: true) insert(:block, consensus: false) - _result = BlockCount.count(BlockTestCache) + _result = BlockCount.get_count() Process.sleep(1000) - updated_value = BlockCount.count(BlockTestCache) + updated_value = BlockCount.get_count() assert updated_value == 2 insert(:block, consensus: true) insert(:block, consensus: true) - _updated_value = BlockCount.count(BlockTestCache) + _updated_value = BlockCount.get_count() Process.sleep(1000) - updated_value = BlockCount.count(BlockTestCache) + updated_value = BlockCount.get_count() assert updated_value == 2 end diff --git a/apps/explorer/test/explorer/chain/cache/block_number_test.exs b/apps/explorer/test/explorer/chain/cache/block_number_test.exs index 381ded440b..87107fe45c 100644 --- a/apps/explorer/test/explorer/chain/cache/block_number_test.exs +++ b/apps/explorer/test/explorer/chain/cache/block_number_test.exs @@ -11,49 +11,63 @@ defmodule Explorer.Chain.Cache.BlockNumberTest do end) end - describe "max_number/1" do + describe "get_max/0" do test "returns max number" do insert(:block, number: 5) - BlockNumber.setup() - - assert BlockNumber.max_number() == 5 + assert BlockNumber.get_max() == 5 end end - describe "min_number/1" do - test "returns max number" do + describe "get_min/0" do + test "returns min number" do insert(:block, number: 2) - BlockNumber.setup() + assert BlockNumber.get_min() == 2 + end + end - assert BlockNumber.max_number() == 2 + describe "get_all/0" do + test "returns min and max number" do + insert(:block, number: 6) + + assert BlockNumber.get_all() == %{min: 6, max: 6} end end - describe "update/1" do + describe "update_all/1" do test "updates max number" do insert(:block, number: 2) - BlockNumber.setup() - - assert BlockNumber.max_number() == 2 + assert BlockNumber.get_max() == 2 - assert BlockNumber.update(3) + assert BlockNumber.update_all(3) - assert BlockNumber.max_number() == 3 + assert BlockNumber.get_max() == 3 end test "updates min number" do insert(:block, number: 2) - BlockNumber.setup() + assert BlockNumber.get_min() == 2 + + assert BlockNumber.update_all(1) + + assert BlockNumber.get_min() == 1 + end + + test "updates min and number" do + insert(:block, number: 2) + + assert BlockNumber.get_all() == %{min: 2, max: 2} + + assert BlockNumber.update_all(1) - assert BlockNumber.min_number() == 2 + assert BlockNumber.get_all() == %{min: 1, max: 2} - assert BlockNumber.update(1) + assert BlockNumber.update_all(6) - assert BlockNumber.min_number() == 1 + assert BlockNumber.get_all() == %{min: 1, max: 6} end end end diff --git a/apps/explorer/test/explorer/chain/cache/blocks_test.exs b/apps/explorer/test/explorer/chain/cache/blocks_test.exs index 87f887ae26..41fe344a1e 100644 --- a/apps/explorer/test/explorer/chain/cache/blocks_test.exs +++ b/apps/explorer/test/explorer/chain/cache/blocks_test.exs @@ -5,8 +5,8 @@ defmodule Explorer.Chain.Cache.BlocksTest do alias Explorer.Repo setup do - Supervisor.terminate_child(Explorer.Supervisor, {ConCache, :blocks}) - Supervisor.restart_child(Explorer.Supervisor, {ConCache, :blocks}) + Supervisor.terminate_child(Explorer.Supervisor, Blocks.child_id()) + Supervisor.restart_child(Explorer.Supervisor, Blocks.child_id()) :ok end diff --git a/apps/explorer/test/explorer/chain/cache/transaction_count_test.exs b/apps/explorer/test/explorer/chain/cache/transaction_count_test.exs index 5020486cb8..5385492de7 100644 --- a/apps/explorer/test/explorer/chain/cache/transaction_count_test.exs +++ b/apps/explorer/test/explorer/chain/cache/transaction_count_test.exs @@ -3,51 +3,51 @@ defmodule Explorer.Chain.Cache.TransactionCountTest do alias Explorer.Chain.Cache.TransactionCount - test "returns default transaction count" do - TransactionCount.start_link([[], [name: TestCache]]) + setup do + Supervisor.terminate_child(Explorer.Supervisor, TransactionCount.child_id()) + Supervisor.restart_child(Explorer.Supervisor, TransactionCount.child_id()) + :ok + end - result = TransactionCount.value(TestCache) + test "returns default transaction count" do + result = TransactionCount.get_count() assert is_nil(result) end test "updates cache if initial value is zero" do - TransactionCount.start_link([[], [name: TestCache]]) - insert(:transaction) insert(:transaction) - _result = TransactionCount.value(TestCache) + _result = TransactionCount.get_count() Process.sleep(1000) - updated_value = TransactionCount.value(TestCache) + updated_value = TransactionCount.get_count() assert updated_value == 2 end test "does not update cache if cache period did not pass" do - TransactionCount.start_link([[], [name: TestCache]]) - insert(:transaction) insert(:transaction) - _result = TransactionCount.value(TestCache) + _result = TransactionCount.get_count() Process.sleep(1000) - updated_value = TransactionCount.value(TestCache) + updated_value = TransactionCount.get_count() assert updated_value == 2 insert(:transaction) insert(:transaction) - _updated_value = TransactionCount.value(TestCache) + _updated_value = TransactionCount.get_count() Process.sleep(1000) - updated_value = TransactionCount.value(TestCache) + updated_value = TransactionCount.get_count() assert updated_value == 2 end diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 10788b60ba..187d503621 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -1121,23 +1121,31 @@ defmodule Explorer.ChainTest do end end - describe "fetch_min_and_max_block_numbers/0" do - test "fetches min and max block numbers" do + describe "fetch_min_block_number/0" do + test "fetches min block numbers" do for index <- 5..9 do insert(:block, number: index) end - assert {5, 9} = Chain.fetch_min_and_max_block_numbers() + assert 5 = Chain.fetch_min_block_number() end - test "fetches min and max when there are no blocks" do - assert {0, 0} = Chain.fetch_min_and_max_block_numbers() + test "fetches min when there are no blocks" do + assert 0 = Chain.fetch_min_block_number() end + end - test "fetches min and max where there is only one block" do - insert(:block, number: 1) + describe "fetch_max_block_number/0" do + test "fetches max block numbers" do + for index <- 5..9 do + insert(:block, number: index) + end + + assert 9 = Chain.fetch_max_block_number() + end - assert {1, 1} = Chain.fetch_min_and_max_block_numbers() + test "fetches max when there are no blocks" do + assert 0 = Chain.fetch_max_block_number() end end diff --git a/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs b/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs index 3c2a9b6feb..b4b3313d6c 100644 --- a/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs +++ b/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs @@ -18,34 +18,6 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do } """ - @json_mkt_data """ - [ - { - "id": "poa-network", - "symbol": "poa", - "name": "POA Network", - "image": "https://assets.coingecko.com/coins/images/3157/large/poa.jpg?1520829019", - "current_price": 0.114782883773693, - "market_cap": 25248999.6735956, - "market_cap_rank": 185, - "total_volume": 2344442.13578437, - "high_24h": 0.115215129840519, - "low_24h": 0.101039753612939, - "price_change_24h": 0.0135970966607094, - "price_change_percentage_24h": 13.437753511298, - "market_cap_change_24h": 3058195.58191147, - "market_cap_change_percentage_24h": 13.7813644304017, - "circulating_supply": "219935174.0", - "total_supply": 252193195, - "ath": 0.935923393359191, - "ath_change_percentage": -87.731057963078, - "ath_date": "2018-05-10T09:45:31.809Z", - "roi": null, - "last_updated": "2018-10-23T01:25:31.764Z" - } - ] - """ - describe "format_data/1" do setup do bypass = Bypass.open() @@ -59,31 +31,30 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do Conn.resp(conn, 200, @json_btc_price) end) - {:ok, expected_date, 0} = "2018-10-23T01:25:31.764Z" |> DateTime.from_iso8601() + json_data = + "#{File.cwd!()}/test/support/fixture/exchange_rates/coin_gecko.json" + |> File.read!() + |> Jason.decode!() expected = [ %Token{ - available_supply: Decimal.new("252193195"), - total_supply: Decimal.new("252193195"), - btc_value: Decimal.new("0.00001753101509231471092879666458"), + available_supply: Decimal.new("220167621.0"), + total_supply: Decimal.new("252193195.0"), + btc_value: Decimal.new("0.000002055310963802830367634997491"), id: "poa-network", - last_updated: expected_date, - market_cap_usd: Decimal.new("25248999.6735956"), + last_updated: ~U[2019-08-21 08:36:49.371Z], + market_cap_usd: Decimal.new("2962791"), name: "POA Network", - symbol: "poa", - usd_value: Decimal.new("0.114782883773693"), - volume_24h_usd: Decimal.new("2344442.13578437") + symbol: "POA", + usd_value: Decimal.new("0.01345698"), + volume_24h_usd: Decimal.new("119946") } ] - assert expected == CoinGecko.format_data(@json_mkt_data) + assert expected == CoinGecko.format_data(json_data) end - test "returns nothing when given bad data", %{bypass: bypass} do - Bypass.expect(bypass, "GET", "/exchange_rates", fn conn -> - Conn.resp(conn, 200, @json_btc_price) - end) - + test "returns nothing when given bad data" do bad_data = """ [{"id": "poa-network"}] """ diff --git a/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs b/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs deleted file mode 100644 index e0f1693212..0000000000 --- a/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs +++ /dev/null @@ -1,59 +0,0 @@ -defmodule Explorer.ExchangeRates.Source.CoinMarketCapTest do - use ExUnit.Case - - alias Explorer.ExchangeRates.Token - alias Explorer.ExchangeRates.Source.CoinMarketCap - - @json """ - [ - { - "id": "poa-network", - "name": "POA Network", - "symbol": "POA", - "rank": "103", - "price_usd": "0.485053", - "price_btc": "0.00007032", - "24h_volume_usd": "20185000.0", - "market_cap_usd": "98941986.0", - "available_supply": "203981804.0", - "total_supply": "254473964.0", - "max_supply": null, - "percent_change_1h": "-0.66", - "percent_change_24h": "12.34", - "percent_change_7d": "49.15", - "last_updated": "1523473200" - } - ] - """ - - describe "format_data/1" do - test "returns valid tokens with valid data" do - expected_date = ~N[2018-04-11 19:00:00] |> DateTime.from_naive!("Etc/UTC") - - expected = [ - %Token{ - available_supply: Decimal.new("203981804.0"), - total_supply: Decimal.new("254473964.0"), - btc_value: Decimal.new("0.00007032"), - id: "poa-network", - last_updated: expected_date, - market_cap_usd: Decimal.new("98941986.0"), - name: "POA Network", - symbol: "POA", - usd_value: Decimal.new("0.485053"), - volume_24h_usd: Decimal.new("20185000.0") - } - ] - - assert expected == CoinMarketCap.format_data(@json) - end - - test "returns nothing when given bad data" do - bad_data = """ - [{"id": "poa-network"}] - """ - - assert [] = CoinMarketCap.format_data(bad_data) - end - end -end diff --git a/apps/explorer/test/explorer/exchange_rates/source/token_bridge_test.exs b/apps/explorer/test/explorer/exchange_rates/source/token_bridge_test.exs index d5bd5f9b96..febb9e7722 100644 --- a/apps/explorer/test/explorer/exchange_rates/source/token_bridge_test.exs +++ b/apps/explorer/test/explorer/exchange_rates/source/token_bridge_test.exs @@ -1,32 +1,41 @@ defmodule Explorer.ExchangeRates.Source.TokenBridgeTest do use Explorer.DataCase + + alias Explorer.ExchangeRates.Source.CoinGecko alias Explorer.ExchangeRates.Source.TokenBridge alias Explorer.ExchangeRates.Token + alias Plug.Conn + + @json "#{File.cwd!()}/test/support/fixture/exchange_rates/coin_gecko.json" + |> File.read!() + |> Jason.decode!() - @json """ - [ - { - "id": "poa-network", - "name": "POA Network", - "symbol": "POA", - "rank": "103", - "price_usd": "0.485053", - "price_btc": "0.00007032", - "24h_volume_usd": "20185000.0", - "market_cap_usd": "98941986.0", - "available_supply": "203981804.0", - "total_supply": "254473964.0", - "max_supply": null, - "percent_change_1h": "-0.66", - "percent_change_24h": "12.34", - "percent_change_7d": "49.15", - "last_updated": "1523473200" + @json_btc_price """ + { + "rates": { + "usd": { + "name": "US Dollar", + "unit": "$", + "value": 6547.418, + "type": "fiat" + } } - ] + } """ describe "format_data/1" do - test "bring a list with one %Token{}" do + setup do + bypass = Bypass.open() + Application.put_env(:explorer, CoinGecko, base_url: "http://localhost:#{bypass.port}") + + {:ok, bypass: bypass} + end + + test "bring a list with one %Token{}", %{bypass: bypass} do + Bypass.expect(bypass, "GET", "/exchange_rates", fn conn -> + Conn.resp(conn, 200, @json_btc_price) + end) + assert [%Token{}] = TokenBridge.format_data(@json) end end diff --git a/apps/explorer/test/support/data_case.ex b/apps/explorer/test/support/data_case.ex index fa87839725..47c15bbca0 100644 --- a/apps/explorer/test/support/data_case.ex +++ b/apps/explorer/test/support/data_case.ex @@ -39,7 +39,8 @@ defmodule Explorer.DataCase do Ecto.Adapters.SQL.Sandbox.mode(Explorer.Repo, {:shared, self()}) end - Explorer.Chain.Cache.BlockNumber.setup() + Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.BlockNumber.child_id()) + Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.BlockNumber.child_id()) Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) Supervisor.restart_child(Explorer.Supervisor, Explorer.Chain.Cache.Blocks.child_id()) Supervisor.terminate_child(Explorer.Supervisor, Explorer.Chain.Cache.Transactions.child_id()) diff --git a/apps/explorer/test/support/fixture/exchange_rates/coin_gecko.json b/apps/explorer/test/support/fixture/exchange_rates/coin_gecko.json new file mode 100644 index 0000000000..cc110eb402 --- /dev/null +++ b/apps/explorer/test/support/fixture/exchange_rates/coin_gecko.json @@ -0,0 +1,1806 @@ +{ + "asset_platform_id": null, + "block_time_in_minutes": 0, + "categories": [], + "coingecko_rank": 376, + "coingecko_score": 33.7, + "community_data": { + "facebook_likes": 0, + "reddit_accounts_active_48h": 0, + "reddit_average_comments_48h": 0.0, + "reddit_average_posts_48h": 0.0, + "reddit_subscribers": 0, + "telegram_channel_user_count": 5125, + "twitter_followers": 17737 + }, + "community_score": 9.403, + "country_origin": "", + "description": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "hu": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "ro": "", + "ru": "", + "sv": "", + "th": "", + "tr": "", + "vi": "", + "zh": "", + "zh-tw": "" + }, + "developer_data": { + "closed_issues": 0, + "code_additions_deletions_4_weeks": { + "additions": 0, + "deletions": 0 + }, + "commit_count_4_weeks": 0, + "forks": 44, + "last_4_weeks_commit_activity_series": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "pull_request_contributors": 6, + "pull_requests_merged": 133, + "stars": 58, + "subscribers": 8, + "total_issues": 0 + }, + "developer_score": 52.776, + "genesis_date": null, + "id": "poa-network", + "image": { + "large": "https://assets.coingecko.com/coins/images/3157/large/poa-network.png?1548331565", + "small": "https://assets.coingecko.com/coins/images/3157/small/poa-network.png?1548331565", + "thumb": "https://assets.coingecko.com/coins/images/3157/thumb/poa-network.png?1548331565" + }, + "last_updated": "2019-08-21T08:36:49.371Z", + "links": { + "announcement_url": [ + "", + "" + ], + "bitcointalk_thread_identifier": null, + "blockchain_site": [ + "https://blockscout.com/poa/core/", + "", + "", + "", + "" + ], + "chat_url": [ + "", + "", + "" + ], + "facebook_username": "", + "homepage": [ + "https://poa.network/", + "", + "" + ], + "official_forum_url": [ + "", + "", + "" + ], + "repos_url": { + "bitbucket": [], + "github": [ + "https://github.com/poanetwork/poa-network-consensus-contracts" + ] + }, + "subreddit_url": null, + "telegram_channel_identifier": "oraclesnetwork", + "twitter_screen_name": "poanetwork" + }, + "liquidity_score": 19.334, + "localization": { + "ar": "POA Network", + "de": "POA Network", + "en": "POA Network", + "es": "POA Network", + "fr": "POA Network", + "hu": "POA Network", + "id": "POA Network", + "it": "POA Network", + "ja": "ポアネットワーク", + "ko": "POA 네트워크", + "nl": "POA Network", + "pl": "POA Network", + "pt": "POA Network", + "ro": "POA Network", + "ru": "POA Network", + "sv": "POA Network", + "th": "POA Network", + "tr": "POA Network", + "vi": "POA Network", + "zh": "POA Network", + "zh-tw": "POA Network" + }, + "market_cap_rank": 499, + "market_data": { + "ath": { + "aed": 3.06, + "ars": 18.93, + "aud": 1.25, + "bch": 0.00076772, + "bdt": 70.74, + "bhd": 0.314495, + "bmd": 0.833914, + "bnb": 0.01322268, + "brl": 3.36, + "btc": 0.00010137, + "cad": 1.2, + "chf": 0.938803, + "clp": 519.58, + "cny": 5.94, + "czk": 17.83, + "dkk": 5.87, + "eos": 0.02444974, + "eth": 0.0011725, + "eur": 0.787803, + "gbp": 0.689151, + "hkd": 7.35, + "huf": 219.96, + "idr": 13179.33, + "ils": 2.97, + "inr": 62.94, + "jpy": 102.6, + "krw": 1000.83, + "kwd": 0.251571, + "lkr": 131.79, + "ltc": 0.00537407, + "mmk": 1125.41, + "mxn": 18.15, + "myr": 3.76, + "nok": 6.67, + "nzd": 1.35, + "php": 48.59, + "pkr": 96.55, + "pln": 3.34, + "rub": 58.27, + "sar": 3.13, + "sek": 8.13, + "sgd": 1.25, + "thb": 26.65, + "try": 3.54, + "twd": 27.89, + "uah": 1.44, + "usd": 0.935923, + "vef": 58307, + "vnd": 1281.67, + "xag": 0.056398, + "xau": 0.00071129, + "xdr": 0.656022, + "xlm": 0.58965135, + "xrp": 0.2920468, + "zar": 11.63 + }, + "ath_change_percentage": { + "aed": -98.3819, + "ars": -96.09901, + "aud": -98.40941, + "bch": -94.11046, + "bdt": -98.39058, + "bhd": -98.38261, + "bmd": -98.38194, + "bnb": -96.24179, + "brl": -98.37442, + "btc": -98.68937, + "cad": -98.49893, + "chf": -98.59269, + "clp": -98.15517, + "cny": -98.39701, + "czk": -98.2406, + "dkk": -98.45473, + "eos": -84.56025, + "eth": -93.8673, + "eur": -98.45627, + "gbp": -98.38711, + "hkd": -98.55948, + "huf": -98.18974, + "idr": -98.54127, + "ils": -98.39903, + "inr": -98.46908, + "jpy": -98.59899, + "krw": -98.37868, + "kwd": -98.3684, + "lkr": -98.16735, + "ltc": -96.51103, + "mmk": -98.17585, + "mxn": -98.53298, + "myr": -98.49907, + "nok": -98.18519, + "nzd": -98.43938, + "php": -98.54716, + "pkr": -97.76349, + "pln": -98.41583, + "rub": -98.4658, + "sar": -98.3821, + "sek": -98.39542, + "sgd": -98.51152, + "thb": -98.44172, + "try": -97.81784, + "twd": -98.48322, + "uah": -76.52065, + "usd": -98.5583, + "vef": -94.2496, + "vnd": -75.59837, + "xag": -98.59644, + "xau": -98.73411, + "xdr": -98.49988, + "xlm": -66.24383, + "xrp": -82.56607, + "zar": -98.23009 + }, + "ath_date": { + "aed": "2018-05-10T00:00:00.000Z", + "ars": "2018-05-10T00:00:00.000Z", + "aud": "2018-05-10T09:45:31.809Z", + "bch": "2018-04-14T00:00:00.000Z", + "bdt": "2018-05-10T00:00:00.000Z", + "bhd": "2018-05-10T00:00:00.000Z", + "bmd": "2018-05-10T00:00:00.000Z", + "bnb": "2018-10-16T12:40:17.749Z", + "brl": "2018-05-10T09:45:31.809Z", + "btc": "2018-05-10T09:45:31.809Z", + "cad": "2018-05-10T09:45:31.809Z", + "chf": "2018-05-10T09:45:31.809Z", + "clp": "2018-05-10T00:00:00.000Z", + "cny": "2018-05-10T09:45:31.809Z", + "czk": "2018-05-10T00:00:00.000Z", + "dkk": "2018-05-10T09:45:31.809Z", + "eos": "2018-10-16T12:40:17.749Z", + "eth": "2018-04-09T00:00:00.000Z", + "eur": "2018-05-10T09:45:31.809Z", + "gbp": "2018-05-10T09:45:31.809Z", + "hkd": "2018-05-10T09:45:31.809Z", + "huf": "2018-05-10T00:00:00.000Z", + "idr": "2018-05-10T09:45:31.809Z", + "ils": "2018-05-10T00:00:00.000Z", + "inr": "2018-05-10T09:45:31.809Z", + "jpy": "2018-05-10T09:45:31.809Z", + "krw": "2018-05-10T09:45:31.809Z", + "kwd": "2018-05-10T00:00:00.000Z", + "lkr": "2018-05-10T00:00:00.000Z", + "ltc": "2018-05-10T00:00:00.000Z", + "mmk": "2018-05-10T00:00:00.000Z", + "mxn": "2018-05-10T09:45:31.809Z", + "myr": "2018-05-10T09:45:31.809Z", + "nok": "2018-05-10T00:00:00.000Z", + "nzd": "2018-05-10T09:45:31.809Z", + "php": "2018-05-10T09:45:31.809Z", + "pkr": "2018-05-10T00:00:00.000Z", + "pln": "2018-05-10T09:45:31.809Z", + "rub": "2018-05-10T09:45:31.809Z", + "sar": "2018-05-10T00:00:00.000Z", + "sek": "2018-05-10T09:45:31.809Z", + "sgd": "2018-05-10T09:45:31.809Z", + "thb": "2018-05-10T00:00:00.000Z", + "try": "2018-05-10T00:00:00.000Z", + "twd": "2018-05-10T09:45:31.809Z", + "uah": "2019-05-27T12:49:29.532Z", + "usd": "2018-05-10T09:45:31.809Z", + "vef": "2018-05-10T00:00:00.000Z", + "vnd": "2019-05-27T12:49:29.532Z", + "xag": "2018-05-10T09:45:31.809Z", + "xau": "2018-05-10T09:45:31.809Z", + "xdr": "2018-05-10T09:45:31.809Z", + "xlm": "2018-10-16T12:49:26.379Z", + "xrp": "2018-10-16T12:40:17.749Z", + "zar": "2018-05-10T09:45:31.809Z" + }, + "circulating_supply": 220167621.0, + "current_price": { + "aed": 0.04942712, + "ars": 0.73641, + "aud": 0.0198328, + "bch": 4.486e-05, + "bdt": 1.14, + "bhd": 0.00507448, + "bmd": 0.01345698, + "bnb": 0.00049505, + "brl": 0.054544, + "btc": 1.32e-06, + "cad": 0.0178991, + "chf": 0.01317061, + "clp": 9.55, + "cny": 0.095047, + "czk": 0.312629, + "dkk": 0.090366, + "eos": 0.0037559, + "eth": 7.147e-05, + "eur": 0.01211961, + "gbp": 0.01107566, + "hkd": 0.105541, + "huf": 3.97, + "idr": 191.75, + "ils": 0.04745883, + "inr": 0.960893, + "jpy": 1.43, + "krw": 16.19, + "kwd": 0.00409361, + "lkr": 2.4, + "ltc": 0.00018598, + "mmk": 20.47, + "mxn": 0.26536, + "myr": 0.056211, + "nok": 0.120606, + "nzd": 0.02100918, + "php": 0.704042, + "pkr": 2.15, + "pln": 0.052749, + "rub": 0.891153, + "sar": 0.050476, + "sek": 0.129909, + "sgd": 0.01861909, + "thb": 0.414071, + "try": 0.076819, + "twd": 0.422042, + "uah": 0.338308, + "usd": 0.01345698, + "vef": 3343.89, + "vnd": 311.66, + "xag": 0.00078867, + "xau": 8.98e-06, + "xdr": 0.00981471, + "xlm": 0.1975895, + "xrp": 0.05067322, + "zar": 0.204922 + }, + "high_24h": { + "aed": 0.053611, + "ars": 0.810805, + "aud": 0.02152674, + "bch": 4.628e-05, + "bdt": 1.23, + "bhd": 0.00550347, + "bmd": 0.0145949, + "bnb": 0.00052215, + "brl": 0.058875, + "btc": 1.37e-06, + "cad": 0.01943935, + "chf": 0.01428979, + "clp": 10.36, + "cny": 0.103044, + "czk": 0.339287, + "dkk": 0.098076, + "eos": 0.00402026, + "eth": 7.423e-05, + "eur": 0.01315448, + "gbp": 0.01201087, + "hkd": 0.114474, + "huf": 4.31, + "idr": 208.11, + "ils": 0.051491, + "inr": 1.04, + "jpy": 1.55, + "krw": 17.63, + "kwd": 0.00443977, + "lkr": 2.6, + "ltc": 0.00019631, + "mmk": 22.24, + "mxn": 0.288202, + "myr": 0.061014, + "nok": 0.131376, + "nzd": 0.02274396, + "php": 0.76332, + "pkr": 2.34, + "pln": 0.057291, + "rub": 0.972261, + "sar": 0.054726, + "sek": 0.14165, + "sgd": 0.02021141, + "thb": 0.449117, + "try": 0.083602, + "twd": 0.457778, + "uah": 0.367456, + "usd": 0.0145949, + "vef": 3626.65, + "vnd": 338.27, + "xag": 0.00085369, + "xau": 9.72e-06, + "xdr": 0.01064365, + "xlm": 0.20827298, + "xrp": 0.05318558, + "zar": 0.223696 + }, + "last_updated": "2019-08-21T08:36:49.371Z", + "low_24h": { + "aed": 0.0491677, + "ars": 0.732555, + "aud": 0.0197477, + "bch": 4.364e-05, + "bdt": 1.13, + "bhd": 0.00504693, + "bmd": 0.01338635, + "bnb": 0.00049273, + "brl": 0.054256, + "btc": 1.3e-06, + "cad": 0.01782004, + "chf": 0.01311131, + "clp": 9.51, + "cny": 0.094517, + "czk": 0.311235, + "dkk": 0.089982, + "eos": 0.00373147, + "eth": 7.098e-05, + "eur": 0.01206786, + "gbp": 0.01103078, + "hkd": 0.104993, + "huf": 3.95, + "idr": 190.79, + "ils": 0.04723279, + "inr": 0.958004, + "jpy": 1.43, + "krw": 16.1, + "kwd": 0.00406945, + "lkr": 2.39, + "ltc": 0.00018228, + "mmk": 20.37, + "mxn": 0.264134, + "myr": 0.055903, + "nok": 0.120189, + "nzd": 0.02091282, + "php": 0.700581, + "pkr": 2.14, + "pln": 0.052569, + "rub": 0.886879, + "sar": 0.050214, + "sek": 0.129578, + "sgd": 0.01853166, + "thb": 0.412199, + "try": 0.076627, + "twd": 0.4198, + "uah": 0.336532, + "usd": 0.01338635, + "vef": 3326.34, + "vnd": 310.32, + "xag": 0.00078625, + "xau": 8.93e-06, + "xdr": 0.0097632, + "xlm": 0.19635382, + "xrp": 0.05037993, + "zar": 0.204544 + }, + "market_cap": { + "aed": 10882251, + "ars": 162133701, + "aud": 4366541, + "bch": 9877, + "bdt": 249997342, + "bhd": 1117236, + "bmd": 2962791, + "bnb": 108994, + "brl": 12008719, + "btc": 290.732, + "cad": 3940802, + "chf": 2899743, + "clp": 2101619696, + "cny": 20926193, + "czk": 68830802, + "dkk": 19895675, + "eos": 826927, + "eth": 15736, + "eur": 2668346, + "gbp": 2438501, + "hkd": 23236814, + "huf": 873552757, + "idr": 42217105275, + "ils": 10448899, + "inr": 211557455, + "jpy": 315583737, + "krw": 3564593111, + "kwd": 901281, + "lkr": 529480380, + "ltc": 40948, + "mmk": 4507718929, + "mxn": 58423768, + "myr": 12375904, + "nok": 26553448, + "nzd": 4625542, + "php": 155007300, + "pkr": 474133000, + "pln": 11613646, + "rub": 196202962, + "sar": 11113192, + "sek": 28601664, + "sgd": 4099321, + "thb": 91165079, + "try": 16912998, + "twd": 92920077, + "uah": 74484427, + "usd": 2962791, + "vef": 736216950688, + "vnd": 68617204931, + "xag": 173639, + "xau": 1976.89, + "xdr": 2160882, + "xlm": 43502811, + "xrp": 11156602, + "zar": 45117091 + }, + "market_cap_change_24h": -160615.84039035, + "market_cap_change_24h_in_currency": { + "aed": -590899.65443375, + "ars": -9124373.5980551, + "aud": -239353.78003874, + "bch": 102.549, + "bdt": -13867874.4362154, + "bhd": -60251.00254582, + "bmd": -160615.84039035, + "bnb": -1507.543569741, + "brl": -718070.38245432, + "btc": 0.03769596, + "cad": -221121.61427417, + "chf": -161095.94704691, + "clp": -127118490.79824165, + "cny": -1134429.68067712, + "czk": -3925858.7665586, + "dkk": -1136450.3780936, + "eos": -24548.1071608166, + "eth": -56.533938946, + "eur": -152193.5816755, + "gbp": -144996.42715597, + "hkd": -1263688.72303977, + "huf": -48860628.81047357, + "idr": -2346101857.217293, + "ils": -576162.08791993, + "inr": -12451722.53525829, + "jpy": -16857632.06248754, + "krw": -209731718.0214291, + "kwd": -49171.67933105, + "lkr": -26048761.01962376, + "ltc": -309.0831858893, + "mmk": -251710124.48363495, + "mxn": -3503488.89323037, + "myr": -687829.52792143, + "nok": -1513569.75537506, + "nzd": -244980.03753899, + "php": -8388263.35503852, + "pkr": -26642819.2931419, + "pln": -696325.10549893, + "rub": -12221976.62125358, + "sar": -601457.67784725, + "sek": -1668070.90346983, + "sgd": -230174.18438848, + "thb": -5107689.97148955, + "try": -927927.24538566, + "twd": -5107834.82635887, + "uah": -4241989.31565817, + "usd": -160615.84039035, + "vef": -39911051485.156494, + "vnd": -4088394297.5983276, + "xag": -9606.58322042, + "xau": -102.32803274, + "xdr": -115659.93877989, + "xlm": -1276957.0373063833, + "xrp": -122973.5124849025, + "zar": -2969034.78716005 + }, + "market_cap_change_percentage_24h": -5.14233, + "market_cap_change_percentage_24h_in_currency": { + "aed": -5.15028, + "ars": -5.32785, + "aud": -5.19668, + "bch": 1.0491, + "bdt": -5.25567, + "bhd": -5.11691, + "bmd": -5.14233, + "bnb": -1.36428, + "brl": -5.6422, + "btc": 0.01297, + "cad": -5.31297, + "chf": -5.26313, + "clp": -5.70361, + "cny": -5.14233, + "czk": -5.39588, + "dkk": -5.4034, + "eos": -2.88301, + "eth": -0.35797, + "eur": -5.3959, + "gbp": -5.61241, + "hkd": -5.15781, + "huf": -5.29704, + "idr": -5.26466, + "ils": -5.22593, + "inr": -5.55858, + "jpy": -5.07086, + "krw": -5.5568, + "kwd": -5.1735, + "lkr": -4.689, + "ltc": -0.74917, + "mmk": -5.28866, + "mxn": -5.65743, + "myr": -5.26518, + "nok": -5.3927, + "nzd": -5.02985, + "php": -5.13372, + "pkr": -5.32031, + "pln": -5.65659, + "rub": -5.86397, + "sar": -5.13424, + "sek": -5.51069, + "sgd": -5.31642, + "thb": -5.30544, + "try": -5.20112, + "twd": -5.21059, + "uah": -5.38827, + "usd": -5.14233, + "vef": -5.14233, + "vnd": -5.62322, + "xag": -5.24248, + "xau": -4.92146, + "xdr": -5.08051, + "xlm": -2.85164, + "xrp": -1.09023, + "zar": -6.17441 + }, + "market_cap_rank": 499, + "price_change_24h": -0.00070501, + "price_change_24h_in_currency": { + "aed": -0.00259384, + "ars": -0.0401764, + "aud": -0.00106049, + "bch": 4.401e-07, + "bdt": -0.06091731, + "bhd": -0.00026442, + "bmd": -0.00070501, + "bnb": -7.9537e-06, + "brl": -0.00316161, + "btc": -7e-10, + "cad": -0.000975, + "chf": -0.00070391, + "clp": -0.55975334, + "cny": -0.00498938, + "czk": -0.01720638, + "dkk": -0.00497873, + "eos": -0.0001041039, + "eth": -1.756e-07, + "eur": -0.00066664, + "gbp": -0.00063744, + "hkd": -0.00554812, + "huf": -0.21652693, + "idr": -10.32117361, + "ils": -0.00254123, + "inr": -0.05433204, + "jpy": -0.07396812, + "krw": -0.92440016, + "kwd": -0.00021588, + "lkr": -0.11324611, + "ltc": -1.1432e-06, + "mmk": -1.10591975, + "mxn": -0.01564173, + "myr": -0.00303114, + "nok": -0.0066618, + "nzd": -0.00108422, + "php": -0.03666507, + "pkr": -0.11708205, + "pln": -0.0030605, + "rub": -0.05396307, + "sar": -0.00263569, + "sek": -0.00737328, + "sgd": -0.00101489, + "thb": -0.02240118, + "try": -0.00415931, + "twd": -0.02243055, + "uah": -0.01864934, + "usd": -0.00070501, + "vef": -175.18566197, + "vnd": -17.91454955, + "xag": -4.268e-05, + "xau": -4.5e-07, + "xdr": -0.00050746, + "xlm": -0.0043814329, + "xrp": -0.0005808077, + "zar": -0.01325238 + }, + "price_change_percentage_14d": -20.09212, + "price_change_percentage_14d_in_currency": { + "aed": -20.09664, + "ars": -3.40252, + "aud": -20.3743, + "bch": -10.35771, + "bdt": -20.21051, + "bhd": -20.07198, + "bmd": -20.09212, + "bnb": -18.90438, + "brl": -18.21564, + "btc": -10.20835, + "cad": -19.99931, + "chf": -19.86474, + "clp": -20.70274, + "cny": -19.67703, + "czk": -19.20224, + "dkk": -19.44946, + "eos": -6.27667, + "eth": -3.85819, + "eur": -19.3615, + "gbp": -19.99287, + "hkd": -20.04155, + "huf": -18.72941, + "idr": -19.92585, + "ils": -19.11955, + "inr": -19.53455, + "jpy": -19.93789, + "krw": -20.72061, + "kwd": -20.08213, + "lkr": -19.39749, + "ltc": 3.01755, + "mmk": -19.52559, + "mxn": -19.64657, + "myr": -20.39088, + "nok": -19.55283, + "nzd": -18.54, + "php": -19.79625, + "pkr": -19.69932, + "pln": -18.70635, + "rub": -18.9447, + "sar": -20.11299, + "sek": -19.43426, + "sgd": -19.93866, + "thb": -19.96922, + "try": -17.50796, + "twd": -20.26871, + "uah": -21.43567, + "usd": -20.09212, + "vef": -20.09212, + "vnd": -20.39781, + "xag": -22.82706, + "xau": -21.25807, + "xdr": -19.80447, + "xlm": -6.90503, + "xrp": -5.82792, + "zar": -18.53383 + }, + "price_change_percentage_1h_in_currency": { + "aed": -0.65082, + "ars": -0.65814, + "aud": -0.81241, + "bch": 1.34916, + "bdt": -0.64945, + "bhd": -0.62736, + "bmd": -0.65082, + "bnb": -0.66128, + "brl": -0.65109, + "btc": -0.64949, + "cad": -0.75327, + "chf": -0.6566, + "clp": -0.81121, + "cny": -0.61001, + "czk": -0.71198, + "dkk": -0.72865, + "eos": -0.27623, + "eth": -0.72711, + "eur": -0.73062, + "gbp": -0.79594, + "hkd": -0.65424, + "huf": -0.65304, + "idr": -0.69877, + "ils": -0.68895, + "inr": -0.85681, + "jpy": -0.70261, + "krw": -0.64504, + "kwd": -0.68347, + "lkr": -0.66193, + "ltc": 0.20669, + "mmk": -0.65082, + "mxn": -0.79588, + "myr": -0.58632, + "nok": -0.94166, + "nzd": -0.77361, + "php": -0.65651, + "pkr": -0.65082, + "pln": -0.82133, + "rub": -0.80523, + "sar": -0.62904, + "sek": -0.92466, + "sgd": -0.72845, + "thb": -0.71559, + "try": -0.93842, + "twd": -0.63818, + "uah": -0.65082, + "usd": -0.65082, + "vef": -0.65082, + "vnd": -0.72098, + "xag": -0.86625, + "xau": -0.66422, + "xdr": -0.65082, + "xlm": -0.6397, + "xrp": -0.05073, + "zar": -1.25864 + }, + "price_change_percentage_1y": -80.39683, + "price_change_percentage_1y_in_currency": { + "aed": -80.39794, + "ars": -61.05676, + "aud": -78.80429, + "bch": -66.67604, + "bdt": -80.26581, + "bhd": -80.39891, + "bmd": -80.39683, + "brl": -79.97401, + "btc": -87.93415, + "cad": -80.00734, + "chf": -80.63119, + "clp": -79.21186, + "cny": -79.80673, + "czk": -79.67769, + "dkk": -79.72199, + "eth": -71.77736, + "eur": -79.71573, + "gbp": -79.34655, + "hkd": -80.41399, + "huf": -79.49619, + "idr": -80.5156, + "ils": -81.08059, + "inr": -79.93604, + "jpy": -81.01454, + "krw": -78.90452, + "kwd": -80.34132, + "lkr": -78.15787, + "ltc": -85.4361, + "mmk": -80.27721, + "mxn": -79.65762, + "myr": -80.02222, + "nok": -79.18424, + "nzd": -79.67365, + "php": -80.76747, + "pkr": -74.51734, + "pln": -79.50758, + "rub": -80.62327, + "sar": -80.39647, + "sek": -79.31728, + "sgd": -80.18923, + "thb": -81.67711, + "try": -81.65737, + "twd": -79.98887, + "uah": -82.20648, + "usd": -80.39683, + "vef": -80.39558, + "vnd": -80.34916, + "xag": -83.03235, + "xau": -84.4215, + "xdr": -80.03907, + "zar": -79.43625 + }, + "price_change_percentage_200d": -50.1114, + "price_change_percentage_200d_in_currency": { + "aed": -50.11196, + "ars": -26.51722, + "aud": -46.67198, + "bch": -80.79243, + "bdt": -49.71149, + "bhd": -50.09578, + "bmd": -50.1114, + "bnb": -87.93302, + "brl": -44.75887, + "btc": -83.02991, + "cad": -49.34427, + "chf": -50.94689, + "clp": -45.88183, + "cny": -47.75857, + "czk": -48.37087, + "dkk": -48.59098, + "eos": -67.57399, + "eth": -71.6239, + "eur": -48.52075, + "gbp": -46.27358, + "hkd": -50.136, + "huf": -46.91923, + "idr": -49.00487, + "ils": -51.63145, + "inr": -50.15368, + "jpy": -51.46878, + "krw": -46.36111, + "kwd": -49.91845, + "lkr": -49.53248, + "ltc": -77.44522, + "mmk": -49.82943, + "mxn": -48.49618, + "myr": -49.12989, + "nok": -47.01887, + "nzd": -46.2816, + "php": -50.10377, + "pkr": -42.33563, + "pln": -47.7461, + "rub": -49.52654, + "sar": -50.10515, + "sek": -46.7992, + "sgd": -48.88484, + "thb": -50.95616, + "try": -45.32063, + "twd": -49.1634, + "uah": -54.76622, + "usd": -50.1114, + "vef": -50.1114, + "vnd": -50.2089, + "xag": -53.50147, + "xau": -56.13406, + "xdr": -49.07152, + "xlm": -39.53366, + "xrp": -42.37148, + "zar": -42.98063 + }, + "price_change_percentage_24h": -4.97817, + "price_change_percentage_24h_in_currency": { + "aed": -4.98614, + "ars": -5.17346, + "aud": -5.07575, + "bch": 0.99066, + "bdt": -5.0917, + "bhd": -4.95271, + "bmd": -4.97817, + "bnb": -1.58124, + "brl": -5.4789, + "btc": -0.05257, + "cad": -5.16583, + "chf": -5.07341, + "clp": -5.53921, + "cny": -4.98758, + "czk": -5.21666, + "dkk": -5.22182, + "eos": -2.69699, + "eth": -0.24506, + "eur": -5.21371, + "gbp": -5.44209, + "hkd": -4.99428, + "huf": -5.17487, + "idr": -5.1077, + "ils": -5.08246, + "inr": -5.35173, + "jpy": -4.90717, + "krw": -5.40119, + "kwd": -5.00939, + "lkr": -4.49721, + "ltc": -0.61091, + "mmk": -5.12476, + "mxn": -5.56641, + "myr": -5.1165, + "nok": -5.23449, + "nzd": -4.90745, + "php": -4.95001, + "pkr": -5.15646, + "pln": -5.48383, + "rub": -5.70968, + "sar": -4.96254, + "sek": -5.3709, + "sgd": -5.16905, + "thb": -5.13232, + "try": -5.13634, + "twd": -5.04655, + "uah": -5.22453, + "usd": -4.97817, + "vef": -4.97817, + "vnd": -5.43568, + "xag": -5.1341, + "xau": -4.8084, + "xdr": -4.91624, + "xlm": -2.16934, + "xrp": -1.13319, + "zar": -6.07423 + }, + "price_change_percentage_30d": -34.83569, + "price_change_percentage_30d_in_currency": { + "aed": -34.83544, + "ars": -15.98426, + "aud": -32.35353, + "bch": -30.11906, + "bdt": -34.93771, + "bhd": -34.7457, + "bmd": -34.83569, + "bnb": -27.08407, + "brl": -29.51868, + "btc": -32.08124, + "cad": -33.60701, + "chf": -35.09987, + "clp": -32.84418, + "cny": -33.12269, + "czk": -33.51308, + "dkk": -34.24389, + "eos": -21.08346, + "eth": -21.69788, + "eur": -34.16271, + "gbp": -32.89529, + "hkd": -34.53494, + "huf": -33.76133, + "idr": -33.48833, + "ils": -35.07099, + "inr": -32.4077, + "jpy": -35.60577, + "krw": -33.33925, + "kwd": -34.83162, + "lkr": -33.78522, + "ltc": -10.07379, + "mmk": -34.67478, + "mxn": -32.46726, + "myr": -33.79734, + "nok": -31.87864, + "nzd": -31.23716, + "php": -33.28065, + "pkr": -34.80085, + "pln": -32.59928, + "rub": -31.5309, + "sar": -34.83447, + "sek": -32.96828, + "sgd": -33.73135, + "thb": -35.04678, + "try": -34.23351, + "twd": -34.17354, + "uah": -36.37221, + "usd": -34.83569, + "vef": -34.83569, + "vnd": -35.19581, + "xag": -38.03606, + "xau": -38.0235, + "xdr": -34.25025, + "xlm": -12.74201, + "xrp": -18.8697, + "zar": -28.75132 + }, + "price_change_percentage_60d": -61.24989, + "price_change_percentage_60d_in_currency": { + "aed": -61.25202, + "ars": -50.32249, + "aud": -60.412, + "bch": -43.0945, + "bdt": -61.20391, + "bhd": -61.23344, + "bmd": -61.24989, + "bnb": -44.49169, + "brl": -58.90604, + "btc": -61.42639, + "cad": -61.04496, + "chf": -61.10703, + "clp": -59.79652, + "cny": -60.16104, + "czk": -60.03065, + "dkk": -60.38034, + "eos": -23.51938, + "eth": -39.23291, + "eur": -60.26215, + "gbp": -59.36192, + "hkd": -61.10542, + "huf": -59.91464, + "idr": -60.90777, + "ils": -62.26651, + "inr": -60.23354, + "jpy": -61.53855, + "krw": -59.78067, + "kwd": -61.16844, + "lkr": -60.71768, + "ltc": -25.65935, + "mmk": -61.20413, + "mxn": -60.04539, + "myr": -60.87356, + "nok": -59.13075, + "nzd": -60.12056, + "php": -60.49041, + "pkr": -60.53743, + "pln": -59.42569, + "rub": -59.28727, + "sar": -61.24451, + "sek": -59.99926, + "sgd": -60.43237, + "thb": -61.1805, + "try": -62.00162, + "twd": -60.74424, + "uah": -62.83383, + "usd": -61.24989, + "vef": -61.24989, + "vnd": -61.16958, + "xag": -65.19693, + "xau": -63.82007, + "xdr": -60.62729, + "xlm": -29.85582, + "xrp": -35.11899, + "zar": -58.83133 + }, + "price_change_percentage_7d": -12.91815, + "price_change_percentage_7d_in_currency": { + "aed": -12.92308, + "ars": -14.25115, + "aud": -12.76443, + "bch": 0.88592, + "bdt": -13.147, + "bhd": -12.88673, + "bmd": -12.91815, + "bnb": -5.78627, + "brl": -10.95714, + "btc": -6.92663, + "cad": -12.35787, + "chf": -12.68629, + "clp": -12.25865, + "cny": -12.67706, + "czk": -12.47009, + "dkk": -12.42719, + "eos": -0.91188, + "eth": -3.2526, + "eur": -12.3442, + "gbp": -13.56715, + "hkd": -12.94473, + "huf": -11.29007, + "idr": -13.63998, + "ils": -11.80257, + "inr": -12.53093, + "jpy": -12.98836, + "krw": -13.1693, + "kwd": -12.90068, + "lkr": -11.99684, + "ltc": 1.8824, + "mmk": -12.2934, + "mxn": -11.39186, + "myr": -13.13461, + "nok": -11.99025, + "nzd": -12.14546, + "php": -12.50757, + "pkr": -13.04362, + "pln": -11.96443, + "rub": -11.16958, + "sar": -12.91768, + "sek": -11.88369, + "sgd": -12.90808, + "thb": -12.98884, + "try": -10.77039, + "twd": -12.26523, + "uah": -12.97908, + "usd": -12.91815, + "vef": -12.91815, + "vnd": -13.40154, + "xag": -13.34686, + "xau": -12.77828, + "xdr": -12.6042, + "xlm": -3.71389, + "xrp": -2.40223, + "zar": -12.40714 + }, + "roi": null, + "total_supply": 252193195.0, + "total_volume": { + "aed": 440559, + "ars": 6563849, + "aud": 176776, + "bch": 399.879, + "bdt": 10120936, + "bhd": 45230, + "bmd": 119946, + "bnb": 4413, + "brl": 486163, + "btc": 11.770053, + "cad": 159540, + "chf": 117394, + "clp": 85082341, + "cny": 847180, + "czk": 2786558, + "dkk": 805460, + "eos": 33477, + "eth": 637.075, + "eur": 108026, + "gbp": 98721, + "hkd": 940723, + "huf": 35365063, + "idr": 1709124708, + "ils": 423015, + "inr": 8564729, + "jpy": 12776147, + "krw": 144309614, + "kwd": 36488, + "lkr": 21435577, + "ltc": 1658, + "mmk": 182491285, + "mxn": 2365238, + "myr": 501028, + "nok": 1074994, + "nzd": 187261, + "php": 6275343, + "pkr": 19194884, + "pln": 470169, + "rub": 7943115, + "sar": 449908, + "sek": 1157915, + "sgd": 165958, + "thb": 3690743, + "try": 684709, + "twd": 3761793, + "uah": 3015441, + "usd": 119946, + "vef": 29805136391, + "vnd": 2777910981, + "xag": 7029.61, + "xau": 80.03, + "xdr": 87482, + "xlm": 1761175, + "xrp": 451666, + "zar": 1826528 + } + }, + "name": "POA Network", + "public_interest_score": 27.778, + "public_interest_stats": { + "alexa_rank": 702581, + "bing_matches": 107000 + }, + "sentiment_votes_down_percentage": null, + "sentiment_votes_up_percentage": null, + "status_updates": [], + "symbol": "poa", + "tickers": [ + { + "base": "POA", + "bid_ask_spread_percentage": 1.503759, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.32e-06, + "eth": 7.139e-05, + "usd": 0.01344331 + }, + "converted_volume": { + "btc": 10.856044, + "eth": 587.121, + "usd": 110562 + }, + "is_anomaly": false, + "is_stale": false, + "last": 1.32e-06, + "last_fetch_at": "2019-08-21T08:34:21+00:00", + "last_traded_at": "2019-08-21T08:34:21+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "binance", + "name": "Binance" + }, + "target": "BTC", + "timestamp": "2019-08-21T08:34:21+00:00", + "trade_url": "https://www.binance.com/trade.html?symbol=POA_BTC", + "trust_score": "green", + "volume": 8224275.5227272725 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 1.729386, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.34e-06, + "eth": 7.226e-05, + "usd": 0.01360764 + }, + "converted_volume": { + "btc": 0.35219856, + "eth": 19.04774, + "usd": 3586.91 + }, + "is_anomaly": false, + "is_stale": false, + "last": 7.238e-05, + "last_fetch_at": "2019-08-21T08:34:26+00:00", + "last_traded_at": "2019-08-21T08:34:26+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "binance", + "name": "Binance" + }, + "target": "ETH", + "timestamp": "2019-08-21T08:34:26+00:00", + "trade_url": "https://www.binance.com/trade.html?symbol=POA_ETH", + "trust_score": "green", + "volume": 263595.07819839736 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 1.39165, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.34e-06, + "eth": 7.259e-05, + "usd": 0.01363846 + }, + "converted_volume": { + "btc": 0.24038472, + "eth": 13.008637, + "usd": 2444.17 + }, + "is_anomaly": false, + "is_stale": false, + "last": 0.000502, + "last_fetch_at": "2019-08-21T08:34:26+00:00", + "last_traded_at": "2019-08-21T08:13:08+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "binance", + "name": "Binance" + }, + "target": "BNB", + "timestamp": "2019-08-21T08:13:08+00:00", + "trade_url": "https://www.binance.com/trade.html?symbol=POA_BNB", + "trust_score": "green", + "volume": 179211.83864541832 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 2.985075, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.3e-06, + "eth": 7.036e-05, + "usd": 0.01324803 + }, + "converted_volume": { + "btc": 0.1595777, + "eth": 8.637423, + "usd": 1626.22 + }, + "is_anomaly": false, + "is_stale": false, + "last": 1.3e-06, + "last_fetch_at": "2019-08-21T08:36:07+00:00", + "last_traded_at": "2019-08-21T08:36:07+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "bibox", + "name": "Bibox" + }, + "target": "BTC", + "timestamp": "2019-08-21T08:36:07+00:00", + "trade_url": "https://www.bibox.com/exchange?coinPair=POA_BTC", + "trust_score": "yellow", + "volume": 122752.0737 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 3.247202, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.31e-06, + "eth": 7.077e-05, + "usd": 0.01332498 + }, + "converted_volume": { + "btc": 0.1127777, + "eth": 6.104291, + "usd": 1149.29 + }, + "is_anomaly": false, + "is_stale": false, + "last": 7.087e-05, + "last_fetch_at": "2019-08-21T08:35:50+00:00", + "last_traded_at": "2019-08-21T08:35:50+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "bibox", + "name": "Bibox" + }, + "target": "ETH", + "timestamp": "2019-08-21T08:35:50+00:00", + "trade_url": "https://www.bibox.com/exchange?coinPair=POA_ETH", + "trust_score": "yellow", + "volume": 86251.0552 + }, + { + "base": "POA20", + "bid_ask_spread_percentage": 13.032676, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.16e-06, + "eth": 6.257e-05, + "usd": 0.01177973 + }, + "converted_volume": { + "btc": 0.00087672, + "eth": 0.04748752, + "usd": 8.94 + }, + "is_anomaly": false, + "is_stale": false, + "last": 1.1551e-06, + "last_fetch_at": "2019-08-21T08:37:38+00:00", + "last_traded_at": "2019-08-21T07:08:25+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "BTC", + "timestamp": "2019-08-21T07:08:25+00:00", + "trade_url": "https://hitbtc.com/POA20-to-BTC", + "trust_score": "red", + "volume": 759.0 + }, + { + "base": "POA20", + "bid_ask_spread_percentage": 33.072445, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.57e-06, + "eth": 8.48e-05, + "usd": 0.01595278 + }, + "converted_volume": { + "btc": 0.00021915, + "eth": 0.0118714, + "usd": 2.23 + }, + "is_anomaly": false, + "is_stale": false, + "last": 8.4891e-05, + "last_fetch_at": "2019-08-21T08:37:21+00:00", + "last_traded_at": "2019-08-21T07:37:25+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "ETH", + "timestamp": "2019-08-21T07:37:25+00:00", + "trade_url": "https://hitbtc.com/POA20-to-ETH", + "trust_score": "red", + "volume": 140.0 + }, + { + "base": "POA20", + "bid_ask_spread_percentage": 53.1004, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.15e-06, + "eth": 6.232e-05, + "usd": 0.0117249 + }, + "converted_volume": { + "btc": 7.478e-05, + "eth": 0.00405098, + "usd": 0.762119 + }, + "is_anomaly": false, + "is_stale": false, + "last": 0.0117249, + "last_fetch_at": "2019-08-21T08:37:46+00:00", + "last_traded_at": "2019-08-21T07:37:33+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "USD", + "timestamp": "2019-08-21T07:37:33+00:00", + "trade_url": "https://hitbtc.com/POA20-to-USD", + "trust_score": null, + "volume": 65.0 + }, + { + "base": "POA20", + "bid_ask_spread_percentage": null, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.32e-06, + "eth": 7.134e-05, + "usd": 0.01339322 + }, + "converted_volume": { + "btc": 0.03831341, + "eth": 2.073192, + "usd": 389.22 + }, + "is_anomaly": false, + "is_stale": false, + "last": 0.034733328618915156, + "last_fetch_at": "2019-08-21T08:21:59+00:00", + "last_traded_at": "2019-08-21T08:21:59+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "bancor", + "name": "Bancor Network" + }, + "target": "BNT", + "timestamp": "2019-08-21T08:21:59+00:00", + "trade_url": null, + "trust_score": null, + "volume": 29061.03634563883 + }, + { + "base": "POA20", + "bid_ask_spread_percentage": null, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.31e-06, + "eth": 7.074e-05, + "usd": 0.0132809 + }, + "converted_volume": { + "btc": 0.009587, + "eth": 0.51876605, + "usd": 97.39 + }, + "is_anomaly": false, + "is_stale": false, + "last": 7.0704231362995e-05, + "last_fetch_at": "2019-08-21T08:26:12+00:00", + "last_traded_at": "2019-08-21T08:21:13+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "uniswap", + "name": "Uniswap" + }, + "target": "ETH", + "timestamp": "2019-08-21T08:21:13+00:00", + "trade_url": null, + "trust_score": null, + "volume": 7333.316809051611 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 40.083051, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.33e-06, + "eth": 7.005e-05, + "usd": 0.01377146 + }, + "converted_volume": { + "btc": 0.0022752, + "eth": 0.12002061, + "usd": 23.59 + }, + "is_anomaly": false, + "is_stale": true, + "last": 7.004e-05, + "last_fetch_at": "2019-08-21T08:32:14+00:00", + "last_traded_at": "2019-08-18T18:43:13+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "ethfinex", + "name": "Ethfinex" + }, + "target": "ETH", + "timestamp": "2019-08-18T18:43:13+00:00", + "trade_url": "https://ethfinex.com", + "trust_score": "red", + "volume": 1713.3067 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 44.440399, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.33e-06, + "eth": 7.311e-05, + "usd": 0.013499 + }, + "converted_volume": { + "btc": 0.00442255, + "eth": 0.24305992, + "usd": 44.88 + }, + "is_anomaly": false, + "is_stale": true, + "last": 0.013499, + "last_fetch_at": "2019-08-21T08:32:13+00:00", + "last_traded_at": "2019-08-14T17:19:27+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "ethfinex", + "name": "Ethfinex" + }, + "target": "USD", + "timestamp": "2019-08-14T17:19:27+00:00", + "trade_url": "https://ethfinex.com", + "trust_score": "red", + "volume": 3324.44883078 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 14.012015, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.36e-06, + "eth": 7.49e-05, + "usd": 0.01446844 + }, + "converted_volume": { + "btc": 5.45e-06, + "eth": 0.00029958, + "usd": 0.057874 + }, + "is_anomaly": false, + "is_stale": true, + "last": 7.4743e-05, + "last_fetch_at": "2019-08-21T08:37:09+00:00", + "last_traded_at": "2019-08-21T02:52:09+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "ETH", + "timestamp": "2019-08-21T02:52:09+00:00", + "trade_url": "https://hitbtc.com/POA-to-ETH", + "trust_score": null, + "volume": 4.0 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 64.645979, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.36e-06, + "eth": 7.473e-05, + "usd": 0.01443604 + }, + "converted_volume": { + "btc": 2.72e-06, + "eth": 0.00014946, + "usd": 0.02887207 + }, + "is_anomaly": false, + "is_stale": true, + "last": 0.0143016, + "last_fetch_at": "2019-08-21T08:37:44+00:00", + "last_traded_at": "2019-08-21T02:52:25+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "DAI", + "timestamp": "2019-08-21T02:52:25+00:00", + "trade_url": "https://hitbtc.com/POA-to-DAI", + "trust_score": null, + "volume": 2.0 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 64.353312, + "coin_id": "poa-network", + "converted_last": { + "btc": 2.23e-06, + "eth": 0.00012505, + "usd": 0.02310309 + }, + "converted_volume": { + "btc": 0.00275182, + "eth": 0.15430951, + "usd": 28.51 + }, + "is_anomaly": true, + "is_stale": true, + "last": 2.23e-06, + "last_fetch_at": "2019-08-21T08:32:12+00:00", + "last_traded_at": "2019-08-17T12:50:06+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "ethfinex", + "name": "Ethfinex" + }, + "target": "BTC", + "timestamp": "2019-08-17T12:50:06+00:00", + "trade_url": "https://ethfinex.com", + "trust_score": "red", + "volume": 1234.0 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 21.080977, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.23e-06, + "eth": 6.72e-05, + "usd": 0.01322824 + }, + "converted_volume": { + "btc": 0.0, + "eth": 0.0, + "usd": 0.0 + }, + "is_anomaly": true, + "is_stale": true, + "last": 1.2331e-06, + "last_fetch_at": "2019-08-21T08:37:17+00:00", + "last_traded_at": "2019-08-20T18:50:31+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "BTC", + "timestamp": "2019-08-20T18:50:31+00:00", + "trade_url": "https://hitbtc.com/POA-to-BTC", + "trust_score": null, + "volume": 0.0 + }, + { + "base": "POA", + "bid_ask_spread_percentage": 36.441715, + "coin_id": "poa-network", + "converted_last": { + "btc": 1.22e-06, + "eth": 6.66e-05, + "usd": 0.0131106 + }, + "converted_volume": { + "btc": 0.0, + "eth": 0.0, + "usd": 0.0 + }, + "is_anomaly": true, + "is_stale": true, + "last": 0.0131106, + "last_fetch_at": "2019-08-21T08:37:14+00:00", + "last_traded_at": "2019-08-20T18:50:15+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "USD", + "timestamp": "2019-08-20T18:50:15+00:00", + "trade_url": "https://hitbtc.com/POA-to-USD", + "trust_score": null, + "volume": 0.0 + }, + { + "base": "POA20", + "bid_ask_spread_percentage": 70.656026, + "coin_id": "poa-network", + "converted_last": { + "btc": 7.522e-07, + "eth": 4.006e-05, + "usd": 0.0080416 + }, + "converted_volume": { + "btc": 0.0, + "eth": 0.0, + "usd": 0.0 + }, + "is_anomaly": true, + "is_stale": true, + "last": 0.008, + "last_fetch_at": "2019-08-21T08:37:29+00:00", + "last_traded_at": "2019-08-19T09:09:06+00:00", + "market": { + "has_trading_incentive": false, + "identifier": "hitbtc", + "name": "HitBTC" + }, + "target": "DAI", + "timestamp": "2019-08-19T09:09:06+00:00", + "trade_url": "https://hitbtc.com/POA20-to-DAI", + "trust_score": null, + "volume": 0.0 + } + ] +} diff --git a/apps/indexer/lib/indexer/block/fetcher.ex b/apps/indexer/lib/indexer/block/fetcher.ex index a8b28d1391..28002f010a 100644 --- a/apps/indexer/lib/indexer/block/fetcher.ex +++ b/apps/indexer/lib/indexer/block/fetcher.ex @@ -184,11 +184,10 @@ defmodule Indexer.Block.Fetcher do end defp update_block_cache(blocks) when is_list(blocks) do - max_block = Enum.max_by(blocks, fn block -> block.number end) - min_block = Enum.min_by(blocks, fn block -> block.number end) + {min_block, max_block} = Enum.min_max_by(blocks, & &1.number) - BlockNumber.update(max_block.number) - BlockNumber.update(min_block.number) + BlockNumber.update_all(max_block.number) + BlockNumber.update_all(min_block.number) BlocksCache.update(blocks) end @@ -269,7 +268,7 @@ defmodule Indexer.Block.Fetcher do end def async_import_internal_transactions(%{transactions: transactions}, EthereumJSONRPC.Geth) do - {_, max_block_number} = Chain.fetch_min_and_max_block_numbers() + max_block_number = Chain.fetch_max_block_number() transactions |> Enum.flat_map(fn diff --git a/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex b/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex index 4dfed6e73a..d6d7d66d71 100644 --- a/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex +++ b/apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex @@ -162,7 +162,7 @@ defmodule Indexer.Fetcher.CoinBalanceOnDemand do end defp latest_block_number do - BlockNumber.max_number() + BlockNumber.get_max() end defp stale_balance_window(block_number) do diff --git a/docs/env-variables.md b/docs/env-variables.md index a0fae07bc3..7e023ef621 100644 --- a/docs/env-variables.md +++ b/docs/env-variables.md @@ -14,54 +14,57 @@ $ export NETWORK=POA ``` -| Variable | Required | Description | Default | Version | Need recompile | -| --- | --- | --- | ---| --- | --- | -| `NETWORK`| :white_check_mark: | Environment variable for the main EVM network such as Ethereum Network or POA Network | POA Network | all | | -| `SUBNETWORK` | :white_check_mark: | Environment variable for the subnetwork such as Core or Sokol Network | Sokol Testnet | all | | -| `NETWORK_ICON` | :white_check_mark: | Environment variable for the main network icon or testnet icon. Two options are `_test_network_icon.html` and `_network_icon.html` | `_test_network_icon.html` | all | | -| `LOGO` | :white_check_mark: | Environment variable for the logo image location. The logo files names for different chains can be found [here](https://github.com/poanetwork/blockscout/tree/master/apps/block_scout_web/assets/static/images) | /images/blockscout_logo.svg | all | | -| `ETHEREUM_JSONRPC_VARIANT` | :white_check_mark: | This environment variable is used to tell the application which RPC Client the node is using (i.e. Geth, Parity, or Ganache) | parity | all | | -| `ETHEREUM_JSONRPC_HTTP_URL` | :white_check_mark: | The RPC endpoint used to fetch blocks, transactions, receipts, tokens. | localhost:8545 | all | | -| `ETHEREUM_JSONRPC_TRACE_URL` | | The RPC endpoint specifically for the Geth/Parity client used by trace_block and trace_replayTransaction. This can be used to designate a tracing node. | localhost:8545 | all | | -| `ETHEREUM_JSONRPC_WS_URL` | :white_check_mark: | The WebSockets RPC endpoint used to subscribe to the `newHeads` subscription alerting the indexer to fetch new blocks. | ws://localhost:8546 | all | | -| `NETWORK_PATH` | | Used to set a network path other than what is displayed in the root directory. An example would be to add /eth/mainnet/ to the root directory. | (empty) | all | | -| `SECRET_KEY_BASE` | :white_check_mark: | Use mix phx.gen.secret to generate a new Secret Key Base string to protect production assets. | (empty) | all | | -| `CHECK_ORIGIN` | | Used to check the origin of requests when the origin header is present. It defaults to false. In case of true, it will check against the host value. | false | all | | -| `PORT` | :white_check_mark: | Default port the application runs on is 4000 | 4000 | all | | -| `COIN` | :white_check_mark: | The coin here is checked via the Coinmarketcap API to obtain USD prices on graphs and other areas of the UI | POA | all | | -| `METADATA_CONTRACT` | | This environment variable is specifically used by POA Network to obtain Validators information to display in the UI. | (empty) | all | | -| `VALIDATORS_CONTRACT` | | This environment variable is specifically used by POA Network to obtain the Emission Fund contract. | (empty) | all | | -| `SUPPLY_MODULE` | | This environment variable is used by the xDai Chain in order to tell the application how to calculate the total supply of the chain. | false | all | | -| `SOURCE_MODULE` | | This environment variable is used to calculate the exchange rate and is specifically used by the xDai Chain. | false | all | | -| `DATABASE_URL` | | Production environment variable to define the Database endpoint. | (empty) | all | | -| `POOL_SIZE` | | Production environment variable to define the number of database connections allowed. | 20 | all | | -| `ECTO_USE_SSL` | | Production environment variable to use SSL on Ecto queries. | true | all | | -| `DATADOG_HOST` | | Host configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/) | (empty) | all | | -| `DATADOG_PORT` | | Port configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/). | (empty} | all | | -| `SPANDEX_BATCH_SIZE` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | -| `SPANDEX_SYNC_THRESHOLD` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | -| `HEART_BEAT_TIMEOUT` | | Production environment variable to restart the application in the event of a crash. | 30 | all | | -| `HEART_COMMAND` | | Production environment variable to restart the application in the event of a crash. | systemctl restart explorer.service | all | | -| `BLOCKSCOUT_VERSION` | | Added to the footer to signify the current BlockScout version. | (empty) | v1.3.4+ | | -| `RELEASE_LINK` | | The link to Blockscout release notes in the footer. | https: //github.com/poanetwork/
blockscout/releases/
tag/${BLOCKSCOUT_VERSION} | v1.3.5+ | | -| `ELIXIR_VERSION` | | Elixir version to install on the node before Blockscout deploy. | (empty) | all | | -| `BLOCK_TRANSFORMER` | | Transformer for blocks: base or clique. | base | v1.3.4+ | | -| `GRAPHIQL_TRANSACTION` | | Default transaction in query to GraphiQL. | (empty) | v1.2.0+ | :white_check_mark: | -| `FIRST_BLOCK` | | The block number, where indexing begins from. | 0 | v1.3.8+ | | -| `LAST_BLOCK` | | The block number, where indexing stops. | (empty) | v2.0.3+ | | -| `TXS_COUNT_CACHE_PERIOD` | | Interval in seconds to restart the task, which calculates the total txs count. | 60 * 60 * 2 | v1.3.9+ | | -| `ADDRESS_WITH_BALANCES`
`_UPDATE_INTERVAL`| | Interval in seconds to restart the task, which calculates addresses with balances. | 30 * 60 | v1.3.9+ | | -| `LINK_TO_OTHER_EXPLORERS` | | true/false. If true, links to other explorers are added in the footer | (empty) | v1.3.0+ | | -| `COINMARKETCAP_PAGES` | | the number of pages on coinmarketcap to list in order to find token's price | 10 | v1.3.10+ | | -| `SUPPORTED_CHAINS` | | Array of supported chains that displays in the footer and in the chains dropdown. This var was introduced in this PR [#1900](https://github.com/poanetwork/blockscout/pull/1900) and looks like an array of JSON objects. | (empty) | v2.0.0+ | | -| `BLOCK_COUNT_CACHE_PERIOD ` | | time to live of cache in seconds. This var was introduced in [#1876](https://github.com/poanetwork/blockscout/pull/1876) | 600 | v2.0.0+ | | -| `ALLOWED_EVM_VERSIONS ` | | the comma-separated list of allowed EVM versions for contracts verification. This var was introduced in [#1964](https://github.com/poanetwork/blockscout/pull/1964) | "homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg" | v2.0.0+ | | -| `AVERAGE_BLOCK_CACHE_PERIOD` | | Update of average block cache, in seconds | 30 minutes | v2.0.2+ | -| `MARKET_HISTORY_CACHE_PERIOD` | | Update of market history cache, in seconds | 6 hours | v2.0.2+ | -| `DISABLE_WEBAPP` | | If `true`, endpoints to webapp are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | -| `DISABLE_READ_API` | | If `true`, read-only endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | -| `DISABLE_WRITE_API` | | If `true`, write endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | -| `DISABLE_INDEXER` | | If `true`, indexer application doesn't run | `false` | v2.0.3+ | :white_check_mark: | -| `WEBAPP_URL` | | Link to web application instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | -| `API_URL` | | Link to API instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | -| `CHAIN_SPEC_PATH` | | Chain specification path (absolute file system path or url) to import block emission reward ranges and genesis account balances from | (empty) | master | | +| Variable | Required | Description | Default | Version | Need recompile | Deprecated in Version | +| --- | --- | --- | ---| --- | --- | --- | +| `NETWORK`| :white_check_mark: | Environment variable for the main EVM network such as Ethereum Network or POA Network | POA Network | all | | | +| `SUBNETWORK` | :white_check_mark: | Environment variable for the subnetwork such as Core or Sokol Network | Sokol Testnet | all | | | +| `NETWORK_ICON` | :white_check_mark: | Environment variable for the main network icon or testnet icon. Two options are `_test_network_icon.html` and `_network_icon.html` | `_test_network_icon.html` | all | | | +| `LOGO` | :white_check_mark: | Environment variable for the logo image location. The logo files names for different chains can be found [here](https://github.com/poanetwork/blockscout/tree/master/apps/block_scout_web/assets/static/images) | /images/blockscout_logo.svg | all | | | +| `ETHEREUM_JSONRPC_VARIANT` | :white_check_mark: | This environment variable is used to tell the application which RPC Client the node is using (i.e. Geth, Parity, or Ganache) | parity | all | | | +| `ETHEREUM_JSONRPC_HTTP_URL` | :white_check_mark: | The RPC endpoint used to fetch blocks, transactions, receipts, tokens. | localhost:8545 | all | | | +| `ETHEREUM_JSONRPC_TRACE_URL` | | The RPC endpoint specifically for the Geth/Parity client used by trace_block and trace_replayTransaction. This can be used to designate a tracing node. | localhost:8545 | all | | | +| `ETHEREUM_JSONRPC_WS_URL` | :white_check_mark: | The WebSockets RPC endpoint used to subscribe to the `newHeads` subscription alerting the indexer to fetch new blocks. | ws://localhost:8546 | all | | | +| `NETWORK_PATH` | | Used to set a network path other than what is displayed in the root directory. An example would be to add /eth/mainnet/ to the root directory. | (empty) | all | | | +| `SECRET_KEY_BASE` | :white_check_mark: | Use mix phx.gen.secret to generate a new Secret Key Base string to protect production assets. | (empty) | all | | | +| `CHECK_ORIGIN` | | Used to check the origin of requests when the origin header is present. It defaults to false. In case of true, it will check against the host value. | false | all | | | +| `PORT` | :white_check_mark: | Default port the application runs on is 4000 | 4000 | all | | | +| `COIN` | :white_check_mark: | The coin here is checked via the CoinGecko API to obtain USD prices on graphs and other areas of the UI | POA | all | | | +| `METADATA_CONTRACT` | | This environment variable is specifically used by POA Network to obtain Validators information to display in the UI. | (empty) | all | | | +| `VALIDATORS_CONTRACT` | | This environment variable is specifically used by POA Network to obtain the Emission Fund contract. | (empty) | all | | | +| `SUPPLY_MODULE` | | This environment variable is used by the xDai Chain in order to tell the application how to calculate the total supply of the chain. | false | all | | | +| `SOURCE_MODULE` | | This environment variable is used to calculate the exchange rate and is specifically used by the xDai Chain. | false | all | | | +| `DATABASE_URL` | | Production environment variable to define the Database endpoint. | (empty) | all | | | +| `POOL_SIZE` | | Production environment variable to define the number of database connections allowed. | 20 | all | | | +| `ECTO_USE_SSL` | | Production environment variable to use SSL on Ecto queries. | true | all | | | +| `DATADOG_HOST` | | Host configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/) | (empty) | all | | | +| `DATADOG_PORT` | | Port configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/). | (empty} | all | | | +| `SPANDEX_BATCH_SIZE` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | +| `SPANDEX_SYNC_THRESHOLD` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | | +| `HEART_BEAT_TIMEOUT` | | Production environment variable to restart the application in the event of a crash. | 30 | all | | | +| `HEART_COMMAND` | | Production environment variable to restart the application in the event of a crash. | systemctl restart explorer.service | all | | | +| `BLOCKSCOUT_VERSION` | | Added to the footer to signify the current BlockScout version. | (empty) | v1.3.4+ | | | +| `RELEASE_LINK` | | The link to Blockscout release notes in the footer. | https: //github.com/poanetwork/
blockscout/releases/
tag/${BLOCKSCOUT_VERSION} | v1.3.5+ | | | +| `ELIXIR_VERSION` | | Elixir version to install on the node before Blockscout deploy. | (empty) | all | | | +| `BLOCK_TRANSFORMER` | | Transformer for blocks: base or clique. | base | v1.3.4+ | | | +| `GRAPHIQL_TRANSACTION` | | Default transaction in query to GraphiQL. | (empty) | v1.2.0+ | :white_check_mark: | | +| `FIRST_BLOCK` | | The block number, where indexing begins from. | 0 | v1.3.8+ | | | +| `LAST_BLOCK` | | The block number, where indexing stops. | (empty) | v2.0.3+ | | | +| `TXS_COUNT_CACHE_PERIOD` | | Interval in seconds to restart the task, which calculates the total txs count. | 60 * 60 * 2 | v1.3.9+ | | | +| `ADDRESS_WITH_BALANCES`
`_UPDATE_INTERVAL`| | Interval in seconds to restart the task, which calculates addresses with balances. | 30 * 60 | v1.3.9+ | | | +| `LINK_TO_OTHER_EXPLORERS` | | true/false. If true, links to other explorers are added in the footer | (empty) | v1.3.0+ | | | +| `COINMARKETCAP_PAGES` | | the number of pages on coinmarketcap to list in order to find token's price | 10 | v1.3.10+ | | v2.0.4 | +| `SUPPORTED_CHAINS` | | Array of supported chains that displays in the footer and in the chains dropdown. This var was introduced in this PR [#1900](https://github.com/poanetwork/blockscout/pull/1900) and looks like an array of JSON objects. | (empty) | v2.0.0+ | | | +| `BLOCK_COUNT_CACHE_PERIOD ` | | time to live of cache in seconds. This var was introduced in [#1876](https://github.com/poanetwork/blockscout/pull/1876) | 600 | v2.0.0+ | | | +| `ALLOWED_EVM_VERSIONS ` | | the comma-separated list of allowed EVM versions for contracts verification. This var was introduced in [#1964](https://github.com/poanetwork/blockscout/pull/1964) | "homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg" | v2.0.0+ | | | +| `AVERAGE_BLOCK_CACHE_PERIOD` | | Update of average block cache, in seconds | 30 minutes | v2.0.2+ | | +| `MARKET_HISTORY_CACHE_PERIOD` | | Update of market history cache, in seconds | 6 hours | v2.0.2+ | | +| `DISABLE_WEBAPP` | | If `true`, endpoints to webapp are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | | +| `DISABLE_READ_API` | | If `true`, read-only endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | | +| `DISABLE_WRITE_API` | | If `true`, write endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | | +| `DISABLE_INDEXER` | | If `true`, indexer application doesn't run | `false` | v2.0.3+ | :white_check_mark: | | +| `WEBAPP_URL` | | Link to web application instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | | +| `API_URL` | | Link to API instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | | +| `CHAIN_SPEC_PATH` | | Chain specification path (absolute file system path or url) to import block emission reward ranges and genesis account balances from | (empty) | v2.0.4+ | | | +| `COIN_GECKO_ID` | | CoinGecko coin id required for fetching an exchange rate | poa-network | v2.0.4+ | | | +| `EMISSION_FORMAT` | | Should be set to `POA` if you have block emission indentical to POA Network. This env var is used only if `CHAIN_SPEC_PATH` is set | `STANDARD` | v2.0.4+ | | | +| `REWARDS_CONTRACT_ADDRESS` | | Emission rewards contract address. This env var is used only if `EMISSION_FORMAT` is set to `POA` | `0xeca443e8e1ab29971a45a9c57a6a9875701698a5` | v2.0.4+ | | |