代码之家  ›  专栏  ›  技术社区  ›  shamon shamsudeen

hyperledger锯齿javascript sdk:提交的批处理无效

  •  2
  • shamon shamsudeen  · 技术社区  · 7 年前

    我试图通过JavaScript SDK实现超分类锯齿事务 https://sawtooth.hyperledger.org/docs/core/releases/1.0/_autogen/sdk_submit_tutorial_js.html#encoding-your-payload 是的。

    /*
    *Create the transaction header
    */
    const createTransactionHeader = function createTransactionHeader(payloadBytes) {
    
        return  protobuf.TransactionHeader.encode({
            familyName: 'intkey',
            familyVersion: '1.0',
            inputs: [],
            outputs: [],
            signerPublicKey: '02cb65a26f7af4286d5f8118400262f7790e20018f2d01e1a9ffc25de1aafabdda',
    
            batcherPublicKey: '02cb65a26f7af4286d5f8118400262f7790e20018f2d01e1a9ffc25de1aafabdda',
            dependencies: [],
            payloadSha512: createHash('sha512').update(payloadBytes).digest('hex')
        }).finish();
    
    
    }
    /*
    * Create the transactions
    */
    const createTransaction = function createTransaction(transactionHeaderBytes, payloadBytes) {
    
        const signature = signer.sign(transactionHeaderBytes)
    
        return transaction = protobuf.Transaction.create({
            header: transactionHeaderBytes,
            headerSignature: Buffer.from(signature, 'utf8').toString('hex'),
            payload: payloadBytes
        });
    }
    

    提交事务时,我从rest api得到以下错误

    {
      "error": {
        "code": 30,
        "message": "The submitted BatchList was rejected by the validator. It was poorly formed, or has an invalid signature.",
        "title": "Submitted Batches Invalid"
      }
    }
    

    发现以下问题与我的问题相似

    Sawtooth Invalid Batch or Signature

    但它在Java中实现的解决方案不适合我的情况。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Rohit Khatri    7 年前

    这应该有效,请尝试:

    const cbor = require('cbor');
    const {createContext, CryptoFactory} = require('sawtooth-sdk/signing');
    const {createHash} = require('crypto');
    const {protobuf} = require('sawtooth-sdk');
    const request = require('request');
    const crypto = require('crypto');
    
    const context = createContext('secp256k1');
    const privateKey = context.newRandomPrivateKey();
    const signer = CryptoFactory(context).newSigner(privateKey);
    
    
    // Here's how you can generate the input output address
    const FAMILY_NAMESPACE = crypto.createHash('sha512').update('intkey').digest('hex').toLowerCase().substr(0, 6);
    const address = FAMILY_NAMESPACE + crypto.createHash('sha512').update('foo').digest('hex').toLowerCase().substr(0, 64);
    
    const payload = {
      Verb: 'set',
      Name: 'foo',
      Value: 42
    };
    
    const payloadBytes = cbor.encode(payload);
    
    const transactionHeaderBytes = protobuf.TransactionHeader.encode({
      familyName: 'intkey',
      familyVersion: '1.0',
      inputs: [address],
      outputs: [address],
      signerPublicKey: signer.getPublicKey().asHex(),
      batcherPublicKey: signer.getPublicKey().asHex(),
      dependencies: [],
      payloadSha512: createHash('sha512').update(payloadBytes).digest('hex')
    }).finish();
    
    const transactionHeaderSignature = signer.sign(transactionHeaderBytes);
    
    const transaction = protobuf.Transaction.create({
      header: transactionHeaderBytes,
      headerSignature: transactionHeaderSignature,
      payload: payloadBytes
    });
    
    const transactions = [transaction]
    
    const batchHeaderBytes = protobuf.BatchHeader.encode({
      signerPublicKey: signer.getPublicKey().asHex(),
      transactionIds: transactions.map((txn) => txn.headerSignature),
    }).finish();
    
    const batchHeaderSignature = signer.sign(batchHeaderBytes)
    
    const batch = protobuf.Batch.create({
      header: batchHeaderBytes,
      headerSignature: batchHeaderSignature,
      transactions: transactions
    };
    
    const batchListBytes = protobuf.BatchList.encode({
      batches: [batch]
    }).finish();
    
    request.post({
      url: 'http://rest.api.domain/batches',
      body: batchListBytes,
      headers: {'Content-Type': 'application/octet-stream'}
    }, (err, response) => {
      if(err) {
        return console.log(err);
      }
    
      console.log(response.body);
    });