美文网首页
长安链--智能合约的开发、编译、安装、调用、查询(二)

长安链--智能合约的开发、编译、安装、调用、查询(二)

作者: 明神特烦恼 | 来源:发表于2021-06-11 14:48 被阅读0次

    作者:明神特烦恼

    智能合约是区块链与业务关联度最大的部分,合约的友好性、安全性、执行效率也是优秀的智能合约引擎的重要指标,长安链的支持多种语言的智能合约,包括go、rust、solidity、c++等。本节使用go语言开发智能合约,使用tinygo进行合约编译、使用go sdk 安装、调用、查询智能合约。

    官方参考文档: https://docs.chainmaker.org.cn/dev/%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6.html

    1.开发智能合约

    1)合约模板

        学习智能合约的开发,通常需要有Demo来学习API的使用方式,项目组织方式。在长安链学习过程中也是如此,所以第一步获取合约模块。
    1.1)拉取镜像:docker pull chainmakerofficial/chainmaker-go-contract:1.1.1
    长安链为我们提供合约开发的镜像,内部包含合约模板。

    1.2)启动并进入容器: docker run -it --name chainmaker-go-contract -v ${PWD}:/home chainmakerofficial/chainmaker-go-contract:1.1.1 bash
    启动chainmaker-go-contract容器并进入,同时将当前目录挂载到容器的 /home目录下

    1.3) 解压并分析合约模板
    cp /home
    tar xzvf contract_go_template.tar.gz

    • 目录结构:
      其中业务逻辑在main.go中,//export 注释的方法被编译器识别,用于外部访问。
      image.png
    • 合约逻辑
      save方法支持传入三个参数file_hashfile_nametime,以file_hash 为索引存入区块链世界状态。
      findByFileHash方法支持传入一个参数file_hash,以file_hash为检索条件进行世界状态检索并返回。
    • 合约逻辑可任意修改,只要后续调用指定export的方法名即可
    2)编译合约

    按照官方参考文档方式 在chainmaker-go-contract容器中执行./build.sh
    生成main.wasm文件

    3)安装、调用、查询合约
    1. 下载go sdk代码

    git clone --recursive https://git.chainmaker.org.cn/chainmaker/chainmaker-sdk-go.git

    1. 拷贝crypto-config文件

    rm -rf chainmaker-sdk-go/testdata/crypto-config
    cp -r chainmaker-go/build/crypto-config chainmaker-sdk-go/testdata/

    1. 编写测试用例
      可基于sdk_user_contract_claim_test.go文件进行修改。
      1)创建文件hash_test.go
    
    package chainmaker_sdk_go
    
    import (
        "chainmaker.org/chainmaker-go/common/random/uuid"
        "chainmaker.org/chainmaker-sdk-go/pb/protogo/common"
        "fmt"
        "github.com/stretchr/testify/require"
        "testing"
        "time"
    )
    
    var (
        hashContractName = "myhash001"
        hashVersion      = "1.0.0"
        hashByteCodePath = "./testdata/hash-cc/main.wasm"
    )
    
    func TestUserContractHash(t *testing.T) {
        fmt.Println("====================== create client ======================")
        client, err := createClientWithCertBytes()
        require.Nil(t, err)
    
        fmt.Println("====================== create admin1 ======================")
        admin1, err := createAdmin(orgId1)
        require.Nil(t, err)
        fmt.Println("====================== create admin2 ======================")
        admin2, err := createAdmin(orgId2)
        require.Nil(t, err)
        fmt.Println("====================== create admin3 ======================")
        admin3, err := createAdmin(orgId3)
        require.Nil(t, err)
        fmt.Println("====================== create admin4 ======================")
        admin4, err := createAdmin(orgId4)
        require.Nil(t, err)
    
        fmt.Println("====================== 创建合约 ======================")
        testUserContractHashCreate(t, client, admin1, admin2, admin3, admin4, true, true)
    
        fmt.Println("====================== 调用合约 ======================")
        fileHash, err := testUserContractHashInvoke(client, "save", true)
        require.Nil(t, err)
    
        fmt.Println("====================== 执行合约查询接口 ======================")
        //txId := "1cbdbe6106cc4132b464185ea8275d0a53c0261b7b1a470fb0c3f10bd4a57ba6"
        //fileHash = txId[len(txId)/2:]
        params := map[string]string{
            "file_hash": fileHash,
        }
        testUserContractHashQuery(t, client, "find_by_file_hash", params)
    }
    
    func testUserContractHashCreate(t *testing.T, client *ChainClient,
        admin1, admin2, admin3, admin4 *ChainClient, withSyncResult bool, isIgnoreSameContract bool) {
    
        resp, err := createUserContract(client, admin1, admin2, admin3, admin4,
            hashContractName, hashVersion, hashByteCodePath, common.RuntimeType_GASM, []*common.KeyValuePair{}, withSyncResult)
        if !isIgnoreSameContract {
            require.Nil(t, err)
        }
    
        fmt.Printf("CREATE claim contract resp: %+v\n", resp)
    }
    
    func testUserContractHashInvoke(client *ChainClient,
        method string, withSyncResult bool) (string, error) {
    
        //curTime := fmt.Sprintf("%d", CurrentTimeMillisSeconds())
        curTime := time.Now().Format("2006-01-02 15:04:05")
    
        fileHash := uuid.GetUUID()
        params := map[string]string{
            "time":      "123",
            "file_hash": fileHash,
            "file_name": fmt.Sprintf("file_%s", curTime),
        }
    
        err := invokeUserContract(client, hashContractName, method, "", params, withSyncResult)
        //err := invokeUserContractStepByStep(client, claimContractName, method, "", params, withSyncResult)
        if err != nil {
            return "", err
        }
    
        return fileHash, nil
    }
    
    func testUserContractHashQuery(t *testing.T, client *ChainClient,
        method string, params map[string]string) {
        resp, err := client.QueryContract(hashContractName, method, params, -1)
        require.Nil(t, err)
        fmt.Printf("QUERY claim contract resp: %+v\n", resp)
    }
    
    
    
    

    2)执行TestUserContractHash Test方法

    2.扩展

        这里使用的是默认配置文件,如果需要改变端口、连接数、TLS使能等等,需要修改chainmaker-sdk-go/testdata/sdk_config.yml

    相关文章

      网友评论

          本文标题:长安链--智能合约的开发、编译、安装、调用、查询(二)

          本文链接:https://www.haomeiwen.com/subject/cyzmeltx.html