¿Cómo conectarse a infura e implementar el uso del contrato web3.py?

la pregunta de origen es la siguiente:

How to connect to Ropston and deploy contract use web3.py?
I have deploy a contract to Ropston use remix and MetaMask.
I want know how to deploy a contract to Ropston via infura using web3.py without geth or parity.
I read the Documention and find there is no how-to chapter.
A small demo code will be very helpful.

Y solo busco e intento Y encuentro que este código puede funcionar. Pero, buildTransaction()la función no puede agregar argumentos toy nonce(recibirá un error ValueError: Cannot set nonce in transaction) Y si simplemente no agrego to noncea la transacción en signTransaction()la función, obtendréerrorTypeError: Not all fields initialized

Debe haber algo mal. Supongo que debería usar otra función en lugar de buildTransaction()Pero no puedo encontrarla en el documento.

Entonces, ¿qué función debo usar? ¿Y cuál es la forma Pythonic de implementar el contrato en https://ropsten.infura.io/ ?

from eth_account import Account
from web3 import Web3, HTTPProvider
from solc import compile_source

privateKey = "xxxxxx"
contract_source_code = '''
pragma solidity ^0.4.0;

contract Greeter {
    string public greeting;

    function Greeter() {
        greeting = 'Hello';
    }

    function setGreeting(string _greeting) public {
        greeting = _greeting;
    }

    function greet() constant returns (string) {
        return greeting;
    }
}
'''

compiled_sol = compile_source(contract_source_code)
contract_interface = compiled_sol['<stdin>:Greeter']
w3 = Web3(HTTPProvider("https://ropsten.infura.io/"))
w3.eth.enable_unaudited_features()
account = Account()
acct = account.privateKeyToAccount(privateKey)
contract_ = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
contract_data = contract_.constructor().buildTransaction({'from': acct.address,
                                                          'gas': 1728712,
                                                          'gasPrice': w3.toWei('21', 'gwei')})
contract_data["to"] = ""  # <----
contract_data["nonce"] = w3.eth.getTransactionCount(acct.address)   #<------
signed = w3.eth.account.signTransaction(contract_data, privateKey)
w3.eth.sendRawTransaction(signed.rawTransaction)
Puedes hacerlo usando eth-testrpc

Respuestas (3)

A partir de v4.2.1, implementar un contrato con una clave local es mucho más sencillo.

Del código de ejemplo de la pregunta, aquí hay un nuevo enfoque:

w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/YOUR_PROJECT_ID"))

contract_ = w3.eth.contract(
    abi=contract_interface['abi'],
    bytecode=contract_interface['bin'])

acct = w3.eth.account.privateKeyToAccount(privateKey)

construct_txn = contract_.constructor().buildTransaction({
    'from': acct.address,
    'nonce': w3.eth.getTransactionCount(acct.address),
    'gas': 1728712,
    'gasPrice': w3.toWei('21', 'gwei')})

signed = acct.signTransaction(construct_txn)

w3.eth.sendRawTransaction(signed.rawTransaction)

Usando web3.pyversion 4.2.1, puede hacer algo como esto para implementar su contrato a través de infuranodos:

from web3 import Web3

class DeployContract:
    def __init__(self, abi, bin, public_key, private_key):
        provider = 'https://ropsten.infura.io/YOUR_INFURA_KEY'
        self.w3 = Web3(Web3.HTTPProvider(provider))
        self.abi = abi # Your contract ABI code
        self.bin = bin # Your contract ByteCode 
        self.priv = private_key
        self.pub = public_key

    def deploy(self):
        instance = self.w3.eth.contract(abi=self.abi, bytecode=self.bin)
        # hacky .. but it works :D
        tx_data = instance.constructor().__dict__.get('data_in_transaction')
        transaction = {
            'from': self.pub, # Only 'from' address, don't insert 'to' address
            'value': 0, # Add how many ethers you'll transfer during the deploy
            'gas': 2000000, # Trying to make it dynamic ..
            'gasPrice': self.w3.eth.gasPrice, # Get Gas Price
            'nonce': self.w3.eth.getTransactionCount(self.pub), # Get Nonce
            'data': tx_data # Here is the data sent through the network
        }
        # Sign the transaction using your private key
        signed = self.w3.eth.account.signTransaction(transaction, self.priv)
        #print(signed.rawTransaction)
        tx_hash = self.w3.eth.sendRawTransaction(signed.rawTransaction)
        print(tx_hash.hex())

Necesita tener acceso a un nodo en todos los casos. Citando web3.py Lea los documentos:

Puede conectarse a su nodo Ethereum (por ejemplo: geth o paridad) utilizando uno de los proveedores disponibles, generalmente IPC o HTTP.

Si su nodo se ejecuta localmente, IPC será más rápido y seguro de exponer. Si comparte el nodo entre máquinas en una red, use HTTP en su lugar. Cita en bloque

Por lo tanto, debe conectarse a un nodo público, por ejemplo (tomado de aquí ):

w3 = Web3.providers.HttpProvider('https://api.myetherapi.com/eth')

¡Entonces puedes hacer tu magia con w3!. Sin embargo, el problema principal aquí es cómo administrar sus claves myetherapi no permite métodos que involucren cuentas.

Nota: ¡No he usado myetherapi.com!

Espero esta ayuda.

tienes razón, he ejecutado un código usando geth. Pero en este proyecto, tengo que usar infura. quiero saber como hacerlo
Recomendaría usar Alchemy ( alchemyapi.io ), en lugar de Infura. Descubrimos que Infura no era confiable y tenía un tiempo de inactividad significativo.