Comment lire le contrat de stockage Ethereum

Tout le monde dit que les données des contrats sont publiques, mais tout le monde ne sait pas comment les lire.

Tous les contrats déployés sur ethereum VM ont un stockage dédié dans lequel les magasins sont en état. Voici un exemple comment lire ce stockage avec la bibliothèque web3.js à l'aide de la méthode eth.getStorageAt ().

Exemple de contrat que nous examinons:

Ce contrat est déployé dans le réseau de test ropsten: à l'adresse 0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b

Tous les paramètres de la mémoire sont indexés depuis le début. Un index prend 256 octets et 64 symboles. Dans cet exemple, nous avons 10 paramètres et nous pouvons les itérer:

let contractAddress = '0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b'
pour (index = 0; index <10; index ++) {
 console.log (`[$ {index}]` +
   web3.eth.getStorageAt (contractAddress, index))
}
résultat:
[0] 0x0000000000000000000000000000000000000000000000000000000000000000f
[1] 0x000000000000000000000000000059b92d9a0000000000000000000000000000299f
[2] 0x00000000000000000000000000000000000074657374310000000000000000000000
[3] 0x746573743132333600000000000000000000000000000000000000000000
[4] 0x6c65747320737472696e6720736f6d657468696e67000000000000000000002a
[5] 0x00000000000000000000000000000000000000000000000000000000000000000000
[6] 0x00000000000000000000000000000000000000000000000000000000000000000000
[7] 0x00000000000000000000000000000000000000000000000000000000000000000002
[8] 0x00000000000000000000000000000000000000000000000000000000000000000002
[9] 0x00000000000000000000000000000000000000000000000000000000000000000000

Regardons de plus près chaque paramètre

Index 0 - stockéint1

let contractAddress = '0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b'
laisser index = 0
console.log (web3.eth.getStorageAt (contractAddress, index))
console.log ('DEC:' + web3.toDecimal (web3.eth.getStorageAt (contractAddress, index)))
résultat:
0x0000000000000000000000000000000000000000000000000000000000000000000f
15 décembre

constuint

Les constantes ne sont pas stockées dans un stockage. Disponible uniquement en code.

Index 1 - investissementsLimit, investissementsDeadlineTimeStamp

laisser index = 1
console.log (web3.eth.getStorageAt (contractAddress, index))
résultat:
 0x00000000000000000000000059b92d9a0000000000000000000000000000429f
DEC: 1505308058 et 17055

Dans l'index 1, deux propriétés sont fusionnées pour optimiser l'utilisation du stockage.

index 2 - chaîne1

indice = 2
console.log (web3.eth.getStorageAt (contractAddress, index))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (contractAddress, index)))
résultat:
0x00000000000000000000000000000000000074657374310000000000000000000000
ASCII: test1

index 3 - chaîne2

indice = 3
console.log (web3.eth.getStorageAt (contractAddress, index))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (contractAddress, index)))
résultat:
0x7465737431323336000000000000000000000000000000000000000000000000
ASCII: test1236

index 4 - chaîne3

indice = 4
console.log (web3.eth.getStorageAt (contractAddress, index))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (contractAddress, index)))
résultat:
0x6c65747320737472696e6720736f6d657468696e67000000000000000000002a
ASCII: permet de corder quelque chose * (42)

Le symbole de fin 2a (déc 42) est la longueur de la chaîne stockée. (plus de détails http://solidity.readthedocs.io/en/latest/misc Miscellaneous.html#layout-of-state-variables-in-ststorage)

index 5 - uints1

indice = 5
console.log (web3.eth.getStorageAt (contractAddress, index))
résultat:
0x00000000000000000000000000000000000000000000000000000000000000000000
PROBLÈME!!!!

Les mappages ont une indexation différente et doivent être lus d'une autre manière. Pour lire la valeur de mappage, vous devez connaître la valeur de clé. Sinon, la lecture de la valeur de mappage est impossible.

index = '00000000000000000000000000000000000000000000000000000000000000000005'
clé = '00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6'
laisser newKey = web3.sha3 (clé + index, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (contractAddress, newKey))
console.log ('DEC:' + web3.toDecimal (web3.eth.getStorageAt (contractAddress, newKey)))
résultat:
0x00000000000000000000000000000000000000000000000000000000000000000058
DEC: 88

index6 - structs1

index = "00000000000000000000000000000000000000000000000000000000000000000006"
clé = "00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6"
laisser newKey = web3.sha3 (clé + index, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (contractAddress, newKey))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (contractAddress, newKey)))
résultat:
0x6465766963654272616e64000000000000000000000000000000000000000016
ASCII: deviceBrand

Pour lire la deuxième valeur de structure, vous devez augmenter la valeur newKey de 1.

augmentation de la fonctionHexByOne (hex) {
 Soit x = nouveau BigNumber (hex)
 let sum = x.add (1)
 let result = '0x' + sum.toString (16)
 résultat retourné
}
index = "00000000000000000000000000000000000000000000000000000000000000000006"
clé = "00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6"
laissez newKey = augmentationHexByOne (
  web3.sha3 (clé + index, {"encoding": "hex"}))
console.log (web3.eth.getStorageAt (contractAddress, newKey))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (contractAddress, newKey)))
résultat:
0x6465766963655965617200000000000000000000000000000000000000000014
ASCII: deviceYear

Si vous voulez une troisième valeur de structure, augmentez une nouvelle fois newKey.

indice 7 - uintarray

index = "7"
console.log (web3.eth.getStorageAt (contractAddress, index))
résultat:
  0x00000000000000000000000000000000000000000000000000000000000000000002

Ce tableau a 2 éléments

index = "00000000000000000000000000000000000000000000000000000000000000000007"
laissez newKey = web3.sha3 (index, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (contractAddress, newKey))
console.log ('DEC:' +
  web3.toDecimal (web3.eth.getStorageAt (contractAddress, newKey)))
résultat:
0x00000000000000000000000000000000000000000000000000000000000000001f40
DEC: 8000
newKey = augmentationHexByOne (web3.sha3 (index, {"encoding": "hex"}))
console.log (web3.eth.getStorageAt (contractAddress, newKey))
console.log ('DEC:' +
  web3.toDecimal (web3.eth.getStorageAt (contractAddress, newKey)))
résultat:
0x00000000000000000000000000000000000000000000000000000000000000002328
DEC: 9000

index 8 - deviceDataArray

index = "00000000000000000000000000000000000000000000000000000000000000000008"
laissez newKey = web3.sha3 (index, {"encoding": "hex"})
console.log (web3.eth.getStorageAt (contractAddress, newKey))
console.log ('ASCII:' +
 web3.toAscii (web3.eth.getStorageAt (contractAddress, newKey)))
résultat:
0x6465766963654272616e64000000000000000000000000000000000000000016
ASCII: deviceBrand
index = "00000000000000000000000000000000000000000000000000000000000000000008"
let newKey = augmentationHexByOne (web3.sha3 (index, {"encoding": "hex"}))
console.log (web3.eth.getStorageAt (contractAddress, newKey))
console.log ('ASCII:' +
web3.toAscii (web3.eth.getStorageAt (contractAddress, newKey)))
résultat:
0x6465766963655965617200000000000000000000000000000000000000000014
ASCII: deviceYear

Augmentation de 2 résultat:

0x776561724c6576656c0000000000000000000000000000000000000000000012

ASCII: wearLevel

Augmentation de 3 vous entrez au deuxième élément dans le résultat du tableau:

0x6465766963654272616e64320000000000000000000000000000000000000018

ASCII: deviceBrand2

Sources:
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

Découvrez notre terrain d'essai - Aigang!

En savoir plus sur Aigang - http://bit.ly/AigangWebsite
Livre blanc Aigang - http://bit.ly/2hwAtkt
Aigang sur Telegram - http://bit.ly/AigangTelegram
Obtenir les dernières mises à jour d'Aigang - http://bit.ly/AigangUpdates