使用Go與以太坊智能合約交互

盡管最近遇到了些麻煩扶歪,但以太坊仍然是區(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與以太坊智能合約交互

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末累澡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子般贼,更是在濱河造成了極大的恐慌愧哟,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哼蛆,死亡現(xiàn)場離奇詭異蕊梧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)腮介,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門肥矢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叠洗,你說我怎么就攤上這事甘改。” “怎么了灭抑?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵十艾,是天一觀的道長。 經(jīng)常有香客問我腾节,道長忘嫉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任案腺,我火速辦了婚禮庆冕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘劈榨。我一直安慰自己访递,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布鞋既。 她就那樣靜靜地躺著力九,像睡著了一般耍铜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跌前,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天棕兼,我揣著相機(jī)與錄音,去河邊找鬼抵乓。 笑死伴挚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灾炭。 我是一名探鬼主播茎芋,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蜈出!你這毒婦竟也來了田弥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤铡原,失蹤者是張志新(化名)和其女友劉穎偷厦,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體燕刻,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡只泼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了卵洗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片请唱。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖过蹂,靈堂內(nèi)的尸體忽然破棺而出十绑,到底是詐尸還是另有隱情,我是刑警寧澤榴啸,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布孽惰,位于F島的核電站晚岭,受9級特大地震影響鸥印,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坦报,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一库说、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧片择,春花似錦潜的、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽信不。三九已至,卻和暖如春亡呵,著一層夾襖步出監(jiān)牢的瞬間抽活,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工锰什, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留下硕,地道東北人。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓汁胆,卻偏偏與公主長得像梭姓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嫩码,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容