second-state/smart-contract-search-engine

Facilitate multiple ABI hashes per contract instance

tpmccallum opened this issue · 5 comments

There will be cases where a contract instance is compatible with more than one ABI i.e. a larger contract could have an ABI but a smaller part of the contract could fully implement another ABI (ERC20) implementation.

We can re-write the harvester to store not just the hash of the single ABI (which is discovers during the first pass/index), but instead test all of the ABI code and store a list of hashes; a list of abiSha3 hashes to which the contract instance is compatible with.

There will only every be a single bytecodeSha3 so we can still produce a unique contract instance version by adding all of the abiSha3s plus the bytecodeSha3.

The added flexibility of this new feature will be that end users/API calls can query the search engine and find contracts which are compatible with certain ABI implementations. For example, "show me all of the contract instances which are ERC20 compliant".

We can now do this well. As you can see the following BAT token has its own unique ABI as well as the ERC20 ABI.

            {
                "_index": "ercchecker",
                "_type": "_doc",
                "_id": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF",
                "_score": 1,
                "_source": {
                    "TxHash": "0x3bf792736cea9760b7cb604dc5b6527f5b9ddd3d3f7db046fa4103ac489d7626",
                    "abiShaList": [
                        "0xf184e89595256b4eff3b1f0a66570fb6944e04eab99156d3f7bfe5b7c082c628",
                        "0x2b5710e2cf7eb7c9bd50bfac8e89070bdfed6eb58f0c26915f034595e5443286"
                    ],
                    "blockNumber": 3788558,
                    "contractAddress": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF",
                    "functionDataList": [
                        {
                            "0xf184e89595256b4eff3b1f0a66570fb6944e04eab99156d3f7bfe5b7c082c6280x0D8775F648430679A709E98d2b0Cb6250d2887EF": {
                                "functionData": {
                                    "tokenExchangeRate": 6400,
                                    "symbol": "BAT",
                                    "ethFundDeposit": "0xAc2fa512DB158F44F5EE2FA5766ea7c282763cdB",
                                    "fundingStartBlock": 3798640,
                                    "batFundDeposit": "0x88E2eFac3D2ef957FcD82Ec201a506871AD06204",
                                    "totalSupply": "1500000000000000000000000000",
                                    "version": "1.0",
                                    "isFinalized": true,
                                    "batFund": "500000000000000000000000000",
                                    "decimals": 18,
                                    "name": "Basic Attention Token",
                                    "fundingEndBlock": 3963480,
                                    "tokenCreationCap": "1500000000000000000000000000",
                                    "tokenCreationMin": "675000000000000000000000000"
                                },
                                "functionDataId": "0xc302313119f8116adcdf297f592f7709c47a0684608ade8539cdc3e5fbb4ce4b"
                            }
                        },
                        {
                            "0x2b5710e2cf7eb7c9bd50bfac8e89070bdfed6eb58f0c26915f034595e54432860x0D8775F648430679A709E98d2b0Cb6250d2887EF": {
                                "functionData": {
                                    "symbol": "BAT",
                                    "totalSupply": "1500000000000000000000000000",
                                    "decimals": 18,
                                    "name": "Basic Attention Token"
                                },
                                "functionDataId": "0x6c24be91e368e01eebfae7c3531ee54068f59e838d153a3981332466ef787457"
                            }
                        }
                    ],
                    "requiresUpdating": "yes",
                    "quality": "50",
                    "indexInProgress": "false",
                    "bytecodeSha3": "0x34ff57ae117b69ae1454a9d8f4fbb0602dd8959bacf69d575a6f74103125a06a"
                }
            }

The different ABIs are listed in the abiShaList data field.

The different sets of data associated with each of the individual ABIs are listed in the functionDataList data field.

The unique key for each set of data consists of:

a) the ABI hash (i.e. the common ERC20 hash etc) 0xf184e89595256b4eff3b1f0a66570fb6944e04eab99156d3f7bfe5b7c082c628

b) the address of this contract instance
0x0D8775F648430679A709E98d2b0Cb6250d2887EF

Altogether the key looks like this ...
0xf184e89595256b4eff3b1f0a66570fb6944e04eab99156d3f7bfe5b7c082c6280x0D8775F648430679A709E98d2b0Cb6250d2887EF

Remember, when writing frontend code we are primarily just querying the abiShaList to pinpoint certain contract ABI combinations (to derive the DApp version)

"abiShaList": [
                        "0xf184e89595256b4eff3b1f0a66570fb6944e04eab99156d3f7bfe5b7c082c628",
                        "0x2b5710e2cf7eb7c9bd50bfac8e89070bdfed6eb58f0c26915f034595e5443286"
                    ]

The functionDataList section is just a way to logically separate the data from each of the individual associated ABIs.

Obviously there will be overlap when one ABI is a subset of another ABI. This should not bother the frontend now because we have new code that will only return a distinct set of data.