README.md 17.5 KB
Newer Older
MigueKun's avatar
MigueKun committed
1 2 3 4 5 6
<p align="center">
  <img src="blockscout.png" width="350" title="BlockScout">
</p>
<p align="center">
Blockchain Explorer for inspecting and analyzing EVM Chains
</p>
MigueKun's avatar
MigueKun committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
BlockScout provides a comprehensive, easy-to-use interface for users to view, confirm, and inspect transactions on **all EVM** (Ethereum Virtual Machine) blockchains. This includes the Ethereum main and test networks as well as **Ethereum forks and sidechains**.

Following is an overview of the project and instructions for [getting started](#getting-started).

Visit the [POA BlockScout forum](https://forum.poa.network/c/blockscout) or the [Gitter Channel](https://gitter.im/poanetwork/blockscout) to access additional information or post questions.

## About BlockScout

BlockScout is an Elixir application that allows users to search transactions, view accounts and balances, and verify smart contracts on the entire Pirl network.


### Features

- [x] **Open source development**: The code is community driven and available for anyone to use, explore and improve.

- [x] **Real time transaction tracking**: Transactions are updated in real time - no page refresh required. Infinite scrolling is also enabled.

- [x] **Smart contract interaction**: Users can read and verify Solidity smart contracts and access pre-existing contracts to fast-track development. Support for Vyper, LLL, and Web Assembly contracts is in progress.

- [x] **Token support**: ERC20 and ERC721 tokens are supported. Future releases will support additional token types including ERC223 and ERC1155.

- [x] **User customization**: Users can easily deploy on a network and customize the Bootstrap interface.

- [x] **Ethereum sidechain networks**: BlockScout supports the Pirl mainnet, Ethereum mainnet, Ethereum testnets, POA network, and forks like Ethereum Classic, xDAI, additional sidechains, and private EVM networks.

### Supported Projects

#### Hosted Chains

* [Pirl Network](http://pirl.es)
* [POA Core Network](https://blockscout.com/poa/core)
* [POA Sokol Testnet](https://blockscout.com/poa/sokol)
* [xDai Chain](https://blockscout.com/poa/dai)
* [Ethereum Mainnet](https://blockscout.com/eth/mainnet)
* [Kovan Testnet](https://blockscout.com/eth/kovan)
* [Ropsten Testnet](https://blockscout.com/eth/ropsten)
* [Goerli Testnet](https://blockscout.com/eth/goerli)
* [Rinkeby Testnet](https://blockscout.com/eth/rinkeby)
* [Ethereum Classic](https://blockscout.com/etc/mainnet)

#### Additional Chains Utilizing BlockScout

MigueKun's avatar
MigueKun committed
49
* [PIRL](http://pirl.es/)
MigueKun's avatar
MigueKun committed
50 51 52 53 54 55 56 57 58
* [Oasis Labs](https://blockexplorer.oasiscloud.io/)
* [Fuse Network](https://explorer.fuse.io/)
* [ARTIS](https://explorer.sigma1.artis.network)
* [SafeChain](https://explorer.safechain.io)
* [SpringChain](https://explorer.springrole.com/)


### Visual Interface

MigueKun's avatar
MigueKun committed
59
Interface for Pirl Network
MigueKun's avatar
MigueKun committed
60

MigueKun's avatar
MigueKun committed
61
![BlockScout Example](explorer_example.gif)
MigueKun's avatar
MigueKun committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

## Getting Started

We use [Terraform](https://www.terraform.io/intro/getting-started/install.html) to build the correct infrastructure to run BlockScout. See [https://github.com/poanetwork/blockscout-terraform](https://github.com/poanetwork/blockscout-terraform) for details.

### Requirements


| Dependency  | Mac | Linux |
|-------------|-----|-------|
| [Erlang/OTP 21.0.4](https://github.com/erlang/otp) | `brew install erlang` | [Erlang Install Example](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L134) |
| [Elixir 1.8.1](https://elixir-lang.org/) | :point_up: | [Elixir Install Example](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L138) |
| [Postgres 10.3](https://www.postgresql.org/) | `brew install postgresql` | [Postgres Install Example](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L187) |
| [Node.js 10.5.0](https://nodejs.org/en/) | `brew install node` | [Node.js Install Example](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L66) |
| [Automake](https://www.gnu.org/software/automake/) | `brew install automake` | [Automake Install Example](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L72) |
| [Libtool](https://www.gnu.org/software/libtool/) | `brew install libtool` | [Libtool Install Example](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L62) |
| [Inotify-tools](https://github.com/rvoicilas/inotify-tools/wiki) | Not Required | Ubuntu - `apt-get install inotify-tools` |
| [GCC Compiler](https://gcc.gnu.org/) | `brew install gcc` | [GCC Compiler Example](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L70) |
| [GMP](https://gmplib.org/) | `brew install gmp` | [Install GMP Devel](https://github.com/poanetwork/blockscout-terraform/blob/33f68e816e36dc2fb055911fa0372531f0e956e7/modules/stack/libexec/init.sh#L74) |

MigueKun's avatar
MigueKun committed
82 83 84 85 86 87 88
### Dependencies 

  1. Install system requirements:
```
  wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
  dpkg -i erlang-solutions_1.0_all.deb
  rm erlang-solutions_1.0_all.deb
MigueKun's avatar
MigueKun committed
89
  echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' >> /etc/apt/sources.list.d/pgdg.list
MigueKun's avatar
MigueKun committed
90 91 92
  wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
  curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
  apt-get update
MigueKun's avatar
MigueKun committed
93
  apt-get install -y esl-erlang=1:21.1.1-1 python python3 git inotify-tools nodejs postgresql-10 postgresql-client-10 automake gcc libgmp3-dev make libtool autoconf unzip elixir=1.8.1-1 build-essential
MigueKun's avatar
MigueKun committed
94
```
MigueKun's avatar
MigueKun committed
95
   
MigueKun's avatar
MigueKun committed
96
### Build and Run
MigueKun's avatar
MigueKun committed
97 98 99 100 101 102 103 104

  1. Clone the repository.
  ```git clone https://git.pirl.io/community/explorer-blockscout```

  2. Go to the explorer subdirectory.
  ```cd explorer-blockscout```

  3. Start the Pirl daemon with rpc settings as service. 
MigueKun's avatar
MigueKun committed
105

MigueKun's avatar
MigueKun committed
106
```
MigueKun's avatar
MigueKun committed
107 108 109
  wget https://git.pirl.io/community/pirl/uploads/f339ecb21997253a80fdbc534715fe0d/pirl-linux-amd64-hulk-1_8_2
  chmod +x pirl-linux-amd64-hulk-1_8_2
  mv pirl-linux-amd64-hulk-1_8_2 /usr/bin/pirl
MigueKun's avatar
MigueKun committed
110 111 112 113
  cp pirl.service /etc/systemd/system/pirl.service
  systemctl daemon-reload
  systemctl enable pirl.service
  systemctl start pirl.service
MigueKun's avatar
MigueKun committed
114
```
MigueKun's avatar
MigueKun committed
115
  4. Set up default configurations.
MigueKun's avatar
MigueKun committed
116 117
  <br />Linux: Update the database username and password configuration in `apps/explorer/config/prod.exs`
  <br />Mac: Remove the `username` and `password` fields from `apps/explorer/config/prod.exs`
MigueKun's avatar
MigueKun committed
118 119
  Example usage: Changing the default Postgres port from localhost:15432 if [Boxen](https://github.com/boxen/boxen) is installed.

MigueKun's avatar
MigueKun committed
120
  5. Install dependencies.
MigueKun's avatar
MigueKun committed
121

MigueKun's avatar
MigueKun committed
122 123
```
  MIX_ENV=prod mix local.hex --force
MigueKun's avatar
MigueKun committed
124
  MIX_ENV=prod mix deps.update libsecp256k1
MigueKun's avatar
MigueKun committed
125 126
  MIX_ENV=prod mix do deps.get, local.rebar --force, deps.compile, compile
```
MigueKun's avatar
MigueKun committed
127

MigueKun's avatar
MigueKun committed
128 129
  6. Set postgres user password as same as point 4.
   
MigueKun's avatar
MigueKun committed
130 131 132 133 134
```
   sudo -u postgres psql
   \password (set the password and press enter)
   \q
```
MigueKun's avatar
MigueKun committed
135
  7. Create and populate DB.
MigueKun's avatar
MigueKun committed
136
```
MigueKun's avatar
MigueKun committed
137
   MIX_ENV=prod mix ecto.create && mix ecto.migrate
MigueKun's avatar
MigueKun committed
138
```
MigueKun's avatar
MigueKun committed
139
  
MigueKun's avatar
MigueKun committed
140
  <br />_Note:_ If you have run previously, drop the previous database
MigueKun's avatar
MigueKun committed
141
```
MigueKun's avatar
MigueKun committed
142
  MIX_ENV=prod mix do ecto.drop, ecto.create, ecto.migrate
MigueKun's avatar
MigueKun committed
143
```
MigueKun's avatar
MigueKun committed
144

MigueKun's avatar
MigueKun committed
145
  8. Install Node.js dependencies.
MigueKun's avatar
MigueKun committed
146

MigueKun's avatar
MigueKun committed
147 148
```
  cd apps/block_scout_web/assets && npm install --unsafe-perm; cd -
MigueKun's avatar
MigueKun committed
149
  cd apps/explorer && npm install --unsafe-perm; cd -
MigueKun's avatar
MigueKun committed
150
  cd apps/block_scout_web/assets && npm run-script deploy; cd -
MigueKun's avatar
MigueKun committed
151
  MIX_ENV=prod mix phx.digest
MigueKun's avatar
MigueKun committed
152
```
MigueKun's avatar
MigueKun committed
153

MigueKun's avatar
MigueKun committed
154
  9. Update your JSON RPC Variant in `apps/explorer/config/prod.exs` and `apps/indexer/config/prod.exs`.
MigueKun's avatar
MigueKun committed
155 156
  For `variant`, enter `ganache`, `geth`, or `parity`

MigueKun's avatar
MigueKun committed
157 158
  10. Update your JSON RPC Endpoint in `apps/explorer/config/prod/` and `apps/indexer/config/prod/`
  For the `variant` chosen in step 9, enter the correct information for the corresponding JSON RPC Endpoint in `parity.exs`, `geth.exs`, or `ganache.exs`
MigueKun's avatar
MigueKun committed
159

MigueKun's avatar
MigueKun committed
160
  11. Start Phoenix Server as service:
MigueKun's avatar
MigueKun committed
161

MigueKun's avatar
MigueKun committed
162
  Edit environment file to meet your system settings: [environment](https://git.pirl.io/community/explorer-blockscout/blob/master/environment)
MigueKun's avatar
MigueKun committed
163
  
MigueKun's avatar
MigueKun committed
164
```
MigueKun's avatar
MigueKun committed
165 166 167 168
  cp blockscout.service /etc/systemd/system/blockscout.service
  systemctl daemon-reload
  systemctl enable blockscout.service
  systemctl start blockscout.service
MigueKun's avatar
MigueKun committed
169
```
MigueKun's avatar
MigueKun committed
170
   
MigueKun's avatar
MigueKun committed
171
Now you can visit `serverip:80`.
MigueKun's avatar
MigueKun committed
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242



### Umbrella Project Organization

This repository is an [umbrella project](https://elixir-lang.org/getting-started/mix-otp/dependencies-and-umbrella-projects.html). Each directory under `apps/` is a separate [Mix](https://hexdocs.pm/mix/Mix.html) project and [OTP application](https://hexdocs.pm/elixir/Application.html), but the projects can use each other as a dependency in their `mix.exs`.

Each OTP application has a restricted domain.

| Directory               | OTP Application     | Namespace         | Purpose                                                                                                                                                                                                                                                                                                                                                                         |
|:------------------------|:--------------------|:------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `apps/ethereum_jsonrpc` | `:ethereum_jsonrpc` | `EthereumJSONRPC` | Ethereum JSONRPC client.  It is allowed to know `Explorer`'s param format, but it cannot directly depend on `:explorer`                                                                                                                                                                                                                                                         |
| `apps/explorer`         | `:explorer`         | `Explorer`        | Storage for the indexed chain.  Can read and write to the backing storage.  MUST be able to boot in a read-only mode when run independently from `:indexer`, so cannot depend on `:indexer` as that would start `:indexer` indexing.                                                                                                                                            |
| `apps/block_scout_web`     | `:block_scout_web`     | `BlockScoutWeb`     | Phoenix interface to `:explorer`.  The minimum interface to allow web access should go in `:block_scout_web`.  Any business rules or interface not tied directly to `Phoenix` or `Plug` should go in `:explorer`. MUST be able to boot in a read-only mode when run independently from `:indexer`, so cannot depend on `:indexer` as that would start `:indexer` indexing. |
| `apps/indexer`          | `:indexer`          | `Indexer`         | Uses `:ethereum_jsonrpc` to index chain and batch import data into `:explorer`.  Any process, `Task`, or `GenServer` that automatically reads from the chain and writes to `:explorer` should be in `:indexer`. This restricts automatic writes to `:indexer` and read-only mode can be achieved by not running `:indexer`.                                             |


### Testing

#### Requirements

  * PhantomJS (for wallaby)

#### Running the tests

  1. Build the assets.
  `cd apps/block_scout_web/assets && npm run build; cd -`

  2. Format the Elixir code.
  `mix format`

  3. Run the test suite with coverage for whole umbrella project.  This step can be run with different configuration outlined below.
  `mix coveralls.html --umbrella`

  4. Lint the Elixir code.
  `mix credo --strict`

  5. Run the dialyzer.
  `mix dialyzer --halt-exit-status`

  6. Check the Elixir code for vulnerabilities.
  `cd apps/explorer && mix sobelow --config; cd -`
  `cd apps/block_scout_web && mix sobelow --config; cd -`

  7. Lint the JavaScript code.
  `cd apps/block_scout_web/assets && npm run eslint; cd -`

  8. Test the JavaScript code.
  `cd apps/block_scout_web/assets && npm run test; cd -`


##### Geth

###### Mox

```shell
export ETHEREUM_JSONRPC_CASE=EthereumJSONRPC.Case.Geth.Mox
export ETHEREUM_JSONRPC_WEB_SOCKET_CASE=EthereumJSONRPC.WebSocket.Case.Mox
mix coveralls.html --umbrella --exclude no_geth
```

###### HTTP / WebSocket

```shell
export ETHEREUM_JSONRPC_CASE=EthereumJSONRPC.Case.Geth.HTTPWebSocket
export ETHEREUM_JSONRPC_WEB_SOCKET_CASE=EthereumJSONRPC.WebSocket.Case.Geth
mix coveralls.html --umbrella --exclude no_geth
```

| Protocol  | URL                                               |
|:----------|:--------------------------------------------------|
MigueKun's avatar
MigueKun committed
243 244
| HTTP      | `http://localhost:8545`                           |
| WebSocket | `ws://localhost:8546`                             |
MigueKun's avatar
MigueKun committed
245 246 247 248 249 250 251 252 253 254 255 256 257 258

### API Documentation

To view Modules and API Reference documentation:

1. Generate documentation.
`mix docs`
2. View the generated docs.
`open doc/index.html`

## Front-end

### Javascript

MigueKun's avatar
MigueKun committed
259
All Javascript files are under *apps/block_scout_web/assets/js* and the main file is *app.js*. This file imports all javascript used in the application. If you want to create a new JS file consider creating into */js/pages* or */js/lib*, as follows:
MigueKun's avatar
MigueKun committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358

#### js/lib
This folder contains all scripts that can be reused in any page or can be used as a helper to some component.

#### js/pages
This folder contains the scripts that are specific for some page.

#### Redux
This project uses Redux to control the state in some pages. There are pages that have things happening in real-time thanks to the Phoenix channels, e.g. Address page, so the page state changes a lot depending on which events it is listening. The redux is also used to load some contents asynchronous, see [async_listing_load.js](https://github.com/poanetwork/blockscout/blob/master/apps/block_scout_web/assets/js/lib/async_listing_load.js).

To understand how to build new pages that need redux in this project, see the [redux_helpers.js](https://github.com/poanetwork/blockscout/blob/master/apps/block_scout_web/assets/js/lib/redux_helpers.js)

## Internationalization

The app is currently internationalized. It is only localized to U.S. English. To translate new strings.

1. To setup translation file.
`cd apps/block_scout_web; mix gettext.extract --merge; cd -`
2. To edit the new strings, go to `apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po`.

## Metrics

BlockScout is setup to export [Prometheus](https://prometheus.io/) metrics at `/metrics`.

### Prometheus

1. Install prometheus: `brew install prometheus`
2. Start the web server `iex -S mix phx.server`
3. Start prometheus: `prometheus --config.file=prometheus.yml`

### Grafana

1. Install grafana: `brew install grafana`
2. Install Pie Chart panel plugin: `grafana-cli plugins install grafana-piechart-panel`
3. Start grafana: `brew services start grafana`
4. Add Prometheus as a Data Source
   1. `open http://localhost:3000/datasources`
   2. Click "+ Add data source"
   3. Put "Prometheus" for "Name"
   4. Change "Type" to "Prometheus"
   5. Set "URL" to "http://localhost:9090"
   6. Set "Scrape Interval" to "10s"
5. Add the dashboards from https://github.com/deadtrickster/beam-dashboards:
   For each `*.json` file in the repo.
   1. `open http://localhost:3000/dashboard/import`
   2. Copy the contents of the JSON file in the "Or paste JSON" entry
   3. Click "Load"
6. View the dashboards.  (You will need to click-around and use BlockScout for the web-related metrics to show up.)

## Tracing

Blockscout supports tracing via
[Spandex](http://git@github.com:spandex-project/spandex.git). Each application
has its own tracer, that is configured internally to that application. In order
to enable it, visit each application's `config/<env>.ex` and update its tracer
configuration to change `disabled?: true` to `disabled?: false`. Do this for
each application you'd like included in your trace data.

Currently, only [Datadog](https://www.datadoghq.com/) is supported as a
tracing backend, but more will be added soon.

### DataDog

If you would like to use DataDog, after enabling `Spandex`, set
`"DATADOG_HOST"` and `"DATADOG_PORT"` environment variables to the
host/port that your Datadog agent is running on. For more information on
Datadog and the Datadog agent, see their
[documentation](https://docs.datadoghq.com/).

### Other

If you want to use a different  backend, remove the
`SpandexDatadog.ApiServer` `Supervisor.child_spec` from
`Explorer.Application` and follow any instructions provided in `Spandex`
for setting up that backend.

## Memory Usage

The work queues for building the index of all blocks, balances (coin and token), and internal transactions can grow quite large.   By default, the soft-limit is 1 GiB, which can be changed in `apps/indexer/config/config.exs`:

```
config :indexer, memory_limit: 1 <<< 30
```

Memory usage is checked once per minute.  If the soft-limit is reached, the shrinkable work queues will shed half their load.  The shed load will be restored from the database, the same as when a restart of the server occurs, so rebuilding the work queue will be slower, but use less memory.

If all queues are at their minimum size, then no more memory can be reclaimed and an error will be logged.

## Acknowledgements

We would like to thank the [EthPrize foundation](http://ethprize.io/) for their funding support.



## License

[![License: GPL v3.0](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

This project is licensed under the GNU General Public License v3.0. See the [LICENSE](LICENSE) file for details.