在上一篇文章中,我展示了如何為RSK Mainnet編寫Solidity ERC20代幣妆档,如何導(dǎo)入和使用OpenZeppelin庫和合約,以及如何使用Truffle來部署和交互我們的智能合約。
雖然我們使用Truffle成功完成了我們的任務(wù)并實(shí)現(xiàn)了我們的目標(biāo)戳寸,但最終這個(gè)套件在你發(fā)送交易兜畸,部署或管理帳戶時(shí)還是可能會出現(xiàn)一些問題努释。在我們的案例中,在遵循之前的文章說明時(shí)咬摇,我在使用Truffle管理新創(chuàng)建的帳戶和發(fā)送交易時(shí)就遇到了一些問題伐蒂。
我遇到的第一個(gè)問題是凍結(jié)了SBTC的部分資金,RSK Labs團(tuán)隊(duì)讓我測試了Mainnet(感謝Maximiliano)肛鹏。雖然我已經(jīng)解鎖了帳戶逸邦,但節(jié)點(diǎn)仍然問我創(chuàng)建的帳戶的私鑰(正如我們在第一篇文章中看到的):
truffle(rsk)> web3.personal.newAccount(‘somePassword’)
truffle(rsk)> web3.personal.unlockAccount(web3.eth.accounts[0],'somePassword')
出于這個(gè)原因,為了保留我的少數(shù)SBTC的安全性在扰,我在合約中添加了銷毀功能缕减,以防萬一出現(xiàn)問題。
當(dāng)我嘗試與已部署的合約進(jìn)行交互時(shí)芒珠,出現(xiàn)了第二個(gè)問題烛卧。在發(fā)送交易時(shí),Truffle將其主體發(fā)送到具有數(shù)據(jù)和其余參數(shù)的節(jié)點(diǎn)(正如我在rsk.log文件中看到的那樣)。但是总放,在20分鐘之后呈宇,交易從未包含在任何塊中,并且節(jié)點(diǎn)也沒有收據(jù)或其哈希值局雄。
我解決這個(gè)問題的方法是通過node.conf
文件中配置cors
參數(shù)甥啄,以允許Metamask連接到節(jié)點(diǎn)。然后炬搭,通過將有問題的函數(shù)及其參數(shù)編碼為十六進(jìn)制字符串并輸入數(shù)據(jù)字段來發(fā)送交易蜈漓。在使用與Truffle發(fā)送的交易相同的nonce
值發(fā)送后,它最終被包含在內(nèi)宫盔。
不要誤會我的意思融虽,Truffle套件對于開發(fā)人員來說是一個(gè)很好的工具,但是如果你在開發(fā)智能合約時(shí)不時(shí)遇到一些問題灼芭,請保持專注并繼續(xù)閱讀有额。
我將在這里討論的工具是Web3的Python版本:Web3.py。
介紹
由于rskj
的行為就像以太坊節(jié)點(diǎn)(即它提供了相同的JSON-RPC API)彼绷,我們可以使用其他實(shí)現(xiàn)來與之交互巍佑。最受歡迎的Web3版本是用JavaScript(Web3.js)編寫的版本。但自11月以來寄悯,Web3.py項(xiàng)目的更新率更高萤衰,大大提高了其可用性。此版本還允許比Web3.js更友好的交互體驗(yàn)猜旬。
在本文中脆栋,我們將討論上一篇文章中使用的相同ERC20代幣合約的部署和交互,以比較兩種工具的可用性洒擦。
從rskj 4.2開始筹吐,RSK Testnet重新上線。出于這個(gè)原因秘遏,并且因?yàn)槲覀冎盁o法使用它丘薛,我們將在本文的網(wǎng)絡(luò)上部署和測試我們的合約。
改為Python
Web3.py是用Python3編寫的邦危。如果你之前從未使用過Python洋侨,那么你可能需要一些軟件包。否則倦蚪,當(dāng)我們在我們的環(huán)境中安裝Web3.py時(shí)希坚,將在編譯期間出錯。我們安裝它們:
$ sudo apt-get install gcc
$ sudo apt-get install python3-dev
設(shè)置環(huán)境
我們希望將Web3.py
的實(shí)例與其他個(gè)人Python模塊分開陵且。為此裁僧,我們需要創(chuàng)建一個(gè)Python的虛擬環(huán)境:
$ sudo apt install virtualenv
$ virtualenv -p python3~ / web3_py
然后个束,我們使用以下命令激活實(shí)例:
$ source web3_py/bin/activate
在終端中,我們應(yīng)該能夠看到命令提示符:
(web3_py) user@computer:~$
這意味著我們的Python虛擬環(huán)境現(xiàn)在處于活動狀態(tài)×钠#現(xiàn)在茬底,我們將安裝項(xiàng)目的庫:
(web3_py) user@computer:~$ pip install web3
你不應(yīng)該看到任何錯誤。
為了改善解釋器的外觀获洲,我建議安裝IPython
(不阱表,不是從App Store):
(web3_py) user@computer:~$ pip install ipython
如果我們想休息并退出虛擬環(huán)境,我們可以這樣做:
(web3_py) user@computer:~$ deactivate
我們將使用測試網(wǎng)絡(luò)來部署我們的合約贡珊,所以請隨時(shí)再次檢查我們已經(jīng)討論過如何更改網(wǎng)絡(luò)的第一篇文章(并自行更改最爬!:))。
現(xiàn)在门岔,我們有一個(gè)合適的環(huán)境來啟動我們的腳本爱致。
安裝SOLC
編譯我們的.sol
(Solidity合約代碼)不是Python的工作。這是我們的Solidity
編譯器的一項(xiàng)任務(wù):Solc
寒随。要安裝它的最新穩(wěn)定版本糠悯,我們這樣做:
$ sudo add-apt-repository ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install solc
有了這個(gè),我們應(yīng)該能夠像這樣編譯我們的合約:
$ solc <contract>.sol --bin --abi --optimize -o <output-dir>/
其中<contract>.sol
是Solidity代碼文件牢裳,<output-dir>
是我們構(gòu)建的ABI和字節(jié)碼文件的位置逢防。
啟動安裝程序
一旦我們從虛擬環(huán)境中打開Python叶沛,我們就需要導(dǎo)入Web3和Json等庫蒲讯,但在此之前,必須注意一個(gè)問題灰署。在某些情況下判帮,即使使用Python3,使用雙TAB的自動完成功能也不起作用溉箕。要解決此問題晦墙,需要導(dǎo)入一些庫,執(zhí)行以下操作:
>>> try:
... import readline
... except ImportError:
... print("Module readline not available.")
... else:
... import rlcompleter
... readline.parse_and_bind("tab: complete")
之后肴茄,我們應(yīng)該激活此功能∩纬現(xiàn)在,要導(dǎo)入其余的庫寡痰,我們只需執(zhí)行以下操作:
>>> from web3 import Web3
>>> import json
然后我們準(zhǔn)備將Python連接到我們已經(jīng)運(yùn)行過的節(jié)點(diǎn)抗楔,我猜想。否則拦坠,我們從以下開始:
$ sudo service rsk start
連接對象按以下方式實(shí)例化:
>>> web3 = Web3(Web3.HTTPProvider("http://MACHINE:PORT"))
其中MACHINE
和PORT
是我們在node.conf
文件中指定的IP连躏,名稱和端口。默認(rèn)情況下贞滨,它是localhost:4444
入热。
為了測試一切是否成功,我們檢查Python解釋器中的塊編號,如下所示:
>>> web3.eth.blockNumber
現(xiàn)在勺良,我們繼續(xù)部署合約绰播。
使用Web3.py部署ERC20合約
我們將基于OpenZeppelin庫部署ERC20令牌合約。為了與我以前的文章保持一致郑气,我像以前一樣重命名這兩個(gè)帳戶幅垮,輸入:
>>> acc0 = web3.eth.accounts[0]
>>> acc1 = web3.eth.accounts[1]
在另一個(gè)終端,我們轉(zhuǎn)到合約代碼所在的文件夾尾组,然后我們使用Solc
編譯它忙芒,如下所示:
$ solc CoinFabrikToken.sol --bin --abi --optimize -o Compiled/
在Compiled
文件夾中,我們不僅找到了合約的ABI和字節(jié)碼讳侨,還找到了它的編譯依賴項(xiàng)呵萨。然而,我們只需要主合約中的那些跨跨。
要將這兩個(gè)文件導(dǎo)入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()
然后,我們可以創(chuàng)建合約的實(shí)例勇婴,為它提供ABI和字節(jié)碼:
>>> cfToken = web3.eth.contract(abi=contract_abi, bytecode=contract_bytecode)
之后忱嘹,我們創(chuàng)建并部署合約輸入:
>>> tx_hash = cfToken.constructor().transact(transaction=tx_args0)
我們保存交易的哈希有兩個(gè)原因:檢查狀態(tài),地址和更多參數(shù)耕渴,因?yàn)槲覀兛梢允褂煤瘮?shù)waitForTransactionReceipt
來知道合約何時(shí)被挖掘拘悦。
要計(jì)算合約的部署地址,我們需要用于部署合約的地址橱脸,acc0
和交易的nonce
础米。我們有兩個(gè)東西,所以我們導(dǎo)入了幾個(gè)庫添诉,然后我們將函數(shù)調(diào)用如下(感謝M. Stolarz的這個(gè)發(fā)現(xiàn)):
>>> 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())
地址在我們的實(shí)例中設(shè)置如下:
>>> cfToken = web3.eth.contract(address = contract_address, abi = contract_abi, bytecode = contract_bytecode)
之后屁桑,我們的合約將被寫入?yún)^(qū)塊鏈。
Python的一個(gè)功能是我們可以創(chuàng)建所有命令的腳本栏赴,然后像這樣一起執(zhí)行它們:
>>> exec(open("deploy_cfToken.py").read())
這意味著我們可以像Truffle一樣在一行中部署合約(但知道它的作用蘑斧!= D)。
我們部署的測試網(wǎng)絡(luò)Token合約現(xiàn)在為0x7C0c436e1E8dCd270a7A306B5AE8A2996f6A25dD
须眷。
與合約的互動
在我們部署了代幣之后竖瘾,應(yīng)該已經(jīng)創(chuàng)建了一個(gè)實(shí)例來輕松調(diào)用它。要調(diào)用未修改區(qū)塊鏈的函數(shù)柒爸,例如getter准浴,我們會:
>>> cfToken.functions.FUNC_CALL().call()
其中FUNC_CALL
是不修改區(qū)塊鏈的合約的可調(diào)用函數(shù)。
如果我們想修改區(qū)塊鏈(設(shè)置值捎稚,進(jìn)行計(jì)算等)乐横,正確的語法是:
>>> cfToken.functions.FUNC_SET(PARAMETERS).transact(TXARG)
其中FUNC_SET
是修改區(qū)塊鏈的合約的函數(shù)求橄,PARAMETERS
是函數(shù)采用的值,TXARG
是交易的參數(shù)葡公,如下所示:
>>> txargs0 = {“from”: acc0 , “gasPrice”: 0, “gas”: 3000000}
我們可以檢查我們名字的變量是否為空:
>>> cfToken.functions.getON().call() // ‘’
因此罐农,和以前一樣,如果我們嘗試修改變量而不是所有者acc1
催什,則交易不成功涵亏。
>>> cfToken.functions.setON('Andrés Bachfischer').transact(txargs1)
提示:如果收到內(nèi)部服務(wù)器錯誤,你的帳戶可能會再次被鎖定蒲凶。它有一個(gè)超時(shí)气筋。
因此,如果我們從acc0而不是acc1發(fā)送相同的交易旋圆,我們獲得:
>>> cfToken.functions.setON('Andrés Bachfischer').transact(txargs0)
我們看到狀態(tài)使我們成功運(yùn)作宠默。
現(xiàn)在我們將關(guān)注代幣的功能,我們檢查我們的帳戶的原始余額輸入:
>>> web3.fromWei(cfToken.functions.balanceOf(acc0).call(),'ether') // = 1000
>>> web3.fromWei(cfToken.functions.balanceOf(acc1).call(),'ether') // = 0
現(xiàn)在灵巧,我們通過執(zhí)行以下操作從所有者帳戶轉(zhuǎn)移到我們的第二個(gè)帳戶:
>>> 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
繼續(xù)下一個(gè)函數(shù)搀矫,我們檢查acc0沒有allowance給acc1的余量:
>>> web3.fromWei(cfToken.functions.allowance(acc1, acc0).call(txargs0),'ether') // = 0
因此,要從acc1向acc0授予10個(gè)代幣限制刻肄,你必須執(zhí)行以下操作:
>>> cfToken.functions.approve(acc0, web3.toWei(10,'ether')).transact(txargs1)
我們代表acc1花費(fèi):
>>> cfToken.functions.transferFrom(acc1, acc0, web3.toWei(5,'ether')).transact(txargs0)
我們看到交易成功瓤球,正如預(yù)期的那樣。
最后敏弃,我們向合約發(fā)送一個(gè)交易而不調(diào)用任何函數(shù)卦羡,這將激活回退函數(shù)(默認(rèn)行為):
將警告我們錯了或者該函數(shù)不存在。
結(jié)論
要添加到上一篇文章的成就权她,在本教程中我們將學(xué)習(xí)如何:
- 設(shè)置合適的開發(fā)人員虛擬環(huán)境虹茶,
- 安裝Solc編譯器逝薪,
- 用Solc編譯我們的合約隅要,
- 安裝和配置Python包,
- 將Python連接到我們的節(jié)點(diǎn)董济,
- 使用Python將已編譯的合約部署到Test網(wǎng)絡(luò)步清,
- 使用Python與合約交互,
- 編寫自動Python腳本以加載已編譯的合約并進(jìn)行部署虏肾。
我們看到兩種工具的語法都很相似廓啊。truffle更容易從頭開始使用,因?yàn)閷⒑霞s代碼放入Solidity足以使其可以從套件中部署封豪。通過兩個(gè)簡單的命令谴轮,你的智能合約即可開始使用。但是因?yàn)槲覀冊诎l(fā)送交易時(shí)遇到使用Truffle套件的問題吹埠,所以需要進(jìn)行更改第步。
在撰寫本文時(shí)疮装,Web3.py
實(shí)現(xiàn)對于開發(fā)人員來說更好。它不僅從Truffle帳戶中檢索資金粘都,而且還有更新版本的Web3廓推,并允許執(zhí)行特別的腳本。truffle的運(yùn)行有時(shí)可能比必要的復(fù)雜翩隧。是的樊展,也許你需要從一開始就設(shè)置更多的包和庫,而不是考慮需要自己編譯代碼堆生,但從長遠(yuǎn)來看专缠,在我看來,這個(gè)工具比Truffle能更穩(wěn)定地開發(fā)合約淑仆。
======================================================================
分享一些以太坊藤肢、EOS、比特幣等區(qū)塊鏈相關(guān)的交互式在線編程實(shí)戰(zhàn)教程:
- java以太坊開發(fā)教程糯景,主要是針對java和android程序員進(jìn)行區(qū)塊鏈以太坊開發(fā)的web3j詳解嘁圈。
- python以太坊,主要是針對python工程師使用web3.py進(jìn)行區(qū)塊鏈以太坊開發(fā)的詳解蟀淮。
- php以太坊最住,主要是介紹使用php進(jìn)行智能合約開發(fā)交互,進(jìn)行賬號創(chuàng)建怠惶、交易涨缚、轉(zhuǎn)賬、代幣開發(fā)以及過濾器和交易等內(nèi)容策治。
- 以太坊入門教程脓魏,主要介紹智能合約與dapp應(yīng)用開發(fā),適合入門通惫。
- 以太坊開發(fā)進(jìn)階教程茂翔,主要是介紹使用node.js、mongodb履腋、區(qū)塊鏈珊燎、ipfs實(shí)現(xiàn)去中心化電商DApp實(shí)戰(zhàn),適合進(jìn)階遵湖。
- C#以太坊悔政,主要講解如何使用C#開發(fā)基于.Net的以太坊應(yīng)用,包括賬戶管理延旧、狀態(tài)與交易谋国、智能合約開發(fā)與交互、過濾器和交易等迁沫。
- EOS教程芦瘾,本課程幫助你快速入門EOS區(qū)塊鏈去中心化應(yīng)用的開發(fā)闷盔,內(nèi)容涵蓋EOS工具鏈、賬戶與錢包旅急、發(fā)行代幣逢勾、智能合約開發(fā)與部署、使用代碼與智能合約交互等核心知識點(diǎn)藐吮,最后綜合運(yùn)用各知識點(diǎn)完成一個(gè)便簽DApp的開發(fā)溺拱。
- java比特幣開發(fā)教程,本課程面向初學(xué)者谣辞,內(nèi)容即涵蓋比特幣的核心概念迫摔,例如區(qū)塊鏈存儲、去中心化共識機(jī)制泥从、密鑰與腳本句占、交易與UTXO等,同時(shí)也詳細(xì)講解如何在Java代碼中集成比特幣支持功能躯嫉,例如創(chuàng)建地址纱烘、管理錢包、構(gòu)造裸交易等祈餐,是Java工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程擂啥。
- php比特幣開發(fā)教程,本課程面向初學(xué)者帆阳,內(nèi)容即涵蓋比特幣的核心概念哺壶,例如區(qū)塊鏈存儲、去中心化共識機(jī)制蜒谤、密鑰與腳本山宾、交易與UTXO等,同時(shí)也詳細(xì)講解如何在Php代碼中集成比特幣支持功能鳍徽,例如創(chuàng)建地址资锰、管理錢包、構(gòu)造裸交易等旬盯,是Php工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程台妆。
- tendermint區(qū)塊鏈開發(fā)詳解翎猛,本課程適合希望使用tendermint進(jìn)行區(qū)塊鏈開發(fā)的工程師胖翰,課程內(nèi)容即包括tendermint應(yīng)用開發(fā)模型中的核心概念,例如ABCI接口切厘、默克爾樹萨咳、多版本狀態(tài)庫等,也包括代幣發(fā)行等豐富的實(shí)操代碼疫稿,是go語言工程師快速入門區(qū)塊鏈開發(fā)的最佳選擇培他。
匯智網(wǎng)原創(chuàng)翻譯鹃两,轉(zhuǎn)載請標(biāo)明出處。這里是原文Python使用Web3.py進(jìn)行ERC20代幣開發(fā)