fisco-bcosV3使用go-sdk使用教程

发布于:2025-03-05 ⋅ 阅读:(14) ⋅ 点赞:(0)

环境:
Ubuntu :20.04.1
fisco-bcos: 3.11.0
go-sdk: v3.0.2
go 1.22.0
solidity 0.8.11

说明

根据官方的文档go-sdk使用 ,在我自己的环境中有些许差异, 所以整理一下步骤与大家分享,本次教程以用go-sdk部署一个helloworld合约为例子

下载go-sdk

在github上git clone或许下载最新版的go-sdkmaster分支
在这里插入图片描述
下载完成后,进入go-sdk里面的v3目录,
执行go mod tidy 命令,把相关依赖包下载下来

编写合约

合约就以简单的helloworld为例子

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.6.10 <0.8.20;

contract HelloWorld {
    string value;
    event setValue(string v, address indexed from, address indexed to, int256 value);
    int public version;

    constructor(string memory initValue) {
        value = initValue;
        version = 0;
    }

    function get() public view returns (string memory) {
        return value;
    }

    function set(string calldata v) public returns (string memory) {
        string memory old = value;
        value = v;
        version = version + 1;
        emit setValue(v, tx.origin, msg.sender, version);
        return old;
    }
}

下载bcos-c-sdk动态库

使用go-sdk文件目录下的download_csdk_lib.sh脚本文件
在这里插入图片描述
或者去github https://github.com/FISCO-BCOS/bcos-c-sdk/releases/tag/v3.6.0
在这里插入图片描述
下载libbcos-c-sdk.so文件
注意,使用脚本下载会默认下载到/usr/local/lib目录下,但是坑就是这么来的,ubuntu系统执行的时候,扫描的动态库不是在这个目录下,所以需要自己找到该系统的默认动态库路径

export $LD_LIBRARY_PATH//使用此命令

结果

-bash: export: “/opt/ros/noetic/lib”: 不是有效的标识符

所以需要把libbcos-c-sdk.so复制到此/opt/ros/noetic/lib目录下 其他linux系统可能也是不同的目录需自己用命令寻找

安装智能合约编译工具

在tools文件夹下有download_solc.sh文件,指定solidity版本

bash ../tools/download_solc.sh -v 0.8.11

下载完成就有一个执行文件
在这里插入图片描述

安装合约转go语言编译工具abigen

在v3目录下执行

go build ./cmd/abigen

执行完后,会有一个abigen执行文件
在这里插入图片描述

开始部署智能合约

在v3目录下新建一个helloworld文件夹,并把abigen和solc-0.8.11,还有HelloWorld.sol复制进该文件夹

生成bin和abi文件

在helloworld文件夹下执行命令

./solc-0.8.11 --bin --abi -o ./ ./HelloWorld.sol

会生成HelloWorld.bin和HelloWorld.abi文件

生成go文件

此时利用abigen工具将HelloWorld.bin和HelloWorld.abi转换成HelloWorld.go

./abigen --bin ./HelloWorld.bin --abi ./HelloWorld.abi --pkg helloworld --type HelloWorld --out ./HelloWorld.go

这样相关业务go文件代码已经生成

编写部署合约

此时我们还需要编写一个部署HelloWorld合约的go文件
在hellowrold文件下新建一个cmd目录,在cmd目录创建一个main.go
下面代码与官方文档给的有所不同,在import代码块里有所改动

package main

import (
	"context"
	"encoding/hex"
	"fmt"
	"github.com/FISCO-BCOS/go-sdk/v3/helloworld"
	"github.com/FISCO-BCOS/go-sdk/v3/types"
	"log"


	"github.com/FISCO-BCOS/go-sdk/v3/client"
)

func main() {
	privateKey, _ := hex.DecodeString("145e247e170ba3afd6ae97e88f00dbc976c2345d511b0f6713355d19d8b80b58")
	config := &client.Config{IsSMCrypto: false, GroupID: "group0",
		PrivateKey: privateKey, Host: "127.0.0.1", Port: 20200, TLSCaFile: "./conf/ca.crt", TLSKeyFile: "./conf/sdk.key", TLSCertFile: "./conf/sdk.crt"}
	client, err := client.DialContext(context.Background(), config)

	if err != nil {
		log.Fatal(err)
	}
	input := "HelloWorld deployment 1.0"
	fmt.Println("=================DeployHelloWorld===============")
	address, receipt, instance, err := helloworld.DeployHelloWorld(client.GetTransactOpts(), client, input)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("contract address: ", address.Hex()) // the address should be saved, will use in next example
	fmt.Println("transaction hash: ", receipt.TransactionHash)

	// load the contract
	// contractAddress := common.HexToAddress("contract address in hex String")
	// instance, err := helloworld.NewStore(contractAddress, client)
	// if err != nil {
	//     log.Fatal(err)
	// }

	fmt.Println("================================")
	helloSession := &helloworld.HelloWorldSession{Contract: instance, CallOpts: *client.GetCallOpts(), TransactOpts: *client.GetTransactOpts()}

	version, err := helloSession.Version()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("version :", version) // "HelloWorld deployment 1.0"

	ret, err := helloSession.Get() //调用合约Get方法
	if err != nil {
		fmt.Printf("helloworld.Get() failed: %v", err)
		return
	}
	done := make(chan bool)
	// 监听合约set事件
	_, err = helloSession.WatchAllSetValue(nil, func(ret int, logs []types.Log) {
		fmt.Printf("WatchAllSetValue receive status: %d, logs: %v\n", ret, logs)
		setValue, err := helloSession.ParseSetValue(logs[0])
		if err != nil {
			fmt.Printf("helloworld.WatchAllSetValue() failed: %v", err)
			panic(any(err))
		}
		fmt.Printf("receive setValue: %+v\n", *setValue)
		done <- true
	})
	if err != nil {
		fmt.Printf("helloworld.WatchAllSetValue() failed: %v", err)
		return
	}
	fmt.Printf("Get: %s\n", ret)
	fmt.Println("================================")

	oldValue, _, receipt, err := helloSession.Set("hello fisco")
	fmt.Println("old value is: ", oldValue)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("transaction hash of receipt: %s\n", receipt.GetTransactionHash())

	ret, err = helloSession.Get()
	if err != nil {
		fmt.Printf("helloworld.Get() failed: %v", err)
		return
	}
	fmt.Printf("Get: %s\n", ret)
	<-done
}

证书拷贝

可以看到部署go文件还需要证书,我们需要把自己的链子的ca.crt ,sdk.crtsdk.key找到,并且在v3目录下新建一个conf文件夹,将三个证书放入conf目录下【因为之后go run需要在v3目录下执行,读取文件需要根据相对路径读取】

执行代码

v3目录下执行

go run helloworld/cmd/main.go

执行成功结果
在这里插入图片描述

结论

相关环境配好了之后,以后写好合约代码,也可以根据此环境进行编译部署执行go文件了


网站公告

今日签到

点亮在社区的每一天
去签到