6 Star 39 Fork 19

有证教师 / rungeth

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 4.03 KB
一键复制 编辑 原始数据 按行查看 历史
有证教师 提交于 2021-10-29 15:49 . add solc download path

通过Go语言调用以太坊智能合约

environment

 Geth version: 1.10.11 
 os          : Linux/Windows
 Solc version: 0.8.7

solc编译器下载地址为:https://github.com/ethereum/solidity/releases/tag/v0.8.7 可以将其下载后放到PATH环境变量中,并将下载的文件名更改为solc.

hello.sol

pragma solidity^0.8.7;

contract hello {
    string mymsg;
    
    constructor(string memory _msg) public {
        mymsg = _msg;
    }
    
    function getMsg() public view returns (string memory) {
        return mymsg;
    }
}

使用abigen编译智能合约

 abigen -sol hello.sol -type hello -pkg main -out hello.go

main.go代码如下

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
)

var connect_cli *ethclient.Client

const keyin = `{"address":"f08db7576803c00aa197b5ca237ef0c62c4e93e6","crypto":{"cipher":"aes-128-ctr","ciphertext":"133137ecee40b8c3417dd011df1ff28f1ea45ec56f051f1a63a9a213a818e013","cipherparams":{"iv":"2d2be6bb86fe4a290ebcdd820f094434"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"b4a2472ceb98fb126931e3fa5e8ddfefad73ff6f6468f0bde2027f9b8e59b859"},"mac":"9b7cd1f75cacaaa7a16a296cdad664c20e35bf6fd81f9169781959fc2b6692e4"},"id":"ec81a896-42e9-4d44-b4f5-a368d84bf05c","version":3}`
const contract_address = ``

func init() {

	client, err := ethclient.Dial("http://localhost:8545")
	if err != nil {
		log.Panic("failed to Dial ", err)
	}

	connect_cli = client

}

func help() {
	fmt.Println("./hello 1 newmsg -- for deploy contract")
	fmt.Println("./hello 2 addr -- for call getMsg")
	fmt.Println("./hello 3 addr newmsg -- for call setMsg")
}

func main() {
	if len(os.Args) < 2 {
		help()
		os.Exit(1)
	}
	if os.Args[1] == "1" {
		DeplyContract(os.Args[2])
	} else if os.Args[1] == "2" {
		callGetMsg(os.Args[2])
	} else if os.Args[1] == "3" {
		callSetMsg(os.Args[2], os.Args[3])
	}

}

func DeplyContract(dmsg string) {

	chainid, _ := connect_cli.ChainID(context.Background())
	auth, err := bind.NewTransactorWithChainID(strings.NewReader(keyin), "123", chainid)
	if err != nil {
		log.Panic("Failed to NewTransactor ", err)
	}

	addr, _, _, err := DeployHello(auth, connect_cli, dmsg)
	if err != nil {
		log.Fatal("faile to DeployHello ", err)
	}

	fmt.Printf("depoly contract sucess, address is%v\n", addr.Hex())

}

func callGetMsg(addr string) {
	instance, err := NewHello(common.HexToAddress(addr), connect_cli)
	if err != nil {
		log.Fatal("Failed to NewHello ", err)
	}
	strmsg, err := instance.GetMsg(nil)
	if err != nil {
		log.Fatal("Failed to GetMsg ", err)
	}
	fmt.Println("getmsg:", strmsg)
}

func callSetMsg(addr, newmsg string) {
	instance, err := NewHello(common.HexToAddress(addr), connect_cli)
	if err != nil {
		log.Fatal("Failed to NewHello ", err)
	}

	chainid, _ := connect_cli.ChainID(context.Background())
	auth, err := bind.NewTransactorWithChainID(strings.NewReader(keyin), "123", chainid)
	if err != nil {
		log.Panic("Failed to NewTransactor ", err)
	}

	_, err = instance.SetMsg(auth, newmsg)
	if err != nil {
		log.Fatal("Failed to SetMsg ", err)
	}
	fmt.Println("callSetMsg done")
}

在windows编译没有出现问题,在Linux系统编译有可能会报错。 也可以将合约的abi文件拷贝过来编译,命令如下

abigen -abi hello.abi -type hello -pkg main -out hello.go

但是光编译abi是没有部署合约的方法,只能通过remix部署合约,获得地址后再调用合约内的函数。

编译代码

go build

编译代码时如果报错,可以将cgo关闭

export CGO_ENABLED=0

测试运行效果

$ ./hello 1 yekai233
depoly contract sucess, address is0x1765D738CC0f5DA23A653064B7321504dd055d9E
$ 
$ ./hello 2 0x1765D738CC0f5DA23A653064B7321504dd055d9E
getmsg: hello233
$ ./hello 3 0x1765D738CC0f5DA23A653064B7321504dd055d9E fuhongxue233
callSetMsg done
$ ./hello 2 0x1765D738CC0f5DA23A653064B7321504dd055d9E
getmsg: fuhongxue233
1
https://gitee.com/teacher233/rungeth.git
git@gitee.com:teacher233/rungeth.git
teacher233
rungeth
rungeth
master

搜索帮助