mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-01-22 19:19:05 +00:00
Use getStorageValue to parse value for string type variable (#29)
* Get string value of variable name. * Use getStorageValue to parse value for string type variable. Co-authored-by: nikugogoi <95nikass@gmail.com>
This commit is contained in:
parent
b243025ca8
commit
00eb129536
@ -1,3 +1,3 @@
|
||||
export { getStorageValue, getStorageInfo, StorageLayout, GetStorageAt } from './storage';
|
||||
export { getStorageValue, getStorageInfo, getValueByType, StorageLayout, GetStorageAt } from './storage';
|
||||
|
||||
export { getEventNameTopics } from './logs';
|
||||
|
@ -74,21 +74,29 @@ it('get storage information', async function () {
|
||||
});
|
||||
|
||||
describe('Get value from storage', function () {
|
||||
const getBlockHash = async () => {
|
||||
const blockNumber = await ethers.provider.getBlockNumber();
|
||||
const { hash } = await ethers.provider.getBlock(blockNumber);
|
||||
return hash;
|
||||
};
|
||||
|
||||
it('get value for integer type variables packed together', async function () {
|
||||
const Integers = await ethers.getContractFactory('TestIntegers');
|
||||
const integers = await Integers.deploy();
|
||||
await integers.deployed();
|
||||
const storageLayout = await getStorageLayout('TestIntegers');
|
||||
|
||||
let value = 12;
|
||||
await integers.setInt1(value);
|
||||
let storageValue = await getStorageValue(integers.address, storageLayout, getStorageAt, 'int1');
|
||||
expect(storageValue).to.equal(value);
|
||||
let expectedValue = 12;
|
||||
await integers.setInt1(expectedValue);
|
||||
let blockHash = await getBlockHash();
|
||||
let { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, integers.address, 'int1');
|
||||
expect(value).to.equal(expectedValue);
|
||||
|
||||
value = 34;
|
||||
await integers.setInt2(value);
|
||||
storageValue = await getStorageValue(integers.address, storageLayout, getStorageAt, 'int2');
|
||||
expect(storageValue).to.equal(value);
|
||||
expectedValue = 34;
|
||||
await integers.setInt2(expectedValue);
|
||||
blockHash = await getBlockHash();
|
||||
({ value } = await getStorageValue(storageLayout, getStorageAt, blockHash, integers.address, 'int2'));
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for integer type variables using single slot', async function () {
|
||||
@ -97,10 +105,11 @@ describe('Get value from storage', function () {
|
||||
await integers.deployed();
|
||||
const storageLayout = await getStorageLayout('TestIntegers');
|
||||
|
||||
const value = 123;
|
||||
await integers.setInt3(value);
|
||||
const storageValue = await getStorageValue(integers.address, storageLayout, getStorageAt, 'int3');
|
||||
expect(storageValue).to.equal(value);
|
||||
const expectedValue = 123;
|
||||
await integers.setInt3(expectedValue);
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, integers.address, 'int3');
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for unsigned integer type variables packed together', async function () {
|
||||
@ -109,15 +118,17 @@ describe('Get value from storage', function () {
|
||||
await unsignedIntegers.deployed();
|
||||
const storageLayout = await getStorageLayout('TestUnsignedIntegers');
|
||||
|
||||
let value = 12;
|
||||
await unsignedIntegers.setUint1(value);
|
||||
let storageValue = await getStorageValue(unsignedIntegers.address, storageLayout, getStorageAt, 'uint1');
|
||||
expect(storageValue).to.equal(value);
|
||||
let expectedValue = 12;
|
||||
await unsignedIntegers.setUint1(expectedValue);
|
||||
let blockHash = await getBlockHash();
|
||||
let { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, unsignedIntegers.address, 'uint1');
|
||||
expect(value).to.equal(expectedValue);
|
||||
|
||||
value = 34;
|
||||
await unsignedIntegers.setUint2(value);
|
||||
storageValue = await getStorageValue(unsignedIntegers.address, storageLayout, getStorageAt, 'uint2');
|
||||
expect(storageValue).to.equal(value);
|
||||
expectedValue = 34;
|
||||
await unsignedIntegers.setUint2(expectedValue);
|
||||
blockHash = await getBlockHash();
|
||||
({ value } = await getStorageValue(storageLayout, getStorageAt, blockHash, unsignedIntegers.address, 'uint2'));
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for unsigned integer type variables using single slot', async function () {
|
||||
@ -126,10 +137,11 @@ describe('Get value from storage', function () {
|
||||
await unsignedIntegers.deployed();
|
||||
const storageLayout = await getStorageLayout('TestUnsignedIntegers');
|
||||
|
||||
const value = 123;
|
||||
await unsignedIntegers.setUint3(value);
|
||||
const storageValue = await getStorageValue(unsignedIntegers.address, storageLayout, getStorageAt, 'uint3');
|
||||
expect(storageValue).to.equal(value);
|
||||
const expectedValue = 123;
|
||||
await unsignedIntegers.setUint3(expectedValue);
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, unsignedIntegers.address, 'uint3');
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for boolean type', async function () {
|
||||
@ -138,15 +150,17 @@ describe('Get value from storage', function () {
|
||||
await booleans.deployed();
|
||||
const storageLayout = await getStorageLayout('TestBooleans');
|
||||
|
||||
let value = true;
|
||||
await booleans.setBool1(value);
|
||||
let storageValue = await getStorageValue(booleans.address, storageLayout, getStorageAt, 'bool1');
|
||||
expect(storageValue).to.equal(value);
|
||||
let expectedValue = true;
|
||||
await booleans.setBool1(expectedValue);
|
||||
let blockHash = await getBlockHash();
|
||||
let { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, booleans.address, 'bool1');
|
||||
expect(value).to.equal(expectedValue);
|
||||
|
||||
value = false;
|
||||
await booleans.setBool2(value);
|
||||
storageValue = await getStorageValue(booleans.address, storageLayout, getStorageAt, 'bool2');
|
||||
expect(storageValue).to.equal(value);
|
||||
expectedValue = false;
|
||||
await booleans.setBool2(expectedValue);
|
||||
blockHash = await getBlockHash();
|
||||
({ value } = await getStorageValue(storageLayout, getStorageAt, blockHash, booleans.address, 'bool2'));
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for address type', async function () {
|
||||
@ -157,9 +171,10 @@ describe('Get value from storage', function () {
|
||||
|
||||
const [signer] = await ethers.getSigners();
|
||||
await address.setAddress1(signer.address);
|
||||
const storageValue = await getStorageValue(address.address, storageLayout, getStorageAt, 'address1');
|
||||
expect(storageValue).to.be.a('string');
|
||||
expect(String(storageValue).toLowerCase()).to.equal(signer.address.toLowerCase());
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, address.address, 'address1');
|
||||
expect(value).to.be.a('string');
|
||||
expect(String(value).toLowerCase()).to.equal(signer.address.toLowerCase());
|
||||
});
|
||||
|
||||
it('get value for contract type', async function () {
|
||||
@ -175,8 +190,9 @@ describe('Get value from storage', function () {
|
||||
const storageLayout = await getStorageLayout('TestContractTypes');
|
||||
|
||||
await testContractTypes.setAddressContract1(testAddress.address);
|
||||
const storageValue = await getStorageValue(testContractTypes.address, storageLayout, getStorageAt, 'addressContract1');
|
||||
expect(storageValue).to.equal(testAddress.address.toLowerCase());
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testContractTypes.address, 'addressContract1');
|
||||
expect(value).to.equal(testAddress.address.toLowerCase());
|
||||
});
|
||||
|
||||
it('get value for fixed size byte arrays packed together', async function () {
|
||||
@ -185,15 +201,17 @@ describe('Get value from storage', function () {
|
||||
await testBytes.deployed();
|
||||
const storageLayout = await getStorageLayout('TestBytes');
|
||||
|
||||
let value = ethers.utils.hexlify(ethers.utils.randomBytes(10));
|
||||
await testBytes.setBytesTen(value);
|
||||
let storageValue = await getStorageValue(testBytes.address, storageLayout, getStorageAt, 'bytesTen');
|
||||
expect(storageValue).to.equal(value);
|
||||
let expectedValue = ethers.utils.hexlify(ethers.utils.randomBytes(10));
|
||||
await testBytes.setBytesTen(expectedValue);
|
||||
let blockHash = await getBlockHash();
|
||||
let { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testBytes.address, 'bytesTen');
|
||||
expect(value).to.equal(expectedValue);
|
||||
|
||||
value = ethers.utils.hexlify(ethers.utils.randomBytes(20));
|
||||
await testBytes.setBytesTwenty(value);
|
||||
storageValue = await getStorageValue(testBytes.address, storageLayout, getStorageAt, 'bytesTwenty');
|
||||
expect(storageValue).to.equal(value);
|
||||
expectedValue = ethers.utils.hexlify(ethers.utils.randomBytes(20));
|
||||
await testBytes.setBytesTwenty(expectedValue);
|
||||
blockHash = await getBlockHash();
|
||||
({ value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testBytes.address, 'bytesTwenty'));
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for fixed size byte arrays using single slot', async function () {
|
||||
@ -202,10 +220,11 @@ describe('Get value from storage', function () {
|
||||
await testBytes.deployed();
|
||||
const storageLayout = await getStorageLayout('TestBytes');
|
||||
|
||||
const value = ethers.utils.hexlify(ethers.utils.randomBytes(30));
|
||||
await testBytes.setBytesThirty(value);
|
||||
const storageValue = await getStorageValue(testBytes.address, storageLayout, getStorageAt, 'bytesThirty');
|
||||
expect(storageValue).to.equal(value);
|
||||
const expectedValue = ethers.utils.hexlify(ethers.utils.randomBytes(30));
|
||||
await testBytes.setBytesThirty(expectedValue);
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testBytes.address, 'bytesThirty');
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for enum types', async function () {
|
||||
@ -214,10 +233,11 @@ describe('Get value from storage', function () {
|
||||
await testEnums.deployed();
|
||||
const storageLayout = await getStorageLayout('TestEnums');
|
||||
|
||||
const value = 1;
|
||||
await testEnums.setChoicesEnum1(value);
|
||||
const storageValue = await getStorageValue(testEnums.address, storageLayout, getStorageAt, 'choicesEnum1');
|
||||
expect(storageValue).to.equal(value);
|
||||
const expectedValue = 1;
|
||||
await testEnums.setChoicesEnum1(expectedValue);
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testEnums.address, 'choicesEnum1');
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
describe('string type', function () {
|
||||
@ -231,17 +251,19 @@ describe('Get value from storage', function () {
|
||||
});
|
||||
|
||||
it('get value for string length less than 32 bytes', async function () {
|
||||
const value = 'Hello world.';
|
||||
await strings.setString1(value);
|
||||
const storageValue = await getStorageValue(strings.address, storageLayout, getStorageAt, 'string1');
|
||||
expect(storageValue).to.equal(value);
|
||||
const expectedValue = 'Hello world.';
|
||||
await strings.setString1(expectedValue);
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, strings.address, 'string1');
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
|
||||
it('get value for string length more than 32 bytes', async function () {
|
||||
const value = 'This sentence is more than 32 bytes long.';
|
||||
await strings.setString2(value);
|
||||
const storageValue = await getStorageValue(strings.address, storageLayout, getStorageAt, 'string2');
|
||||
expect(storageValue).to.equal(value);
|
||||
const expectedValue = 'This sentence is more than 32 bytes long.';
|
||||
await strings.setString2(expectedValue);
|
||||
const blockHash = await getBlockHash();
|
||||
const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, strings.address, 'string2');
|
||||
expect(value).to.equal(expectedValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ export interface StorageInfo extends Storage {
|
||||
types: { [type: string]: Type; }
|
||||
}
|
||||
|
||||
export type GetStorageAt = (address: string, position: string) => Promise<string>
|
||||
export type GetStorageAt = (param: { blockHash: string, contract: string, slot: string }) => Promise<{ value: string, proof: { data: string } }>
|
||||
|
||||
/**
|
||||
* Function to get storage information of variable from storage layout.
|
||||
@ -47,96 +47,123 @@ export const getStorageInfo = (storageLayout: StorageLayout, variableName: strin
|
||||
|
||||
/**
|
||||
* Function to get the value from storage for a contract variable.
|
||||
* @param address
|
||||
* @param storageLayout
|
||||
* @param getStorageAt
|
||||
* @param blockHash
|
||||
* @param address
|
||||
* @param variableName
|
||||
*/
|
||||
export const getStorageValue = async (address: string, storageLayout: StorageLayout, getStorageAt: GetStorageAt, variableName: string): Promise<number | string | boolean | undefined> => {
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export const getStorageValue = async (storageLayout: StorageLayout, getStorageAt: GetStorageAt, blockHash: string, address: string, variableName: string): Promise<{ value: any, proof: { data: string } }> => {
|
||||
const { slot, offset, type, types } = getStorageInfo(storageLayout, variableName);
|
||||
const { encoding, numberOfBytes, label } = types[type];
|
||||
const { encoding, numberOfBytes, label: typeLabel } = types[type];
|
||||
let value: string, proof: { data: string };
|
||||
|
||||
// Get value according to encoding i.e. how the data is encoded in storage.
|
||||
// https://docs.soliditylang.org/en/v0.8.4/internals/layout_in_storage.html#json-output
|
||||
switch (encoding) {
|
||||
// https://docs.soliditylang.org/en/v0.8.4/internals/layout_in_storage.html#layout-of-state-variables-in-storage
|
||||
case 'inplace': {
|
||||
const valueArray = await getInplaceArray(address, slot, offset, numberOfBytes, getStorageAt);
|
||||
|
||||
// Parse value for boolean type.
|
||||
if (label === 'bool') {
|
||||
return !BigNumber.from(valueArray).isZero();
|
||||
}
|
||||
|
||||
// Parse value for uint/int type.
|
||||
if (label.match(/^enum|u?int[0-9]+/)) {
|
||||
return BigNumber.from(valueArray).toNumber();
|
||||
}
|
||||
|
||||
return utils.hexlify(valueArray);
|
||||
}
|
||||
case 'inplace':
|
||||
({ value, proof } = await getInplaceValue(blockHash, address, slot, offset, numberOfBytes, getStorageAt));
|
||||
break;
|
||||
|
||||
// https://docs.soliditylang.org/en/v0.8.4/internals/layout_in_storage.html#bytes-and-string
|
||||
case 'bytes': {
|
||||
const valueArray = await getBytesArray(address, slot, getStorageAt);
|
||||
|
||||
return utils.toUtf8String(valueArray);
|
||||
}
|
||||
case 'bytes':
|
||||
({ value, proof } = await getBytesValue(blockHash, address, slot, getStorageAt));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
throw new Error(`Encoding ${encoding} not implemented.`);
|
||||
}
|
||||
|
||||
return {
|
||||
value: getValueByType(value, typeLabel),
|
||||
proof
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to get array value for inplace encoding.
|
||||
* Get value according to type described by the label.
|
||||
* @param storageValue
|
||||
* @param typeLabel
|
||||
*/
|
||||
// getStorageByType
|
||||
export const getValueByType = (storageValue: string, typeLabel: string): number | string | boolean => {
|
||||
// Parse value for boolean type.
|
||||
if (typeLabel === 'bool') {
|
||||
return !BigNumber.from(storageValue).isZero();
|
||||
}
|
||||
|
||||
// Parse value for uint/int type or enum type.
|
||||
if (typeLabel.match(/^enum|u?int[0-9]+/)) {
|
||||
return BigNumber.from(storageValue).toNumber();
|
||||
}
|
||||
|
||||
// Parse value for string type.
|
||||
if (typeLabel.includes('string')) {
|
||||
return utils.toUtf8String(storageValue);
|
||||
}
|
||||
|
||||
return storageValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to get value for inplace encoding.
|
||||
* @param address
|
||||
* @param slot
|
||||
* @param offset
|
||||
* @param numberOfBytes
|
||||
* @param getStorageAt
|
||||
*/
|
||||
const getInplaceArray = async (address: string, slot: string, offset: number, numberOfBytes: string, getStorageAt: GetStorageAt) => {
|
||||
const value = await getStorageAt(address, slot);
|
||||
const uintArray = utils.arrayify(value);
|
||||
const getInplaceValue = async (blockHash: string, address: string, slot: string, offset: number, numberOfBytes: string, getStorageAt: GetStorageAt) => {
|
||||
const { value, proof } = await getStorageAt({ blockHash, contract: address, slot });
|
||||
const valueLength = utils.hexDataLength(value);
|
||||
|
||||
// Get value according to offset.
|
||||
const start = uintArray.length - (offset + Number(numberOfBytes));
|
||||
const end = uintArray.length - offset;
|
||||
const offsetArray = uintArray.slice(start, end);
|
||||
const start = valueLength - (offset + Number(numberOfBytes));
|
||||
const end = valueLength - offset;
|
||||
|
||||
return offsetArray;
|
||||
return {
|
||||
value: utils.hexDataSlice(value, start, end),
|
||||
proof
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to get array value for bytes encoding.
|
||||
* Function to get value for bytes encoding.
|
||||
* @param address
|
||||
* @param slot
|
||||
* @param getStorageAt
|
||||
*/
|
||||
const getBytesArray = async (address: string, slot: string, getStorageAt: GetStorageAt) => {
|
||||
const value = await getStorageAt(address, slot);
|
||||
const uintArray = utils.arrayify(value);
|
||||
const getBytesValue = async (blockHash: string, address: string, slot: string, getStorageAt: GetStorageAt) => {
|
||||
const { value, proof } = await getStorageAt({ blockHash, contract: address, slot });
|
||||
let length = 0;
|
||||
|
||||
// Get length of bytes stored.
|
||||
if (BigNumber.from(uintArray[0]).isZero()) {
|
||||
if (BigNumber.from(utils.hexDataSlice(value, 0, 1)).isZero()) {
|
||||
// If first byte is not set, get length directly from the zero padded byte array.
|
||||
const slotValue = BigNumber.from(value);
|
||||
length = slotValue.sub(1).div(2).toNumber();
|
||||
} else {
|
||||
// If first byte is set the length is lesser than 32 bytes.
|
||||
// Length of the value can be computed from the last byte.
|
||||
length = BigNumber.from(uintArray[uintArray.length - 1]).div(2).toNumber();
|
||||
const lastByteHex = utils.hexDataSlice(value, 31, 32);
|
||||
length = BigNumber.from(lastByteHex).div(2).toNumber();
|
||||
}
|
||||
|
||||
// Get value from the byte array directly if length is less than 32.
|
||||
if (length < 32) {
|
||||
return uintArray.slice(0, length);
|
||||
return {
|
||||
value: utils.hexDataSlice(value, 0, length),
|
||||
proof
|
||||
};
|
||||
}
|
||||
|
||||
// Array to hold multiple bytes32 data.
|
||||
const values = [];
|
||||
const proofs = [
|
||||
JSON.parse(proof.data)
|
||||
];
|
||||
|
||||
// Compute zero padded hexstring to calculate hashed position of storage.
|
||||
// https://github.com/ethers-io/ethers.js/issues/1079#issuecomment-703056242
|
||||
@ -145,10 +172,21 @@ const getBytesArray = async (address: string, slot: string, getStorageAt: GetSto
|
||||
|
||||
// Get value from consecutive storage slots for longer data.
|
||||
for (let i = 0; i < length / 32; i++) {
|
||||
const value = await getStorageAt(address, BigNumber.from(position).add(i).toHexString());
|
||||
const { value, proof } = await getStorageAt({
|
||||
blockHash,
|
||||
contract: address,
|
||||
slot: BigNumber.from(position).add(i).toHexString()
|
||||
});
|
||||
|
||||
values.push(value);
|
||||
proofs.push(JSON.parse(proof.data));
|
||||
}
|
||||
|
||||
// Slice trailing bytes according to length of value.
|
||||
return utils.concat(values).slice(0, length);
|
||||
return {
|
||||
value: utils.hexDataSlice(utils.hexConcat(values), 0, length),
|
||||
proof: {
|
||||
data: JSON.stringify(proofs)
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -51,8 +51,18 @@ export const getStorageLayout = async (contractName: string): Promise<StorageLay
|
||||
* @param address
|
||||
* @param position
|
||||
*/
|
||||
export const getStorageAt: GetStorageAt = async (address, position) => {
|
||||
const value = await ethers.provider.getStorageAt(address, position);
|
||||
export const getStorageAt: GetStorageAt = async ({ blockHash, contract, slot }) => {
|
||||
// TODO: Fix use of blockHash as hex string in getStorageAt.
|
||||
// Using blockHash in getStorageAt throws error.
|
||||
// https://github.com/ethers-io/ethers.js/pull/1550#issuecomment-841746994
|
||||
// Using latest tag for temporary fix.
|
||||
blockHash = 'latest';
|
||||
const value = await ethers.provider.getStorageAt(contract, slot, blockHash);
|
||||
|
||||
return value;
|
||||
return {
|
||||
value,
|
||||
proof: {
|
||||
data: JSON.stringify(null)
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ import debug from 'debug';
|
||||
import { Connection } from "typeorm";
|
||||
import { invert } from "lodash";
|
||||
import { EthClient, getMappingSlot, topictoAddress } from "@vulcanize/ipld-eth-client";
|
||||
import { getStorageInfo, getEventNameTopics } from '@vulcanize/solidity-mapper';
|
||||
import { getStorageInfo, getEventNameTopics, getStorageValue } from '@vulcanize/solidity-mapper';
|
||||
|
||||
import { storageLayout, abi } from './artifacts/ERC20.json';
|
||||
|
||||
@ -70,32 +70,28 @@ export class Indexer {
|
||||
}
|
||||
|
||||
async name(blockHash, token) {
|
||||
const { slot } = getStorageInfo(storageLayout, '_name');
|
||||
|
||||
const vars = {
|
||||
const result = await getStorageValue(
|
||||
storageLayout,
|
||||
this._ethClient.getStorageAt.bind(this._ethClient),
|
||||
blockHash,
|
||||
contract: token,
|
||||
slot
|
||||
};
|
||||
token,
|
||||
'_name'
|
||||
)
|
||||
|
||||
// TODO: Integrate with storage-mapper to get string value (currently hex encoded).
|
||||
const result = await this._ethClient.getStorageAt(vars);
|
||||
log(JSON.stringify(result, null, 2));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async symbol(blockHash, token) {
|
||||
const { slot } = getStorageInfo(storageLayout, '_symbol');
|
||||
|
||||
const vars = {
|
||||
const result = await getStorageValue(
|
||||
storageLayout,
|
||||
this._ethClient.getStorageAt.bind(this._ethClient),
|
||||
blockHash,
|
||||
contract: token,
|
||||
slot
|
||||
};
|
||||
token,
|
||||
'_symbol'
|
||||
)
|
||||
|
||||
// TODO: Integrate with storage-mapper to get string value (currently hex encoded).
|
||||
const result = await this._ethClient.getStorageAt(vars);
|
||||
log(JSON.stringify(result, null, 2));
|
||||
|
||||
return result;
|
||||
@ -163,4 +159,4 @@ export class Indexer {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user