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

How do I set the sender for a Contract? #973

Closed
biahoi opened this issue Jul 26, 2020 · 5 comments
Closed

How do I set the sender for a Contract? #973

biahoi opened this issue Jul 26, 2020 · 5 comments
Labels
discussion Questions, feedback and general information.

Comments

@biahoi
Copy link

biahoi commented Jul 26, 2020

Hi,
I used to use web3.js, just now learning for ethers. In web3, when I want to test interaction from account[x], I can have following code to call a function. How should I write similar thing with eths.js?
(I am using etherlime ganache + ethers)
await contractName.methodName(arg, {value: 1000, from: accounts[x]})

@ricmoo
Copy link
Member

ricmoo commented Jul 26, 2020

You will need a signer to connect the contract too. In ethers there is a very explicit separation from a Provider (which is a read-only connection to the blockchain) and a Signer (which may write; such as sending transactions). This is one of the biggest differences people coming from Web3 people have to learn and one that is initially the most confusing. Once you are used to it though, it helps keep your code abstract and re-usable. :)

If you use a JSON-RPC, the JsonRpcProvider happens to also control the Signers.

To connect a contract to a specific signer, you use the connect method, which returns a new instance of a Contract object connected to the same on-chain contract.

You above code would look like:

await contract.connect(provider.getSigner(accounts[x]).methodName(arg, { value: 1000 });

// or if you wanted many operations to be executed with the same signer, you may want to keep it around as a variable:
const contractAccountX = contract.connect(provider.getSigner(accounts[x]);

The getSigner method accepts and address or an index directly (so you could probably also just use provider.getSigner(x).

One key to help remember this is that from isn’t actually part of the transaction, it’s more of a hint to a JSON-RPC provider, so it doesn’t go into the transaction overrides, but needs to be set further up the chain (it’s more of a UX property).

Now it is easy in the future to swap out whatever holds the private key, whether it is a Geth instance, JSON wallet, GSN managed account, hardware wallet or whatever else you can dream up. Just use a different Signer. The provider doesn’t need to change. :)

Make sense? :)

@ricmoo ricmoo added the discussion Questions, feedback and general information. label Jul 26, 2020
@ricmoo ricmoo changed the title Override sender account address How do I set the sender for a Contract? Jul 26, 2020
@biahoi
Copy link
Author

biahoi commented Jul 27, 2020

Thank you.
But I found in the etherlime documentation the (may be more simple?) solution like this:

await contractName .from(accounts[x].signer) .methodName(arg {value: xxx});
It works.
But do I missed something?

@ricmoo
Copy link
Member

ricmoo commented Jul 27, 2020

That may be an etherlime-specific extension? I’m not sure, I don’t use etherlime, but if it works for you, awesome. :)

@ricmoo
Copy link
Member

ricmoo commented Sep 5, 2020

I think this is resolved? If not, please re-open.

Thanks! :)

@ricmoo ricmoo closed this as completed Sep 5, 2020
@MisterDefender99
Copy link

Hi @ricmoo, when we want to call a method with different account we uses .connect() for it, so what is the need of .attach()??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Questions, feedback and general information.
Projects
None yet
Development

No branches or pull requests

3 participants