成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

通過 web3.py 用 Python 存取 Ethereum

開發(fā) 后端
在本篇當(dāng)中,因?yàn)槭窍胍粋€(gè)輕量級(jí)的客戶端來與區(qū)塊鏈互動(dòng),并不想要準(zhǔn)備龐大的儲(chǔ)存空間來存放區(qū)塊鏈的資料,因此會(huì)以 web3.py 為主。

想要通過 Python 存取 Ethereum,從 Ethereum 官方的 Github 中可以看到有兩種模塊可以達(dá)成:web3.py 和 pyethereum 。就我目前的理解來說,兩者的差別在于 web3.py 主要是作為外部存取 Ethereum 的客戶端,也就是說 web3.py 函數(shù)庫本身不會(huì)成為區(qū)塊鏈節(jié)點(diǎn),也不會(huì)進(jìn)行區(qū)塊鏈同步,而是連接一個(gè)區(qū)塊鏈上的節(jié)點(diǎn),把區(qū)塊鏈當(dāng)成是外部資料庫一樣取用而已;而 pyethereum 則比較像是 geth 那樣,是用來把自己做成一個(gè)區(qū)塊鏈節(jié)點(diǎn),會(huì)正常進(jìn)行區(qū)塊同步,也可以作為礦工開始挖礦。

在本篇當(dāng)中,因?yàn)槭窍胍粋€(gè)輕量級(jí)的客戶端來與區(qū)塊鏈互動(dòng),并不想要準(zhǔn)備龐大的儲(chǔ)存空間來存放區(qū)塊鏈的資料,因此會(huì)以 web3.py 為主。

  • 配置 web3.py 執(zhí)行環(huán)境
  • 通過 web3.py 連結(jié) Ethereum 節(jié)點(diǎn)
  • 存取區(qū)塊鏈上的 ERC20 合約
  • 簽署并送出交易

配置 web3.py 執(zhí)行環(huán)境

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

pip install web3

需注意的是,在 Windows 上想安裝時(shí),會(huì)需要事先安裝 Visual C++ Builder,否則在安裝的最后階段會(huì)因?yàn)闊o法編譯而失敗。

通過 web3.py 連結(jié) Ethereum 節(jié)點(diǎn)

web3.py 因?yàn)樽陨聿粫?huì)作為一個(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 測(cè)試鏈,連結(jié)的網(wǎng)址是 https://ropsten.infura.io/v3/api_key,其中 api_key 要去注冊(cè)帳號(hào)才取得。以下的程序仿照了 web3.py 內(nèi)建的 auto.infura 的作法,會(huì)從環(huán)境變數(shù)讀取 INFURA_API_KEY 這個(gè)參數(shù)來組出 infura.io 的 HTTP 位址,用來建立跟 Ropsten 測(cè)試鏈的連線。

存取區(qū)塊鏈上的 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()))

在開始存取合約之前,需要先談?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 測(cè)試鏈上位址是 0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6 的智能合約。這個(gè)合約是透過 etherscan 隨便找的某個(gè) ERC20 的合約,因此可以用標(biāo)準(zhǔn)的 ERC20 的 ABI 來存取它。我們?cè)诮⑦@個(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: <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

簽署并送出交易

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

假設(shè)我們一樣是要呼叫一個(gè) ERC20 的合約,要執(zhí)行合約上的 transferFrom() 這個(gè)函數(shù)。transferFrom() 需要三個(gè)參數(shù) _from、 _to、 _value,表示要從 _from 帳號(hào)轉(zhuǎn)帳給 _to 帳號(hào),轉(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)境變量中讀取我們要使用的帳號(hào),這個(gè)帳號(hào)將會(huì)用來發(fā)送交易,當(dāng)然要付 gas 時(shí)也會(huì)從這個(gè)帳號(hào)扣。第 10 ~ 20 行建立一個(gè)原始交易(raw transaction),這個(gè)交易中因?yàn)槲覀冃枰孕兄付ò?gas、nonce 等參數(shù),因此需要在前面 11 ~ 12 行確認(rèn)參數(shù)要設(shè)定多少。然后最重要的第 25 ~ 26 行讀取私鑰,并且用私鑰去簽署交易。這里假設(shè)私鑰的組成會(huì)是用 Hex 編碼的文字,所以使用 bytes.fromhex 把 Hex 編碼轉(zhuǎn)回成 byte 格式。簽好以后就送出交易,送出交易時(shí) API 會(huì)回傳 byte 格式的交易的 transaction hash,可以把它編碼后印出來,之后就可以去 etherscan 上查找這筆交易了。

責(zé)任編輯:龐桂玉 來源: Python中文社區(qū)
相關(guān)推薦

2022-04-23 16:47:52

以太坊Web3.py區(qū)塊鏈

2021-10-26 00:27:28

Python以太坊智能

2022-04-20 10:11:45

PythonBrownie編程語言

2009-03-27 09:26:36

SilverlightSilverlight微軟

2011-12-12 08:58:52

Python

2012-02-21 16:39:29

響應(yīng)式Web設(shè)計(jì)

2023-01-18 08:10:34

Web3Web2JavaScript

2012-01-12 11:05:05

響應(yīng)式Web設(shè)計(jì)

2009-04-13 11:38:27

IBMdWWeb

2017-09-21 10:00:07

緩存web服務(wù)器

2021-02-23 09:50:42

PythonJSWeb SSH

2017-06-08 15:53:38

PythonWeb框架

2013-08-13 09:56:00

PythonWeb2py

2010-03-16 14:27:06

Python Web

2021-10-27 16:03:43

Python編程語言代碼

2022-07-28 21:17:46

福布斯數(shù)字化Web3

2021-02-11 09:03:48

Web3技術(shù)Web 3.0

2022-08-18 15:21:42

區(qū)塊鏈DevOps

2021-08-17 09:00:00

架構(gòu)PythonWeb

2023-02-25 16:02:48

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩在线一区二区 | 九色在线观看 | 少妇久久久久 | 亚洲精品性视频 | 久久久青草婷婷精品综合日韩 | 一级欧美一级日韩片 | 亚洲福利一区二区 | 91久久 | 婷婷久久一区 | 日本免费在线 | 国产视频一区二区 | 亚洲第一av网站 | 日韩午夜场 | 中文字幕精品视频在线观看 | 99精品欧美一区二区三区 | 91成人精品 | 一本一道久久a久久精品蜜桃 | 日韩国产在线 | 国产亚洲精品久久久久久豆腐 | 亚洲精品视频免费观看 | 日韩成人高清 | 欧美一级艳情片免费观看 | 国内久久 | 中文字幕av第一页 | 午夜精品久久久 | 欧州一区 | 亚洲精品综合 | 久久精品国产一区二区三区不卡 | 九九伦理片| 国产99热精品| 久久久久久国产 | 人成在线视频 | 成人免费一区二区三区视频网站 | 精精国产xxxx视频在线播放 | 色爱综合网 | 在线日韩精品视频 | 午夜久久久久久久久久一区二区 | 国产综合第一页 | 中文字幕在线视频免费视频 | 亚洲最大成人综合 | 人人干人人草 |