您好,登錄后才能下訂單哦!
這篇文章主要介紹了如何通過web3.py用Python存取Ethereum的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇如何通過web3.py用Python存取Ethereum文章都會有所收獲,下面我們一起來看看吧。
web3.py 可以直接通過 pip 安裝。
pip install web3
需注意的是,在 Windows 上想安裝時(shí),會需要事先安裝 Visual C++ Builder,否則在安裝的最后階段會因?yàn)闊o法編譯而失敗。
web3.py 因?yàn)樽陨聿粫鳛橐粋€(gè)區(qū)塊鏈的節(jié)點(diǎn)存在,因此它需要有一個(gè)節(jié)點(diǎn)用來存取區(qū)塊鏈上的資料。一般來說最安全的方式應(yīng)該是自己使用 geth 或者 parity 來自建節(jié)點(diǎn),不過如果在不想要自建節(jié)點(diǎn)的狀況時(shí),可以考慮看看 infura 提供的 HTTP 節(jié)點(diǎn)服務(wù)。
以 infura 現(xiàn)在的 API 來說,如果要連結(jié) Ropsten 測試鏈,連結(jié)的網(wǎng)址是 https://ropsten.infura.io/v3/api_key,其中 api_key 要去注冊帳號才取得。以下的程序仿照了 web3.py 內(nèi)建的 auto.infura 的作法,會從環(huán)境變數(shù)讀取 INFURA_API_KEY 這個(gè)參數(shù)來組出 infura.io 的 HTTP 位址,用來建立跟 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()))
在開始存取合約之前,需要先談?wù)勈裁词?ABI 。在 Ethereum 中,因?yàn)楹霞s都是以編譯過的 binary code 形式存在,因此其實(shí)函數(shù)庫沒辦法直接知道合約傳輸?shù)膬?nèi)容到底是什么,因?yàn)楹霞s的回傳值全都是 binary。因此在操作合約之前,需要提供一份 ABI 文件,告訴函數(shù)庫如何使用合約。
# 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())
這里假設(shè)我們想存取 Ropsten 測試鏈上位址是 0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6 的智能合約。這個(gè)合約是透過 etherscan 隨便找的某個(gè) ERC20 的合約,因此可以用標(biāo)準(zhǔn)的 ERC20 的 ABI 來存取它。我們在建立這個(gè)合約的 instance 時(shí),先跑一個(gè)回圈印出合約內(nèi)所有的 function(這個(gè)步驟其實(shí)是在列出 ABI 上的信息),接著試著呼叫合約中的 name() 來取得這個(gè)合約宣告的代幣名稱。最后輸出的內(nèi)容如下:
2018-09-07 15:02:53,815 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,816 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions:2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions:2018-09-07 15:02:54,359 | __main__ | DEBUG | Name of the token: KyberNetwork
在上面的例子中,呼叫智能合約時(shí)是直接呼叫合約里的 function,但這一般只能用在讀取區(qū)塊鏈上的資料的狀況。如果是想要通過呼叫智能合約來寫入資料到區(qū)塊鏈,就必須要用另一種方式來呼叫合約,也就是必須先簽署交易,然后付 gas 去執(zhí)行這個(gè)交易。
假設(shè)我們一樣是要呼叫一個(gè) ERC20 的合約,要執(zhí)行合約上的 transferFrom() 這個(gè)函數(shù)。transferFrom() 需要三個(gè)參數(shù) _from、 _to、 _value,表示要從 _from 帳號轉(zhuǎn)帳給 _to 帳號,轉(zhuǎn)帳金額是 _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))
在上面的程序中,首先第 2 ~ 3 行先從環(huán)境變量中讀取我們要使用的帳號,這個(gè)帳號將會用來發(fā)送交易,當(dāng)然要付 gas 時(shí)也會從這個(gè)帳號扣。第 10 ~ 20 行建立一個(gè)原始交易(raw transaction),這個(gè)交易中因?yàn)槲覀冃枰孕兄付ò?gas、nonce 等參數(shù),因此需要在前面 11 ~ 12 行確認(rèn)參數(shù)要設(shè)定多少。然后最重要的第 25 ~ 26 行讀取私鑰,并且用私鑰去簽署交易。這里假設(shè)私鑰的組成會是用 Hex 編碼的文字,所以使用 bytes.fromhex 把 Hex 編碼轉(zhuǎn)回成 byte 格式。簽好以后就送出交易,送出交易時(shí) API 會回傳 byte 格式的交易的 transaction hash,可以把它編碼后印出來,之后就可以去 etherscan 上查找這筆交易了。
關(guān)于“如何通過web3.py用Python存取Ethereum”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“如何通過web3.py用Python存取Ethereum”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。