Sawtooth Invalid Batch or Signature

后端 未结 3 1834
心在旅途
心在旅途 2021-01-06 08:23

I have started playing atound with Hyperledger Sawtooth recently, and having trouble to submit transactions on java, while python code seems okay.

I have prepared t

相关标签:
3条回答
  • 2021-01-06 08:43

    I've just have the same issue. In my case the problem was in setting payload data.

    Be sure that:

    • You made a sha512 hash of your PayloadByteArray and pass it to TransactionHeader creation
    • You pass PayloadByteArray to transaction creation.

    So:

    • PayloadByteArray -> Transaction creation
    • sha512 Hash of PayloadByteArray -> TransactionHeader creation
    0 讨论(0)
  • 2021-01-06 08:48

    The Sawtooth Java SDK comes with a Signing class that can be helpful in generating private/public key pairs and signing messages.

    I have modified your code to use the specified class and included the changes from Boyd Johnson's answer for a working example (this is using Sawtooth Java SDK version 1.0):

    import com.google.protobuf.ByteString;
    import com.mashape.unirest.http.Unirest;
    import com.mashape.unirest.http.exceptions.UnirestException;
    import org.bitcoinj.core.ECKey;
    import sawtooth.sdk.client.Signing;
    import sawtooth.sdk.processor.Utils;
    import sawtooth.sdk.protobuf.Batch;
    import sawtooth.sdk.protobuf.BatchHeader;
    import sawtooth.sdk.protobuf.BatchList;
    import sawtooth.sdk.protobuf.Transaction;
    import sawtooth.sdk.protobuf.TransactionHeader;
    
    import java.security.SecureRandom;
    
    public class BatchSender {
    
      public static void main(String []args) throws UnirestException {
        ECKey privateKey = Signing.generatePrivateKey(new SecureRandom());
        String publicKey = Signing.getPublicKey(privateKey);
    
        ByteString publicKeyByteString = ByteString.copyFromUtf8(publicKey);
    
        String payload = "{'key':1, 'value':'value comes here'}";
        String payloadBytes = Utils.hash512(payload.getBytes());
        ByteString payloadByteString  = ByteString.copyFrom(payload.getBytes());
    
        TransactionHeader txnHeader = TransactionHeader.newBuilder()
                .setBatcherPublicKeyBytes(publicKeyByteString)
                .setSignerPublicKeyBytes(publicKeyByteString)
                .setFamilyName("plain_info")
                .setFamilyVersion("1.0")
                .addInputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
                .setNonce("1")
                .addOutputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
                .setPayloadSha512(payloadBytes)
                .setSignerPublicKey(publicKey)
                .build();
        ByteString txnHeaderBytes = txnHeader.toByteString();
        String txnHeaderSignature = Signing.sign(privateKey, txnHeaderBytes.toByteArray());
    
        Transaction txn = Transaction.newBuilder()
                .setHeader(txnHeaderBytes)
                .setPayload(payloadByteString)
                .setHeaderSignature(txnHeaderSignature)
                .build();
    
        BatchHeader batchHeader = BatchHeader.newBuilder()
                .setSignerPublicKey(publicKey)
                .addTransactionIds(txn.getHeaderSignature())
                .build();
        ByteString batchHeaderBytes = batchHeader.toByteString();
        String batchHeaderSignature = Signing.sign(privateKey, batchHeaderBytes.toByteArray());
    
        Batch batch = Batch.newBuilder()
                .setHeader(batchHeaderBytes)
                .setHeaderSignature(batchHeaderSignature)
                .addTransactions(txn)
                .build();
    
        BatchList batchList = BatchList.newBuilder()
                .addBatches(batch)
                .build();
        ByteString batchBytes = batchList.toByteString();
    
        String serverResponse =  Unirest.post("http://localhost:8008/batches")
                .header("Content-Type","application/octet-stream")
                .body(batchBytes.toByteArray())
                .asString()
                .getBody();
    
        System.out.println(serverResponse);
      }
    }
    
    0 讨论(0)
  • 2021-01-06 09:01

    The problem is in setting the batch header signature and the transaction header signature. Those should not have the sha-512 hash taken of them. Those bytes should be encoded as hex strings.

    Using the apache-commons-codec library that can be done as:

    import org.apache.commons.codec.binary.Hex;
    
    Transaction txn = Transaction.newBuilder()
                          .setHeader(txnHeaderBytes)
                          .setPayload(payloadByteString)
                          .setHeaderSignature(Hex.encodeHexString(txnHeaderSignature))
                        .build();
    

    The Utils.sha512 should only be used on the payload bytes.

    0 讨论(0)
提交回复
热议问题