You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Java/Node SDK完成需双组织管理员签名的链码交易?多签可行吗?

如何满足2-of-2多签名链码交易策略

当然可行!这种多签名(multisig)场景是联盟链的核心能力之一,专门用来处理需要多方授权的敏感交易。你现在的问题是仅持有Org1 Admin的凭证,缺少Org2 Admin的签名,解决思路是先生成半签名的交易提案,将其传递到Org2完成二次签名,最后合并双签名提交给网络。下面分Java和Node.js SDK分别说明具体实现步骤:

一、核心流程概述

不管用哪个SDK,核心逻辑都是一致的:

  1. 用Org1 Admin身份生成并签名交易提案,此时提案仅含一个签名,不满足2-of-2策略。
  2. 将半签名提案安全传递给Org2授权客户端,用Org2 Admin身份完成二次签名。
  3. 收集双签名后组装完整交易请求,提交给排序节点完成上链。

二、Java SDK 实现步骤

假设你已配置好Org1的Wallet和Gateway实例:

  • 步骤1:生成半签名提案
    // 从Wallet获取Org1 Admin身份
    Identity org1Admin = wallet.get("org1Admin");
    try (Gateway gateway = Gateway.createBuilder()
             .identity(org1Admin)
             .networkConfig(Paths.get("connection-org1.yaml"))
             .discovery(true)
             .build()) {
        Network network = gateway.getNetwork("mychannel");
        Contract contract = network.getContract("mycc");
    
        // 生成仅含Org1签名的交易提案
        byte[] proposalBytes = contract.createTransaction("transfer")
                .createProposal();
    
        // 将提案序列化后传递给Org2(可通过加密REST接口、消息队列等方式)
        Files.write(Paths.get("half-signed-proposal.bin"), proposalBytes);
    }
    
  • 步骤2:Org2端完成二次签名
    在Org2的客户端中加载Admin身份,对收到的提案签名:
    // 读取半签名提案
    byte[] proposalBytes = Files.readAllBytes(Paths.get("half-signed-proposal.bin"));
    Identity org2Admin = wallet.get("org2Admin");
    
    // 解析提案并添加Org2签名
    Proposal proposal = Proposal.parseFrom(proposalBytes);
    SignedProposal signedProposal = SignedProposal.newBuilder(proposal)
            .setSignature(org2Admin.sign(proposal.getProposalBytes().toByteArray()))
            .build();
    
    // 将双签名提案序列化回传Org1
    Files.write(Paths.get("full-signed-proposal.bin"), signedProposal.toByteArray());
    
  • 步骤3:Org1端提交完整交易
    拿到双签名提案后,提交给背书节点并完成上链:
    byte[] signedProposalBytes = Files.readAllBytes(Paths.get("full-signed-proposal.bin"));
    SignedProposal signedProposal = SignedProposal.parseFrom(signedProposalBytes);
    
    try (Gateway gateway = Gateway.createBuilder()
             .identity(org1Admin)
             .networkConfig(Paths.get("connection-org1.yaml"))
             .discovery(true)
             .build()) {
        Network network = gateway.getNetwork("mychannel");
        Contract contract = network.getContract("mycc");
    
        // 获取背书节点响应
        Collection<ProposalResponse> responses = contract.evaluateTransaction(signedProposal);
    
        // 组装交易并提交到排序节点
        byte[] transactionBytes = contract.createTransaction("transfer")
                .createTransaction(responses);
        network.submitTransaction(transactionBytes);
    }
    

三、Node.js SDK 实现步骤

基于已配置的Org1钱包和网关:

  • 步骤1:生成半签名提案
    const { Gateway, Wallets } = require('fabric-network');
    const fs = require('fs');
    const path = require('path');
    
    async function generateHalfSignedProposal() {
        const wallet = await Wallets.newFileSystemWallet('./org1-wallet');
        const org1Admin = await wallet.get('org1Admin');
        const gateway = new Gateway();
        await gateway.connect(path.resolve(__dirname, 'connection-org1.json'), {
            identity: org1Admin,
            discovery: { enabled: true, asLocalhost: true }
        });
        const network = await gateway.getNetwork('mychannel');
        const contract = network.getContract('mycc');
    
        // 创建半签名提案并序列化保存
        const proposal = await contract.createTransaction('transfer').createProposal();
        fs.writeFileSync('half-signed-proposal.json', JSON.stringify(proposal.toJSON()));
        await gateway.disconnect();
    }
    
  • 步骤2:Org2端添加签名
    在Org2客户端中处理:
    async function addOrg2Signature() {
        const wallet = await Wallets.newFileSystemWallet('./org2-wallet');
        const org2Admin = await wallet.get('org2Admin');
        // 加载半签名提案
        const proposalJson = JSON.parse(fs.readFileSync('half-signed-proposal.json', 'utf8'));
        const proposal = Proposal.fromJSON(proposalJson);
    
        // 添加Org2签名
        const signature = await org2Admin.sign(Buffer.from(proposal.proposal_bytes));
        proposal.signature = signature.toString('base64');
    
        // 保存双签名提案回传Org1
        fs.writeFileSync('full-signed-proposal.json', JSON.stringify(proposal.toJSON()));
    }
    
  • 步骤3:Org1端提交交易
    async function submitFullTransaction() {
        const wallet = await Wallets.newFileSystemWallet('./org1-wallet');
        const org1Admin = await wallet.get('org1Admin');
        const gateway = new Gateway();
        await gateway.connect(path.resolve(__dirname, 'connection-org1.json'), {
            identity: org1Admin,
            discovery: { enabled: true, asLocalhost: true }
        });
        const network = await gateway.getNetwork('mychannel');
        const contract = network.getContract('mycc');
    
        // 加载双签名提案
        const signedProposalJson = JSON.parse(fs.readFileSync('full-signed-proposal.json', 'utf8'));
        const signedProposal = Proposal.fromJSON(signedProposalJson);
    
        // 获取背书响应并提交交易
        const responses = await contract.evaluateTransaction(signedProposal);
        const transaction = await contract.createTransaction('transfer').createTransaction(responses);
        await network.submitTransaction(transaction);
        await gateway.disconnect();
    }
    

四、关键注意事项

  • 传输安全性:半签名提案在Org1和Org2之间传递时,必须通过加密通道(如TLS、加密消息队列)传输,防止提案被篡改或泄露。
  • 权限校验:Org2客户端需验证请求签名的交易合法性,避免为未经授权的交易签名。
  • SDK版本兼容:不同Fabric SDK版本(如v2.x与v1.x)的API细节存在差异,需根据实际使用版本调整代码。
  • 签名顺序无关:无论先由Org1还是Org2签名,只要最终收集到两个有效签名,即可满足2-of-2策略要求。

内容的提问来源于stack exchange,提问作者Thinker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:49:10