Python 使用 Web3 進行 ERC20 代幣開發

geeker發表於2018-12-03

上一篇文章中,我展示瞭如何為RSK Mainnet編寫Solidity ERC20代幣,如何匯入和使用OpenZeppelin庫和合約,以及如何使用Truffle來部署和互動我們的智慧合約。

雖然我們使用Truffle成功完成了我們的任務並實現了我們的目標,但最終這個套件在你傳送交易,部署或管理帳戶時還是可能會出現一些問題。在我們的案例中,在遵循之前的文章說明時,我在使用Truffle管理新建立的帳戶和傳送交易時就遇到了一些問題。

我遇到的第一個問題是凍結了SBTC的部分資金,RSK Labs團隊讓我測試了Mainnet(感謝Maximiliano)。雖然我已經解鎖了帳戶,但節點仍然問我建立的帳戶的私鑰(正如我們在第一篇文章中看到的):

truffle(rsk)> web3.personal.newAccount(‘somePassword’)
truffle(rsk)> web3.personal.unlockAccount(web3.eth.accounts[0],'somePassword')

出於這個原因,為了保留我的少數SBTC的安全性,我在合約中新增了銷燬功能,以防萬一出現問題。

當我嘗試與已部署的合約進行互動時,出現了第二個問題。在傳送交易時,Truffle將其主體傳送到具有資料和其餘引數的節點(正如我在rsk.log檔案中看到的那樣)。但是,在20分鐘之後,交易從未包含在任何塊中,並且節點也沒有收據或其雜湊值。

我解決這個問題的方法是通過node.conf檔案中配置cors引數,以允許Metamask連線到節點。然後,通過將有問題的函式及其引數編碼為十六進位制字串並輸入資料欄位來傳送交易。在使用與Truffle傳送的交易相同的nonce值傳送後,它最終被包含在內。

不要誤會我的意思,Truffle套件對於開發人員來說是一個很好的工具,但是如果你在開發智慧合約時不時遇到一些問題,請保持專注並繼續閱讀。

我將在這裡討論的工具是Web3的Python版本:Web3.py。

介紹

由於rskj的行為就像以太坊節點(即它提供了相同的JSON-RPC API),我們可以使用其他實現來與之互動。最受歡迎的Web3版本是用JavaScript(Web3.js)編寫的版本。但自11月以來,Web3.py專案的更新率更高,大大提高了其可用性。此版本還允許比Web3.js更友好的互動體驗。

在本文中,我們將討論上一篇文章中使用的相同ERC20代幣合約的部署和互動,以比較兩種工具的可用性。

從rskj 4.2開始,RSK Testnet重新上線。出於這個原因,並且因為我們之前無法使用它,我們將在本文的網路上部署和測試我們的合約。

改為Python

Web3.py是用Python3編寫的。如果你之前從未使用過Python,那麼你可能需要一些軟體包。否則,當我們在我們的環境中安裝Web3.py時,將在編譯期間出錯。我們安裝它們:

$ sudo apt-get install gcc
$ sudo apt-get install python3-dev

設定環境

我們希望將Web3.py的例項與其他個人Python模組分開。為此,我們需要建立一個Python的虛擬環境:

$ sudo apt install virtualenv
$ virtualenv -p python3~ / web3_py

然後,我們使用以下命令啟用例項:

$ source web3_py/bin/activate

在終端中,我們應該能夠看到命令提示符:

(web3_py) user@computer:~$

這意味著我們的Python虛擬環境現在處於活動狀態。現在,我們將安裝專案的庫:

(web3_py) user@computer:~$ pip install web3

你不應該看到任何錯誤。

為了改善直譯器的外觀,我建議安裝IPython(不,不是從App Store):

(web3_py) user@computer:~$ pip install ipython

如果我們想休息並退出虛擬環境,我們可以這樣做:

(web3_py) user@computer:~$ deactivate

我們將使用測試網路來部署我們的合約,所以請隨時再次檢查我們已經討論過如何更改網路的第一篇文章(並自行更改!:))。

現在,我們有一個合適的環境來啟動我們的指令碼。

安裝SOLC

編譯我們的.sol(Solidity合約程式碼)不是Python的工作。這是我們的Solidity編譯器的一項任務:Solc。要安裝它的最新穩定版本,我們這樣做:

$ sudo add-apt-repository ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install solc

有了這個,我們應該能夠像這樣編譯我們的合約:

$ solc <contract>.sol --bin --abi --optimize -o <output-dir>/

其中<contract>.sol是Solidity程式碼檔案,<output-dir>是我們構建的ABI和位元組碼檔案的位置。

啟動安裝程式

一旦我們從虛擬環境中開啟Python,我們就需要匯入Web3和Json等庫,但在此之前,必須注意一個問題。在某些情況下,即使使用Python3,使用雙TAB的自動完成功能也不起作用。要解決此問題,需要匯入一些庫,執行以下操作:

>>> try:
...    import readline
... except ImportError:
...    print("Module readline not available.")
... else:
...    import rlcompleter
...    readline.parse_and_bind("tab: complete")

之後,我們應該啟用此功能。現在,要匯入其餘的庫,我們只需執行以下操作:

>>> from web3 import Web3
>>> import json

然後我們準備將Python連線到我們已經執行過的節點,我猜想。否則,我們從以下開始:

$ sudo service rsk start

連線物件按以下方式例項化:

>>> web3 = Web3(Web3.HTTPProvider("http://MACHINE:PORT"))

其中MACHINEPORT是我們在node.conf檔案中指定的IP,名稱和埠。預設情況下,它是localhost:4444

為了測試一切是否成功,我們檢查Python直譯器中的塊編號,如下所示:

>>> web3.eth.blockNumber

現在,我們繼續部署合約。

使用Web3.py部署ERC20合約

我們將基於OpenZeppelin庫部署ERC20令牌合約。為了與我以前的文章保持一致,我像以前一樣重新命名這兩個帳戶,輸入:

>>> acc0 = web3.eth.accounts[0]
>>> acc1 = web3.eth.accounts[1]

在另一個終端,我們轉到合約程式碼所在的資料夾,然後我們使用Solc編譯它,如下所示:

$ solc CoinFabrikToken.sol --bin --abi --optimize -o Compiled/

Compiled資料夾中,我們不僅找到了合約的ABI和位元組碼,還找到了它的編譯依賴項。然而,我們只需要主合約中的那些。

要將這兩個檔案匯入Python VM,我們可以這樣做:

>>> with open("./Compiled/CoinFabrikToken.abi") as contract_abi_file:
...   contract_abi = json.load(contract_abi_file)
>>> with open("./Compiled/CoinFabrikToken.bin") as contract_bin_file:
...   contract_bytecode = '0x' + contract_bin_file.read()

然後,我們可以建立合約的例項,為它提供ABI和位元組碼:

>>> cfToken = web3.eth.contract(abi=contract_abi, bytecode=contract_bytecode)

之後,我們建立並部署合約輸入:

>>> tx_hash = cfToken.constructor().transact(transaction=tx_args0)

我們儲存交易的雜湊有兩個原因:檢查狀態,地址和更多引數,因為我們可以使用函式waitForTransactionReceipt來知道合約何時被挖掘。

要計算合約的部署地址,我們需要用於部署合約的地址,acc0和交易的nonce。我們有兩個東西,所以我們匯入了幾個庫,然後我們將函式呼叫如下(感謝M. Stolarz的這個發現):

>>> import rlp
>>> from eth_utils import keccak, to_checksum_address

>>> contract_address = to_checksum_address('0x' + keccak(rlp.encode([bytes(bytearray.fromhex(acc0[2:])), web3.eth.getTransaction(tx_hash).nonce]))[-20:].hex())

地址在我們的例項中設定如下:

>>> cfToken = web3.eth.contract(address = contract_address, abi = contract_abi, bytecode = contract_bytecode)

之後,我們的合約將被寫入區塊鏈。

Python的一個功能是我們可以建立所有命令的指令碼,然後像這樣一起執行它們:

>>> exec(open("deploy_cfToken.py").read())

這意味著我們可以像Truffle一樣在一行中部署合約(但知道它的作用!= D)。

我們部署的測試網路Token合約現在為0x7C0c436e1E8dCd270a7A306B5AE8A2996f6A25dD

與合約的互動

在我們部署了代幣之後,應該已經建立了一個例項來輕鬆呼叫它。要呼叫未修改區塊鏈的函式,例如getter,我們會:

>>> cfToken.functions.FUNC_CALL().call()

其中FUNC_CALL是不修改區塊鏈的合約的可呼叫函式。

如果我們想修改區塊鏈(設定值,進行計算等),正確的語法是:

>>> cfToken.functions.FUNC_SET(PARAMETERS).transact(TXARG)

其中FUNC_SET是修改區塊鏈的合約的函式,PARAMETERS是函式採用的值,TXARG是交易的引數,如下所示:

>>> txargs0 = {“from”: acc0 , “gasPrice”: 0, “gas”: 3000000}

我們可以檢查我們名字的變數是否為空:

>>> cfToken.functions.getON().call() // ‘’

因此,和以前一樣,如果我們嘗試修改變數而不是所有者acc1,則交易不成功。

>>> cfToken.functions.setON('Andrés Bachfischer').transact(txargs1)

提示:如果收到內部伺服器錯誤,你的帳戶可能會再次被鎖定。它有一個超時。

因此,如果我們從acc0而不是acc1傳送相同的交易,我們獲得:

>>> cfToken.functions.setON('Andrés Bachfischer').transact(txargs0)

我們看到狀態使我們成功運作。

現在我們將關注代幣的功能,我們檢查我們的帳戶的原始餘額輸入:

>>> web3.fromWei(cfToken.functions.balanceOf(acc0).call(),'ether') // = 1000
>>> web3.fromWei(cfToken.functions.balanceOf(acc1).call(),'ether') // = 0

現在,我們通過執行以下操作從所有者帳戶轉移到我們的第二個帳戶:

>>> cfToken.functions.transfer(acc1, web3.toWei(88.8, 'ether')).transact(txargs0)

我們得到了新的餘額:

>>> web3.fromWei(cfToken.functions.balanceOf(acc0).call(),'ether') // = 911.2
>>> web3.fromWei(cfToken.functions.balanceOf(acc1).call(),'ether') // = 88.8

繼續下一個函式,我們檢查acc0沒有allowance給acc1的餘量:

>>> web3.fromWei(cfToken.functions.allowance(acc1, acc0).call(txargs0),'ether') // = 0

因此,要從acc1向acc0授予10個代幣限制,你必須執行以下操作:

>>> cfToken.functions.approve(acc0, web3.toWei(10,'ether')).transact(txargs1)

我們代表acc1花費:

>>> cfToken.functions.transferFrom(acc1, acc0, web3.toWei(5,'ether')).transact(txargs0)

我們看到交易成功,正如預期的那樣。

最後,我們向合約傳送一個交易而不呼叫任何函式,這將啟用回退函式(預設行為):

將警告我們錯了或者該函式不存在。

結論

要新增到上一篇文章的成就,在本教程中我們將學習如何:

  • 設定合適的開發人員虛擬環境,
  • 安裝Solc編譯器,
  • 用Solc編譯我們的合約,
  • 安裝和配置Python包,
  • 將Python連線到我們的節點,
  • 使用Python將已編譯的合約部署到Test網路,
  • 使用Python與合約互動,
  • 編寫自動Python指令碼以載入已編譯的合約並進行部署。

我們看到兩種工具的語法都很相似。truffle更容易從頭開始使用,因為將合約程式碼放入Solidity足以使其可以從套件中部署。通過兩個簡單的命令,你的智慧合約即可開始使用。但是因為我們在傳送交易時遇到使用Truffle套件的問題,所以需要進行更改。

在撰寫本文時,Web3.py實現對於開發人員來說更好。它不僅從Truffle帳戶中檢索資金,而且還有更新版本的Web3,並允許執行特別的指令碼。truffle的執行有時可能比必要的複雜。是的,也許你需要從一開始就設定更多的包和庫,而不是考慮需要自己編譯程式碼,但從長遠來看,在我看來,這個工具比Truffle能更穩定地開發合約。

安利個以太坊區塊鏈相關的互動式線上程式設計實戰教程:

python以太坊,主要是針對python工程師使用web3.py進行區塊鏈以太坊開發的詳解。

這裡是原文Python使用Web3.py進行ERC20代幣開發

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章