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 to
y nonce
(recibirá un error ValueError: Cannot set nonce in transaction
) Y si simplemente no agrego to
nonce
a 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)
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.py
version 4.2.1
, puede hacer algo como esto para implementar su contrato a través de infura
nodos:
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.
kherwa