Hey @ricmoo
I'm creating this issue cause I've seen lots of people confused about an ENS related error being thrown when a signer is used instead of an address. To make things worse, the signer gets JSON.stringifyd so the error is HUGE sometimes.
Have you consider treating this as a special case and throwing something like "hey, you should use an address instead of a signer"? Or maybe add a toJSON to the abstract signer to at least avoid those huge errors?
Would this cause an Invalid ENS error: name undefined? Because I'm having this error pop up and I can't see any reason why?
I'm getting this error too, any tips on the solution?
It will be helpful if you can provide some more information, i.e. what ethers version are you using, what network are you on, sample code to reproduce this.
I have seen this happen when passing in an invalid address and ethers treating it as an ENS name and trying to resolve the address from it.
Example problematic code:
const C = await ethers.getContractFactory("Contract");
const [owner, addr1, ...addrs] = await ethers.getSigners();
const c = await Contract.deploy(owner);
Yields confusing error:
Error: invalid ENS name (argument="name", value="<SignerWithAddress 0x10957970C51812dc3A010C7d01b70e0d17dc79A8>", code=INVALID_ARGUMENT, version=providers/5.0.22)
Fix:
const c = await Contract.deploy(owner.address);
I guess extra confusing for typescript users, as the types are happy with it, only breaks at runtime.
@ryan-snyder @aindigo is this what you're referring to?
I haven鈥檛 looked much into this, but there is no getContractFactory on ethers. I think that is something Hardhat adds? Are you using Hardhat? Could there be a problem there?
There is also no getSigners, maybe something else Hardhat added?
My guess is you want to call deploy(owner.getAddress()) instead?
I haven鈥檛 looked much into this, but there is no
getContractFactoryon ethers. I think that is something Hardhat adds? Are you using Hardhat? Could there be a problem there?
One of my deepest regrets 馃ゲ We need to come up with a better way of doing this. Originally that ethers object just contained some helpers, and some users asked for it to re-export the actual ethers because the name clash made importing it annoying.
This problem mostly happens when users pass a Signer or Contract instead of an address. I think something that would improve it is checking if the value is a string, and only throw ENS-related errors in that case.
This problem mostly happens when users pass a Signer or Contract instead of an address. I think something that would improve it is checking if the value is a string, and only throw ENS-related errors in that case.
This may also be extended by running some fuzzy "validation" of the string. Like, only consider it an ENS name if it has a dot.
If I get the reports correctly, just checking typeof $x === 'string' would solve it - the users are probably passing in some object from hardhat rather than the actual address.
For me, something that fixed the original error was just changing a function call token.balanceOf(user) to token.balanceOf(user.address). Not quite sure why this throws the Invalid ENS name error though but maybe this might help.
@Legogris if you use TypeChain you WILL get compile-time error when you forget to call .address.
That being said it's extremely confusing and I feel like ethers should treat signers as addresses representing these signers in this case. Would you accept a PR fixing this?
@alcuadrado proposed some ideas in the original post. I can also imagine a check something like "if parameter is an instanceOf Signer use signer.address instead.
This has already been added to my local v6. You should actually generally call .getAddress() instead of .address, since .address is not part of the Signer API (most signers do not have synchronous access to their address).
For v5, I can add a condition like that to the JavaScript side, but cannot change the signature to allow Signer and Contract since that would break any existing sub-classes.
This has already been added to my local v6
Great! Any ETA for the v6 release?
You should actually generally call .getAddress() instead of .address, since .address is not part of the Signer API (most signers do not have synchronous access to their address).
Yeah... I get that it's just getAddress() is async so it needs await and it makes code harder to read. But being able to just push a signer should fix that anyway way.
For v5, I can add a condition like that to the JavaScript side, but cannot change the signature to allow Signer and Contract since that would break any existing sub-classes.
I think adding it JS side should be good enough! I believe that we can still generate TS typings in TypeChain in the way that it accepts signers (for smartcontract calls).
Hi there, I'm having the same error but with somewhat different code, and I'd greatly appreciate some insight about this since I've been stuck with it for a few days.
My Signer-based contract instance has worked with signer.sendTransaction(tx), and with a simple state-changing function that simply updates a uint256 with a single input parameter.
My contract's createThing method uses AbiEncoderV2 to accept some structs. I have worked through some errors complaining about the format of the parameters, after which I got the "Invalid ENS name" issue, but I do wonder if this is a problem with how the method is called, or the complex parameters.
[Dev] Error creating Thing Error: invalid ENS name (argument="name", value=undefined, code=INVALID_ARGUMENT, version=providers/5.2.0)
...
resolveAddresses index.js:51
resolveAddresses index.js:54
resolveAddresses index.js:53
...
resolveAddresses index.js:51
populateTransaction index.js:111
Please let me know if you want more of the error's trace, it was quite repetitive
About the source below:
stringToPaddedBytes32 is just a utility I wrote that uses Buffer.from and utils.hexZeroPad to convert like it says.
getNetwork().endpoint is a URL, in the case of my development environment it is 127.0.0.1:8545 connecting to Ganache.
import { Contract, Signer, BigNumber, providers, utils } from 'ethers';
export default (props: any) => {
const provider = new providers.JsonRpcProvider(getNetwork().endpoint);
const signer = provider.getSigner();
const myContract = new Contract(
myContractAddress,
myContractAbi,
signer
);
async function create() {
await myContract.createThing(
[],
utils.solidityPack(["uint256", "uint256"],
[bigNumberA,bigNumberB]),
utils.solidityPack(["uint256","uint256"],
[bigNumberC,bigNumberD]),
utils.solidityPack(["bytes32","bytes32"],
[stringToPaddedBytes32(stringA),stringToPaddedBytes32(stringB)])
);
}
return (<div>...</div>)
}
function createThing(
address[] calldata someAddresses,
StructA calldata _a,
StructB calldata _b,
StructC calldata _c
)
Hey there, same problem as @slhodak if anyone found a solution please let me know
What parameters are you passing in? Can you console.log them?
Hey thanks for the quick reply ! That's totaly on me. I found out the problem 5 mins after posting (stupid bad venv ariable names hidden deep in my code...). Sorry for the inconvenience !
Most helpful comment
Example problematic code:
Yields confusing error:
Fix:
I guess extra confusing for typescript users, as the types are happy with it, only breaks at runtime.