盡管最近遇到了些麻煩扶歪,但以太坊仍然是區(qū)塊鏈領(lǐng)域內(nèi)智能合約的最大參與者,這似乎不會很快改變乃摹。
在我看來,技術(shù)本身具有很大的潛力跟衅,是從學(xué)術(shù)的角度看很有意思孵睬,但正如上面提到的問題和之前的許多問題是區(qū)塊鏈技術(shù)方面的,智能合約伶跷,特別是具有Solidity的以太坊生態(tài)系統(tǒng)還是不太成熟的掰读,并沒有為prime-time和生產(chǎn)用例做好準(zhǔn)備。
然而叭莫,這是一個學(xué)習(xí)和了解這項(xiàng)技術(shù)的好時機(jī)蹈集,并且當(dāng)它達(dá)到嚴(yán)格應(yīng)用程序的可接受成熟度前,需要做好準(zhǔn)備雇初。
在我之前關(guān)于Solidity的帖子中拢肆,我創(chuàng)建了一個帶有簡單的Winner-Takes-All Crowdfunding合約的小應(yīng)用程序。在這篇文章中靖诗,我們將用到其中的contract.sol善榛,看看我們是否可以使用Go部署它并與之交互。
為什么是go呻畸?好問題移盆,go語言是令人驚訝的而且使用最廣泛的以太坊客戶端使用go寫的,這意味著有一個很好的生態(tài)系統(tǒng)使用已經(jīng)轉(zhuǎn)為具有很好的功能伤为,如代碼生成和可重復(fù)使用的助手和智能合約互動的共享庫咒循。
在這個例子中,我們將不使用真實(shí)的區(qū)塊鏈作為部署目標(biāo)绞愚,而是使用由go-ethereum叙甸,所以我們可以安全地測試并沒有花費(fèi)任何金錢實(shí)驗(yàn)提供的SimulatedBackend。
智能合約本身非常簡單:我不會詳細(xì)介紹它的功能或工作方式位衩,因?yàn)橐呀?jīng)涵蓋了這一點(diǎn)裆蒸。可以說糖驴,合約部署有3個參數(shù):
- 項(xiàng)目的最低入場費(fèi)僚祷。
- 提交新項(xiàng)目的截止日期。
- 支持項(xiàng)目的截止日期贮缕。
然后辙谜,在第一階段,可以使用名稱和網(wǎng)址提交項(xiàng)目感昼,其中至少包含交易的最低費(fèi)用装哆。在第二階段,可以通過將以太發(fā)送到合約中的地址來支持項(xiàng)目。
但是蜕琴,在這篇文章中萍桌,我們將重點(diǎn)關(guān)注:
- 部署合約
- 從合約中讀取數(shù)據(jù)
- 與合約互動(交易)
- 通過地址實(shí)例化已部署的合約
我們將在Go和70行代碼中完成所有操作。讓我們開始吧凌简!
代碼示例
為了能夠跟蹤梗夸,你需要一些東西。首先也是最重要的是号醉,你需要solc Solidity編譯器。
然后辛块,只需獲取go-ethereum并構(gòu)建它:
go get github.com/ethereum/go-ethereum
cd $GOPATH/src/github.com/ethereum/go-ethereum/
make
make devtools
好吧畔派,使用solc和geth devtools,我們可以從生成contract.sol文件的Go版本開始润绵,該文件包含我們的智能合約:
abigen --sol=Contract.sol --pkg=main --out=contract.go
生成的代碼看這里线椰。
如你所見,我們有部署和實(shí)例化合約的方法尘盼,以及所有公共合約方法到Go的映射憨愉。
下一步是將合約部署到模擬后端。
為此卿捎,需要進(jìn)行一些設(shè)置配紫。如上所述,為了簡單起見午阵,我們將使用SimulatedBackend作為我們的目標(biāo)區(qū)塊鏈躺孝,但在本文的最后,將有一個關(guān)于如何使用testnet甚至真正的以太坊區(qū)塊鏈進(jìn)行此操作的簡短部分底桂。
使用go-ethereum的一些依賴關(guān)系植袍,我們可以開始設(shè)置:
import(
"fmt"
"log"
"math/big"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
)
func main() {
key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key)
alloc := make(core.GenesisAlloc)
alloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(133700000)}
sim := backends.NewSimulatedBackend(alloc)
我們只需創(chuàng)建一個密鑰,用一堆以太創(chuàng)建一個Genesis帳戶并啟動模擬后端籽懦,它會返回一個bind.ContractBackend于个。
現(xiàn)在我們可以使用生成的DeployWinnerTakesAll方法部署合約:
addr, _, contract, err := DeployWinnerTakesAll(auth, sim, big.NewInt(10), big.NewInt(time.Now().Add(2*time.Minute).Unix()), big.NewInt(time.Now().Add(5*time.Minute).Unix()))
if err != nil {
log.Fatalf("could not deploy contract: %v", err)
}
我們使用bigInt傳遞一個auth對象,它表示我們的身份暮顺,后端sim和最小入場費(fèi)厅篓,項(xiàng)目截止日期和活動截止日期的值。該方法返回將部署合約的地址以及合約的句柄和錯誤捶码。還有一個返回的交易對象贷笛,但我們不會在這里處理它。
現(xiàn)在合約已經(jīng)部署宙项,我們應(yīng)該能夠與它進(jìn)行交互乏苦。例如,我們可以檢查我們發(fā)送的截止日期是否在合約中正確設(shè)置:
deadlineCampaign, _ := contract.DeadlineCampaign(nil)
fmt.Printf("Pre-mining Campaign Deadline: %s\n", deadlineCampaign)
但是,如果我們執(zhí)行此操作汇荐,我們會在截止日期前返回<nil>洞就。也就是說,因?yàn)槲覀兊暮霞s尚未開采掀淘。如果我們使用真實(shí)網(wǎng)絡(luò)作為后端旬蟋,我們將不得不等到發(fā)生這種情況,但是使用我們的模擬后端革娄,我們可以簡單地執(zhí)行此操作:
fmt.Println("Mining...")
sim.Commit()
postDeadlineCampaign, _ := contract.DeadlineCampaign(nil)
fmt.Printf("Post-mining Campaign Deadline: %s\n", time.Unix(postDeadlineCampaign.Int64(), 0))
我們回到部署期間設(shè)置的日期:
Post-mining Campaign Deadline: 2017-07-23 20:37:22 +0200 CEST
ok倾贰。因此,我們可以讀取合約中公開的數(shù)據(jù)±雇铮現(xiàn)在我們想與它互動匆浙。在這種情況下,最簡單的事情是我們通過發(fā)送一個帶有名稱和項(xiàng)目網(wǎng)址的交易來提出一個新項(xiàng)目厕妖,其中至少有最低費(fèi)用作為值:
numOfProjects, _ := contract.NumberOfProjects(nil)
fmt.Printf("Number of Projects before: %d\n", numOfProjects)
fmt.Println("Adding new project...")
contract.SubmitProject(&bind.TransactOpts{
From: auth.From,
Signer: auth.Signer,
GasLimit: big.NewInt(2381623),
Value: big.NewInt(10),
}, "test project", "http://www.example.com")
當(dāng)然我們需要繼續(xù)挖礦:
fmt.Println("Mining...")
sim.Commit()
numOfProjects, _ = contract.NumberOfProjects(nil)
fmt.Printf("Number of Projects after: %d\n", numOfProjects)
info, _ := contract.GetProjectInfo(nil, auth.From)
fmt.Printf("Project Info: %v\n", info)
...但是我們得到以下輸出:
Number of Projects before: 0
Adding new project...
Mining...
Number of Projects after: 1
Project Info: {test project http://www.example.com 0}
太棒了首尼,這意味著我們的項(xiàng)目已經(jīng)創(chuàng)建。因此言秸,我們能夠部署合約软能,對其進(jìn)行讀寫。
但是如果合約已經(jīng)部署并且我們只想與它進(jìn)行交互怎么辦举畸?幸運(yùn)的是查排,生成的代碼包含一個NewWinnerTakesAll方法,它只使用已部署合約的地址抄沮,允許我們實(shí)例化合約:
instContract, err := NewWinnerTakesAll(addr, sim)
if err != nil {
log.Fatalf("could not instantiate contract: %v", err)
}
numOfProjects, _ = instContract.NumberOfProjects(nil)
fmt.Printf("Number of Projects of instantiated Contract: %d\n", numOfProjects)
我們獲得與已部署合約相同的返回值雹嗦,并且可以與此版本完全相同的方式進(jìn)行交互,該版本由地址實(shí)例化合是。
好的了罪,所以我們完成了與合約有意義地交互所需的所有步驟,但僅限于模擬的后端聪全。為了使用testnet或真正的以太坊區(qū)塊鏈泊藕,我們只需要調(diào)整一些事項(xiàng):
const key = "your key json"
conn, err := rpc.NewIPCClient("/path/to/your/.ethereum/testnet/geth.ipc")
if err != nil {
log.Fatalf("could not create ipc client: %v", err)
}
auth, err := bind.NewTransactor(strings.NewReader(key), "your password")
if err != nil {
log.Fatalf("could not create auth: %v", err)
}
這會產(chǎn)生我們自己創(chuàng)建的auth對象。當(dāng)然难礼,請不要在代碼中使用純文本的密鑰和/或密碼娃圆,而是以安全的方式加載它們。:)
如果已經(jīng)部署了合約蛾茉,我們不需要創(chuàng)建NewIPCClient讼呢,但只需Dial一個節(jié)點(diǎn):
conn, err := ethclient.Dial("/path/to/your/.ethereum/testnet/geth.ipc")
if err != nil {
log.Fatalf("could not connect to remote node: %v", err)
}
如此而已!可以在此處找到該示例的完整代碼谦炬。
結(jié)論
正如我在本文開頭所述悦屏,在我看來节沦,依靠Solidity智能合約進(jìn)行認(rèn)真的應(yīng)用還為時尚早,但這種以及其他幾種基于區(qū)塊鏈的智能合約方法的潛力巨大础爬,因此了解周邊技術(shù)肯定是值得的甫贯。
Go非常適合與基于以太坊的智能合約交互的任務(wù),因?yàn)橛泻芏鄟碜詆eth的可重用代碼看蚜,甚至還有一些關(guān)于如何開始使用的文檔叫搁。這當(dāng)然可以用任何其他語言來實(shí)現(xiàn)(例如:使用web3),但如果Go是你喜歡的供炎,它似乎是一個可靠的選擇渴逻。:)
======================================================================
分享一些比特幣、以太坊音诫、EOS惨奕、Fabric等區(qū)塊鏈相關(guān)的交互式在線編程實(shí)戰(zhàn)教程:
- java比特幣開發(fā)教程,本課程面向初學(xué)者纽竣,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲茧泪、去中心化共識機(jī)制蜓氨、密鑰與腳本、交易與UTXO等队伟,同時也詳細(xì)講解如何在Java代碼中集成比特幣支持功能穴吹,例如創(chuàng)建地址、管理錢包嗜侮、構(gòu)造裸交易等港令,是Java工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程。
- php比特幣開發(fā)教程锈颗,本課程面向初學(xué)者顷霹,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲击吱、去中心化共識機(jī)制淋淀、密鑰與腳本、交易與UTXO等覆醇,同時也詳細(xì)講解如何在Php代碼中集成比特幣支持功能朵纷,例如創(chuàng)建地址、管理錢包永脓、構(gòu)造裸交易等袍辞,是Php工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程。
- c#比特幣開發(fā)教程常摧,本課程面向初學(xué)者搅吁,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲、去中心化共識機(jī)制似芝、密鑰與腳本那婉、交易與UTXO等,同時也詳細(xì)講解如何在C#代碼中集成比特幣支持功能党瓮,例如創(chuàng)建地址详炬、管理錢包、構(gòu)造裸交易等寞奸,是C#工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程呛谜。
- 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)階。
- ERC721以太坊通證實(shí)戰(zhàn)构灸,課程以一個數(shù)字藝術(shù)品創(chuàng)作與分享DApp的實(shí)戰(zhàn)開發(fā)為主線蚪拦,深入講解以太坊非同質(zhì)化通證的概念、標(biāo)準(zhǔn)與開發(fā)方案冻押。內(nèi)容包含ERC-721標(biāo)準(zhǔn)的自主實(shí)現(xiàn)驰贷,講解OpenZeppelin合約代碼庫二次開發(fā),實(shí)戰(zhàn)項(xiàng)目采用Truffle洛巢,IPFS括袒,實(shí)現(xià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)完成一個便簽DApp的開發(fā)城侧。
- 深入淺出玩轉(zhuǎn)EOS錢包開發(fā)易遣,本課程以手機(jī)EOS錢包的完整開發(fā)過程為主線,深入學(xué)習(xí)EOS區(qū)塊鏈應(yīng)用開發(fā)嫌佑,課程內(nèi)容即涵蓋賬戶豆茫、計算資源、智能合約屋摇、動作與交易等EOS區(qū)塊鏈的核心概念揩魂,同時也講解如何使用eosjs和eosjs-ecc開發(fā)包訪問EOS區(qū)塊鏈,以及如何在React前端應(yīng)用中集成對EOS區(qū)塊鏈的支持摊册。課程內(nèi)容深入淺出肤京,非常適合前端工程師深入學(xué)習(xí)EOS區(qū)塊鏈應(yīng)用開發(fā)颊艳。
- Hyperledger Fabric 區(qū)塊鏈開發(fā)詳解茅特,本課程面向初學(xué)者,內(nèi)容即包含Hyperledger Fabric的身份證書與MSP服務(wù)棋枕、權(quán)限策略白修、信道配置與啟動、鏈碼通信接口等核心概念重斑,也包含F(xiàn)abric網(wǎng)絡(luò)設(shè)計兵睛、nodejs鏈碼與應(yīng)用開發(fā)的操作實(shí)踐,是Nodejs工程師學(xué)習(xí)Fabric區(qū)塊鏈開發(fā)的最佳選擇窥浪。
- Hyperledger Fabric java 區(qū)塊鏈開發(fā)詳解祖很,課程面向初學(xué)者,內(nèi)容即包含Hyperledger Fabric的身份證書與MSP服務(wù)漾脂、權(quán)限策略假颇、信道配置與啟動、鏈碼通信接口等核心概念骨稿,也包含F(xiàn)abric網(wǎng)絡(luò)設(shè)計笨鸡、java鏈碼與應(yīng)用開發(fā)的操作實(shí)踐姜钳,是java工程師學(xué)習(xí)Fabric區(qū)塊鏈開發(fā)的最佳選擇。
- 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)明出處硼一。這里是使用Go與以太坊智能合約交互