Last active
April 18, 2018 12:28
-
-
Save PhABC/4f405cd096da64d83fb99b3b294cd16e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Imports | |
var Trie = require('merkle-patricia-tree'); | |
var rlp = require('rlp'); | |
var levelup = require('levelup'); | |
var leveldown = require('leveldown'); | |
var keccak256 = require('js-sha3').keccak256; | |
// Chains' path | |
var dbPathRinkeby = '/home/user/.ethereum/rinkeby/geth/chaindata'; | |
var dbPathMainnet = '/home/user/.ethereum/geth/chaindata'; | |
//Path to chain to use | |
dbPath = dbPathMainnet; | |
//Contract address | |
var contract = '0x5db9b94f23d6722E5C30934B53b352B967fb0F7d'; | |
//Create database | |
var db = levelup(leveldown(dbPath)); | |
// Can be obtained with web3.eth.getBlock(<blockNumber>).stateRoot | |
var ROOT = '0x5e27b33d4fa2349b744f7c80c60f5bcdfa9c0754b7f2be61972b220bf2ec4d78'; | |
var trie = new Trie(db, ROOT); | |
/* | |
@dev Will return the contract's storage size in bytes | |
@param address Contract address to query storage size. | |
@param ROOT Block stateRoot to query storage. | |
*/ | |
async function getContractStorageSize(address, ROOT){ | |
//Checking if 0x was provided for address | |
if (address.substr(0,2) == '0x'){ | |
address = address.substr(2); | |
} | |
//Take hash of address | |
var addressHash = keccak256(new Buffer(address, 'hex')); | |
// Will count the byte size of the contract's storage | |
var contractStorageSize = 0; | |
//Promise to return | |
return new Promise(function(resolve, reject){ | |
//Verifying if ROOT exists | |
trie.checkRoot(ROOT, function (err, ifExists) { | |
if (!ifExists) { | |
console.log('State root does not exists'); | |
} | |
}); | |
//Querying the state trie of the given contract | |
trie.get('0x' + addressHash, function (err, val) { | |
var decodedVal = rlp.decode(val); | |
//Verifying if decoded value is valid | |
if (!decodedVal || decodedVal.length < 4) { | |
reject('The value for the address must be an array of 4 elements'); | |
} | |
// 3rd element in the array is storage root, 1st - nonce, 2nd - balance, 4th - codeHash | |
var storageRoot = decodedVal[2]; | |
//Set trie root to storageRoot | |
trie.root = storageRoot; | |
// Verifying if storage root exists | |
trie.checkRoot(storageRoot, function (err, ifExists) { | |
if (!ifExists) { | |
reject('Storage root does not exists'); | |
}; | |
}); | |
// Read all entries from contract storage | |
var stream = trie.createReadStream(); | |
stream.on('data', function (data) { | |
// Obtain Buffer value for current storage node | |
var decodedValNode = rlp.decode(data.value); | |
// Update contract Storage size | |
contractStorageSize += decodedValNode.byteLength; | |
}); | |
//When stream over | |
stream.on('end', async function (val) { | |
resolve(contractStorageSize); | |
}); | |
}); | |
}); | |
}; | |
//Printing the contract storage size for test contract | |
getContractStorageSize(contract, ROOT).then( | |
function(contractSize){ | |
console.log('Contract address : ', contract); | |
console.log('Contract Storage size (Bytes): ', contractSize); | |
} | |
); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment