4

I deployed contracts to Ropsten test net using truffle and a metamask wallet to pay for the transactions and Infura as a Hosted ethereum node.

To do that in Truffle, I have to use the truffle-hdwallet-provider package to import the keys from my metamask wallet.

var HDWalletProvider = require("truffle-hdwallet-provider")
const mnemonic = "mnemonic words from metamask here"

module.exports = {
 networks : {
    ganache : {
      host : 'localhost',
      port : 8545,    // By default Ganache runs on this port.
      network_id : "*" // network_id for ganache is 5777. However, by keeping * as value you can run this node on  any network
    },
     ropsten: {
        provider: function(){
            return new HDWalletProvider(mnemonic,'https://ropsten.infura.io/v3/<infura_api_key>')
        },
         network_id: 3,
         gas: 4500000,
     }
  }
};

Now I want to Use web3.py to interact with the contracts and I am using the Automatic infura connector from web3.py, web3.auto.infura.w3. I didn't find in the documentation how to import the keys from my metamask wallet to pay for the transactions on the Ropsten network.

for example: suppose I have a contract instance, and I want to call a function on it:

token_contract_instance = w3.eth.contract(address=token_address, abi=token_artifact['abi'])
bal = token_contract_instance.functions.balanceOf(address).call()

But I want that msg.sender on this call to be the ethereum address I created with metamask.

Notice this is taking place in the server-side of the web app.

My guess is that the answer is to define eth.DefaultAccount but the deocumentation is non-existing for this method.

Can anyone show me how to do this?

3 Answers 3

2

You have access to the network through infura as you said. Web3py allows you to do everything (signing, sending, etc.) which is what you are doing with metamask -on websites. Metamask is running on the browser! and it injects web3 so that the methods to interact with the network are available in your webpage (and also allows you to sign transactions without exposing your keys).

In short, web3py allows you to do all you need without intermediary applications.

2
  • 1
    Yes I know, I just want to know what are the best practices use a pre-existing wallet with Web3.py: i.e. How to I call a function in the contract with this adress as msg.sender.
    – fccoelho
    Nov 13, 2018 at 15:54
  • 1
    You can find examples of how to do this here as for the wallet you can get the address and the privatekey and use it on web3py
    – Jaime
    Nov 13, 2018 at 17:05
1

Basically, if you want to use a given wallet to sign trtansactions, you can use the private key from said account, and first sign the transaction and then send it as a raw transaction. for example, say you have a transaction like so:

transaction = {
        'from': <ethereum address which signs this transaction>,
        'to': '<ethereum address>',
        'data': bytes(mtroot, encoding='ascii'),
        'value': value,
        'gas': 100000,
        'gasPrice': 0,  # W3.eth.gasPrice,
        'nonce': 0
    }

first you sign the transaction with your wallet private key:

signed_txn = W3.eth.account.signTransaction(transaction, private_key=os.environ['PRIVATE_KEY'])

then, you send the raw transaction:

txid = W3.toHex(W3.eth.sendRawTransaction(signed_txn.rawTransaction))

That's it!

1
  • 1
    Hi, What is bytes(mtroot, encoding='ascii')? Jan 27, 2021 at 9:50
0

Another solution for nowadays would be to get your wallet private key and put it in a .env file.

Then via script you will be able to load your account :

from dotenv import load_dotenv
load_dotenv()
deployerPrivateKey = os.getenv("ACCOUNT_PRIVATE_KEY")
account = w3.eth.account.privateKeyToAccount(deployerPrivateKey)
print(account.address) # Will print your address

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.