Rumah >pembangunan bahagian belakang >Tutorial Python >Akses Ethereum dengan Python melalui web3.py
Jika anda ingin mengakses Ethereum melalui Python, anda boleh melihat dari Github rasmi Ethereum bahawa terdapat dua modul yang boleh melakukannya: web3.py dan pyethereum. Setakat pemahaman semasa saya, perbezaan antara kedua-duanya ialah web3.py digunakan terutamanya sebagai pelanggan untuk akses luaran ke Ethereum, yang bermaksud perpustakaan fungsi web3.py itu sendiri tidak akan menjadi nod blokchain, dan tidak akan ia melakukan penyegerakan rantaian adalah untuk menyambungkan nod pada rantaian blok dan menggunakan rantaian sebagai pangkalan data luaran manakala pyethereum lebih seperti geth, yang digunakan untuk menjadikan dirinya sebagai penyegerakan blok akan dilakukan secara normal, dan anda boleh juga mula melombong sebagai pelombong.
Dalam artikel ini, kerana saya mahu pelanggan yang ringan berinteraksi dengan blockchain, dan tidak mahu menyediakan ruang storan yang besar untuk menyimpan data blockchain, saya akan menggunakan web3 adalah yang utama.
web3.py boleh dipasang terus melalui pip.
pip install web3
Perlu diingatkan bahawa apabila anda ingin memasang pada Windows, anda perlu memasang Visual C++ Builder terlebih dahulu, jika tidak, ia akan gagal kerana ia tidak boleh disusun pada peringkat akhir pemasangan.
web3.py tidak akan wujud sebagai nod blockchain, jadi ia memerlukan nod untuk mengakses bahan blockchain. Secara umumnya, cara paling selamat ialah menggunakan geth atau pariti untuk membina nod anda sendiri Walau bagaimanapun, jika anda tidak mahu membina nod anda sendiri, anda boleh mempertimbangkan untuk melihat perkhidmatan nod HTTP yang disediakan oleh infura.
Berdasarkan API semasa infura, jika anda ingin menyambung ke rantai ujian Ropsten, URL pautan ialah https://ropsten.infura.io/v3/api_key, di mana api_key perlu didaftarkan untuk mendapatkan sebuah akaun. Program berikut meniru amalan auto.infura terbina dalam web3.py, yang membaca parameter INFURA_API_KEY daripada pembolehubah persekitaran untuk membentuk alamat HTTP infura.io, yang digunakan untuk mewujudkan sambungan dengan rantai ujian Ropsten.
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()))
Sebelum anda mula mendeposit dan mengeluarkan kontrak, anda perlu bercakap tentang apa itu ABI. Dalam Ethereum, kerana kontrak semuanya wujud dalam bentuk kod binari yang disusun, perpustakaan fungsi tidak mempunyai cara untuk mengetahui secara langsung kandungan yang dihantar oleh kontrak itu, kerana nilai pulangan kontrak semuanya adalah binari. Oleh itu, sebelum mengendalikan kontrak, fail ABI perlu disediakan untuk memberitahu perpustakaan fungsi cara menggunakan kontrak.
# 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())
Di sini kami mengandaikan bahawa kami ingin mengakses kontrak pintar di alamat 0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6 pada rantai ujian Ropsten. Kontrak ini ialah kontrak ERC20 yang ditemui secara rawak melalui etherscan, jadi anda boleh menggunakan ERC20 ABI standard untuk mengaksesnya. Apabila kami mencipta contoh kontrak ini, kami mula-mula menjalankan gelung untuk mencetak semua fungsi dalam kontrak (langkah ini sebenarnya menyenaraikan maklumat pada ABI), dan kemudian cuba memanggil nama() dalam kontrak untuk mendapatkan pengisytiharan kontrak. Output akhir adalah seperti berikut:
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
Dalam contoh di atas, apabila memanggil kontrak pintar, fungsi dalam kontrak ialah dipanggil terus, tetapi Ini biasanya hanya digunakan apabila membaca data pada blockchain. Jika anda ingin menulis data ke blockchain dengan memanggil kontrak pintar, anda mesti memanggil kontrak dengan cara lain, iaitu, anda mesti menandatangani transaksi dahulu dan kemudian membayar gas untuk melaksanakan transaksi.
Andaikan kita juga ingin memanggil kontrak ERC20 dan melaksanakan fungsi transferFrom() pada kontrak. transferFrom() memerlukan tiga parameter _from, _to, dan _value, yang bermaksud amaun pindahan akan dipindahkan daripada _from akaun ke _to akaun, dan amaun pindahan ialah _value.
# 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))
Dalam program di atas, baris 2 ~ 3 mula-mula membaca akaun yang ingin kita gunakan daripada pembolehubah persekitaran Akaun ini akan digunakan untuk menghantar urus niaga, ia juga akan digunakan daripada Akaun ini akan didebitkan. Baris 10 ~ 20 mencipta transaksi mentah Dalam urus niaga ini, kerana kita perlu menentukan parameter termasuk gas, nonce, dsb., kita perlu mengesahkan berapa banyak parameter untuk ditetapkan dalam baris 11 ~ 12 sebelumnya. Kemudian baris yang paling penting 25 ~ 26 membaca kunci peribadi dan menggunakan kunci peribadi untuk menandatangani transaksi. Adalah diandaikan di sini bahawa kunci persendirian akan terdiri daripada teks yang dikodkan Hex, jadi bytes.fromhex digunakan untuk menukar pengekodan Hex kembali kepada format bait. Selepas menandatangani, hantar transaksi Apabila menghantar transaksi, API akan mengembalikan cincang transaksi dalam format bait Anda boleh mengekodnya dan mencetaknya.
Atas ialah kandungan terperinci Akses Ethereum dengan Python melalui web3.py. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!