Kuidas lugeda Ethereumi lepingulist salvestust

Kõik räägivad, et lepingutes sisalduvad andmed on avalikud, kuid mitte kõik ei tea, kuidas neid lugeda.

Kõigil ethereumi VM-is kasutusele võetud lepingutel on spetsiaalne salvestusruum, kus asuvad kauplused. Siin on näide selle kohta, kuidas seda salvestust veebi.js teegiga lugeda, kasutades meetodit eth.getStorageAt ().

Lepingunäide, mida uurime:

See leping on paigaldatud ropsten test net: aadressil 0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b

Kõik salvestuse parameetrid on algusest peale indekseeritud. Ühel indeksil on 256 baiti ja see sobib 64 sümboliga. Selles näites on meil 10 parameetrit ja saame neid korrata:

let lepingAddress = '0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b'
jaoks (indeks = 0; indeks <10; indeks ++) {
 console.log (`[$ {index}]` +
   web3.eth.getStorageAt (lepingu aadress, register)
}
tulemus:
[0] 0x0000000000000000000000000000000000000000000000000000000000000000000f
[1] 0x00000000000000000000000055bbdd9a000000000000000000000000000000429f
[2] 0x00000000000000000000000000000000007465737431000000000000000000000000
[3] 0x74657374313233360000000000000000000000000000000000000000000000000000
[4] 0x6c65747320737472696e6720736f6d657468696e67000000000000000000002a
[5] 0x00000000000000000000000000000000000000000000000000000000000000000000
[6] 0x00000000000000000000000000000000000000000000000000000000000000000000
[7] 0x000000000000000000000000000000000000000000000000000000000000000002
[8] 0x000000000000000000000000000000000000000000000000000000000000000002
[9] 0x00000000000000000000000000000000000000000000000000000000000000000000

Vaatame iga parameetrit sügavamalt

Indeks 0 - pood1

let lepingAddress = '0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b'
las indeks = 0
console.log (web3.eth.getStorageAt (lepingAadress, register))
console.log ('DEC:' + web3.toDecimal (web3.eth.getStorageAt (lepingu aadress, register))))
tulemus:
0x0000000000000000000000000000000000000000000000000000000000000000000000f
DEC: 15

konstaabel

Konstante ei ladustata salvestusruumi. Saadaval ainult koodina.

Indeks 1 - investeeringudLimit, InvestmentDeadlineTimeStamp

las indeks = 1
console.log (web3.eth.getStorageAt (lepingAadress, register))
tulemus:
 0x00000000000000000000000059b92d9a000000000000000000000000000000429f
DEC: 1505308058 ja 17055

Indeksis 1 on salvestusruumi kasutamise optimeerimiseks liidetud 2 atribuuti.

indeks 2 - string1

indeks = 2
console.log (web3.eth.getStorageAt (lepingAadress, register))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (lepinguaadress, register)))
tulemus:
0x0000000000000000000000000000000000007465737431000000000000000000000000
ASCII: test1

indeks 3 - string2

indeks = 3
console.log (web3.eth.getStorageAt (lepingAadress, register))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (lepinguaadress, register)))
tulemus:
0x74657374313233360000000000000000000000000000000000000000000000000000
ASCII: test1236

register 4— string3

indeks = 4
console.log (web3.eth.getStorageAt (lepingAadress, register))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (lepinguaadress, register)))
tulemus:
0x6c65747320737472696e6720736f6d657468696e6700000000000000000000002a
ASCII: laseb midagi stringida * (42)

Lõppsümbol 2a (detsember 42) on salvestatud stringi pikkus. (lisateave http://solidity.readthedocs.io/et/latest/miscellaneous.html#layout-of-state-variables-in-storage)

indeks 5 - uints1

indeks = 5
console.log (web3.eth.getStorageAt (lepingAadress, register))
tulemus:
0x0000000000000000000000000000000000000000000000000000000000000000000000
PROBLEEM !!!!

Kaardistustel on erinev indekseerimine ja neid tuleks lugeda muul viisil. Kaardiväärtuse lugemiseks peaksite teadma võtme väärtust. Vastasel juhul on kaardistamise väärtuse lugemine võimatu.

indeks = '000000000000000000000000000000000000000000000000000000000000000000005'
võti = '00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6'
lase newKey = web3.sha3 (võti + register, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (lepingAadress, newKey))
console.log ('DEC:' + web3.toDecimal (web3.eth.getStorageAt (lepingAadress, newKey))))
tulemus:
0x000000000000000000000000000000000000000000000000000000000000000000558
DEC: 88

indeks6 - konstruktsioonid1

indeks = "00000000000000000000000000000000000000000000000000000000000000000006"
võti = "00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6"
lase newKey = web3.sha3 (võti + register, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (lepingAadress, newKey))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (lepingu aadress, newKey)))
tulemus:
0x6465766963654272616e640000000000000000000000000000000000000000000016
ASCII: seadeBrand

Teise struktuuri väärtuse lugemiseks peate suurendama newKey väärtust ühe võrra

funktsiooni suurendamineHexByOne (heksa) {
 las x = uus BigNumber (heksaarv)
 laske summa = x.add (1)
 laske tulemus = '0x' + summa.toString (16)
 tagastamise tulemus
}
indeks = "00000000000000000000000000000000000000000000000000000000000000000006"
võti = "00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6"
lase newKey = suurendadaHexByOne (
  web3.sha3 (võti + register, {"kodeering": "heks"}))
console.log (web3.eth.getStorageAt (lepingAadress, newKey))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (lepingu aadress, newKey)))
tulemus:
0x64657669636559656172000000000000000000000000000000000000000000000014
ASCII: seadme aasta

Kui soovite kolmanda struktuuri väärtust, suurendage newKey veel kord.

indeks 7— uintarray

indeks = "7"
console.log (web3.eth.getStorageAt (lepingAadress, register))
tulemus:
  0x0000000000000000000000000000000000000000000000000000000000000000000002

Selles massiivis on 2 eset

register = "00000000000000000000000000000000000000000000000000000000000000000007"
lase newKey = web3.sha3 (register, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (lepingAadress, newKey))
console.log ('DEC:' +
  web3.toDecimal (web3.eth.getStorageAt (lepingu aadress, newKey)))
tulemus:
0x0000000000000000000000000000000000000000000000000000000000000000100140
DEC: 8000
newKey = suurendadaHexByOne (web3.sha3 (register, {"kodeering": "heks"}))
console.log (web3.eth.getStorageAt (lepingAadress, newKey))
console.log ('DEC:' +
  web3.toDecimal (web3.eth.getStorageAt (lepingu aadress, newKey)))
tulemus:
0x0000000000000000000000000000000000000000000000000000000000000000002328
DEC: 9000

register 8 - deviceDataArray

indeks = "00000000000000000000000000000000000000000000000000000000000000000008"
lase newKey = web3.sha3 (register, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (lepingAadress, newKey))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (lepingu aadress, newKey)))
tulemus:
0x6465766963654272616e640000000000000000000000000000000000000000000016
ASCII: seadeBrand
indeks = "00000000000000000000000000000000000000000000000000000000000000000008"
lase newKey = suurendadaHexByOne (web3.sha3 (register, {"encoding": "hex"}))
console.log (web3.eth.getStorageAt (lepingAadress, newKey))
console.log ('ASCII:' +
web3.toAscii (web3.eth.getStorageAt (lepingu aadress, newKey)))
tulemus:
0x64657669636559656172000000000000000000000000000000000000000000000014
ASCII: seadme aasta

Suurenda 2 tulemuse võrra:

0x776561724c6576656c00000000000000000000000000000000000000000000000012

ASCII: wearLevel

Suurendage 3-ga, kui sisestate massiivi tulemuse teisele üksusele:

0x6465766963654272616e643200000000000000000000000000000000000000001818

ASCII: seadeBrand2

Allikad:
https://github.com/ethereum/solidity/issues/1550
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getstorageat
https://ethereum.stackexchange.com/questions/13910/how-to-read-a-private-variable-from-a-contract
https://github.com/ethereum/web3.js/issues/445

Vaadake meie prooviplatsi - Aigang!

Lisateave Aigangi kohta - http://bit.ly/AigangWebsite
Aigangi valge paber - http://bit.ly/2hwAtkt
Aigang telegrammis - http://bit.ly/AigangTelegram
Hankige Aigangi uusimad värskendused - http://bit.ly/AigangUpdates