中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何通過web3.py用Python存取Ethereum

發布時間:2023-04-13 15:33:44 來源:億速云 閱讀:132 作者:iii 欄目:編程語言

這篇文章主要介紹了如何通過web3.py用Python存取Ethereum的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇如何通過web3.py用Python存取Ethereum文章都會有所收獲,下面我們一起來看看吧。

配置 web3.py 執行環境

web3.py 可以直接通過 pip 安裝。

pip install web3

需注意的是,在 Windows 上想安裝時,會需要事先安裝 Visual C++ Builder,否則在安裝的最后階段會因為無法編譯而失敗。

通過 web3.py 連結 Ethereum 節點

web3.py 因為自身不會作為一個區塊鏈的節點存在,因此它需要有一個節點用來存取區塊鏈上的資料。一般來說最安全的方式應該是自己使用 geth 或者 parity 來自建節點,不過如果在不想要自建節點的狀況時,可以考慮看看 infura 提供的 HTTP 節點服務。

以 infura 現在的 API 來說,如果要連結 Ropsten 測試鏈,連結的網址是 https://ropsten.infura.io/v3/api_key,其中 api_key 要去注冊帳號才取得。以下的程序仿照了 web3.py 內建的 auto.infura 的作法,會從環境變數讀取 INFURA_API_KEY 這個參數來組出 infura.io 的 HTTP 位址,用來建立跟 Ropsten 測試鏈的連線。

存取區塊鏈上的 ERC20 合約
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()))

在開始存取合約之前,需要先談談什么是 ABI 。在 Ethereum 中,因為合約都是以編譯過的 binary code 形式存在,因此其實函數庫沒辦法直接知道合約傳輸的內容到底是什么,因為合約的回傳值全都是 binary。因此在操作合約之前,需要提供一份 ABI 文件,告訴函數庫如何使用合約。

# 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())

這里假設我們想存取 Ropsten 測試鏈上位址是 0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6 的智能合約。這個合約是透過 etherscan 隨便找的某個 ERC20 的合約,因此可以用標準的 ERC20 的 ABI 來存取它。我們在建立這個合約的 instance 時,先跑一個回圈印出合約內所有的 function(這個步驟其實是在列出 ABI 上的信息),接著試著呼叫合約中的 name() 來取得這個合約宣告的代幣名稱。最后輸出的內容如下:

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
簽署并送出交易

在上面的例子中,呼叫智能合約時是直接呼叫合約里的 function,但這一般只能用在讀取區塊鏈上的資料的狀況。如果是想要通過呼叫智能合約來寫入資料到區塊鏈,就必須要用另一種方式來呼叫合約,也就是必須先簽署交易,然后付 gas 去執行這個交易。

假設我們一樣是要呼叫一個 ERC20 的合約,要執行合約上的 transferFrom() 這個函數。transferFrom() 需要三個參數 _from、 _to、 _value,表示要從 _from 帳號轉帳給 _to 帳號,轉帳金額是 _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 行先從環境變量中讀取我們要使用的帳號,這個帳號將會用來發送交易,當然要付 gas 時也會從這個帳號扣。第 10 ~ 20 行建立一個原始交易(raw transaction),這個交易中因為我們需要自行指定包括 gas、nonce 等參數,因此需要在前面 11 ~ 12 行確認參數要設定多少。然后最重要的第 25 ~ 26 行讀取私鑰,并且用私鑰去簽署交易。這里假設私鑰的組成會是用 Hex 編碼的文字,所以使用 bytes.fromhex 把 Hex 編碼轉回成 byte 格式。簽好以后就送出交易,送出交易時 API 會回傳 byte 格式的交易的 transaction hash,可以把它編碼后印出來,之后就可以去 etherscan 上查找這筆交易了。

關于“如何通過web3.py用Python存取Ethereum”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“如何通過web3.py用Python存取Ethereum”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

伽师县| 万源市| 柘荣县| 岢岚县| 长宁县| 乌鲁木齐县| 呼伦贝尔市| 定陶县| 泉州市| 德兴市| 江源县| 克拉玛依市| 长顺县| 全南县| 西贡区| 改则县| 栖霞市| 民乐县| 浦江县| 锦屏县| 辽阳市| 盱眙县| 衡水市| 田林县| 子洲县| 叶城县| 元朗区| 曲周县| 新乡县| 襄樊市| 沅江市| 沂南县| 德化县| 龙井市| 白水县| 昌宁县| 兴山县| 静乐县| 大厂| 长沙市| 襄汾县|