3

最近、Hyperledger Sawtoothでatoundをプレイしていて、Javaでトランザクションを送信できませんでしたが、Pythonコードは大丈夫です。Sawtoothが無効なバッチまたは署名

私はapi docs hereに基づいてPythonコードを準備してから、Javaでも書き込もうとしました。以下は、私はそれを実行したら、私はドッカーズログの

{ 
    "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" 
    } 
} 

を取得しています

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); 
    } 


} 

のJavaのコードは、私は、キーのサイズをチェックした

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' 

見ることができますし、署名を確認してください、それはすべてOKですが、私はバッチが拒否された理由を見つけることができませんでした...

誰もが似ていました前に鋸歯からのエラー応答?それは上記のコードのバッチ形式かまだ署名問題ですか?

+0

これが解決しましたか?もしそうなら、修正は何ですか? –

+1

@FrankC。いいえ、解決されていません – stephanruhl

答えて

3

問題は、バッチヘッダーシグネチャとトランザクションヘッダーシグネチャを設定することです。それらはsha-512ハッシュを持っているべきではありません。これらのバイトは、16進文字列としてエンコードする必要があります。

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

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

Utils.sha512のみペイロードバイトで使用する必要があります。

として行うことができるのapache-コモンズ・コーデックライブラリを使用しました。