-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CCIP Read implementation #41
base: master
Are you sure you want to change the base?
Conversation
This is now fully working:
feedback on the implementation is more than welcome |
lgtm! works fine with real examples. only small problem is that the following test fails, probably because of some custom error change;
|
thanks for reviewing it, mate. this test is failing on the main branch as well, I'll fix it with a similar scenario. |
the |
any updated on this? |
I think in that case this should be handled in the original go-ens repo. It's surely unrelated with the current PR. All good for me. |
@pikonha Thanks for putting this together, was looking for an implementation just like this to help with x-chain reads for a project of mine. Anything I can do to help get it merged? |
@dneilroth it's pretty much done from my end tbh, just waiting for the review and approval. |
@mcdee is it possible to get this one merged? cc @mdtanrikulu |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Various comments on the PR.
Note that I have not yet looked closely at the changes in resolver.go
, I will attempt them at a later date.
universal_resolver.go
Outdated
|
||
// NewUniversalResolver obtains the ENS UniversalResolver. | ||
func NewUniversalResolver(backend bind.ContractBackend) (*UniversalResolver, error) { | ||
address, err := UniversalResolverContractAddress(backend, "mainnet") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fail for non-mainnet instances. The backend should be queried for the chain ID and a suitable address returned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it is possible to fetch the chainID from the ethClient
injected into the Resolver
, however, I haven't found a way to fetch it from the bind.ContractBackend
interface. any idea on how to solve this without changing the Resolver signature?
resolver.go
Outdated
@@ -214,21 +240,11 @@ func resolveName(backend bind.ContractBackend, input string) (common.Address, er | |||
} | |||
|
|||
func resolveHash(backend bind.ContractBackend, domain string) (common.Address, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the purpose of the changes here. Please don't use shortened names, it doesn't add anything (especially in a world where we have registry, registrar and resolver; r is not a useful letter). I also don't understand why the returned error has been changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renaming all the aliased variables to a more meaningful version.
the resolver.go
had to be changed to support offchain domains the same way it does for the on-chain ones. the main goal is to maintain the syntax for both types of domain:
r, _ := NewResolver(client, "onchain.eth")
actual, err := r.Text("com.twitter")
r, _ := NewResolver(client, "offchain.eth")
actual, err := r.Text("com.twitter")
the implementation was inspired by the Viem's implementation of the CCIP-Read which relies on the Universal Resolver instead of directly on the Resolver itself.
return nil, err | ||
} | ||
|
||
sender := errArgs[0].(common.Address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of casting and array access here without checks, please add checks to avoid potential panics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the returned error to have the OffchainLookup
signature (0x556f1830
), it must have the following arguments:
- sender
- urls
- calldata
- callback
- extraData
so I assume those variables will be on the errArgs
variable and so they can be accessed directly by the index. otherwise, it would have failed on the (len(errData) >= 10 && errData[:10] == offchainLookupSignature)
condition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is easy for an error to be returned with the same four bytes but representing a different function (see 4byte.info for an example of clashes), and if done maliciously then it would cause a panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the selector conflict and I did some testing to ensure it would break before an unexpected panic. in every scenario I've tested these conditions would return an error in case of an unexpected error since it wouldn't be present on the Universal Resolver's ABI
var sig [4]byte
copy(sig[:], hexBytes[:4])
abiErr, err := uAbi.ErrorByID(sig)
if err != nil {
return nil, err
}
var errorData []byte
copy(errorData[:], hexBytes[4:])
errArgs, err := abiErr.Inputs.Unpack(errorData)
if err != nil {
return nil, err
}
I'll go through the comments ASAP, thanks for reviewing it, mate. |
Hey there, may I ask what is the current status of this PR? I see that most of the issues have been addressed, but is there anything else that needs to be done to finalize it? cc @mcdee @dneilroth |
CCIP Read implementation
Description
This pull request adds the CCIP-Read support to the Go-ENS library. This function enables users to read data from offchain data sources that follow the EIP-3668 standard.
These additions enhance the versatility and utility of the Go-ENS library by enabling seamless interaction with contracts and providing efficient domain resolution capabilities. The implementation aligns with the library's objective of comprehensive support for Ethereum Name Service (ENS) operations.
How it works
jesse.cd.id
(externally handled by Coinbase's Offchain Resolver)addr(namehash)
orresolve(labelhash, encodedArgs)
function on the contract which reverts withOffchainLookup
as described on the EIP-3668sender
andcalldata
as arguments following the Gateway InterfacecallbackFunction
is then called with the API's response and theextraData
to validate the authenticity of the dataRelated Issue
Issue #38
PR #40
Changes
Changes to Core Features:
Additional Notes
I'm working on the CCIP Read implementation for the other features such as reading text, multicoin addresses, and
contenthash
.The Subdomain resolution PR was used as a starting point for this implementation, which enables this PR to handle both, CCIP-Read and subdomain resolution. They have been decoupled to make the review process easier.
Cheers from the Blockful team 👋🏼