Hyperledger Fabric Java SDK:查询事务有效,但创建事务失败,出现无效事务合约异常

问题描述 投票:0回答:1

我正在开发一个 Hyperledger Fabric 应用程序,使用 Java SDK 与智能合约进行交互。我的查询事务工作正常,但是当我尝试执行创建事务时,它失败并出现“合同异常”。并显示消息“无效交易”。

详情如下:

智能合约代码(Go):

我的 Fabric 网络上部署了智能合约。 CreateContract函数如下:

此函数使用提供的参数创建一个新合约,如果合约已存在,则抛出错误。

func (s *SmartContract) CreateContract(ctx contractapi.TransactionContextInterface, contractId string, client string, supplier string, description string) (string, error) {
    if contractId == "" {
        return "", fmt.Errorf("Contract Id cannot be empty.")
    }
    if client == "" {
        return "", fmt.Errorf("Client field cannot be empty.")
    }
    if supplier == "" {
        return "", fmt.Errorf("Supplier field cannot be empty.")
    }

    chatAsBytes, err := ctx.GetStub().GetState(contractId)
    if err != nil {
        return "", fmt.Errorf("Failed to read from world state. %s", err.Error())
    }

    if chatAsBytes == nil {
        newContract := LegalContractSchema{
            DocType:      "Legal Contract",
            Participants: []string{client, supplier},
            Description:  description,
        }
        newContractAsBytes, _ := json.Marshal(newContract)
        err := ctx.GetStub().PutState(contractId, newContractAsBytes)

        if err != nil {
            return "", fmt.Errorf("Failed writing to world state. %s", err.Error())
        }
        return "Successfully created contract", nil
    } else {
        return "", fmt.Errorf("Failed to create contract schema, contract already exists.")
    }
}

Java SDK代码:

我正在使用 Java SDK 与智能合约交互。我调用CreateContract函数的代码如下:

Gateway.Builder builder = Gateway.createBuilder()
        .identity(wallet, "admin")
        .networkConfig(networkConfigFile)
        .discovery(true)
        .commitTimeout(60, TimeUnit.SECONDS);

try (Gateway gateway = builder.connect()) {
    Network network = gateway.getNetwork("mychannel");
    Contract contract = network.getContract("legalContract");

    // Submit a create transaction
    byte[] createResult = contract.createTransaction("CreateContract")
            .submit("contractId123", "ClientName", "SupplierName", "This is a test description");

    System.out.println("Create Transaction Result: " + new String(createResult, StandardCharsets.UTF_8));
}

查询交易:

查询事务 (GetLegalContractCert) 使用相同的 Java 代码结构完美运行:

byte[] queryResult = contract.evaluateTransaction("GetLegalContractCert", "contractId123");
System.out.println("Query Result: " + new String(queryResult, StandardCharsets.UTF_8));

问题: 当我调用 CreateContract 函数时,出现以下错误:

Invalid transaction Contract Exception
查询事务工作正常,但创建事务失败。

我尝试过的:

  1. 验证输入参数:确保contractId、客户、供应商和描述值作为UTF-8编码字符串传递。
  2. 检查背书策略:验证背书策略是否与交易中使用的节点相匹配。
  3. 调试了智能合约:向 CreateContract 函数添加了日志记录,但没有看到任何日志被触发,这表明交易未到达智能合约。
  4. 增加超时:为提交和交付设置更长的超时。

环境:

  • 超级账本结构:v2.4
  • Java SDK:v2.4
  • Go 智能合约:Fabric 合约 API
  • 网络:具有两个组织和两个对等点的单通道(mychannel)。

我的连接配置文件如下所示:

{
  "name": "test-network-org1",
  "version": "1.0.0",
  "client": {
    "organization": "Org1",
    "connection": {
      "timeout": {
        "peer": {
          "endorser": "300"
        }
      }
    }
  },
  "organizations": {
    "Org1": {
      "mspid": "Org1MSP",
      "peers": [
        "peer0.org1.example.com"
      ],
      "certificateAuthorities": [
        "ca.org1.example.com"
      ]
    }
  },
  "peers": {
    "peer0.org1.example.com": {
      "url": "grpcs://localhost:7051",
      "tlsCACerts": {
        "pem": "-----BEGIN CERTIFICATE-----\XYF\n-----END CERTIFICATE-----\n"
      },
      "grpcOptions": {
        "ssl-target-name-override": "peer0.org1.example.com",
        "hostnameOverride": "peer0.org1.example.com"
      }
    }
  },
  "certificateAuthorities": {
    "ca.org1.example.com": {
      "url": "https://localhost:7054",
      "caName": "ca-org1",
      "tlsCACerts": {
        "pem": ["-----BEGIN CERTIFICATE-----\XYZ\n-----END CERTIFICATE-----\n"]
      },
      "httpOptions": {
        "verify": false
      }
    }
  }
}
java hyperledger-fabric hyperledger gateway
1个回答
0
投票

如果您正在使用(或可以使用)Fabric v2.4 或更高版本,则最佳解决方案是使用 Fabric Gateway 客户端 API 而不是 旧版 Java SDK 来构建客户端应用程序。

如果您确实无法迁移到当前的 Fabric 版本并且必须继续使用旧版 Java SDK,我怀疑您的问题可能是需要设置

as_localhost
配置属性以进行服务发现。这基于您的连接配置文件,列出了您的同级和订购者的 localhost 地址。请参阅 API 文档,了解需要此设置的场景以及如何使用环境变量进行配置。

© www.soinside.com 2019 - 2024. All rights reserved.