在以太坊上獲得一個(gè)基本的智能合約是一個(gè)很簡單的事冒晰,只需google查詢“ERC20代幣教程”同衣,你會(huì)發(fā)現(xiàn)有關(guān)如何做到這一點(diǎn)的大量信息。以編程方式與合約交互完全是另一回事壶运,如果你是一個(gè)Python程序員耐齐,那么教程就很少。所以寫這個(gè)Python中的以太坊智能合約開發(fā)指南蒋情。
按我的統(tǒng)計(jì)對我們來說幸運(yùn)的是埠况,2017年Web3.py的第4版發(fā)布,這意味著現(xiàn)在比以往更容易運(yùn)行python腳本并觀察區(qū)塊鏈上發(fā)生的神奇事情棵癣。像幽靈般的辕翰。
Piper Merriam,Jason Carver以及其他所有在Web3.py上努力工作以使我們其他人生活更輕松的人大聲呼喊狈谊,在Sempo金蜀,我們正在使用以太坊來使災(zāi)難般的響應(yīng)更加透明刷后,而且它是只有Web3.py
才能真正實(shí)現(xiàn)。
設(shè)置
首先我們進(jìn)行設(shè)置渊抄,確保我們安裝了相關(guān)的python庫尝胆。
Python庫無處不在,但它們的用途是什么护桦?
有很多與以太坊相關(guān)的python庫含衔,但是當(dāng)人們談?wù)撘蕴粫r(shí),有兩個(gè)會(huì)出現(xiàn)很多:Web3.py和Pyethereum二庵。乍一看贪染,你應(yīng)該使用哪一個(gè)并不明顯喉刘。
Pyethereum
以太坊虛擬機(jī)(EVM)的Python實(shí)現(xiàn)打毛。反過來甘有,EVM是以太坊協(xié)議的一部分窖张,它實(shí)際運(yùn)行智能合約中的代碼并確定其輸出。因此钠导,如果你想在Python中運(yùn)行以太坊節(jié)點(diǎn)芜抒,那么Pyethereum是一個(gè)很好的起點(diǎn)锅纺。
即使你非常高興在不運(yùn)行自己的節(jié)點(diǎn)的情況下運(yùn)行智能合約攀涵,Pyethereum仍然是一個(gè)很好的庫铣耘,它包含許多功能,可以執(zhí)行有用的功能以故,例如從私鑰計(jì)算用戶的地址等等蜗细。
Web3.py
用于實(shí)際與以太坊區(qū)塊鏈交互的庫。我們談?wù)摰氖虑榘ㄔ谫~戶之間轉(zhuǎn)移以太網(wǎng)怒详,發(fā)布智能合約以及觸發(fā)附加現(xiàn)有智能合約的功能炉媒。它受到流行的JavaScript庫Web3.js的啟發(fā),它將成為我們在本教程中使用的主庫昆烁。
好的吊骤,少說多做!
起初我嘗試使用Python3.5版本善玫,但在運(yùn)行時(shí)我遇到了問題水援,顯然是由Python的類型提示造成的密强∶├桑基于Python3.6創(chuàng)建虛擬環(huán)境解決了這個(gè)問題,所以我建議你做同樣的事情或渤。
繼續(xù)并pip-install web3 (確保你獲得版本4)系冗。
除非你喜歡花錢,否則你需要在以太坊測試網(wǎng)上使用錢包薪鹦,例如Ropsten和其他大量以太玩法掌敬。一個(gè)簡單的方法是下載Chrome的Metamask擴(kuò)展惯豆,并從那里創(chuàng)建一個(gè)新帳戶。
確保你還選擇左側(cè)的'Ropsten Test Net'奔害。
即使你的現(xiàn)有錢包中包含真正的以太幣楷兽,我也強(qiáng)烈建議你為開發(fā)目的創(chuàng)建一個(gè)新的錢包。我們將使用私鑰做一些相對無法預(yù)測的事华临,所以如果它們不小心變成公共主網(wǎng)絡(luò)的話就不會(huì)有問題(公私鑰芯杀?)
為新創(chuàng)建的錢包獲取測試Ether非常簡單:只需訪問faucet.metamask.io并點(diǎn)擊“請求來自faucet的1個(gè) 以太”。對于我們將要做的事情雅潭,這應(yīng)該是充足的揭厚。
最后,因?yàn)槲覀儗⒃跊]有托管我們自己的節(jié)點(diǎn)的情況下使用Ropsten TestNet
扶供,我們需要一個(gè)可以連接Blockchain的供應(yīng)商筛圆。Infura.io適用于此,所以去那里創(chuàng)建一個(gè)免費(fèi)帳戶椿浓。記下Ropsten TestNet的提供者URL(看起來像https://ropsten.infura.io/FE2Gfedcm3tfed3)太援。
部署智能合約
使用Python來部署智能合約而不運(yùn)行自己的節(jié)點(diǎn)是非常困難的,所以我們將在這一步上做點(diǎn)兒手腳轰绵。對于許多智能合約用例粉寞,你只需要執(zhí)行一次。
正如我之前提到的左腔,有關(guān)如何部署ERC20合約的百萬條指南唧垦,因此我們將部署一些不同的(并且更方便地更短)。
問:誰喜歡在互聯(lián)網(wǎng)上分享他們的意見液样?
大家都喜歡振亮?
好答案。以下我稱之為“Soap Box”肥皂盒的智能合約允許任何人向區(qū)塊鏈廣播他們想要的任何意見鞭莽,在永恒的剩余時(shí)間(給予或接受)可以看到它坊秸。
但是有一個(gè)問題:只有支付了必要的0.02以太網(wǎng)費(fèi)用的地址才能播出他們的意見。聽起來不太公平澎怒,但就這樣褒搔。
Remix,以太坊的在線代碼編輯器非常出色喷面,因此在那里創(chuàng)建一個(gè)新文件并粘貼以下代碼星瘾。它是用Solidity(Smart Contracts的編程語言)編寫的。如果代碼沒有太多意義并不重要惧辈,我們將在稍后詳細(xì)介紹相關(guān)部分琳状,但最終這是一個(gè)Python教程。
pragma solidity ^0.4.0;
contract SoapBox {
// Our 'dict' of addresses that are approved to share opinions
//我們批準(zhǔn)分享意見的地址的“字典”
mapping (address => bool) approvedSoapboxer;
string opinion;
// Our event to announce an opinion on the blockchain
//我們的事件發(fā)布對區(qū)塊鏈的意見
event OpinionBroadcast(address _soapboxer, string _opinion);
// This is a constructor function, so its name has to match the contract
//這是一個(gè)構(gòu)造函數(shù)盒齿,所以它的名字必須與合約相匹配
function SoapBox() public {
}
// Because this function is 'payable' it will be called when ether is sent to the contract address.
//因?yàn)檫@個(gè)函數(shù)是“支付”念逞,所以當(dāng)以太網(wǎng)被發(fā)送到合約地址時(shí)將被調(diào)用困食。
function() public payable{
// msg is a special variable that contains information about the transaction
// msg是一個(gè)特殊變量,包含有關(guān)交易的信息
if (msg.value > 20000000000000000) {
//if the value sent greater than 0.02 ether (in Wei)
//如果發(fā)送的值大于0.02 ether(在Wei中)
// then add the sender's address to approvedSoapboxer
//然后將發(fā)件人的地址添加到approvedSoapboxer
approvedSoapboxer[msg.sender] = true;
}
}
// Our read-only function that checks whether the specified address is approved to post opinions.
//我們的只讀函數(shù)翎承,用于檢查指定地址是否被批準(zhǔn)發(fā)布意見硕盹。
function isApproved(address _soapboxer) public view returns (bool approved) {
return approvedSoapboxer[_soapboxer];
}
// Read-only function that returns the current opinion
//返回當(dāng)前意見的只讀函數(shù)
function getCurrentOpinion() public view returns(string) {
return opinion;
}
//Our function that modifies the state on the blockchain
//我們的函數(shù)修改了區(qū)塊鏈上的狀態(tài)
function broadcastOpinion(string _opinion) public returns (bool success) {
// Looking up the address of the sender will return false if the sender isn't approved
//如果發(fā)件人未獲批準(zhǔn),查找發(fā)件人的地址將返回false
if (approvedSoapboxer[msg.sender]) {
opinion = _opinion;
emit OpinionBroadcast(msg.sender, opinion);
return true;
} else {
return false;
}
}
}
以下是Metamask變得非常有用的地方:如果你點(diǎn)擊重新混音窗口右上角的“run”運(yùn)行標(biāo)簽并在“Environment”環(huán)境下拉列表中選擇“Injected Web3”注入的Web3叨咖,則“Account”帳戶下拉列表中應(yīng)填充你的帳戶地址早在MetaMask中創(chuàng)建莱睁。如果沒有,只需刷新瀏覽器即可芒澜。
然后單擊“create”創(chuàng)建仰剿。Metamask應(yīng)該彈出一個(gè)彈出窗口,要求你確認(rèn)交易痴晦。如果沒有南吮,只需打開Metamask擴(kuò)展并在那里執(zhí)行:
你將在Remix控制臺底部收到一條消息,告知你合約的創(chuàng)建正在等待處理誊酌。單擊鏈接以在Etherscan上查看其狀態(tài)部凑。如果刷新并且“To”收件人字段填充了合約地址,則合約已成功部署碧浊。
一旦你記下了合約地址涂邀,我們就該開始通過Web3.py與合約進(jìn)行交互了。
在我看來箱锐,有四種(半)方式可以與以太坊智能合約進(jìn)行互動(dòng)比勉。最后兩個(gè)(一半)經(jīng)常混在一起驹止,但差異很重要浩聋。我們已經(jīng)看到了第一個(gè):在區(qū)塊鏈上部署智能合約。現(xiàn)在我們將介紹其余的python:
- 向合約發(fā)送以太:真正自我解釋臊恋,將以太幣從錢包發(fā)送到智能合約的地址衣洁。希望換取有用的東西。
- 調(diào)用函數(shù):執(zhí)行智能合約的只讀功能以獲取某些信息(例如地址的余額)抖仅。
- 與功能進(jìn)行交易:執(zhí)行智能合約的功能坊夫,該功能可以更改區(qū)塊鏈的狀態(tài)。
- 查看事件:查看由于先前的功能交易而發(fā)布到區(qū)塊鏈的信息撤卢。
將以太幣發(fā)送給合約
一些(但不是全部)智能合約包括“payable”應(yīng)付功能环凿。如果你將Ether發(fā)送到合約的地址,則會(huì)觸發(fā)這些功能凸丸。一個(gè)典型的用例就是ICO:將以太送到合約中拷邢,然后返回給你的是代幣袱院。
首先屎慢,我們將從導(dǎo)入開始瞭稼,創(chuàng)建一個(gè)新的web3對象,通過Infura.io連接到Ropsten TestNet腻惠。
import time
from web3 import Web3, HTTPProvider
contract_address = [YOUR CONTRACT ADDRESS]
wallet_private_key = [YOUR TEST WALLET PRIVATE KEY]
wallet_address = [YOUR WALLET ADDRESS]
w3 = Web3(HTTPProvider([YOUR INFURA URL]))
w3.eth.enable_unaudited_features()
你可以在Metamask中的帳戶名稱旁邊的菜單中找到你的錢包私鑰环肘。因?yàn)槲覀兪褂玫腤eb3.py的某些功能尚未經(jīng)過完全審核以確保安全性,所以我們需要調(diào)用w3.eth.enable_unaudited_features()
來確認(rèn)我們知道可能會(huì)發(fā)生問題的情況集灌。我告訴過你我們用私鑰做了一些危險(xiǎn)的事情悔雹!
現(xiàn)在我們將編寫一個(gè)函數(shù),將以太幣從我們的錢包發(fā)送到合約:
def send_ether_to_contract(amount_in_ether):
amount_in_wei = w3.toWei(amount_in_ether,'ether');
nonce = w3.eth.getTransactionCount(wallet_address)
txn_dict = {
'to': contract_address,
'value': amount_in_wei,
'gas': 2000000,
'gasPrice': w3.toWei('40', 'gwei'),
'nonce': nonce,
'chainId': 3
}
signed_txn = w3.eth.account.signTransaction(txn_dict, wallet_private_key)
txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
txn_receipt = None
count = 0
while txn_receipt is None and (count < 30):
txn_receipt = w3.eth.getTransactionReceipt(txn_hash)
print(txn_receipt)
time.sleep(10)
if txn_receipt is None:
return {'status': 'failed', 'error': 'timeout'}
return {'status': 'added', 'txn_receipt': txn_receipt}
首先讓我們回顧一下交易字典txn_dict
:它包含了定義我們發(fā)送給智能合約的交易所需的大部分信息欣喧。
-
to
:我們將以太送到哪里(在這種情況下是智能合約)腌零。 -
Vaule
:我們送多少錢單位wei。 -
gas
:gas是衡量在以太坊上執(zhí)行交易的計(jì)算工作量度唆阿。在這種情況下益涧,我們指定了我們愿意執(zhí)行此交易的天然氣量的上限。 -
gasPrice
:我們愿意為每單位gas支付多少錢(以wei為單位)驯鳖。 -
Nonce
:這是一個(gè)地址nonce而不是更常見的工作證明闲询。它只是發(fā)送地址所做的先前交易次數(shù)的計(jì)數(shù),用于防止雙重花費(fèi)浅辙。 -
Chain ID
:每個(gè)以太坊網(wǎng)絡(luò)都有自己的鏈ID:主網(wǎng)的ID為1扭弧,而Ropsten為3。你可以在這里找到更長的列表记舆。
關(guān)于gas限制的快速說明:有一些功能可以讓你估算交易將使用多少gas鸽捻。但是,我發(fā)現(xiàn)選擇限制的最佳方法是計(jì)算出你愿意支付多少錢泽腮,然后再讓交易失敗泊愧,然后再去做。
一旦我們定義了交易的重要部分盛正,我們就會(huì)使用我們錢包的私鑰對其進(jìn)行簽名删咱。然后它就可以發(fā)送到網(wǎng)絡(luò)了,我們將使用sendRawTransaction
方法豪筝。
在礦工決定將其包含在一個(gè)區(qū)塊中之前痰滋,我們的交易實(shí)際上不會(huì)完成。一般而言续崖,你為每個(gè)單位支付的費(fèi)用Gas(記住我們的天然氣價(jià)格參數(shù))決定了一個(gè)節(jié)點(diǎn)決定將你的交易包含在一個(gè)區(qū)塊中的速度(如果有的話)敲街。
https://ethgasstation.info/是一個(gè)很好的地方,可以確定你將等待你的交易包含在一個(gè)區(qū)塊中的時(shí)間严望。
此時(shí)間延遲意味著交易是異步的多艇。當(dāng)我們調(diào)用sendRawTransaction時(shí),我們會(huì)立即獲得交易的唯一哈希值像吻。你可以隨時(shí)使用此哈希來查詢你的交易是否已包含在塊中峻黍。我們知道复隆,當(dāng)且僅當(dāng)我們能夠獲得交易收據(jù)時(shí)才將交易添加到區(qū)塊鏈中(因?yàn)樗泻玫馁徺I都帶有收據(jù)嗎?)姆涩。這就是為什么我們創(chuàng)建循環(huán)來定期檢查我們是否有收據(jù):
txn_receipt = None
count = 0
while txn_receipt is None and (count < 30):
txn_receipt = w3.eth.getTransactionReceipt(txn_hash)
print(txn_receipt)
time.sleep(10)
值得注意的是挽拂,交易可以添加到區(qū)塊鏈中,但仍然因各種原因而失敗骨饿,例如沒有足夠的gas亏栈。
這就是將以太符號發(fā)送給合約的Python代碼。讓我們快速回顧一下我們在Solidity中寫的應(yīng)付函數(shù):
function() public payable{
if (msg.value >= 20000000000000000) {
approvedSoapboxer[msg.sender] = true;
}
}
Msg是智能合約中的一個(gè)特殊變量宏赘,其中包含有關(guān)發(fā)送到智能合約的交易的信息绒北。在這種情況下,我們使用msg.value
察署,它給出了交易中發(fā)送的Ether數(shù)量(在Wei而不是raw Ether中)镇饮。同樣,msg.sender
給出了進(jìn)行交易的錢包的地址:如果已經(jīng)發(fā)送了足夠的以太幣箕母,我們會(huì)將其添加到已批準(zhǔn)帳戶的字典中储藐。
繼續(xù)運(yùn)行send_ether_to_contract
函數(shù)。希望你能收到回執(zhí)嘶是。你還可以通過在Etherscan的Ropsten Network部分查找你的錢包地址來檢查交易是否完成钙勃。我們將在下一節(jié)中獲得Python中的更多信息。
調(diào)用一個(gè)函數(shù)
我們剛剛向我們的智能合約發(fā)送了一些以太幣聂喇,因此我們想檢查我們的錢包地址是否已被批準(zhǔn)分享意見是有意義的辖源。為此,我們在智能合約中定義了以下功能:
function isApproved(address _soapboxer) public view returns (bool approved) {
return approvedSoapboxer[_soapboxer];
}
與python相比希太,這個(gè)函數(shù)附帶了很多額外的東西克饶,比如聲明類型(地址和bool)。盡管如此誊辉,這個(gè)函數(shù)只需要一個(gè)地址(_soapboxer參數(shù))矾湃,在有效(但不完全)的哈希表/python dict中查找相應(yīng)的批準(zhǔn)布爾值并返回該值。
你調(diào)用的時(shí)候一個(gè)智能合約函數(shù)堕澄,以太坊節(jié)點(diǎn)將計(jì)算結(jié)果邀跃,并將其返回給你。這里的事情變得有點(diǎn)復(fù)雜:調(diào)用是只讀的蛙紫,這意味著它們不會(huì)對區(qū)塊鏈進(jìn)行任何更改拍屑。如果上述函數(shù)包含一行代碼來記錄數(shù)字時(shí)間,則檢查地址是否已批準(zhǔn):
approvedCheckedCount[_soapboxer] = approvedCheckedCount[_soapboxer] + 1
然后坑傅,當(dāng)調(diào)用該函數(shù)時(shí)僵驰,該節(jié)點(diǎn)將計(jì)算approvedCheckedCount
的新值,但一旦返回結(jié)果就丟棄它。
作為只讀的交換蒜茴,函數(shù)調(diào)用不會(huì)花費(fèi)你運(yùn)行任何以太星爪,因此你可以愉快地檢查帳戶是否已被批準(zhǔn)而不必?fù)?dān)心成本。
讓我們跳回到我們的python文件的頂部并添加一些更多的設(shè)置代碼矮男。
import contract_abi
contract = w3.eth.contract(address = contract_address, abi = contract_abi.abi)
你需要?jiǎng)?chuàng)建另一個(gè)名為contract_abi
的python文件。這將包含一個(gè)大的JSON信息字符串室谚,Python需要與我們在智能合約中定義的函數(shù)進(jìn)行交互毡鉴,稱為應(yīng)用程序二進(jìn)制接口(ABI)。你可以在Remix中找到智能合約的ABI的JSON字符串:
- 單擊編譯“Compile”選項(xiàng)卡秒赤。
- 單擊詳細(xì)信息“Details”——應(yīng)顯示包含大量信息的模式猪瞬。
- 向下滾動(dòng)到ABI部分,然后單擊復(fù)制到剪貼板“Copy to clipboard”圖標(biāo)入篮。
將復(fù)制的字符串粘貼到contract_abi.py
文件中陈瘦,該文件應(yīng)如下所示:
abi = """[
{
A BIG LIST OF ABI INFO SPREAD ACROSS MULTIPLE DICTS
}
]""
我們添加到主python文件的另一行現(xiàn)在使用此ABI JSON字符串并使用它來設(shè)置合約對象。如果你瀏覽合約潮售,你會(huì)注意到它包含一個(gè)函數(shù)屬性痊项,其中包含我們在智能合約中創(chuàng)建的三個(gè)函數(shù)。
現(xiàn)在我們將創(chuàng)建一個(gè)python函數(shù)酥诽,該函數(shù)調(diào)用Smart Contract
智能合約的isApproved
函數(shù)來檢查指定的地址是否被批準(zhǔn)分享意見鞍泉。
def check_whether_address_is_approved(address):
return contract.functions.isApproved(address).call()
那很短暫。
你現(xiàn)在可以使用它來檢查你的錢包地址是否已獲批準(zhǔn)肮帐。如果你之前運(yùn)行了send_ether_to_contract
函數(shù)并發(fā)送了足夠數(shù)量的以太咖驮,那么希望你能回到true
。
與函數(shù)交易
我們正在與智能合約進(jìn)行最后的主要互動(dòng):廣播意見训枢。再一次托修,我們來看看我們的Solidity Code:
function broadcastOpinion(string _opinion) public returns (bool success) {
if (approvedSoapboxer[msg.sender]) {
opinion = _opinion;
emit OpinionBroadcast(msg.sender, opinion);
return true;
} else {
return false;
}
}
這里沒有什么新東西:我們采用傳入的_opinion
參數(shù)并使用它來設(shè)置全局變量意見。(如果你愿意恒界,可以通過getter函數(shù)查詢實(shí)習(xí)生)睦刃。有一條線有點(diǎn)不同:
emit OpinionBroadcast(msg.sender, opinion)
我們很快就會(huì)介紹。
當(dāng)你通過交易與智能合約的功能進(jìn)行交互時(shí)十酣,功能對智能合約狀態(tài)所做的任何更改都會(huì)在區(qū)塊鏈上發(fā)布眯勾。為了換取這種特權(quán),你必須向礦工支付一些(希望很衅攀摹)的以太量吃环。Python時(shí)間:
def broadcast_an_opinion(covfefe):
nonce = w3.eth.getTransactionCount(wallet_address)
txn_dict = contract.functions.broadcastOpinion(covfefe).buildTransaction({
'chainId': 3,
'gas': 140000,
'gasPrice': w3.toWei('40', 'gwei'),
'nonce': nonce,
})
signed_txn = w3.eth.account.signTransaction(txn_dict, private_key=wallet_private_key)
result = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
tx_receipt = w3.eth.getTransactionReceipt(result)
count = 0
while tx_receipt is None and (count < 30):
time.sleep(10)
tx_receipt = w3.eth.getTransactionReceipt(result)
print(tx_receipt)
if tx_receipt is None:
return {'status': 'failed', 'error': 'timeout'}
processed_receipt = contract.events.OpinionBroadcast().processReceipt(tx_receipt)
print(processed_receipt)
output = "Address {} broadcasted the opinion: {}"\
.format(processed_receipt[0].args._soapboxer, processed_receipt[0].args._opinion)
print(output)
return {'status': 'added', 'processed_receipt': processed_receipt}
這實(shí)際上與將Ether發(fā)送到智能合約時(shí)使用的過程相同。我們將創(chuàng)建并簽署一個(gè)交易洋幻,然后將其發(fā)送到網(wǎng)絡(luò)郁轻。再一次,交易是異步的,這意味著無論函數(shù)被告知在Solidity代碼中返回什么好唯,你實(shí)際得到的東西總是交易的哈希竭沫。
鑒于交易本身并沒有返回任何有用的信息,我們需要其他東西骑篙。這導(dǎo)致我們采用最后(半)方式與智能合約進(jìn)行互動(dòng)蜕提。
事件events
我將事件稱為與智能合約交互的“一半”方式,因?yàn)閺募夹g(shù)上講靶端,它們是由交易發(fā)出的谎势。 事件是智能合約以易于閱讀的形式在區(qū)塊鏈上記錄事物的方式,它們基本上只是一組可以使用特定交易的收據(jù)查找的值杨名。我們在智能合約的最頂層定義了一個(gè):
event OpinionBroadcast(address _soapboxer, string _opinion);
然后脏榆,當(dāng)我們使用broadcastOpinion函數(shù)時(shí),我們使用它向區(qū)塊鏈發(fā)出信息台谍。
將交易添加到塊后须喂,你可以使用交易哈希查詢區(qū)塊鏈以查找OpinionBroadcast
事件發(fā)出的特定值。這是我們在函數(shù)broadcast_an_opinion
中的最后一點(diǎn)python代碼趁蕊。你會(huì)注意到我們要求事件發(fā)出的信息存儲(chǔ)在'args'屬性中坞生。
這個(gè)事件非常公開。實(shí)際上掷伙,任何人都可以輕松使用Etherscan或類似工具來查看智能合約發(fā)出的所有事件的日志恨胚。
Etherscan會(huì)自動(dòng)檢測“Transfer”轉(zhuǎn)移事件并列出所有事件。Nifty
如果你已經(jīng)做到這一點(diǎn)炎咖,你就有權(quán)發(fā)表意見赃泡。繼續(xù)用你選擇的意見運(yùn)行broadcast_an_opinion
。
如果一切順利進(jìn)行乘盼,你應(yīng)該很快就會(huì)收到已處理的收據(jù)升熊,以及已放入?yún)^(qū)塊鏈的OpinionBroadcast
事件的打印輸出。
Nice绸栅。
這是完整的python代碼:
import time
from web3 import Web3, HTTPProvider
contract_address = [YOUR CONTRACT ADDRESS]
wallet_private_key = [YOUR TEST WALLET PRIVATE KEY]
wallet_address = [YOUR WALLET ADDRESS]
w3 = Web3(HTTPProvider([YOUR INFURA URL]))
w3.eth.enable_unaudited_features()
contract = w3.eth.contract(address = contract_address, abi = contract_abi.abi)
def send_ether_to_contract(amount_in_ether):
amount_in_wei = w3.toWei(amount_in_ether,'ether');
nonce = w3.eth.getTransactionCount(wallet_address)
txn_dict = {
'to': contract_address,
'value': amount_in_wei,
'gas': 2000000,
'gasPrice': w3.toWei('40', 'gwei'),
'nonce': nonce,
'chainId': 3
}
signed_txn = w3.eth.account.signTransaction(txn_dict, wallet_private_key)
txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
txn_receipt = None
count = 0
while txn_receipt is None and (count < 30):
txn_receipt = w3.eth.getTransactionReceipt(txn_hash)
print(txn_receipt)
time.sleep(10)
if txn_receipt is None:
return {'status': 'failed', 'error': 'timeout'}
return {'status': 'added', 'txn_receipt': txn_receipt}
def check_whether_address_is_approved(address):
return contract.functions.isApproved(address).call()
def broadcast_an_opinion(covfefe):
nonce = w3.eth.getTransactionCount(wallet_address)
txn_dict = contract.functions.broadcastOpinion(covfefe).buildTransaction({
'chainId': 3,
'gas': 140000,
'gasPrice': w3.toWei('40', 'gwei'),
'nonce': nonce,
})
signed_txn = w3.eth.account.signTransaction(txn_dict, private_key=wallet_private_key)
result = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
tx_receipt = w3.eth.getTransactionReceipt(result)
count = 0
while tx_receipt is None and (count < 30):
time.sleep(10)
tx_receipt = w3.eth.getTransactionReceipt(result)
print(tx_receipt)
if tx_receipt is None:
return {'status': 'failed', 'error': 'timeout'}
processed_receipt = contract.events.OpinionBroadcast().processReceipt(tx_receipt)
print(processed_receipt)
output = "Address {} broadcasted the opinion: {}"\
.format(processed_receipt[0].args._soapboxer, processed_receipt[0].args._opinion)
print(output)
return {'status': 'added', 'processed_receipt': processed_receipt}
if __name__ == "__main__":
send_ether_to_contract(0.03)
is_approved = check_whether_address_is_approved(wallet_address)
print(is_approved)
broadcast_an_opinion('Despite the Constant Negative Press')
打包封裝
所以關(guān)于它级野。正如我所提到的,我們還沒有達(dá)到使用python實(shí)際部署智能合約很容易的地步粹胯,但其他一切都在那里蓖柔。在Sempo,我們正在使用上面提到的所有技術(shù)來使問題響應(yīng)更加透明风纠。
感謝Sebastian Dirman指出w3.toWei(value, ‘ether’)是一種更好的方式在Ether和Wei之間進(jìn)行轉(zhuǎn)換——只需將以太量乘以1000000000000000000即可導(dǎo)致類型錯(cuò)誤况鸣!
======================================================================
分享一些以太坊、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ū)塊鏈存儲(chǔ)杆查、去中心化共識機(jī)制、密鑰與腳本臀蛛、交易與UTXO等根灯,同時(shí)也詳細(xì)講解如何在Java代碼中集成比特幣支持功能,例如創(chuàng)建地址、管理錢包烙肺、構(gòu)造裸交易等纳猪,是Java工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程。
- php比特幣開發(fā)教程桃笙,本課程面向初學(xué)者氏堤,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲(chǔ)搏明、去中心化共識機(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以太坊智能合約開發(fā)指南