本教程介紹 Go 中多模塊工作區(qū)的基礎(chǔ)知識(shí)。使用多模塊工作區(qū),您可以告訴 Go 命令您正在同時(shí)在多個(gè)模塊中編寫代碼,并輕松地在這些模塊中構(gòu)建和運(yùn)行代碼。
創(chuàng)新互聯(lián)是創(chuàng)新、創(chuàng)意、研發(fā)型一體的綜合型網(wǎng)站建設(shè)公司,自成立以來(lái)公司不斷探索創(chuàng)新,始終堅(jiān)持為客戶提供滿意周到的服務(wù),在本地打下了良好的口碑,在過(guò)去的十余年時(shí)間我們累計(jì)服務(wù)了上千家以及全國(guó)政企客戶,如成都廣告推廣等企業(yè)單位,完善的項(xiàng)目管理流程,嚴(yán)格把控項(xiàng)目進(jìn)度與質(zhì)量監(jiān)控加上過(guò)硬的技術(shù)實(shí)力獲得客戶的一致表?yè)P(yáng)。
在本教程中,您將在共享的多模塊工作區(qū)中創(chuàng)建兩個(gè)模塊,對(duì)這些模塊進(jìn)行更改,并在構(gòu)建中查看這些更改的結(jié)果。
本教程需要 go1.18 或更高版本。使用go.dev/dl中的鏈接確保您已在 Go 1.18 或更高版本中安裝了 Go 。
首先,為您要編寫的代碼創(chuàng)建一個(gè)模塊。
1、打開命令提示符并切換到您的主目錄。
在 Linux 或 Mac 上:
在 Windows 上:
2、在命令提示符下,為您的代碼創(chuàng)建一個(gè)名為工作區(qū)的目錄。
3、初始化模塊
我們的示例將創(chuàng)建一個(gè)hello依賴于 golang.org/x/example 模塊的新模塊。
創(chuàng)建你好模塊:
使用 . 添加對(duì) golang.org/x/example 模塊的依賴項(xiàng)go get。
在 hello 目錄下創(chuàng)建 hello.go,內(nèi)容如下:
現(xiàn)在,運(yùn)行 hello 程序:
在這一步中,我們將創(chuàng)建一個(gè)go.work文件來(lái)指定模塊的工作區(qū)。
在workspace目錄中,運(yùn)行:
該go work init命令告訴為包含目錄中模塊的工作空間go創(chuàng)建一個(gè)文件 。go.work./hello
該go命令生成一個(gè)go.work如下所示的文件:
該go.work文件的語(yǔ)法與go.mod相同。
該go指令告訴 Go 應(yīng)該使用哪個(gè)版本的 Go 來(lái)解釋文件。它類似于文件中的go指令go.mod 。
該use指令告訴 Go在進(jìn)行構(gòu)建時(shí)hello目錄中的模塊應(yīng)該是主模塊。
所以在模塊的任何子目錄中workspace都會(huì)被激活。
2、運(yùn)行工作區(qū)目錄下的程序
在workspace目錄中,運(yùn)行:
Go 命令包括工作區(qū)中的所有模塊作為主模塊。這允許我們?cè)谀K中引用一個(gè)包,即使在模塊之外。在模塊或工作區(qū)之外運(yùn)行g(shù)o run命令會(huì)導(dǎo)致錯(cuò)誤,因?yàn)樵揼o命令不知道要使用哪些模塊。
接下來(lái),我們將golang.org/x/example模塊的本地副本添加到工作區(qū)。然后,我們將向stringutil包中添加一個(gè)新函數(shù),我們可以使用它來(lái)代替Reverse.
在這一步中,我們將下載包含該模塊的 Git 存儲(chǔ)庫(kù)的副本golang.org/x/example,將其添加到工作區(qū),然后向其中添加一個(gè)我們將從 hello 程序中使用的新函數(shù)。
1、克隆存儲(chǔ)庫(kù)
在工作區(qū)目錄中,運(yùn)行g(shù)it命令來(lái)克隆存儲(chǔ)庫(kù):
2、將模塊添加到工作區(qū)
該go work use命令將一個(gè)新模塊添加到 go.work 文件中。它現(xiàn)在看起來(lái)像這樣:
該模塊現(xiàn)在包括example.com/hello模塊和 `golang.org/x/example 模塊。
這將允許我們使用我們將在模塊副本中編寫的新代碼,而不是使用命令stringutil下載的模塊緩存中的模塊版本。
3、添加新功能。
我們將向golang.org/x/example/stringutil包中添加一個(gè)新函數(shù)以將字符串大寫。
將新文件夾添加到workspace/example/stringutil包含以下內(nèi)容的目錄:
4、修改hello程序以使用該功能。
修改workspace/hello/hello.go的內(nèi)容以包含以下內(nèi)容:
從工作區(qū)目錄,運(yùn)行
Go 命令在go.work文件指定的hello目錄中查找命令行中指定的example.com/hello模塊 ,同樣使用go.work文件解析導(dǎo)入golang.org/x/example。
go.work可以用來(lái)代替添加replace 指令以跨多個(gè)模塊工作。
由于這兩個(gè)模塊在同一個(gè)工作區(qū)中,因此很容易在一個(gè)模塊中進(jìn)行更改并在另一個(gè)模塊中使用它。
現(xiàn)在,要正確發(fā)布這些模塊,我們需要發(fā)布golang.org/x/example 模塊,例如在v0.1.0. 這通常通過(guò)在模塊的版本控制存儲(chǔ)庫(kù)上標(biāo)記提交來(lái)完成。發(fā)布完成后,我們可以增加對(duì) golang.org/x/example模塊的要求hello/go.mod:
這樣,該go命令可以正確解析工作區(qū)之外的模塊。
智能合約調(diào)用是實(shí)現(xiàn)一個(gè) DApp 的關(guān)鍵,一個(gè)完整的 DApp 包括前端、后端、智能合約及區(qū)塊 鏈系統(tǒng),智能合約的調(diào)用是連接區(qū)塊鏈與前后端的關(guān)鍵。
我們先來(lái)了解一下智能合約調(diào)用的基礎(chǔ)原理。智能合約運(yùn)行在以太坊節(jié)點(diǎn)的 EVM 中。因此要 想調(diào)用合約必須要訪問(wèn)某個(gè)節(jié)點(diǎn)。
以后端程序?yàn)槔?,后端服?wù)若想連接節(jié)點(diǎn)有兩種可能,一種是雙 方在同一主機(jī),此時(shí)后端連接節(jié)點(diǎn)可以采用 本地 IPC(Inter-Process Communication,進(jìn) 程間通信)機(jī)制,也可以采用 RPC(Remote Procedure Call,遠(yuǎn)程過(guò)程調(diào)用)機(jī)制;另 一種情況是雙方不在同一臺(tái)主機(jī),此時(shí)只能采用 RPC 機(jī)制進(jìn)行通信。
提到 RPC, 讀者應(yīng)該對(duì) Geth 啟動(dòng)參數(shù)有點(diǎn)印象,Geth 啟動(dòng)時(shí)可以選擇開啟 RPC 服務(wù),對(duì)應(yīng)的 默認(rèn)服務(wù)端口是 8545。。
接著,我們來(lái)了解一下智能合約運(yùn)行的過(guò)程。
智能合約的運(yùn)行過(guò)程是后端服務(wù)連接某節(jié)點(diǎn),將 智能合約的調(diào)用(交易)發(fā)送給節(jié)點(diǎn),節(jié)點(diǎn)在驗(yàn)證了交易的合法性后進(jìn)行全網(wǎng)廣播,被礦工打包到 區(qū)塊中代表此交易得到確認(rèn),至此交易才算完成。
就像數(shù)據(jù)庫(kù)一樣,每個(gè)區(qū)塊鏈平臺(tái)都會(huì)提供主流 開發(fā)語(yǔ)言的 SDK(Software Development Kit,軟件開發(fā)工具包),由于 Geth 本身就是用 Go 語(yǔ)言 編寫的,因此若想使用 Go 語(yǔ)言連接節(jié)點(diǎn)、發(fā)交易,直接在工程內(nèi)導(dǎo)入 go-ethereum(Geth 源碼) 包就可以了,剩下的問(wèn)題就是流程和 API 的事情了。
總結(jié)一下,智能合約被調(diào)用的兩個(gè)關(guān)鍵點(diǎn)是節(jié)點(diǎn)和 SDK。
由于 IPC 要求后端與節(jié)點(diǎn)必須在同一主機(jī),所以很多時(shí)候開發(fā)者都會(huì)采用 RPC 模式。除了 RPC,以太坊也為開發(fā)者提供了 json- rpc 接口,本文就不展開討論了。
接下來(lái)介紹如何使用 Go 語(yǔ)言,借助 go-ethereum 源碼庫(kù)來(lái)實(shí)現(xiàn)智能合約的調(diào)用。這是有固定 步驟的,我們先來(lái)說(shuō)一下總體步驟,以下面的合約為例。
步驟 01:編譯合約,獲取合約 ABI(Application Binary Interface,應(yīng)用二進(jìn)制接口)。 單擊【ABI】按鈕拷貝合約 ABI 信息,將其粘貼到文件 calldemo.abi 中(可使用 Go 語(yǔ)言IDE 創(chuàng)建該文件,文件名可自定義,后綴最好使用 abi)。
最好能將 calldemo.abi 單獨(dú)保存在一個(gè)目錄下,輸入“l(fā)s”命令只能看到 calldemo.abi 文件,參 考效果如下:
步驟 02:獲得合約地址。注意要將合約部署到 Geth 節(jié)點(diǎn)。因此 Environment 選擇為 Web3 Provider。
在【Environment】選項(xiàng)框中選擇“Web3 Provider”,然后單擊【Deploy】按鈕。
部署后,獲得合約地址為:0xa09209c28AEf59a4653b905792a9a910E78E7407。
步驟 03:利用 abigen 工具(Geth 工具包內(nèi)的可執(zhí)行程序)編譯智能合約為 Go 代碼。abigen 工具的作用是將 abi 文件轉(zhuǎn)換為 Go 代碼,命令如下:
其中各參數(shù)的含義如下。 (1)abi:是指定傳入的 abi 文件。 (2)type:是指定輸出文件中的基本結(jié)構(gòu)類型。 (3)pkg:指定輸出文件 package 名稱。 (4)out:指定輸出文件名。 執(zhí)行后,將在代碼目錄下看到 funcdemo.go 文件,讀者可以打開該文件欣賞一下,注意不要修改它。
步驟 04:創(chuàng)建 main.go,填入如下代碼。 注意代碼中 HexToAddress 函數(shù)內(nèi)要傳入該合約部署后的地址,此地址在步驟 01 中獲得。
步驟 04:設(shè)置 go mod,以便工程自動(dòng)識(shí)別。
前面有所提及,若要使用 Go 語(yǔ)言調(diào)用智能合約,需要下載 go-ethereum 工程,可以使用下面 的指令:
該指令會(huì)自動(dòng)將 go-ethereum 下載到“$GOPATH/src/github.com/ethereum/go-ethereum”,這樣還算 不錯(cuò)。不過(guò),Go 語(yǔ)言自 1.11 版本后,增加了 module 管理工程的模式。只要設(shè)置好了 go mod,下載 依賴工程的事情就不必關(guān)心了。
接下來(lái)設(shè)置 module 生效和 GOPROXY,命令如下:
在項(xiàng)目工程內(nèi),執(zhí)行初始化,calldemo 可以自定義名稱。
步驟 05:運(yùn)行代碼。執(zhí)行代碼,將看到下面的效果,以及最終輸出的 2020。
上述輸出信息中,可以看到 Go 語(yǔ)言會(huì)自動(dòng)下載依賴文件,這就是 go mod 的神奇之處??吹?2020,相信讀者也知道運(yùn)行結(jié)果是正確的了。
在本節(jié)中,您將使用 Go 執(zhí)行 SQL INSERT語(yǔ)句以向數(shù)據(jù)庫(kù)添加新行。
您已經(jīng)了解了如何使用Query和QueryRow處理返回?cái)?shù)據(jù)的 SQL 語(yǔ)句。要執(zhí)行 不 返回?cái)?shù)據(jù)的 SQL 語(yǔ)句,請(qǐng)使用Exec.
1、在albumByID下面,粘貼以下addAlbum函數(shù)以在數(shù)據(jù)庫(kù)中插入新專輯,然后保存 main.go。
在此代碼中:
(1)用DB.Exec執(zhí)行INSERT語(yǔ)句。
Exec接受一條 SQL 語(yǔ)句,后跟 SQL 語(yǔ)句的參數(shù)值。
(2)檢查嘗試INSERT中的錯(cuò)誤。
(3)使用Result.LastInsertId檢索插入的數(shù)據(jù)庫(kù)行的 ID 。
(4)檢查嘗試檢索 ID 的錯(cuò)誤。
2、更新main以調(diào)用新addAlbum函數(shù)。
在main函數(shù)末尾添加以下代碼。
在新代碼中:
(1)調(diào)用addAlbum添加新專輯,將要添加的專輯的 ID 分配給albID變量。
從包含 main.go 目錄的命令行中,運(yùn)行代碼。
恭喜!您剛剛使用 Go 對(duì)關(guān)系數(shù)據(jù)庫(kù)執(zhí)行了簡(jiǎn)單的操作。
本節(jié)包含您使用本教程構(gòu)建的應(yīng)用程序的代碼。