ApeWorX / ape

The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals
https://apeworx.io
Apache License 2.0
899 stars 135 forks source link

Querying: allow block-series `.query` method on any `ContractCall` object #380

Open fubuloubu opened 2 years ago

fubuloubu commented 2 years ago

Elevator pitch:

Be able to form datasets from querying a view method in a contract over a specified range of blocks.

For example:

# Plot DAI's total supply over specified range of blocks
total_supply = dai.totalSupply.query(start_block=N, end_block=M)
plt.plot(range(N, M), total_supply // 10 ** dai.decimals())

# Plot DAI's % ownership of DAI in Uni v2 DAI/WETH pool over specified range of blocks
plt.plot(
    range(N, M),
    dai.balanceOf.query(uniswap_v2_dai_weth, start_block=N, end_block=M) // total_supply,
)
plt.show()

Value:

This is valuable for data scientists who quickly want to perform an efficient query over a range of blocks to obtain a timeseries dataset.

Dependencies:

In order to be efficient, significant caching is necessary, coupled with an archive node for historical retrieval. Explore making these types of queries as efficient as possible.

Design approach:

class ContractCall:
    def query(self, *args, **kwargs):
        # Encode the call w/ *args
        ...
        # Perform query using ProviderAPI over `kwargs` query args
        ...

class ContractCallContainer:
    def query(self, *args, **kwargs):
        # Figure out which `ContractCall` to route to
        ...
        return contract_caller(*args, **kwargs)

Task list:

Estimated completion date:

Design review:

Do not signoff unless:

(Please leave a comment to sign off)

fubuloubu commented 2 years ago

NOTE: Blocks are a natural way to conduct this type of query, because they are explicit. Timestamps sometimes are tricky to work with in this context (but should be explored regardless)

fubuloubu commented 2 years ago

Related: #390