Skip to content
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

The ethr-did-resolver is unable to resolve a DID created using EthrDID. Receiving a call revert exception #107

Open
sramanan0425 opened this issue Feb 13, 2023 · 6 comments
Labels
bug Something isn't working

Comments

@sramanan0425
Copy link

sramanan0425 commented Feb 13, 2023

Current Behavior

I am using Ganache to run a local ethereum blockchain network. I am trying to create a DID using EthrDID from the ethr-did package (v2.3.6). I am trying to use the ethr-did-resolver providing the network configuration for Ganache network.
I expect to resolve to a DID document as per documentation in this project's README. The DID generated is like did:ethr:0x539:0xc753...

Expected Behavior

I do see a eth_call in the Ganache logs when the resolve is being called which. But if fails to resolve and get a call revert exception with code=CALL_EXCEPTION. I have already referred to https://docs.ethers.org/v5/troubleshooting/errors/ with not much details.

Failure Information

The error is:
call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="changed(address)", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.7.0)

Steps to Reproduce

Here is a code snippet used to create a DID and trying to resolve using ethr-did-resolver

const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const sign = didJWT.ES256KSigner(didJWT.hexToBytes(privateKey))
const ethrDid = new EthrDID({provider: provider, identifier: registry, chainNameOrId: chainNameOrId})
const privateNetworkConfig = [ {
  name: "0x539",
  rpcUrl: rpcUrl,
  chainId: 1337,
  registry: registry,
  address: issuerAddress
}]
const ethrDidResolver = getResolver({networks: privateNetworkConfig})
const didResolver = new Resolver(ethrDidResolver)
const resolved = await didResolver.resolve(ethrDid.did)

I expect the resolve to resolve to a DID document. The DID generated is like did:ethr:0x539:0xc753...

Environment Details

I installed Ganache to run a local blockchain network and my provider config uses the RPC URL as shown on the Ganache network. My chainId is 1337.

@sramanan0425 sramanan0425 added the bug Something isn't working label Feb 13, 2023
@mirceanis
Copy link
Contributor

The DIDs you are creating seem to have the right format.
For did:ethr, creating a DID doesn't require an interaction with the blockchain, so you will only spot an error in configuration if you try to resolve a DID or modify the DID document.

The first thing that comes to mind is that maybe the registry wasn't deployed, or you are pointing to a different address.

There are some things I'd change about your configuration:

  • in your EthrDID constructor call you are specifying the registry address as the identifier. The identifier should be the DID you are trying to use or control, if any, not the registry.
  • in your privateNetworkConfig you are also specifying an address property. That is irrelvant for the resolver config and will only cause confusion.

I am assuming that the registry variable in your code refers to the ethr-did-registry contract address deployed on your Ganache blockchain. If that's not the case, it should be.

I hope this helps.

@sramanan0425
Copy link
Author

The registry variable in actually the address of the DID that I am trying to control. This is a valid address on my Ganache blockchain. I am new to this did & blockchain stuff and so maybe I am missing some step. To resolve a DID, does it need a smart contract to be actually deployed? How do I find out the registry address?

@mirceanis
Copy link
Contributor

The registry variable in actually the address of the DID that I am trying to control. This is a valid address on my Ganache blockchain. I am new to this did & blockchain stuff and so maybe I am missing some step. To resolve a DID, does it need a smart contract to be actually deployed? How do I find out the registry address?

I see. In the case of did:ethr, it does require the registry contract to be deployed.
For ethereum mainnet, some testnets and some layer2 ethereum networks the registry address is published in the readme of the ethr-did-registry contract repository.

Ganache creates a local blockchain, that only lives on your machine and is meant to be used only for testing.
When deployed to ganache, you can get the address of the contract from the script that deploys it.
It's also possible to deploy to a deterministic address, just like the original contracts were deployed, by running the generateDeployTx script but it's probably not worth the hassle of doing that.

The reason that the contract needs to be deployed first is because of how did:ethr works.
When you create a did:ethr, that is a local operation. It's equivalent to creating a key pair.
To update the corresponding DID document (add or remove a key or service, or change owners), the owner of the DID needs to send some transactions to the registry. The event logs generated by these transactions will determine how the DID document is constructed.

When you resolve a did:ethr, the resolver has no way of knowing in advance if the DID document for that DID has been updated or not; it needs to ask somewhere. The place where it checks to see if a DID has any updates is the registry contract.

@sramanan0425
Copy link
Author

sramanan0425 commented Feb 15, 2023

Thanks, the above helped me advance a bit though the resolve on this DID continues to fail. I created a smart contract and deployed to my local ganache blockchain. I used the contract address as shown in the migration script output. I also sent some transactions from the identifier account to this registry which went through successfully. My code is like below. The registry variable holds my deployed smart contract address. The issuerAddress is the identifier whose DID I want to control. It continues to fail with same error below. I do see the eth_call method in Ganache's logs.

call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="changed(address)", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.7.0)

   ```
   const issuerAddress = "0x31f....."
    const chainNameOrId = 1337
    const rpcUrl ="http://127.0.0.1:7545"
    const registry = '0xA952....';
    const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
   const ethrDid = new EthrDID({provider: provider, registry: registry, identifier: issuerAddress, chainNameOrId: chainNameOrId})
    

    const privateNetworkConfig = [ {
        name: "0x539",
        rpcUrl: rpcUrl,
        registry: registry,
        chainNameOrId: 1337

    }]
    const ethrDidResolver = getResolver({networks: privateNetworkConfig})
    const didResolver = new Resolver(ethrDidResolver)
    const resolved = await didResolver.resolve(ethrDid.did)

But when I try the eth_call method using the same registry & issuerAddress as the "to" & "from" in the provider's send method like below, it works fine without any revert. I am unable to see the underlying POST that is done by the did-resolver to compare what I could be missing in the provider config. 

       ```
const networkUrl = "http://127.0.0.1:7545"
        const ethersProvider = new ethers.providers.JsonRpcProvider(networkUrl);
        const registry = '0x99F705.....'
        const issuerAddress = "0x31f13......"
        const callParams = [
            {
                to: registry,
                from: issuerAddress,
                data: "0xf96d0f9f0000......" 
            },
            "latest"
        ];
        const call = await ethersProvider.send("eth_call", callParams);

@mirceanis
Copy link
Contributor

This is puzzling. From your description, you are doing everything right.
That is also the way it is implemented in the test suite. The only difference is that it's creating the ganache instance programmatically instead of calling it through an RPC URL.

Do you happen to have a project that is manifesting this behavior so that I can try to debug?

@francesco-plt
Copy link

Thanks, the above helped me advance a bit though the resolve on this DID continues to fail. I created a smart contract and deployed to my local ganache blockchain. I used the contract address as shown in the migration script output. I also sent some transactions from the identifier account to this registry which went through successfully. My code is like below. The registry variable holds my deployed smart contract address. The issuerAddress is the identifier whose DID I want to control. It continues to fail with same error below. I do see the eth_call method in Ganache's logs.

call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="changed(address)", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.7.0)

const issuerAddress = "0x31f....."
const chainNameOrId = 1337
const rpcUrl ="http://127.0.0.1:7545"
const registry = '0xA952....';
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const ethrDid = new EthrDID({provider: provider, registry: registry, identifier: issuerAddress, chainNameOrId: chainNameOrId})

const privateNetworkConfig = [ {
    name: "0x539",
    rpcUrl: rpcUrl,
    registry: registry,
    chainNameOrId: 1337

}]
const ethrDidResolver = getResolver({networks: privateNetworkConfig})
const didResolver = new Resolver(ethrDidResolver)
const resolved = await didResolver.resolve(ethrDid.did)

But when I try the eth_call method using the same registry & issuerAddress as the "to" & "from" in the provider's send method like below, it works fine without any revert. I am unable to see the underlying POST that is done by the did-resolver to compare what I could be missing in the provider config.

   ```

const networkUrl = "http://127.0.0.1:7545"
const ethersProvider = new ethers.providers.JsonRpcProvider(networkUrl);
const registry = '0x99F705.....'
const issuerAddress = "0x31f13......"
const callParams = [
{
to: registry,
from: issuerAddress,
data: "0xf96d0f9f0000......"
},
"latest"
];
const call = await ethersProvider.send("eth_call", callParams);

I was in a really similar situation and I fixed the problem by deploying the contract as follows:

$ npx hardhat run scripts/deploy.ts --network localhost

After starting the network, as described here: NomicFoundation/hardhat#1566

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants