长安链sdk合约部署和调用合约返回失败
部署合约: 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)
}

