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

Invalid ENS name error when a signer is used instead of an address #1051

Closed
alcuadrado opened this issue Sep 18, 2020 · 26 comments
Closed

Invalid ENS name error when a signer is used instead of an address #1051

alcuadrado opened this issue Sep 18, 2020 · 26 comments
Labels
enhancement New feature or improvement. fixed/complete This Bug is fixed or Enhancement is complete and published.

Comments

@alcuadrado
Copy link

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?

@ricmoo ricmoo added enhancement New feature or improvement. on-deck This Enhancement or Bug is currently being worked on. labels Nov 24, 2020
@ryan-snyder
Copy link

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?

@pavildon
Copy link

I'm getting this error too, any tips on the solution?

@yuetloo
Copy link
Collaborator

yuetloo commented Feb 10, 2021

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.

@Legogris
Copy link

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.

@Legogris
Copy link

Legogris commented Feb 12, 2021

@ryan-snyder @Aindigo is this what you're referring to?

@ricmoo
Copy link
Member

ricmoo commented Feb 12, 2021

I haven’t 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?

@ricmoo
Copy link
Member

ricmoo commented Feb 12, 2021

There is also no getSigners, maybe something else Hardhat added?

My guess is you want to call deploy(owner.getAddress()) instead?

@alcuadrado
Copy link
Author

alcuadrado commented Feb 18, 2021

I haven’t 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?

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.

@alcuadrado
Copy link
Author

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.

@Legogris
Copy link

Legogris commented Feb 18, 2021

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.

@AlbertSu123
Copy link

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.

@krzkaczor
Copy link

krzkaczor commented Mar 17, 2021

@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.

@ricmoo
Copy link
Member

ricmoo commented Mar 18, 2021

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.

@krzkaczor
Copy link

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).

@slhodak
Copy link

slhodak commented Jun 8, 2021

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.

Error

[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

My code, simplified a bit

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>)
}

Solidity function signature

function createThing(
    address[] calldata someAddresses,
    StructA calldata _a,
    StructB calldata _b,
    StructC calldata _c
)

@xenoliss
Copy link

Hey there, same problem as @slhodak if anyone found a solution please let me know

@ricmoo
Copy link
Member

ricmoo commented Jun 20, 2021

What parameters are you passing in? Can you console.log them?

@xenoliss
Copy link

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 !

@murrlincoln
Copy link

I'm still getting an error when I try to run this code. I'm new to frontend smart contract work, so this may be an obvious error, but I can't figure out what I'm doing wrong here:

var contract = new Contract(addresses.erc20, abis.erc20, provider.getSigner(0));

  var spender = addresses.smartContract;

  const signer = await provider.getSigner();
  const owner = await signer.getAddress();
  
  console.log("Account:", owner.toString());

  
  

  var allowance = await contract.allowance(owner, spender);

  console.log(allowance);

  return allowance;

I get the owner.toString() to come back as expected, but afterwards I get the 'invalid ENS name' error

@zemse
Copy link
Collaborator

zemse commented Aug 13, 2021

Can you console log the spender as well? Maybe that is not a valid address.

@delaaxe
Copy link

delaaxe commented Sep 14, 2021

Ran into this error as well. An error message like "Invalid address" would make it much less confusing than "Invalid ENS name"

ricmoo added a commit that referenced this issue Oct 16, 2021
@ricmoo ricmoo added fixed/complete This Bug is fixed or Enhancement is complete and published. and removed on-deck This Enhancement or Bug is currently being worked on. labels Oct 20, 2021
@ricmoo
Copy link
Member

ricmoo commented Oct 20, 2021

This should be better in 5.5.0. The error thrown is more meaningful and does not mention ENS.

In v6, Signers and Contracts inherit Addressable, so they are valid to passed in for addresses, but in v5 this change seems riskier than I'd prefer, so the current behaviour is preserved, but with better errors. :)

Thanks! :)

@vblackwhale
Copy link

vblackwhale commented Apr 26, 2022

For anyone reading this and whose solution isn't above be aware that this error can be thrown when the contract code is too large. Look at the logs of your local node, I had Error: Transaction reverted: trying to deploy a contract whose code is too large.

@aczire
Copy link

aczire commented Sep 22, 2022

For any one wondering why const c = await Contract.deploy(owner.address); still breaks...
Ensure the address the properly resolved.

Try, const c = await Contract.deploy((await owner).address);

@asif-code
Copy link

Hey there, same problem as @slhodak if anyone found a solution please let me know

Use this code to resolve the error in the ### console

import React, { useEffect, useState } from "react";
import { Contract, Signer, BigNumber, providers, utils } from "ethers";
import { ethers } from "ethers";

import { contractABI, contractAddress } from "../utils/constants";

export const TransacionContext = React.createContext();

const { ethereum } = window;

const getEthereumContract = () => {
const provider = new providers.JsonRpcProvider(ethereum);
const signer = provider.getSigner();
const transactionContact = new ethers.Contract(
contractAddress,
contractABI,
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)]
)
);
}

console.log({
provider,
signer,
transactionContact,
});
};

@asif-code
Copy link

asif-code commented Oct 27, 2022

Hey there, same problem as @slhodak if anyone found a solution please let me know

Use this code to resolve the error in the ### console

import React, { useEffect, useState } from "react"; import { Contract, Signer, BigNumber, providers, utils } from "ethers"; import { ethers } from "ethers";

import { contractABI, contractAddress } from "../utils/constants";

export const TransacionContext = React.createContext();

const { ethereum } = window;

const getEthereumContract = () => { const provider = new providers.JsonRpcProvider(ethereum); const signer = provider.getSigner(); const transactionContact = new ethers.Contract( contractAddress, contractABI, 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)] ) ); }

console.log({ provider, signer, transactionContact, }); };

For Buffer Warning in the console Use This package

Install buffer package, as correctly: npm i buffer
Add this snippet to your index.html:

<script> var global = global || window </script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement. fixed/complete This Bug is fixed or Enhancement is complete and published.
Projects
None yet
Development

No branches or pull requests