前言
在網(wǎng)上看了一堆go和智能合約交互的教程,大部分都是抄襲的,一抄二,二抄三。加上現(xiàn)在網(wǎng)絡(luò)環(huán)境不好經(jīng)常被墻,搞半天搞不完。本試驗環(huán)境win10,例子參考官方文檔。
remix + 測試網(wǎng) + abigen + golandIDE
第一步寫合約
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0 < 0.9.0;
/**
* @title Storage
* @dev store or retrieve variable value
*/
contract Storage {
uint256 value;
function store(uint256 number) public{
value = number;
}
function retrieve() public view returns (uint256){
return value;
}
第二步 編譯合約加部署
選擇injected Provider 喚起小狐貍部署
第三步 安裝go-ethereum
這里網(wǎng)上大部分會讓你在github下載,然后讓你go build 或者是其他,但是我這邊網(wǎng)絡(luò)就算翻了墻配置好代理也會超時。這里原來實際上是abigen是geth的一個開發(fā)工具,go-ethereum就是go語言實現(xiàn)的geth而已,里面會有很多個不同工具,你在倉庫的readme就可以看到會有make geth 或者make all
但是我們直接點,直接下安裝包安裝,更加省心。
地址:https://geth.ethereum.org/downloads/
選windows
安裝選
然后會出現(xiàn)一個PATH的報錯(可能也沒有)這個時候去電腦環(huán)境變量把安裝地址加入進(jìn)PATH即可
這樣就安裝好了
第三步通過abi生成go文件
abi獲取方法,在remix那復(fù)制
然后在命令行
abigen --abi Storage.abi --pkg main --type Storage --out Storage.go
這個時候就會生成一個go文件,這里面的參數(shù)自己看看就知道啥意思了不解釋了。
然后用goland打開這個文件夾
go mod init test
go mod tidy
初始化項目
然后再新建一個go文件來與合約交互
package main
import (
"fmt"
"log"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
// Create an IPC based RPC connection to a remote node
// NOTE update the path to the ipc file!
conn, err := ethclient.Dial("/home/go-ethereum/goerli/geth.ipc")
if err != nil {
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
}
// Instantiate the contract and display its name
// NOTE update the deployment address!
store, err := NewStorage(common.HexToAddress("0x21e6fc92f93c8a1bb41e2be64b4e1f88a54d3576"), conn)
if err != nil {
log.Fatalf("Failed to instantiate Storage contract: %v", err)
}
這里的ethclient.Dial()里面實際上要填一個客戶端地址,這里我們?nèi)ttps://infura.io/zh注冊申請一個
選好對應(yīng)的測試網(wǎng)絡(luò)NewStorage(common.HexToAddress(“0x21e6fc92f93c8a1bb41e2be64b4e1f88a54d3576”), conn)
填入合約地址,這里就是new一個調(diào)用合約的實例,很多方法都封裝好,更加容易調(diào)用。
然后就可以訪問鏈上合約的數(shù)據(jù)了。
和合約進(jìn)行交易
交易和普通查詢不同,需要私鑰。并且對代碼做點改動
代碼
package main
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"log"
"math/big"
)
const key = `json object from keystore`
func main() {
PrivateKey, _ := crypto.HexToECDSA("你的私鑰")
// Create an IPC based RPC connection to a remote node and instantiate a contract binding
conn, err := ethclient.Dial("你的節(jié)點地址")
if err != nil {
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
}
store, err := NewStorage(common.HexToAddress("你的合約地址"), conn)
if err != nil {
log.Fatalf("Failed to instantiate a Storage contract: %v", err)
}
// Create an authorized transactor and call the store function
nonce, _ := conn.NonceAt(context.Background(), common.HexToAddress("你私鑰對應(yīng)的賬戶地址"), nil)
gasPrice, _ := conn.SuggestGasPrice(context.Background())
//用哪條鏈,就用那個id
auth, err := bind.NewKeyedTransactorWithChainID(PrivateKey, big.NewInt(5))
auth.GasLimit = uint64(300000)
auth.Nonce = new(big.Int).SetUint64(nonce)
auth.GasPrice = gasPrice
if err != nil {
log.Fatalf("Failed to create authorized transactor: %v", err)
}
// Call the store() function
tx, err := store.Store(auth, big.NewInt(420))
if err != nil {
log.Fatalf("Failed to update value: %v", err)
}
fmt.Printf("Update pending: 0x%x\n", tx.Hash())
}
核心步驟,獲取nonce,獲取gasprice,綁定,發(fā)交易
還有一種方式是直接通過讀abi文件就能發(fā)交易,那種的話大概差不多只是寫代碼沒那么簡潔。
就這樣吧,希望對大家有幫助文章來源:http://www.zghlxwxcb.cn/news/detail-786405.html
參考資料
https://geth.ethereum.org/docs/dapp/native-bindings
https://medium.com/nerd-for-tech/smart-contract-with-golang-d208c92848a9文章來源地址http://www.zghlxwxcb.cn/news/detail-786405.html
到了這里,關(guān)于【全網(wǎng)最細(xì)】win10環(huán)境下go和智能合約交互的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!