def unmake(batch_object, signer_public_key=None, batcher_public_key=BATCHER_KEY_PAIR.public_key): """Will unmake a batch_request, batch_list, batch, transaction or payload, and return a list of the included messages. Validation of signatures will occur if public keys are provided. Only used for testing purposes. """ if isinstance( batch_object, client_batch_submit_pb2.ClientBatchSubmitRequest) or isinstance( batch_object, batch_pb2.BatchList): return list( itertools.chain(*[unmake(batch) for batch in batch_object.batches])) if isinstance(batch_object, batch_pb2.Batch): batch_header = batch_pb2.BatchHeader() batch_header.ParseFromString(batch_object.header) if batcher_public_key: assert batch_header.signer_public_key == batcher_public_key batcher_keypair = Key(public_key=batcher_public_key) assert batcher_keypair.verify( signature=batch_object.header_signature, message=batch_object.header) transactions = list(batch_object.transactions) return [unmake_item(transaction) for transaction in transactions] return [ unmake_item( batch_object=batch_object, signer_public_key=signer_public_key, batcher_public_key=batcher_public_key, ) ]
def _assert_validator_transaction(self, public_key, target_file): filename = os.path.join(self._temp_dir, target_file) batch_list = batch_pb.BatchList() with open(filename, 'rb') as batch_file: batch_list.ParseFromString(batch_file.read()) self.assertEqual(1, len(batch_list.batches)) batch = batch_list.batches[0] self.assertEqual(1, len(batch.transactions)) batch_header = batch_pb.BatchHeader() batch_header.ParseFromString(batch.header) self.assertEqual(public_key, batch_header.signer_public_key) txn = batch.transactions[0] txn_header = txn_pb.TransactionHeader() txn_header.ParseFromString(txn.header) self.assertEqual(public_key, txn_header.signer_public_key) self.assertEqual('sawtooth_validator_registry', txn_header.family_name) payload = vr_pb.ValidatorRegistryPayload() payload.ParseFromString(txn.payload) self._assert_key_state(payload.signup_info.poet_public_key)
def wrap_payload_in_txn_batch(txn_key, payload, header, batch_key): """Takes the serialized RBACPayload and creates a batch_list, batch signature tuple. Args: txn_key (sawtooth_signing.Signer): The txn signer's key pair. payload (bytes): The serialized RBACPayload. header (bytes): The serialized TransactionHeader. batch_key (sawtooth_signing.Signer): The batch signer's key pair. Returns: tuple The zeroth element is a BatchList, and the first element is the batch header_signature. """ transaction = transaction_pb2.Transaction( payload=payload, header=header, header_signature=txn_key.sign(header)) transaction_ids = [transaction.header_signature] logging.info(f"This is the transaction id {transaction_ids}") batch_header = batch_pb2.BatchHeader( signer_public_key=batch_key.get_public_key().as_hex(), transaction_ids=[transaction.header_signature]).SerializeToString() batch = batch_pb2.Batch(header=batch_header, header_signature=batch_key.sign(batch_header), transactions=[transaction]) batch_list_bytes = BatchList(batches=[batch]).SerializeToString() return transaction_ids, [batch], batch.header_signature, batch_list_bytes
def assertValidBatch(self, batch, payload, signer_public_key, batcher_public_key): """Check a batch is valid given a payload""" self.assertIsInstance(batch, batch_pb2.Batch) batch_header = batch_pb2.BatchHeader() batch_header.ParseFromString(batch.header) self.assertIsInstance(batch_header, batch_pb2.BatchHeader) self.assertEqual(batch_header.signer_public_key, batcher_public_key) batcher_keypair = Key(public_key=batcher_public_key) self.assertTrue( batcher_keypair.verify( signature=batch.header_signature, message=batch_header.SerializeToString(), )) other_key = Key() self.assertFalse( other_key.verify( signature=batch.header_signature, message=batch_header.SerializeToString(), )) transactions = list(batch.transactions) self.assertEqual(len(transactions), 1) self.assertValidTransaction( transaction=transactions[0], payload=payload, signer_public_key=signer_public_key, )
def _make_batch(self, payload, inputs, outputs, signer): """Creates and signs a batch. """ signer_public_key = signer.get_public_key().as_hex() payload_bytes = payload.SerializeToString() txn_header = transaction_pb2.TransactionHeader( family_name=self._family_name, family_version=self._family_version, inputs=inputs, outputs=outputs, signer_public_key=signer_public_key, batcher_public_key=signer_public_key, payload_sha512=hashlib.sha512(payload_bytes).hexdigest()) txn_header_bytes = txn_header.SerializeToString() txn = transaction_pb2.Transaction( header=txn_header_bytes, header_signature=signer.sign(txn_header_bytes), payload=payload_bytes) batch_header = batch_pb2.BatchHeader( signer_public_key=signer_public_key, transaction_ids=[txn.header_signature]) batch_header_bytes = batch_header.SerializeToString() batch = batch_pb2.Batch( header=batch_header_bytes, header_signature=signer.sign(batch_header_bytes), transactions=[txn]) return batch
def _batch_header(batch_key, transactions): batch_header_bytes = batch_pb2.BatchHeader( signer_public_key=batch_key.get_public_key().as_hex(), transaction_ids=[txn.header_signature for txn in transactions]).SerializeToString() signature = batch_key.sign(batch_header_bytes) return batch_header_bytes, signature
def make_batch(transaction, batcher_keypair=BATCHER_KEY_PAIR): """Batch a transaction""" batch_header = batch_pb2.BatchHeader( signer_public_key=batcher_keypair.public_key, transaction_ids=[transaction.header_signature], ).SerializeToString() return batch_pb2.Batch( header=batch_header, header_signature=batcher_keypair.sign(batch_header), transactions=[transaction], )
def make_batch_from_txns(transactions, signer_keypair): """ Given a list of transactions, create a batch to be applied on the Sawtooth blockchain. """ batch_header = batch_pb2.BatchHeader( signer_public_key=signer_keypair.public_key, transaction_ids=[txn.header_signature for txn in transactions], ).SerializeToString() return batch_pb2.Batch( header=batch_header, header_signature=signer_keypair.sign(batch_header), transactions=transactions, )
def create_batch(transactions, private_key, public_key): transaction_signatures = [t.header_signature for t in transactions] header = batch_pb2.BatchHeader(signer_pubkey=public_key, transaction_ids=transaction_signatures) header_bytes = header.SerializeToString() signature = signing.sign(header_bytes, private_key) batch = batch_pb2.Batch(header=header_bytes, transactions=transactions, header_signature=signature) return batch
def multi_transactions_batch(transactions, batch_key): if type(transactions) != list: raise CustomError("Transactions must be instance of list") batch_header = batch_pb2.BatchHeader( signer_public_key=batch_key.get_public_key().as_hex(), transaction_ids=[transaction.header_signature for transaction in transactions]).SerializeToString() batch = batch_pb2.Batch( header=batch_header, header_signature=batch_key.sign(batch_header), transactions=transactions) batch_list_bytes = BatchList(batches=[batch]).SerializeToString() return batch.header_signature, batch_list_bytes
def create_batch(transactions, private_key, public_key): transaction_signatures = [t.signature for t in transactions] header = batch_pb2.BatchHeader( signer=public_key, transaction_signatures=transaction_signatures) header_bytes = header.SerializeToString() signature = pybitcointools.ecdsa_sign(header_bytes, private_key) batch = batch_pb2.Batch(header=header_bytes, transactions=transactions, signature=signature) return batch
def create_batch(transactions, signer): transaction_signatures = [t.header_signature for t in transactions] header = batch_pb2.BatchHeader( signer_public_key=signer.get_public_key().as_hex(), transaction_ids=transaction_signatures) header_bytes = header.SerializeToString() signature = signer.sign(header_bytes) batch = batch_pb2.Batch(header=header_bytes, transactions=transactions, header_signature=signature) return batch
def _create_batch(signer, transactions): """Creates a batch from a list of transactions and a signer, and signs the resulting batch with the given signing key. Args: signer (:obj:`Signer`): Cryptographic signer to sign the batch transactions (list of `Transaction`): The transactions to add to the batch. Returns: `Batch`: The constructed and signed batch. """ txn_ids = [txn.header_signature for txn in transactions] batch_header = batch_pb.BatchHeader( signer_public_key=signer.get_public_key().as_hex(), transaction_ids=txn_ids).SerializeToString() return batch_pb.Batch(header=batch_header, header_signature=signer.sign(batch_header), transactions=transactions)
def assertValidBatch( self, batch, message, message_type, inputs, outputs, signer_public_key, batcher_public_key, ): self.assertIsInstance(batch, batch_pb2.Batch) batch_header = batch_pb2.BatchHeader() batch_header.ParseFromString(batch.header) self.assertIsInstance(batch_header, batch_pb2.BatchHeader) self.assertEqual(batch_header.signer_public_key, batcher_public_key) batcher_keypair = Key(public_key=batcher_public_key) self.assertTrue( batcher_keypair.verify( signature=batch.header_signature, message=batch_header.SerializeToString(), ) ) other_key = Key() self.assertFalse( other_key.verify( signature=batch.header_signature, message=batch_header.SerializeToString(), ) ) transactions = list(batch.transactions) self.assertEqual(len(transactions), 1) self.assertValidTransaction( transaction=transactions[0], message=message, message_type=message_type, inputs=inputs, outputs=outputs, signer_public_key=signer_public_key, )
def wrap_payload_in_txn_batch(txn_key, payload, header, batch_key): """Takes the serialized RBACPayload and creates a batch_list, batch signature tuple. Args: txn_key (Key): The txn signer's public/private key pair. payload (bytes): The serialized RBACPayload. header (bytes): The serialized TransactionHeader. batch_key (Key): The batch signer's public/private key pair. Returns: tuple The zeroth element is a BatchList, and the first element is the batch header_signature. """ factory = CryptoFactory(sawtooth_signing.create_context("secp256k1")) txn_signer = factory.new_signer( Secp256k1PrivateKey.from_hex(txn_key.private_key)) transaction = transaction_pb2.Transaction( payload=payload, header=header, header_signature=txn_signer.sign(header)) batch_header = batch_pb2.BatchHeader( signer_public_key=batch_key.public_key, transaction_ids=[transaction.header_signature], ).SerializeToString() batch_signer = factory.new_signer( Secp256k1PrivateKey.from_hex(batch_key.private_key)) batch = batch_pb2.Batch( header=batch_header, header_signature=batch_signer.sign(batch_header), transactions=[transaction], ) batch_list = batch_pb2.BatchList(batches=[batch]) return batch_list, batch.header_signature