¿Cómo usar una billetera metamask de web3, py?

Implementé contratos en la red de prueba de Ropsten usando truffle y una billetera metamask para pagar las transacciones e Infura como un nodo Ethereum alojado.

Para hacer eso en Truffle, tengo que usar el truffle-hdwallet-providerpaquete para importar las claves de mi billetera metamask.

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,
     }
  }
};

Ahora quiero usar web3.py para interactuar con los contratos y estoy usando el conector Infura automático de web3.py, web3.auto.infura.w3. No encontré en la documentación cómo importar las claves de mi billetera metamask para pagar las transacciones en la red Ropsten.

por ejemplo: supongamos que tengo una instancia de contrato y quiero llamar a una función en ella:

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

Pero quiero que msg.sender en esta llamada sea la dirección ethereum que creé con metamask.

Tenga en cuenta que esto ocurre en el lado del servidor de la aplicación web.

Supongo que la respuesta es definir eth.DefaultAccount, pero la documentación no existe para este método.

¿Alguien puede mostrarme cómo hacer esto?

Respuestas (3)

Tienes acceso a la red a través de infura como dijiste. Web3py le permite hacer todo (firmar, enviar, etc.) que es lo que está haciendo con metamask en los sitios web. ¡Metamask se está ejecutando en el navegador! e inyecta web3 para que los métodos para interactuar con la red estén disponibles en su página web (y también le permite firmar transacciones sin exponer sus claves).

En resumen, web3py te permite hacer todo lo que necesitas sin aplicaciones intermedias.

Sí, lo sé, solo quiero saber cuáles son las mejores prácticas para usar una billetera preexistente con Web3.py: es decir, cómo llamar a una función en el contrato con esta dirección como msg.sender.
Puede encontrar ejemplos de cómo hacer esto aquí. En cuanto a la billetera, puede obtener la dirección y la clave privada y usarla en web3py.

Básicamente, si desea usar una billetera determinada para firmar transacciones, puede usar la clave privada de dicha cuenta, y primero firmar la transacción y luego enviarla como una transacción sin procesar. por ejemplo, supongamos que tiene una transacción como esta:

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
    }

primero firma la transacción con la clave privada de su billetera:

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

luego, envía la transacción sin procesar:

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

¡Eso es todo!

Hola, ¿Qué es bytes(mtroot, encoding='ascii')?

Otra solución para hoy en día sería obtener la clave privada de su billetera y ponerla en un archivo .env.

Luego, a través de un script, podrá cargar su cuenta:

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