Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Sign in
O
opensoure trainingcamp
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 11
    • Issues 11
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 2
    • Merge Requests 2
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Package Registry
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar

新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

  • 长安链
  • opensoure trainingcamp
  • Issues
  • #12

Closed
Open
Opened Nov 11, 2025 by changye@13692190102Contributor

长安链sdk合约部署和调用合约返回失败

image image

部署合约: counter-real-cert 合约部署失败: 合约已存在,跳过部署 尝试使用已存在的合约名称进行测试... 调用错误: 调用失败,状态码: 11, 消息:

附源码

package main

import (
        "fmt"
        "strings"

        "chainmaker.org/chainmaker/pb-go/v2/common"
        sdk "chainmaker.org/chainmaker/sdk-go/v2"
)

func initClient() (*sdk.ChainClient, error) {
        // 使用配置文件初始化客户端
        return sdk.NewChainClient(
                sdk.WithConfPath("./sdk_config.yml"),
        )
}

// 检查合约是否存在
func contractExists(client *sdk.ChainClient, contractName string) (bool, error) {
        contractInfo, err := client.GetContractInfo(contractName)
        if err != nil {
                // 如果错误信息包含合约不存在的相关内容,返回false
                if strings.Contains(err.Error(), "contract not exist") || strings.Contains(err.Error(), "not found") {
                        return false, nil
                }
                return false, err
        }
        return contractInfo != nil, nil
}

// 部署合约
func deployContract(client *sdk.ChainClient) (string, error) {
        return deployContractWithName(client, "counter")
}

// 使用指定名称部署合约
func deployContractWithName(client *sdk.ChainClient, contractName string) (string, error) {
        payload, err := client.CreateContractCreatePayload(
                contractName, "1.0", "./contracts/counter.wasm",
                common.RuntimeType_WASMER, nil)
        if err != nil {
                return "", err
        }
        // 签名payload
        endorsers, err := client.SignPayload(payload)
        if err != nil {
                return "", err
        }
        resp, err := client.SendContractManageRequest(payload, []*common.EndorsementEntry{endorsers}, -1, true)
        if err != nil {
                return "", fmt.Errorf("部署失败: %v", err)
        }
        if resp.Code != common.TxStatusCode_SUCCESS {
                // 如果状态码是4,通常表示合约已存在,可以继续执行
                if resp.Code == 4 {
                        return "", fmt.Errorf("合约已存在,跳过部署")
                }
                return "", fmt.Errorf("部署失败,状态码: %d, 消息: %s", resp.Code, resp.Message)
        }
        return resp.TxId, nil
}

// 调用合约
func invokeContract(client *sdk.ChainClient, contractName string, amount int64) (string, error) {
        // 使用 KeyValuePair 格式传递参数,SDK 会自动转换为合约需要的格式
        kvs := []*common.KeyValuePair{
                {
                        Key:   "amount",
                        Value: []byte(fmt.Sprintf("%d", amount)),
                },
        }

        resp, err := client.InvokeContract(contractName, "increase", "", kvs, -1, true)
        if err != nil {
                return "", fmt.Errorf("调用失败: %v", err)
        }
        if resp.Code != common.TxStatusCode_SUCCESS {
                return "", fmt.Errorf("调用失败,状态码: %d, 消息: %s", resp.Code, resp.Message)
        }
        return resp.TxId, nil
}

// 查询合约
func queryContract(client *sdk.ChainClient, contractName string) (int64, error) {
        // getCount 方法不需要参数,使用空字符串
        resp, err := client.QueryContract(contractName, "getCount", nil, -1)
        if err != nil {
                return 0, fmt.Errorf("查询失败: %v", err)
        }
        if resp.Code != common.TxStatusCode_SUCCESS {
                return 0, fmt.Errorf("查询失败,状态码: %d, 消息: %s", resp.Code, resp.Message)
        }

        // 将返回的byte数组转换为int64
        if len(resp.ContractResult.Result) > 0 {
                result := string(resp.ContractResult.Result)
                fmt.Printf("查询原始结果: %s\n", result)
                var count int64
                _, err := fmt.Sscanf(result, "%d", &count)
                if err != nil {
                        return 0, fmt.Errorf("解析结果失败: %v", err)
                }
                return count, nil
        }
        return 0, nil
}
func main() {
        client, err := initClient()
        if err != nil {
                fmt.Printf("客户端错误: %v\n", err)
                return
        }
        defer client.Stop()

        // 测试客户端连接
        chainInfo, err := client.GetChainInfo()
        if err != nil {
                fmt.Printf("获取链信息失败: %v\n", err)
                return
        }
        fmt.Printf("链信息: %+v\n", chainInfo)

        // 1. 先尝试部署合约
        contractName := "counter-real-cert"
        fmt.Printf("部署合约: %s\n", contractName)

        txId, err := deployContractWithName(client, contractName)
        if err != nil {
                fmt.Printf("合约部署失败: %v\n", err)
                fmt.Println("尝试使用已存在的合约名称进行测试...")
                contractName = "test-permission-001"
        } else {
                fmt.Printf("✅ 合约部署成功,交易ID: %s\n", txId)
        }

        // 2. 调用合约(增加 5)
        invokeTx, err := invokeContract(client, contractName, 5)
        if err != nil {
                fmt.Printf("调用错误: %v\n", err)
                return
        }
        fmt.Printf("合约调用成功,交易哈希: %s\n", invokeTx)

        // 3. 查询合约
        count, err := queryContract(client, contractName)
        if err != nil {
                fmt.Printf("查询错误: %v\n", err)
                return
        }
        fmt.Printf("当前计数值: %d\n", count)
}
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: songqingli/opensoure-trainingcamp#12

Copyright © 2021 ChainMaker Org. All Rights Reserved. 长安链 版权所有。