incubed
Version:
Typescript-version of the incubed client
125 lines • 6.03 kB
JavaScript
;
/***********************************************************
* This file is part of the Slock.it IoT Layer. *
* The Slock.it IoT Layer contains: *
* - USN (Universal Sharing Network) *
* - INCUBED (Trustless INcentivized remote Node Network) *
************************************************************
* Copyright (C) 2016 - 2018 Slock.it GmbH *
* All Rights Reserved. *
************************************************************
* You may use, distribute and modify this code under the *
* terms of the license contract you have concluded with *
* Slock.it GmbH. *
* For information about liability, maintenance etc. also *
* refer to the contract concluded with Slock.it GmbH. *
************************************************************
* For more information, please refer to https://slock.it *
* For questions, please contact info@slock.it *
***********************************************************/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const ethereumjs_util_1 = require("ethereumjs-util");
const util_1 = require("../../util/util");
const serialize_1 = require("./serialize");
const transport_1 = require("../../util/transport");
/**
* calc the storrage array key
*/
function getStorageArrayKey(pos, arrayIndex, structSize = 1, structPos = 0) {
return arrayIndex === undefined
? serialize_1.bytes32(pos)
: serialize_1.bytes32(exports.toBN(ethereumjs_util_1.keccak256(serialize_1.bytes32(pos))).add(exports.toBN(arrayIndex * structSize + structPos)));
}
exports.getStorageArrayKey = getStorageArrayKey;
/**
* calcs the storage Map key.
* @param pos position of the map in the contract
* @param key key to search for
* @param structPos if the value is a struct - the position in the struct
*/
function getStorageMapKey(pos, key, structPos = 0) {
return serialize_1.bytes32(exports.toBN(ethereumjs_util_1.keccak256(Buffer.concat([serialize_1.bytes32(key), serialize_1.bytes32(pos)]))).add(exports.toBN(structPos)));
}
exports.getStorageMapKey = getStorageMapKey;
/**
* creates a string from storage.
* @param data the data of the frst slot.
* @param storageKey the key.
* if the length is bigger than 32, this function will return the keys needed in order to create the value, otherwise the string is returned.
*/
function getStringValue(data, storageKey) {
if (data.length > 32)
throw new Error('storrage value is too long. Must be 32bytes!');
if (data[31] % 2 === 0)
return data.slice(0, data[31] / 2).toString('utf8');
const len = (util_1.toNumber(data) - 1) / 2;
const slot = exports.toBN(ethereumjs_util_1.keccak256(storageKey));
const storageKeys = [];
for (let i = 0; i < len / 32; i++)
storageKeys.push(serialize_1.bytes32(slot.add(exports.toBN(i))));
return { len, storageKeys };
}
exports.getStringValue = getStringValue;
/**
* concats the storage values to a string.
* @param values
* @param len
*/
function getStringValueFromList(values, len) {
return Buffer.concat(values).slice(0, len).toString('utf8');
}
exports.getStringValueFromList = getStringValueFromList;
/**
* converts any value to BN
*/
exports.toBN = val => new ethereumjs_util_1.BN(util_1.toHex(val).substr(2), 16);
/**
* get a storage value from the server
* @param rpc url of the client
* @param contract address of the contract
* @param pos position in the contract
* @param type type of the value
* @param keyOrIndex if number this is in the index in the array if hex, this is the key in the map
* @param structSize size if the value in the array of map
* @param structPos position in the struct-value in the array of map
*/
function getStorageValue(rpc, contract, pos, type, keyOrIndex, structSize, structPos) {
return __awaiter(this, void 0, void 0, function* () {
const t = new transport_1.AxiosTransport();
const storageKey = keyOrIndex === undefined
? getStorageArrayKey(pos)
: structSize
? getStorageArrayKey(pos, keyOrIndex, structSize, structPos)
: getStorageMapKey(pos, keyOrIndex, structPos);
const val = yield t.handle(rpc, {
id: 1, jsonrpc: '2.0', method: 'eth_getStorageAt', params: [contract, util_1.toHex(storageKey)]
}).then(_ => _.result);
if (type === 'int')
return exports.toBN(val);
else if (type === 'bytes32')
return val;
else if (type === 'bytes16')
return val.substr(34, 32);
else if (type === 'bytes4')
return val.substr(58, 8);
else if (type === 'address')
return ethereumjs_util_1.toChecksumAddress('0x' + val.substr(26));
const stringValue = getStringValue(serialize_1.bytes32(val), storageKey);
if (typeof stringValue === 'string')
return stringValue;
else
return t.handle(rpc, stringValue.storageKeys.map((sk, i) => ({
id: i + 1, jsonrpc: '2.0', method: 'eth_getStorageAt', params: [contract, util_1.toHex(sk)]
}))).then((all) => getStringValueFromList(all.map(serialize_1.bytes32), stringValue.len));
});
}
exports.getStorageValue = getStorageValue;
//# sourceMappingURL=storage.js.map