· 8 years ago · Apr 17, 2018, 08:06 PM
1package tcs.examples.ethereum.sql
2
3import tcs.blockchain.BlockchainLib
4import tcs.db.sql.Table
5import tcs.db.{DatabaseSettings, PostgreSQL}
6import scalikejdbc._
7import tcs.blockchain.ethereum.EthereumSettings
8
9object EthereumPools {
10 def main(args: Array[String]): Unit = {
11 val start = 500000
12 val end = start + 20
13 val blockchain = BlockchainLib.getEthereumBlockchain(new EthereumSettings("https://mainnet.infura.io/lGhdnAJw7n56K0xXGP3i:8545")).start(start).end(end)
14 val pg = new DatabaseSettings("ethereum", PostgreSQL, "postgres", "0")
15
16 val blockTable = new Table(
17 sql"""
18 CREATE TABLE IF NOT EXISTS balances(
19 address CHARACTER VARYING(100) NOT NULL PRIMARY KEY,
20 sent DECIMAL,
21 received DECIMAL,
22 total DECIMAL,
23 n_sent DECIMAL,
24 n_received DECIMAL
25 )
26 """,
27 sql"""
28 INSERT INTO balances(address,sent,received, total, n_sent, n_received)
29 VALUES (?, ?, ?, ?, ?, ?)
30 """,
31 pg, 100
32 )
33
34 println("table created")
35
36 // address => sent, received, total, n_withdrawals, n_sent
37 var map = Map[String, Array[scala.math.BigInt]]()
38
39 var counter = 0
40
41 println("foreach starting...")
42 blockchain.foreach(block => {
43 counter += 1
44
45 block.txs.foreach(transaction => {
46 println(counter.toString + ") n transactions: " + map.values.toList.length)
47
48 if (map.contains(transaction.from)) {
49 // if the address "from" is already present in the map
50 // we can update its balance
51
52 /** how to update:
53 * the "value" goes from the "from" address to the "to" address
54 * 1. add "value" to the sent ethereums
55 * 2. substract "value" from the total
56 * 3. increment the number of transactions that have taken
57 * eth from "from", i.e. increment n_sent
58 */
59
60 // first, save the current balance
61 val balance: Array[BigInt] = map(transaction.from)
62 map -= transaction.from // delete the value from the map
63
64 // update of the quantities
65
66 // update of the quantity of eth sent
67 balance(0) += transaction.value // sent += value
68
69 // update of the total
70 balance(2) -= transaction.value // total -= value
71
72 // update of the number of transaction that the address has sent to
73 balance(3) += 1 // n_sent ++
74
75 // re-add the value to the map
76 map += transaction.from -> balance
77 }
78 else {
79 // the address "from" is not in the map, so it must be added
80 // only if there is a transaction sending money
81 if (transaction.value > 0)
82 /** add an entry to the map which goes from the "from" address to
83 * an array with:
84 * sent: value
85 * received: 0
86 * total: -value
87 * n_sent: 1
88 * n_received: 0
89 */
90 map += transaction.from -> Array(transaction.value, 0, -transaction.value, 1, 0)
91 }
92
93 if (map.contains(transaction.to)) {
94 // if the address "to" is already present in the map,
95 // we can update its balance
96
97 /** how to update:
98 * the "value" goes from the "from" address to the "to" address
99 * 1. add "value" to the received ethereums
100 * 2. add "value" from the total
101 * 3. increment the number of transactions that have sent
102 * eth to "to", i.e. increment n_receivd
103 */
104
105 // first, save the current balance
106 val balance: Array[BigInt] = map(transaction.to)
107 map -= transaction.to // delete the value from the map
108
109 // update of the quantity of eth sent
110 balance(1) += transaction.value // received += value
111
112 // update of the total
113 balance(2) += transaction.value // total += value
114
115 // update of the number of transaction that have taken eth from that address
116 balance(4) += 1 // n_received ++
117
118 // re-add the value to the map
119 map += transaction.to -> balance
120 }
121 else {
122 // the address "to" is not in the map, so it must be added
123 // only if there is a transaction sending money
124 if (transaction.value > 0)
125 /** add an entry to the map which goes from the "to" address to
126 * an array with:
127 * sent: 0
128 * received: value
129 * total: value
130 * n_sent: 0
131 * n_received: 1
132 */
133 map += transaction.to -> Array(0, transaction.value, transaction.value, 0, 1)
134 }
135 })
136 })
137 println("...foreach ended")
138
139 for(address <- map.keys) {
140 blockTable.insert(address :: map(address).toList) // insert each element of the map in the db
141 println(address::map(address).toList)
142 }
143 println("data inserted")
144
145 blockTable.close
146 println("table closed")
147
148 println("END")
149 }
150}