Skip to content

Commit 94ebc9a

Browse files
committed
Update Readme
1 parent ceddaeb commit 94ebc9a

File tree

3 files changed

+70
-93
lines changed

3 files changed

+70
-93
lines changed

README.md

Lines changed: 69 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ Known Ethereum nodes lack functionality to get transaction list for ETH address
44

55
Indexer is written in Python. It works as a service in background:
66

7-
- connects to Ethereum node (works well with openethereum, geth or parity, others are not tested)
8-
- stores all transactions in Postgres database
9-
- provides data for API to get transactions by address with postgrest
10-
11-
We've also found this [Indexer fork for mongodb](https://github.com/jin10086/ETH-transactions-storage), but didn't test it.
7+
- Connects to Ethereum node (works well with Geth, Nethermind or other node, which provides http/ws/ipc API)
8+
- Stores all transactions in Postgres database
9+
- Provides data for API to get transactions by address with postgrest
1210

1311
## Stored information
1412

@@ -24,6 +22,7 @@ All indexed transactions includes (database field names shown):
2422
- `txhash` is a transaction's hash
2523
- `contract_to` indicates recipient's Ethereum address in case of contract
2624
- `contract_value` stores amount of ERC20 transaction in its tokens
25+
- `status` tx status
2726

2827
To reduce storage requirements, Indexer stores only token transfer ERC20 transaction, started with `0xa9059cbb` in raw tx input.
2928

@@ -37,10 +36,11 @@ An example:
3736
"gas": 21000,
3837
"gasprice": 2500000000,
3938
"block": 9084957,
40-
"txhash": "\\xcf56a031dfc89f5a3686cd441ea97ae96a66f5809a4c8c1b370485a04fb37e0e",
39+
"txhash": "0xcf56a031dfc89f5a3686cd441ea97ae96a66f5809a4c8c1b370485a04fb37e0e",
4140
"value": 1200000000000000,
4241
"contract_to": "",
43-
"contract_value": ""
42+
"contract_value": "",
43+
"status": true
4444
}
4545
```
4646

@@ -53,36 +53,37 @@ To get Ethereum transactions by address, Postgrest is used. It provides RESTful
5353
After index is created, you can use requests like
5454

5555
```
56-
curl -k -X GET "http://localhost:3000/?and=(contract_to.eq.,or(txfrom.eq.0x6b924750e56a674a2ad01fbf09c7c9012f16f094,txto.eq.0x6b924750e56a674a2ad01fbf09c7c9012f16f094))&order=time.desc&limit=25"
56+
curl -k -X GET "http://localhost:3000/?and=(contract_to.eq.,or(txfrom.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98,txto.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98))&order=time.desc&limit=25"
5757
```
5858

59-
The request will show 25 last transactions for Ethereum address 0x6b924750e56a674a2ad01fbf09c7c9012f16f094, ordered by timestamp. For API reference, see [Postgrest](https://postgrest.org/en/v5.2/api.html).
59+
The request will show 25 last transactions for Ethereum address 0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98 (Bittrex), ordered by timestamp. For API reference, see [Postgrest](https://postgrest.org/en/stable/api.html).
6060

6161
# Ethereum Indexer Setup
6262

6363
## Prerequisites
6464

65-
- geth or openethereum (with currently synchronized chain)
66-
- Python 3.6
67-
- Postgresql 10.5
65+
- Ethereum node with RPC API enabled: Geth, Nethermind, etc.
66+
- Python 3
67+
- Postgresql
6868
- Postgrest for API
6969
- nginx or other web server (in case of public API)
7070

7171
## Installation
7272

7373
### Ethereum Node
7474

75-
Make sure your Ethereum node is installed and is fully synced. In case of openethereum, you can check its API and best block height with the command:
75+
Make sure your Ethereum node is installed and is fully synced. You can check its API and best block height with the command:
7676

7777
```
7878
curl --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
7979
```
8080

8181
### Python modules
8282

83-
Install Python. Install python modules:
83+
Install Python 3. Install python modules:
8484

8585
```
86+
apt install python3-pip
8687
pip3 install web3
8788
pip3 install psycopg2
8889
```
@@ -92,27 +93,23 @@ pip3 install psycopg2
9293
Install Postgres. Create Postgres user:
9394

9495
```
95-
createuser -s <yourusername>
96+
createuser -s api_user
9697
```
9798

98-
`<yourusername>` — user who will run service.
99-
100-
(As example we create superuser. You can use your own grants.)
99+
Where `api_user` is a user who will run indexer service. (As example we create superuser. You can use your own grants.)
101100

102-
Create database for Ethereum transaction index:
101+
Create database `index` for Ethereum transaction index:
103102

104103
```
105104
CREATE DATABASE index;
106105
```
107106

108-
Create table using sql script `create_table.sql`:
107+
Add tables into `index` using SQL script `create_table.sql`:
109108

110109
```
111-
psql -f create_table.sql <yourDB>
110+
psql -f create_table.sql index
112111
```
113112

114-
`<yourDB>` — target Postgres database.
115-
116113
Note, for case insensitive comparisons we use `citex` data type instead of `text`.
117114

118115
Remember to grant privileges to psql database and tables for users you need. Example:
@@ -128,56 +125,34 @@ GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO api_user;
128125

129126
### Ethereum transaction Indexer
130127

131-
`ethsync.py` is a script which makes Ethereum transactions index to get transactions by ETH address using API.
132-
133-
Log is stored in `/var/log/ethindexer.log`.
134-
135-
By default, Indexer connects to [Openethereum](https://github.com/openethereum/openethereum) node. You can also connect to other Ethereum node like geth:
136-
137-
``` python
138-
# Connect to geth node
139-
#web3 = Web3(Web3.IPCProvider("/home/geth/.ethereum/geth.ipc"))
140-
141-
# Or connect to openethereum node
142-
web3 = Web3(Web3.IPCProvider("/home/parity/.local/share/openethereum/jsonrpc.ipc"))
143-
```
144-
145-
Indexer can fetch transactions not from the beginning, but from special block number. It will speed up indexing process and reduce database size. If you want to indicate starting Ethereum block number, set it instead of default `10000000` value.
146-
147-
``` python
148-
if maxblockindb is None:
149-
maxblockindb = 10000000
150-
```
151-
152-
For a reference:
128+
`ethsync.py` is a script which makes Ethereum transaction index. It accepts the following env variables:
153129

154-
- index size starting from 5,555,555 block to 9,000,000 is about 190 GB.
155-
- index size starting from 11,000,000 block to 12,230,000 is about 83 GB.
156-
157-
First Indexer will store transactions starting from block you set. It will take a time. After that, it will check for new blocks every 20 seconds and update the index. If you want to change the interval, change the line:
130+
- DB_NAME: Postgres database name. Example: `index`.
131+
- ETH_URL: Ethereum node url to reach the node. Supports websocket, http and ipc. See examples in `ethsync.py`.
132+
- START_BLOCK: the first block to synchronize from. Default is 1.
133+
- CONFIRMATIONS_BLOCK: the number of blocks to leave out of the synch from the end. I.e., last block is current `blockNumber - CONFIRMATIONS_BLOCK`. Default is 0.
134+
- PERIOD: Number of seconds between to synchronization. Default is 20 sec.
135+
- LOG_FILE: optional file path and name where s=to save logs. If not provided, use StreamHandler.
158136

159-
```
160-
time.sleep(20)
161-
```
137+
Indexer can fetch transactions not from the beginning, but from special block number `START_BLOCK`. It will speed up indexing process and reduce database size. For a reference:
162138

163-
To run the Indexer:
139+
- index size starting from 5,555,555 block to 9,000,000 is about 190 GB
140+
- index size starting from 11,000,000 block to 12,230,000 is about 83 GB
141+
- index size starting from 14,600,000 block to 15,100,000 is about 27 GB
164142

165-
```
166-
python3.6 you/path/to/script/ethsync.py <yourDB>
167-
```
143+
At first start, Indexer will store transactions starting from the block you set. It will take a time. After that, it will check for new blocks every `PERIOD` seconds and update the index.
168144

169-
We recommend to run Indexer script `ethsync.py` as a background service. See `ethstorage.service` as an example. Before run, update the line:
145+
Sample run string:
170146

171147
```
172-
ExecStart=/usr/bin/python3.6 you/path/to/script/ethsync.py <yourDB>
148+
DB_NAME=index ETH_URL=http://127.0.0.1:8545 START_BLOCK=14600000 LOG_FILE=/home/api_user/ETH-transactions-storage/ethsync.log python3 /home/api_user/ETH-transactions-storage/ethsync.py
173149
```
174150

175-
Put the file to `/lib/systemd/system`. Then register a service:
151+
We recommend to run Indexer script `ethsync.py` as a background service to make sure it will be restarted in case of failure. See `ethsync.service` as an example. Copy it to /lib/systemd/system/ethsync.service, update according to your settings, then register a service:
176152

177153
```
178-
systemctl daemon-reload
179-
systemctl start ethstorage.service
180-
systemctl enable ethstorage.service
154+
systemctl start ethsync.service
155+
systemctl enable ethsync.service
181156
```
182157

183158
Note, indexing takes time. To check indexing process, get the last indexed block:
@@ -188,9 +163,15 @@ psql -d index -c 'SELECT MAX(block) FROM ethtxs;'
188163

189164
And compare to Ethereum node's best block.
190165

166+
### Troubleshooting
167+
168+
To test connection from script, set a connection line in `ethtest.py`, and run it. In case of success, it will print current Ethereum's last block.
169+
170+
To test a connection to a Postgres database `index`, run `pgtest.py`.
171+
191172
### Transaction API with Postgrest
192173

193-
Install and [configure](https://postgrest.org/en/v5.2/install.html#configuration) Postgrest.
174+
[Install and configure](https://postgrest.org/en/stable/install.html) Postgrest.
194175
Here is an example to run API for user `api_user` connected to `index` database on 3000 port:
195176

196177
```
@@ -208,7 +189,7 @@ Make sure you add Postgrest in crontab for autostart on reboot:
208189
@reboot cd /usr/share && /usr/bin/postgrest ./postgrest.conf
209190
```
210191

211-
## Make Indexer's API public
192+
### Make Indexer's API public
212193

213194
If you need to provide public API, use any web server like nginx and setup proxy to Postgrest port in config:
214195

@@ -225,62 +206,57 @@ location /max_block {
225206
226207
```
227208

228-
This way two endpoints will be available:
209+
This way endpoints will be available:
229210

230211
- `/ethtxs` used to fetch Ethereum transactions by address
231212
- `/aval` returns status of service. Endpoint `aval` is a table with `status` field just to check API availability.
232213
- `/max_block` returns max Ethereum indexed block
233214

234-
## API request examples
235-
236-
Get last 25 Ethereum transactions without ERC-20 transactions for address 0x1143e097e134f3407ef6b088672ccece9a4f8cdd:
215+
Example:
237216

238217
```
239-
https://ethnode1.adamant.im/ethtxs?and=(contract_to.eq.,or(txfrom.eq.0x1143e097e134f3407ef6b088672ccece9a4f8cdd,txto.eq.0x1143e097e134f3407ef6b088672ccece9a4f8cdd))&order=time.desc&limit=25
240-
218+
https://yourdomain.com/max_block
241219
```
242220

243-
Get last 25 ERC-20 transactions without Ethereum transactions for address 0x1143e097e134f3407ef6b088672ccece9a4f8cdd:
221+
## Dockerized and docker compose
244222

245-
```
246-
https://ethnode1.adamant.im/ethtxs?and=(contract_to.neq.,or(txfrom.eq.0x1143e097e134f3407ef6b088672ccece9a4f8cdd,txto.eq.0x1143e097e134f3407ef6b088672ccece9a4f8cdd))&order=time.desc&limit=25
223+
by Guénolé de Cadoudal ([email protected])
247224

248-
```
225+
In the `docker-compose.yml` you find a configuration that show how this tool can be embedded in a docker configuration with the following processes:
226+
227+
- postgres db: to store the indexed data
228+
- postgREST tool to expose the data as a REST api (see above comments)
229+
- GETH node in POA mode. Can be Openethereum, or another node, but not tested
230+
- EthSync tool (this tool)
231+
232+
[Set env variables](#ethereum-transaction-indexer).
233+
234+
# API request examples
249235

250-
Get last 25 transactions for both ERC-20 and Ethereum for address 0x1143e097e134f3407ef6b088672ccece9a4f8cdd:
236+
Get last 25 Ethereum transactions without ERC-20 transactions for address 0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98:
251237

252238
```
253-
https://ethnode1.adamant.im/ethtxs?and=(or(txfrom.eq.0x1143e097e134f3407ef6b088672ccece9a4f8cdd,txto.eq.0x1143e097e134f3407ef6b088672ccece9a4f8cdd))&order=time.desc&limit=25
239+
curl -k -X GET "http://localhost:3000/ethtxs?and=(contract_to.eq.,or(txfrom.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98,txto.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98))&order=time.desc&limit=25"
254240
255241
```
256242

257-
Zabbix API availability trigger examples:
243+
Get last 25 ERC-20 transactions without Ethereum transactions for address 0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98:
258244

259245
```
260-
{API for Ethereum transactions:system.run["curl -s https://ethnode1.adamant.im/aval | jq .[].status"].last()}<>1
246+
curl -k -X GET "http://localhost:3000/ethtxs?and=(contract_to.neq.,or(txfrom.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98,txto.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98))&order=time.desc&limit=25"
261247
262-
{API for Ethereum transactions:system.run["curl -s --connect-timeout 7 https://ethnode1.adamant.im/max_block | jq .[].max"].change()}<1
263248
```
264249

265-
# Dockerized and docker compose
266-
by Guénolé de Cadoudal ([email protected])
250+
Get last 25 transactions for both ERC-20 and Ethereum for address 0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98:
267251

268-
In the `docker-compose.yml` you find a configuration that show how this tool can be embedded in a docker configuration with the following processes:
269-
- postgres db: to store the indexed data
270-
- postgREST tool to expose the data as a REST api (see above comments)
271-
- GETH node in POA mode. Can be Openethereum, or another node, but not tested
272-
- EthSync tool (this tool)
252+
```
253+
curl -k -X GET "http://localhost:3000/ethtxs?and=(or(txfrom.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98,txto.eq.0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98))&order=time.desc&limit=25"
273254
274-
The EthSync tool accepts the following env variables:
275-
- DB_NAME: postgres url of the db
276-
- ETH_URL: eth node url to reach the node. Supports websocket, http and ipc.
277-
- START_BLOCK: the first block to synchronize from. Default is 1.
278-
- CONFIRMATIONS_BLOCK: the number of blocks to leave out of the synch from the end. I.e., last block is current `blockNumber - CONFIRMATIONS_BLOCK`. Default is 0.
279-
- PERIOD: Number of seconds between to synchronization. Default is 20 sec.
255+
```
280256

281257
# License
282258

283-
Copyright © 2020-2021 ADAMANT Foundation
259+
Copyright © 2020-2022 ADAMANT Foundation
284260
Copyright © 2017-2020 ADAMANT TECH LABS LP
285261

286262
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
File renamed without changes.

ethtest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from web3 import Web3
22
web3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))
33
#web3 = Web3(Web3.WebsocketProvider("ws://127.0.0.1:8546"))
4+
#web3 = Web3(Web3.IPCProvider("/home/geth/.ethereum/geth.ipc"))
45
print(web3.eth.blockNumber)

0 commit comments

Comments
 (0)