Implement method for storage based access in subgraph mapping code (#162)

* Implement storage call in subgraph mapping code

* Add test for mapping type variable storage call

* Use vulcanize graph-ts

* Revert to graph-ts version 0.22.1
This commit is contained in:
2022-08-17 16:25:49 +05:30
committed by GitHub
parent 80682e2755
commit ec56de057f
21 changed files with 503 additions and 17 deletions
+1
View File
@@ -0,0 +1 @@
!artifacts
@@ -0,0 +1,183 @@
{
"abi": [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "param1",
"type": "string"
},
{
"indexed": false,
"internalType": "uint8",
"name": "param2",
"type": "uint8"
},
{
"indexed": false,
"internalType": "uint256",
"name": "param3",
"type": "uint256"
}
],
"name": "Test",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint128",
"name": "bidAmount1",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "bidAmount2",
"type": "uint128"
}
],
"name": "addMethod",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "addressUintMap",
"outputs": [
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "emitEvent",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getMethod",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint128",
"name": "bidAmount1",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "bidAmount2",
"type": "uint128"
}
],
"name": "structMethod",
"outputs": [
{
"components": [
{
"internalType": "uint128",
"name": "bidAmount1",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "bidAmount2",
"type": "uint128"
}
],
"internalType": "struct Example.Bid",
"name": "",
"type": "tuple"
}
],
"stateMutability": "pure",
"type": "function"
}
],
"storageLayout": {
"storage": [
{
"astId": 3,
"contract": "Example.sol:Example",
"label": "_test",
"offset": 0,
"slot": "0",
"type": "t_uint256"
},
{
"astId": 7,
"contract": "Example.sol:Example",
"label": "addressUintMap",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_address,t_uint128)"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_uint128)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => uint128)",
"numberOfBytes": "32",
"value": "t_uint128"
},
"t_uint128": {
"encoding": "inplace",
"label": "uint128",
"numberOfBytes": "16"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
@@ -5,6 +5,8 @@ pragma solidity ^0.8.0;
contract Example {
uint256 private _test;
mapping (address => uint128) public addressUintMap;
struct Bid {
uint128 bidAmount1;
uint128 bidAmount2;
@@ -12,6 +14,11 @@ contract Example {
event Test(string param1, uint8 param2, uint256 param3);
constructor() {
_test = 1;
addressUintMap[address(0)] = 123;
}
function getMethod() public view virtual returns (string memory)
{
return 'test';
@@ -0,0 +1 @@
@graphprotocol:registry=https://npm.pkg.github.com
@@ -10,7 +10,7 @@
"deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 example1"
},
"dependencies": {
"@graphprotocol/graph-ts": "^0.22.1",
"@graphprotocol/graph-ts": "npm:@vulcanize/graph-ts@0.22.1",
"@vulcanize/graph-cli": "0.22.5"
}
}
@@ -159,6 +159,27 @@ export function testStructEthCall (): void {
}
}
export function testGetStorageValue (): void {
log.debug('In test get storage value', []);
// Bind the contract to the address.
const contractAddress = dataSource.address();
const contract = Example1.bind(contractAddress);
const res = contract.getStorageValue('_test', []);
log.debug('Storage call result: {}', [res!.toBigInt().toString()]);
}
export function testMapStorageValue (): void {
log.debug('In test map storage value', []);
// Bind the contract to the address.
const contractAddress = dataSource.address();
const contract = Example1.bind(contractAddress);
const addressValue = ethereum.Value.fromAddress(Address.zero());
const res = contract.getStorageValue('addressUintMap', [addressValue]);
log.debug('Storage call result: {}', [res!.toBigInt().toString()]);
}
export function testBytesToHex (): string {
log.debug('In test bytesToHex', []);
@@ -23,10 +23,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@graphprotocol/graph-ts@^0.22.1":
"@graphprotocol/graph-ts@npm:@vulcanize/graph-ts@0.22.1":
version "0.22.1"
resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.22.1.tgz#3189b2495b33497280f617316cce68074d48e236"
integrity sha512-T5xrHN0tHJwd7ZnSTLhk5hAL3rCIp6rJ40kBCrETnv1mfK9hVyoojJK6VtBQXTbLsYtKe4SYjjD0cdOsAR9QiA==
resolved "https://npm.pkg.github.com/download/@vulcanize/graph-ts/0.22.1/7a14baaab8b99d4a88e19620dc7200aa501fbecf#7a14baaab8b99d4a88e19620dc7200aa501fbecf"
integrity sha512-0CoKeFezskYjAsLmqfdxmS7q+gWy1V1wFgiNB4tMJSa2EiPTVG62qlPKkqTduApK2gZX9//rmE5Vb2xcF/v2+w==
dependencies:
assemblyscript "0.19.10"
+10 -2
View File
@@ -4,12 +4,15 @@
import { BaseProvider } from '@ethersproject/providers';
import { getCustomProvider } from '@vulcanize/util';
import { EthClient } from '@vulcanize/ipld-eth-client';
import { StorageLayout } from '@vulcanize/solidity-mapper';
import { EventData } from '../../src/utils';
import { Database } from '../../src/database';
import { Indexer } from './indexer';
const NETWORK_URL = 'http://127.0.0.1:8081';
const IPLD_ETH_SERVER_GQL_URL = 'http://127.0.0.1:8082/graphql';
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const ZERO_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000';
@@ -71,8 +74,13 @@ export const getTestDatabase = (): Database => {
return new Database({ type: 'postgres' }, '');
};
export const getTestIndexer = (): Indexer => {
return new Indexer();
export const getTestIndexer = (storageLayout?: Map<string, StorageLayout>): Indexer => {
const ethClient = new EthClient({
gqlEndpoint: IPLD_ETH_SERVER_GQL_URL,
cache: undefined
});
return new Indexer(ethClient, storageLayout);
};
export const getTestProvider = (): BaseProvider => {
+30 -1
View File
@@ -6,14 +6,43 @@ import {
BlockProgressInterface,
EventInterface,
SyncStatusInterface,
ServerConfig as ServerConfigInterface
ServerConfig as ServerConfigInterface,
ValueResult
} from '@vulcanize/util';
import { EthClient } from '@vulcanize/ipld-eth-client';
import { GetStorageAt, getStorageValue, MappingKey, StorageLayout } from '@vulcanize/solidity-mapper';
export class Indexer implements IndexerInterface {
_getStorageAt: GetStorageAt;
_storageLayoutMap: Map<string, StorageLayout> = new Map()
constructor (ethClient: EthClient, storageLayoutMap?: Map<string, StorageLayout>) {
this._getStorageAt = ethClient.getStorageAt.bind(ethClient);
if (storageLayoutMap) {
this._storageLayoutMap = storageLayoutMap;
}
}
get serverConfig () {
return new ServerConfig();
}
get storageLayoutMap (): Map<string, StorageLayout> {
return this._storageLayoutMap;
}
async getStorageValue (storageLayout: StorageLayout, blockHash: string, contractAddress: string, variable: string, ...mappingKeys: MappingKey[]): Promise<ValueResult> {
return getStorageValue(
storageLayout,
this._getStorageAt,
blockHash,
contractAddress,
variable,
...mappingKeys
);
}
async getBlockProgress (blockHash: string): Promise<BlockProgressInterface | undefined> {
assert(blockHash);