Professional Documents
Culture Documents
Web3.py Patterns_ Off-chain Lookups
Web3.py Patterns_ Off-chain Lookups
Web3.py Patterns_ Off-chain Lookups
Web3.py
Use case
In order to extend its functionality into additional scaling layers and blockchains,
ENS enables its resolvers to return addresses stored somewhere other than
Mainnet Ethereum via ENSIP-10 (Wildcard Resolution) and EIP-3668 (CCIP
Reads). With these two protocol upgrades, foo.whatever.eth can resolve an
Ethereum (or any other) address, without the foo subdomain having been
deployed to Ethereum Mainnet. An example implementation of this functionality
can be found here.
How it works
EIP-3668 defines a custom exception, OffchainLookup , whose payload is used
to communicate where off-chain data can be retrieved. The Solidity syntax for the
custom error is as follows:
Note that this feature is intentionally flexible. The security model for verifying the
legitimacy of the off-chain data is up to the client and gateway to agree on and
will vary based on use case. Nick Johnson, author of EIP-3668, describes the
usage pattern of an ENS resolver verifying an address via an L2 Optimism
gateway in this PEEP an EIP episode.
Web3.py example
A library like Web3.py can enable off-chain lookups without a user needing to
understand how the feature works or that it even occurred. Let's run through a
quick example.
The ENS team deployed their off-chain lookup proof of concept utilizing the
domain offchainexample.eth . Using Web3.py's ens module, let's try to fetch
the address of test.offchainexample.eth :
# connect to mainnet
>>> w3 = Web3(HTTPProvider('https://provider-link-here...'))
>>> w3.ens.address('test.offchainexample.eth')
'0x41563129cDbbD0c5D3e1c86cf9563926b243834d'
https://snakecharmers.ethereum.org/web3-py-patterns-off-chain-lookups/ 1/3
5/30/24, 8:06 PM Web3.py Patterns: Off-chain Lookups
>>> w3.ens.address('web3py.offchainexample.eth')
'0x41563129cDbbD0c5D3e1c86cf9563926b243834d'
The web3py subdomain isn't registered, but the same address is returned. And
just like that, you've used Web3.py to resolve an off-chain address.
Let's peek under the hood and verify that an off-chain lookup was actually
performed. We'll disable CCIP Read functionality, rerun the query, and examine
the resolver contract response. CCIP Read may be turned off globally via a flag on
the provider: global_ccip_read_enabled . We'll then capture the
OffchainLookup error and review the payload.
urls : A list of URLs where the off-chain data can be found. Multiple
URLs allow for better reliability as fallback requests for the same
information. This list should be sorted by the contract in order of URL
importance.
sender : The contract address. This value is used to replace any string
matching {sender} in the urls field provided by the revert.
For Web3.py's part, when CCIP Read functionality is enabled, the library will
catch any OffchainLookup exceptions and perform a fetch using the URL(s)
provided, populating the {data} and {sender} fields as appropriate, then
initiate the follow-up callbackFunction in the same contract.
Again, the callback function in the contract is responsible for verifying that the
off-chain data is valid before it returns the resolved address. In the ENS example,
the resolveWithProof function verifies a valid signed message before returning
an address.
Wrapping Up
https://snakecharmers.ethereum.org/web3-py-patterns-off-chain-lookups/ 2/3
5/30/24, 8:06 PM Web3.py Patterns: Off-chain Lookups
Through cheeky use of a custom error, EIP-3668 introduces a new primitive that
makes cross-chain interaction measurably easier. Building something with off-
chain data lookups? Tell us about your use case in the Ethereum Python Discord!
Powered by Ghost
https://snakecharmers.ethereum.org/web3-py-patterns-off-chain-lookups/ 3/3