操作中要注意版本问题
geth版本、golang版本等
在remix环境中写好合约后,进行编译得到abi文件
简单举例
Hello.sol合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Hello {
string Msg;
function setMsg(string memory _msg) public{
Msg=_msg;
}
function getMsg() view public returns(string memory){
return Msg;
}
}
编译后abi文件(Hello.abi)内容
[
{
"inputs": [],
"name": "getMsg",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_msg",
"type": "string"
}
],
"name": "setMsg",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
然后需要一个
abigen工具
可以将abi、bin等编译后的智能合约文件内容生成go代码
abigen可以在geth官网下载geth的时候下载Geth&Tools版本 里面带有abigen工具
采用以下命令将Hello.abi生成hello.go文件
其中
-out hello.go:指定输出为hello.go文件
-pkg main:指定该go文件属于哪个包
-type hello:指定合约的名称为hello
abigen -abi Hello.abi -pkg main -type hello -out hello.go
如果合约已经部署成功,采用上面的abigen生成的合约绑定就足够调用合约了,但是要部署合约还需要一些编译字节码形式的附加信息
可以通过remix合约直接得到合约编码后的字节码,也可以通过solc来编译
得到Hello.bin文件
然后 abigen 可以再次运行,这次传递 Hello.bin:
abigen --abi Hello.abi --pkg main --type Hello --out hello.go --bin Hello.bin
部署合约过程
1 连接到以太坊(创建客户端)
//1 创建客户端
client, err := ethclient.Dial("http://localhost:8545")
if err != nil {
log.Panic("failed to Dail", err)
}
2 创建一个用户部署合约的身份
//2 身份准备
//自己的账户文件的内容
var keyinfo = `{"address":"470455a4b2492d75f19ec7b29d25e19aee0c48b1","crypto":{"cipher":"aes-128-ctr","ciphertext":"08ef3a09df1d731bf71d8ce52a0fed4d4c9187f7a5ef845833bac9854700cd70","cipherparams":{"iv":"e8b8b6ed222f8906b31e391e6ef8b7d7"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e0970e0f38759ee32152429f692df30c0b4efd1d8adef6a9cf2a58e4f67fdcc7"},"mac":"0bea42bc7c1284307f518f4939f2de3af2278ac83e329541bf9e258e107c2feb"},"id":"83cb1145-c55b-439f-a1f0-5416a3805beb","version":3}`
keyin := strings.NewReader(keyinfo)
chainID, err := client.ChainID(context.Background())
if err != nil {
log.Panic(err)
}
auth, err := bind.NewTransactorWithChainID(keyin, "123456", chainID)
if err != nil {
log.Panic(err)
}
3 部署合约
这里我不知道我用abigen生成的go合约代码中没有DeployHello方法
//3 部署合约
//3 部署合约
// 合约地址,部署交易,合约对象
address, tx, HelloInstance, err := DeployHello(auth, client)
if err != nil {
log.Panic(err)
}
fmt.Println("address:", address.Hex())
fmt.Println("tx:", tx.Hash())
fmt.Println("contractInstance", HelloInstance)
部署后得到的结果
address: 0xEC1Bd1468F090cf41ddbf9463d7c27689a4002De
tx: 0x3c3a4d51efa0ea1d736a0ce6b415282dff22e41a2a9f3aa0147e2e8365cbcab3
contractInstance &{{0xc00007ec80} {0xc00007ec80} {0xc00007ec80}}
可以拿着这个交易hash在geth控制台查看交易数据
调用合约过程
1 连接到以太坊(创建客户端)
2 加载合约对象
3 创建一个用户部署合约的身份
4 调用合约
func main() {
//1 创建客户端
client, err := ethclient.Dial("http://localhost:8545")
if err != nil {
log.Panic("failed to Dail", err)
}
//2 身份准备
var keyinfo = `{"address":"470455a4b2492d75f19ec7b29d25e19aee0c48b1","crypto":{"cipher":"aes-128-ctr","ciphertext":"08ef3a09df1d731bf71d8ce52a0fed4d4c9187f7a5ef845833bac9854700cd70","cipherparams":{"iv":"e8b8b6ed222f8906b31e391e6ef8b7d7"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e0970e0f38759ee32152429f692df30c0b4efd1d8adef6a9cf2a58e4f67fdcc7"},"mac":"0bea42bc7c1284307f518f4939f2de3af2278ac83e329541bf9e258e107c2feb"},"id":"83cb1145-c55b-439f-a1f0-5416a3805beb","version":3}`
keyin := strings.NewReader(keyinfo)
chainID, err := client.ChainID(context.Background())
if err != nil {
log.Panic(err)
}
auth, err := bind.NewTransactorWithChainID(keyin, "123456", chainID)
if err != nil {
log.Panic(err)
}
//3 创建合约对象
// 合约地址,部署交易,合约对象
HelloInstance, err := NewHello(common.HexToAddress("0xEC1Bd1468F090cf41ddbf9463d7c27689a4002De"), client)
if err != nil {
log.Panic("failed to New ", err)
}
tx, err := HelloInstance.SetMsg(auth, "test")
if err != nil {
log.Panic("failed to set ", err)
}
fmt.Println("setmsg tx:", tx.Hash())
time.Sleep(time.Second * 20)
msg, err := HelloInstance.GetMsg(nil)
if err != nil {
log.Panic("failed to get ", err)
}
fmt.Println("getmsg:", msg)
}
结果展示: