以太坊v1.9.15 golang部署並調用合約


轉載請注明:https://www.cnblogs.com/tkblack/p/13559254.html

說實話對以太坊還不太熟,這幾個月研究並基於以太坊搭建聯盟鏈平台,主要是圍繞CA認證、國密兼容和共識算法展開,最近需要整一個go的sdk,於是翻了各種資料如何部署和調用智能合約。

以hello合約作為示例:

// SPDX-License-Identifier: SimPL-2.0
pragma solidity >=0.4.0 <=0.7.0;

contract HelloWorld {

    function Hello() pure public returns(string){
        return "hello world!";
    }

}

說實話,單單安裝solc我都費了一番功夫,老是報版本錯誤,我裝的是0.6.12版本,這里要說一點就是:pure 要寫在public前面,不然會報錯。。。(剛接觸solidity,還不知道為什么,如果你知道可以評論指出,先行感謝)

接下來就是編譯:

solc --bin hello.sol -o hello.abi

solc --abi hello.sol -o hello.bin

abigen --bin=hello.bin --abi=hello.abi --pkg=contract --out=hello.go

這樣就得到了可用的hello.go文件,后續需要導入並使用。

接着是部署和調用:

package ethclient

import(
    "github.com/ethereum/go-ethereum/ethclient/contract"    //hello.go放在該文件夾下
    "github.com/ethereum/go-ethereum/accounts/abi/bind"
    //其他包懶得寫,主要是兩個
)

func TestDeployContract(t *testing.T) {
    ethclient, err := Dial("http://localhost:8545")
    if err != nil {
        t.Error(err)
    }

    keyJson, err := ioutil.ReadFile("../build/bin/data/keystore/UTC--2020-08-17T03-35-30.955610100Z--520613668132f205d5ee27246098c72bbb793896")
    if err != nil {
        t.Error(err)
    }

    key, err := keystore.DecryptKey(keyJson, "")
    if err != nil {
        t.Error(err)
    }

    publicKey := key.PrivateKey.Public()
    publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
    if !ok {
        t.Error("error casting public key to ECDSA")
    }

    fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
    nonce, err := ethclient.PendingNonceAt(context.Background(), fromAddress)
    if err != nil {
        t.Error(err)
    }

    gasPrice, err := ethclient.SuggestGasPrice(context.Background())
    if err != nil {
        t.Error(err)
    }

    auth := bind.NewKeyedTransactor(key.PrivateKey)
    auth.Nonce = big.NewInt(int64(nonce))
    auth.Value = big.NewInt(0)     // in wei
    auth.GasLimit = uint64(300000) // in units
    auth.GasPrice = gasPrice

    address, tx, _, err := contract.DeployHello(auth, ethclient)    // 部署合約
    if err != nil {
        t.Error(err)
    }

    fmt.Println(address.Hex())      // 0x80bec2b5FbFC19Bc06c3423b6b1De65156528929
    fmt.Println(tx.Hash().Hex())    // 0x414d211952688a35c9a08619823e40ef6c2dd6b288c89375c269bb7946e1aa9b

    // 調用合約,建議部署和調用不要寫在同一個函數中,我這里為了簡便所以合到了一起
    nonce1, err := ethclient.PendingNonceAt(context.Background(), fromAddress)
    if err != nil {
        t.Error(err)
    }
    auth.Nonce = big.NewInt(int64(nonce1))

    hello, err := contract.NewHello(address, ethclient)

    helloRaw := contract.HelloRaw{hello}

    helloTx, err := helloRaw.Transact(auth, "Hello")   // 這是hello.go中已經封裝好的方法,也可以自己組裝交易然后Send
    if err != nil {
        t.Error(err)
    }

    fmt.Printf("txid : %v\n", helloTx.Hash().String())  

}    

細節就不描述了,主要是就兩個函數,DeployHello和Transact;其實,在Dial的時候是需要傳入一個證書(畢竟是聯盟鏈),但是,這里被我省掉了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM