FISCO-BCOS / go-sdk

golang SDK of FISCO BCOS
Apache License 2.0
73 stars 58 forks source link

将部署的合约地址以 文件 的形式进行保存后 将其读出 在调用合约的获取相关函数时 出现0x1a的 被调用的合约地址不存在 #169

Closed wxj-cyber closed 2 years ago

wxj-cyber commented 2 years ago

```go

package models

import ( "bufio" // "errors"

"io"

"log"
"math/big"
"os"
manage "proj3/manage"

"github.com/FISCO-BCOS/go-sdk/client"
"github.com/FISCO-BCOS/go-sdk/conf"
"github.com/FISCO-BCOS/go-sdk/core/types"
"github.com/ethereum/go-ethereum/common"
// import store

)

type ContractServiceType struct { // ConfigPath string Client client.Client Instance manage.Manage Session *manage.ManageSession isCreated bool ContractAddr common.Address }

// 判断所给路径文件/文件夹是否存在 func Exists(path string) bool { _, err := os.Stat(path) //os.Stat获取文件信息 if err != nil { if os.IsExist(err) { return true } return false } return true }

/ 函数名:WriteString2File 描述:将数据以字符串的形式写入到文件中。 / func WriteString2File(data string) { //创建文件,将部署的合约写进取 fliePath := "./config.txt" file, err := os.OpenFile(fliePath, os.O_WRONLY|os.OCREATE, 0666) if err != nil { log.Fatal("file open error:", err) } defer file.Close() write := bufio.NewWriter(file) , err = write.WriteString(data) if err != nil { log.Fatal("write addr error:", err) } //刷新缓冲区 write.Flush() }

/ 函数名:ReadStringFromFile 描述:从之前写入的文件中读取部署的合约地址。 / func ReadStringFromFile() (contractAddr []byte, ret bool) { filePath := "./config.txt" file, err := os.Open(filePath) if err != nil { log.Fatal("file open error:", err) return nil, false } defer file.Close()

var chunk []byte
buf := make([]byte, 1024)
//以字节的形式进行读取。
for {
    //从file读取到buff中。
    n, err := file.Read(buf)
    if err != nil && err != io.EOF {
        log.Fatal("读取文件到缓冲区失败!")
        file.Close()
        return nil, false
    }

    if n == 0 {
        break
    }

    //读取到最终的缓冲区中。
    chunk = append(chunk, buf[:n]...)
}
return chunk, true

}

/ 函数名:CreateConnectSession 描述:基于配置文件与区块链节点创建会话,连接成功后,会将部署的合约地址进行文件写入操作。 / func (server *ContractServiceType) CreateConnectSession(config string) {

if config == "" {
    return
}

//1.解析配置
configs, err := conf.ParseConfigFile(config)
if err != nil {
    log.Fatal("parse config file error:", err)
    return
}
//2.连接远程
server.Client, err = client.Dial(&configs[0])
if err != nil {
    log.Fatal("connect error:", err)
    return
}
if Exists("./config.txt") { //之前已经对其进行部署.

    //读取出之前部署的合约地址,将其与新的client进行绑定。
    contractAddrByte, ret := ReadStringFromFile()
    if !ret {
        log.Fatal("while read config from file error")
        return
    }
    server.ContractAddr = common.BytesToAddress(contractAddrByte)
    server.Instance, err = manage.NewManage(server.ContractAddr, server.Client)

    if err != nil {
        log.Fatal("create manange new instance error:", err)
        return
    }

} else {
    //3.部署合约
    server.ContractAddr, _, server.Instance, err = manage.DeployManage(server.Client.GetTransactOpts(), server.Client)
    if err != nil {
        log.Fatal("deploy contract error:", err)
        return
    }
    //3.1将合约地址写入文件。
    WriteString2File(server.ContractAddr.String())
}

//4.连接合约
server.Session = &manage.ManageSession{Contract: server.Instance, CallOpts: *server.Client.GetCallOpts(), TransactOpts: *server.Client.GetTransactOpts()}
server.isCreated = true

}

/ 函数名:NewVaccine 描述:产生一个新的疫苗。 / func (server ContractServiceType) NewVaccine(name string, id big.Int, addr string, validity big.Int) (types.Transaction, *types.Receipt, error) {

if server.Instance == nil || server.Client == nil || server.Session == nil || len(server.ContractAddr) == 0 {
    // log.Fatal("instance is null then constructor it again please.")
    // return nil, nil, errors.New("示例为空,是否存在没有为其进行合约部署。或者是client为空,没有正确的连接到区块链。Session为空,要确保有一个正确的连接。")
    server.CreateConnectSession("./conf/config.toml")
}
//ame string, id *big.Int, addr string, range1 *big.Int
return server.Session.CreateVaccine(name, id, addr, validity)

}

/ 函数名:GetVaccineById 描述:基于id获取疫苗信息。 / func (server ContractServiceType) GetVaccineById(id big.Int) (string, big.Int, string, big.Int, *big.Int, error) { if server.Instance == nil || server.Client == nil || server.Session == nil || len(server.ContractAddr) == 0 { // log.Fatal("instance is null then constructor it again please.") // return "", nil, "", nil, nil, errors.New("示例为空,是否存在没有为其进行合约部署。或者是client为空,没有正确的连接到区块链。Session为空,要确保有一个正确的连接。") server.CreateConnectSession("./conf/config.toml") }

return server.Session.GetVaccineInfo(id)

}

/ 函数名:GetVaccineCnt 描述:获取工厂疫苗的数量。 / func (server ContractServiceType) GetVaccineCnt() (big.Int, error) { if server.Instance == nil || server.Client == nil || server.Session == nil || len(server.ContractAddr) == 0 { // log.Fatal("instance is null then constructor it again please.") // return nil, errors.New("示例为空,是否存在没有为其进行合约部署。或者是client为空,没有正确的连接到区块链。Session为空,要确保有一个正确的连接。") server.CreateConnectSession("./conf/config.toml") }

return server.Session.GetVaccineCount()

}

/ 函数名:GetVaccineWithAll 描述:获取所有疫苗信息。 / func (server ContractServiceType) GetVaccineWithAll() ([]string, []big.Int, []string, []big.Int, []big.Int, error) { if server.Instance == nil || server.Client == nil || server.Session == nil || len(server.ContractAddr) == 0 { // log.Fatal("instance is null then constructor it again please.") // return nil, nil, nil, nil, nil, errors.New("示例为空,是否存在没有为其进行合约部署。或者是client为空,没有正确的连接到区块链。Session为空,要确保有一个正确的连接。") server.CreateConnectSession("./conf/config.toml") }

return server.Session.GetVaccineAll()

}

/ 函数名:GetVaccineWithAll 描述:获取疫苗的追踪链信息。 / func (server ContractServiceType) GetTransitOfVaccineAll(id big.Int) ([]string, []*big.Int, []string, error) { if server.Instance == nil || server.Client == nil || server.Session == nil || len(server.ContractAddr) == 0 { // log.Fatal("instance is null then constructor it again please.") // return nil, nil, nil, errors.New("示例为空,是否存在没有为其进行合约部署。或者是client为空,没有正确的连接到区块链。Session为空,要确保有一个正确的连接。") server.CreateConnectSession("./conf/config.toml") } return server.Session.GetVaccineTransit(id) }

/ 函数名:AddTransitForVaccineById 描述:为疫苗的行径添加到区块链。 / func (server ContractServiceType) AddTransitForVaccineById(id big.Int, addr string, time big.Int, remark string) (types.Transaction, *types.Receipt, error) { if server.Instance == nil || server.Client == nil || server.Session == nil || len(server.ContractAddr) == 0 { // log.Fatal("instance is null then constructor it again please.") // return nil, nil, errors.New("示例为空,是否存在没有为其进行合约部署。或者是client为空,没有正确的连接到区块链。Session为空,要确保有一个正确的连接。") server.CreateConnectSession("./conf/config.toml") } return server.Session.AddTransit(id, addr, time, remark) }



首先,简要介绍一下这个代码。
它根据配置文件进行解析,并进行连接,然后会根据config.txt是否存在来决定之前是否已经存在一个合约。
如果是,我们就会进行合约地址的读取,这里的读取是采用了以 字节 的形式进行读取,然后到绑定时,通过```common.ByteToAddress()```进行转换;如果为否,那么我就进行合约的部署并对其地址进行 文件写入。

现在,我们假定一个前提,就是已经存在config.txt,然后进行地址的转换。
在进行疫苗的创建时,我们可以看到:合约地址为
wxj-cyber commented 2 years ago

这是一个错误的编辑