UNPKG

incubed

Version:

Typescript-version of the incubed client

125 lines 6.03 kB
"use strict"; /*********************************************************** * 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