Wenn Sie über Python auf Ethereum zugreifen möchten, können Sie dem offiziellen Github von Ethereum entnehmen, dass zwei Module erreicht werden können: web3.py und pyethereum. Nach meinem derzeitigen Verständnis besteht der Unterschied zwischen den beiden darin, dass web3.py hauptsächlich als Client für den externen Zugriff auf Ethereum verwendet wird, was bedeutet, dass die Funktionsbibliothek web3.py selbst kein Blockchain-Knoten wird und dies auch nicht tun wird Bei der Kettensynchronisierung geht es darum, einen Knoten auf der Blockchain zu verbinden und die Blockchain als externe Datenbank zu verwenden. Pyethereum ähnelt eher der Funktion, sich selbst zu einem Blockchain-Knoten zu machen, und Sie können dies auch tun Beginnen Sie auch als Bergmann mit dem Bergbau.
Da ich in diesem Artikel möchte, dass ein leichter Client mit der Blockchain interagiert, möchte ich keinen großen Speicherplatz zum Speichern der Blockchain-Daten vorbereiten, also werde ich web3.py verwenden Hauptsächlich.
web3.py kann direkt über pip installiert werden.
pip install web3
Es ist zu beachten, dass Sie bei der Installation unter Windows den Visual C++ Builder im Voraus installieren müssen, da er sonst fehlschlägt, da er in der Endphase der Installation nicht kompiliert werden kann.
web3.py Da es nicht als Blockchain-Knoten existiert, benötigt es einen Knoten, um auf die Bereichsdaten in der Blockchain zuzugreifen. Im Allgemeinen ist es am sichersten, Geth oder Parity zum Erstellen eigener Knoten zu verwenden. Wenn Sie jedoch keine eigenen Knoten erstellen möchten, können Sie einen Blick auf den von infura bereitgestellten HTTP-Knotendienst werfen.
Wenn Sie sich basierend auf der aktuellen API von infura mit der Ropsten-Testkette verbinden möchten, lautet die Link-URL https://ropsten.infura.io/v3/api_key, wo der api_key registriert werden muss um ein Konto zu erhalten. Das folgende Programm imitiert die Vorgehensweise von web3.pys integriertem auto.infura, das den Parameter INFURA_API_KEY aus der Umgebungsvariablen liest, um die HTTP-Adresse von infura.io zu bilden, die zum Herstellen einer Verbindung mit der Ropsten-Testkette verwendet wird.
import os from web3 import ( HTTPProvider, Web3, ) INFURA_ROPSTEN_BASE_URL = 'https://ropsten.infura.io/v3' def load_infura_url(): key = os.environ.get('INFURA_API_KEY', '') return "%s/%s" % (INFURA_ROPSTEN_BASE_URL, key) w3 = Web3(HTTPProvider(load_infura_url()))
Bevor Sie mit der Einzahlung und Abhebung von Verträgen beginnen, müssen Sie darüber sprechen, was ABI ist. Da in Ethereum alle Verträge in Form von kompiliertem Binärcode vorliegen, hat die Funktionsbibliothek keine Möglichkeit, direkt zu wissen, was der vom Vertrag übertragene Inhalt ist, da die Rückgabewerte des Vertrags alle binär sind. Daher muss vor der Ausführung des Vertrags eine ABI-Datei bereitgestellt werden, um der Funktionsbibliothek mitzuteilen, wie der Vertrag verwendet werden soll.
# Assume the contract we're going to invoke is a standard ERC20 contract. with open("erc20.abi.json") as f: erc20_abi = json.load(f) # Web3 accept only checksum address. So we should ensure the given address is a # checksum address before accessing the corresponding contract. contract_addr = w3.toChecksumAddress('0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6'); erc20_contract = w3.eth.contract(address=contract_addr, abi=erc20_abi) for func in erc20_contract.all_functions(): logger.debug('contract functions: %s', func) logger.debug("Name of the token: %s", erc20_contract.functions.name().call())
Gehen wir hier davon aus, dass wir auf den Smart Contract mit der Adresse 0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6 in der Ropsten-Testkette zugreifen möchten. Bei diesem Vertrag handelt es sich um einen zufällig über Etherscan gefundenen ERC20-Vertrag, sodass Sie mit dem Standard-ERC20-ABI darauf zugreifen können. Wenn wir die Instanz dieses Vertrags erstellen, führen wir zunächst eine Schleife aus, um alle Funktionen im Vertrag auszudrucken (dieser Schritt listet tatsächlich die Informationen zum ABI auf) und versuchen dann, name() im Vertrag aufzurufen, um die zu erhalten Vertragserklärung. Die endgültige Ausgabe lautet wie folgt:
2018-09-07 15:02:53,815 | __main__ | DEBUG | contract functions: <Function name()> 2018-09-07 15:02:53,816 | __main__ | DEBUG | contract functions: <Function approve(address,uint256)> 2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function totalSupply()> 2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function transferFrom(address,address,uint256)> 2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function decimals()> 2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function balanceOf(address)> 2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function symbol()> 2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions: <Function transfer(address,uint256)> 2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions: <Function allowance(address,address)> 2018-09-07 15:02:54,359 | __main__ | DEBUG | Name of the token: KyberNetwork
Im obigen Beispiel wird beim Aufrufen des Smart-Vertrags der Vertrag wird direkt als Funktion bezeichnet, diese kann jedoch im Allgemeinen nur zum Lesen von Daten auf der Blockchain verwendet werden. Wenn Sie Daten in die Blockchain schreiben möchten, indem Sie einen Smart Contract aufrufen, müssen Sie den Vertrag auf andere Weise aufrufen, das heißt, Sie müssen zuerst die Transaktion signieren und dann Gas bezahlen, um die Transaktion auszuführen.
Angenommen, wir möchten auch einen ERC20-Vertrag aufrufen und die Funktion transferFrom() für den Vertrag ausführen. transferFrom() benötigt drei Parameter _from, _to und _value, was bedeutet, dass der Überweisungsbetrag vom _from-Konto auf das _to-Konto übertragen werden soll und der Überweisungsbetrag _value ist.
# Set the account which makes the transaction. account = w3.toChecksumAddress(os.environ.get('ETHEREUM_ACCOUNT', '')) w3.eth.defaultAccount = account # Web3 accept only checksum address. So we should ensure the given address is a # checksum address before accessing the corresponding contract. contract_address = w3.toChecksumAddress('0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6') contract = w3.eth.contract(address=contract_address, abi=contract_abi) # Prepare the necessary parameters for making a transaction on the blockchain. estimate_gas = contract.functions.transferFrom(account, account, w3.toWei('1', 'eth')).estimateGas() nonce = w3.eth.getTransactionCount(account) # Build the transaction. txn = contract.functions.transferFrom(account, account, w3.toWei('1', 'eth')).buildTransaction({ 'chainId': 3, 'gas': estimate_gas, 'gasPrice': w3.toWei('1', 'gwei'), 'nonce': nonce }) logger.debug('Transaction: %s', txn) # Sign the transaction. private_key = bytes.fromhex(os.environ.get('ETHEREUM_ACCOUNT_PKEY', '')) signed_txn = w3.eth.account.signTransaction(txn, private_key=private_key) tx_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction) logger.debug('Txhash: 0x%s', bytes.hex(tx_hash))
Im obigen Programm lesen die Zeilen 2 bis 3 zuerst das Konto, das wir verwenden möchten, aus der Umgebungsvariablen. Dieses Konto wird natürlich auch zum Senden von Transaktionen verwendet Dieses Konto wird belastet. In den Zeilen 10 bis 20 wird eine Rohtransaktion erstellt. Da wir Parameter wie Gas, Nonce usw. angeben müssen, müssen wir bestätigen, wie viele Parameter in den vorherigen Zeilen 11 bis 12 festgelegt werden sollen. Dann lesen die wichtigsten Zeilen 25 bis 26 den privaten Schlüssel und signieren die Transaktion mit dem privaten Schlüssel. Hier wird davon ausgegangen, dass der private Schlüssel aus Hex-kodiertem Text besteht, daher wird bytes.fromhex verwendet, um die Hex-Kodierung zurück in das Byte-Format zu konvertieren. Senden Sie die Transaktion nach dem Signieren. Die API gibt den Transaktions-Hash im Byte-Format zurück. Anschließend können Sie auf Etherscan nach der Transaktion suchen.
Das obige ist der detaillierte Inhalt vonGreifen Sie mit Python über web3.py auf Ethereum zu. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!