Invalid Batch or signature in Savtooth

0 votes

I am following the tutorial on https://sawtooth.hyperledger.org/docs/core/releases/latest/_autogen/txn_submit_tutorial.html

I have made some changes just to learn about how things actually work, and this is the java code:

import com.google.protobuf.ByteString;
import com.mashape.unirest.http.Unirest;
import sawtooth.sdk.processor.Utils;
import sawtooth.sdk.protobuf.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.spec.ECGenParameterSpec;
public class BatchSender {
    public static void main(String[] args) throws Exception{
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
        ECGenParameterSpec parameterSpec = new ECGenParameterSpec("secp256k1");
        keyPairGenerator.initialize(parameterSpec);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
        ecdsaSign.initSign(keyPair.getPrivate());
        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        String publicKeyHex = Utils.hash512(publicKeyBytes);
        ByteString publicKeyByteString = ByteString.copyFrom(new String(publicKeyBytes),"UTF-8");
        String payload = "{'key':1, 'value':'value comes here'}";
        String payloadBytes = Utils.hash512(payload.getBytes());
        ByteString payloadByteString  = ByteString.copyFrom(payload.getBytes());
        TransactionHeader txnHeader = TransactionHeader.newBuilder().
                setBatcherPubkeyBytes(publicKeyByteString).
                setFamilyName("plain_info").
                setFamilyVersion("1.0").
                addInputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7").
                setNonce("1").
                addOutputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7").
                setPayloadEncoding("application/json").
                setPayloadSha512(payloadBytes).
                setSignerPubkey(publicKeyHex).build();
        ByteString txnHeaderBytes = txnHeader.toByteString();
        ecdsaSign.update(txnHeaderBytes.toByteArray());
        byte[] txnHeaderSignature = ecdsaSign.sign();
        Transaction txn = Transaction.newBuilder().setHeader(txnHeaderBytes).setPayload(payloadByteString).setHeaderSignature(Utils.hash512(txnHeaderSignature)).build();
        BatchHeader batchHeader = BatchHeader.newBuilder().setSignerPubkey(publicKeyHex).addTransactionIds(txn.getHeaderSignature()).build();
        ByteString batchHeaderBytes = batchHeader.toByteString();
        ecdsaSign.update(batchHeaderBytes.toByteArray());
        byte[] batchHeaderSignature = ecdsaSign.sign();
        Batch batch = Batch.newBuilder().setHeader(batchHeaderBytes).setHeaderSignature(Utils.hash512(batchHeaderSignature)).addTransactions(txn).build();
        BatchList batchList = BatchList.newBuilder().addBatches( batch).build();
        ByteString batchBytes = batchList.toByteString();
        String serverResponse =  Unirest.post("http://rest-api:8080/batches").header("Content-Type","application/octet-stream").body(batchBytes.toByteArray()).asString().getBody();
        System.out.println(serverResponse);
    }
}

The docker log is as follows:

sawtooth-validator-default | [2017-11-21 08:20:09.842 DEBUG    interconnect] ServerThread receiving CLIENT_BATCH_SUBMIT_REQUEST message: 1242 bytes
sawtooth-validator-default | [2017-11-21 08:20:09.844 DEBUG    signature_verifier] batch failed signature validation: 30a2f4a24be3e624f5a35b17cb505b65cb8dd41600545c6dcfac7534205091552e171082922d4eb71f1bb186fe49163f349c604b631f64fa8f1cfea1c8bb2818
sawtooth-validator-default | [2017-11-21 08:20:09.844 DEBUG    interconnect] ServerThread sending CLIENT_BATCH_SUBMIT_RESPONSE to b'50b094689ac14b39'

The batch is getting rejected. How to solve this problem?

Aug 1, 2018 in Blockchain by slayer
• 29,050 points
54 views

1 answer to this question.

0 votes

This will solve your problem

import org.apache.commons.codec.binary.Hex;


Transaction txn = Transaction.newBuilder()
                      .setHeader(txnHeaderBytes)
                      .setPayload(payloadByteString)
                      .setHeaderSignature(Hex.encodeHexString(txnHeaderSignature))
                    .build();

The problem was that you were using sha-512 hash for the signature whereas, you have to use encoded hex string.

answered Aug 1, 2018 by digger
• 27,620 points

Related Questions In Blockchain

0 votes
1 answer

Sawtooth Invalid Batch or Signature

The problem is in setting the batch ...READ MORE

answered Jun 16, 2018 in Blockchain by charlie_brown
• 7,710 points
101 views
+1 vote
1 answer

Is it possible to store blockchain in a sql or no-sql database?

Currently, following are the options to store ...READ MORE

answered Apr 20, 2018 in Blockchain by Perry
• 17,010 points

edited Aug 9, 2018 by Omkar 52 views
0 votes
1 answer

Bitstamp API signature in Ruby

Here is a code that works: require 'open-uri' require ...READ MORE

answered Aug 28, 2018 in Blockchain by slayer
• 29,050 points
80 views
0 votes
1 answer
+1 vote
1 answer
0 votes
1 answer

Any security issues in migrating sensitive data in CouchDB to hyperledger composer

Hyperledger Composer and the underlying Hyperledger Fabric ...READ MORE

answered Aug 3, 2018 in Blockchain by Johnathon
• 9,070 points
105 views
0 votes
1 answer

What encoding or data type can be used to get alphanumeric string in elixir?

Integers in Elixir are arbitrary precision integers, ...READ MORE

answered Aug 31, 2018 in Blockchain by digger
• 27,620 points
39 views
+1 vote
1 answer

What problem does pow(proof of work) solves in blockchain?

Proof of Work: When a miner gets a ...READ MORE

answered Aug 6, 2018 in Blockchain by digger
• 27,620 points
42 views