def create_intkey_transaction(verb, name, value, private_key, public_key): payload = IntKeyPayload(verb=verb, name=name, value=value) # The prefix should eventually be looked up from the # validator's namespace registry. intkey_prefix = hashlib.sha512('intkey'.encode('utf-8')).hexdigest()[0:6] addr = intkey_prefix + hashlib.sha512(name.encode('utf-8')).hexdigest() header = transaction_pb2.TransactionHeader( signer_pubkey=public_key, family_name='intkey', family_version='1.0', inputs=[addr], outputs=[addr], dependencies=[], payload_encoding="application/cbor", payload_sha512=payload.sha512(), batcher_pubkey=public_key, nonce=time.time().hex().encode()) header_bytes = header.SerializeToString() signature = bitcoin.ecdsa_sign(header_bytes, private_key) transaction = transaction_pb2.Transaction(header=header_bytes, payload=payload.to_cbor(), header_signature=signature) return transaction
def make_transaction( self, message, message_type, inputs, outputs, signer_keypair, batcher_public_key=BATCHER_KEY_PAIR.public_key, ): payload = self.make_payload(message=message, message_type=message_type) header, signature = self.make_transaction_header( payload=payload, inputs=inputs, outputs=outputs, signer_keypair=signer_keypair, batcher_public_key=batcher_public_key, ) return transaction_pb2.Transaction( payload=payload.SerializeToString(), header=header.SerializeToString(), header_signature=signature, )
def create_bgt_transaction(verb, name, value, signer): payload = BgtPayload( verb=verb, name=name, value=value) # The prefix should eventually be looked up from the # validator's namespace registry. addr = make_bgt_address(name) header = transaction_pb2.TransactionHeader( signer_public_key=signer.get_public_key().as_hex(), family_name='bgt', family_version='1.0', inputs=[addr], outputs=[addr], dependencies=[], payload_sha512=payload.sha512(), batcher_public_key=signer.get_public_key().as_hex(), nonce=hex(random.randint(0, 2**64))) header_bytes = header.SerializeToString() signature = signer.sign(header_bytes) transaction = transaction_pb2.Transaction( header=header_bytes, payload=payload.to_cbor(), header_signature=signature) return transaction
def make_ping(): """ Makes a ping transaction (a transaction that does nothing but make sure the validator and transaction processor is up and responding) """ payload = "ping".encode("utf-8") header = transaction_pb2.TransactionHeader( inputs=[], outputs=[], batcher_public_key=BATCHER_KEY_PAIR.public_key, dependencies=[], family_name=addresser.family.name, family_version=addresser.family.version, nonce=uuid4().hex, signer_public_key=BATCHER_KEY_PAIR.public_key, payload_sha512=sha512(payload).hexdigest(), ) transaction = transaction_pb2.Transaction( payload=payload, header=header.SerializeToString(), header_signature=BATCHER_KEY_PAIR.sign(header.SerializeToString()), ) batch = make_batch(transaction=transaction, batcher_keypair=BATCHER_KEY_PAIR) batch_list = batch_to_list(batch=batch) batch_request = make_batch_request(batch_list=batch_list) return transaction, batch, batch_list, batch_request
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 create_intkey_transaction(verb, name, value, private_key, public_key): payload = IntKeyPayload( verb=verb, name=name, value=value) # The prefix should eventually be looked up from the # validator's namespace registry. addr = make_intkey_address(name) header = transaction_pb2.TransactionHeader( signer_public_key=public_key, family_name='intkey', family_version='1.0', inputs=[addr], outputs=[addr], dependencies=[], payload_sha512=payload.sha512(), batcher_public_key=public_key, nonce=time.time().hex().encode()) header_bytes = header.SerializeToString() signature = signing.sign(header_bytes, private_key) transaction = transaction_pb2.Transaction( header=header_bytes, payload=payload.to_cbor(), header_signature=signature) return transaction
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 create_intkey_transaction(verb, name, value, deps, signer): payload = IntKeyPayload(verb=verb, name=name, value=value) addr = make_intkey_address(name) header = transaction_pb2.TransactionHeader( signer_public_key=signer.get_public_key().as_hex(), family_name='intkey', family_version='1.0', inputs=[addr], outputs=[addr], dependencies=deps, payload_sha512=payload.sha512(), batcher_public_key=signer.get_public_key().as_hex(), nonce=hex(random.randint(0, 2**64))) header_bytes = header.SerializeToString() signature = signer.sign(header_bytes) transaction = transaction_pb2.Transaction(header=header_bytes, payload=payload.to_cbor(), header_signature=signature) return transaction
def make_transaction(payload, signer_keypair): """ Make a transaction from a payload """ header, signature = make_transaction_header(payload=payload, signer_keypair=signer_keypair) return transaction_pb2.Transaction( payload=payload.SerializeToString(), header=header.SerializeToString(), header_signature=signature, )
def create_jvm_sc_transaction(verb, private_key, public_key, bytecode=None, methods=None, byte_addr=None, method=None, parameters=None, addresses=None): payload = JVM_SC_Payload(verb=verb, bytecode=bytecode, methods=methods, byte_addr=byte_addr, method=method, parameters=parameters) if addresses is None: addresses = [] # The prefix should eventually be looked up from the # validator's namespace registry. if byte_addr is not None: addr = byte_addr elif bytecode is not None: addr = get_address('jvm_sc', bytecode) else: raise Exception addresses.append(addr) header = transaction_pb2.TransactionHeader( signer_pubkey=public_key, family_name='jvm_sc', family_version='1.0', inputs=addresses, outputs=addresses, dependencies=[], payload_encoding="application/protobuf", payload_sha512=payload.sha512(), batcher_pubkey=public_key, nonce=str(time.time())) header_bytes = header.SerializeToString() signature = signing.sign(header_bytes, private_key) transaction = transaction_pb2.Transaction(header=header_bytes, payload=payload.payload_bytes, header_signature=signature) return transaction
def create_intkey_transaction(verb, name, value, deps, private_key, public_key): """Creates a signed intkey transaction. Args: verb (str): the action the transaction takes, either 'set', 'inc', or 'dec' name (str): the variable name which is altered by verb and value value (int): the amount to set, increment, or decrement deps ([str]): a list of transaction header_signatures which are required dependencies which must be processed prior to processing this transaction private_key (str): the private key used to sign the transaction public_key (str): the public key associated with the private key - the public key is included in the transaction as signer_pubkey Returns: transaction (transaction_pb2.Transaction): the signed intkey transaction """ payload = IntKeyPayload(verb=verb, name=name, value=value) # The prefix should eventually be looked up from the # validator's namespace registry. intkey_prefix = hashlib.sha512('intkey'.encode('utf-8')).hexdigest()[0:6] addr = intkey_prefix + hashlib.sha512(name.encode('utf-8')).hexdigest() header = transaction_pb2.TransactionHeader( signer_pubkey=public_key, family_name='intkey', family_version='1.0', inputs=[addr], outputs=[addr], dependencies=deps, payload_encoding="application/cbor", payload_sha512=payload.sha512(), batcher_pubkey=public_key, nonce=time.time().hex().encode()) header_bytes = header.SerializeToString() signature = signing.sign(header_bytes, private_key) transaction = transaction_pb2.Transaction(header=header_bytes, payload=payload.to_cbor(), header_signature=signature) return transaction
def make_transaction(payload, signer_keypair, batcher_public_key=BATCHER_KEY_PAIR.public_key): """Make a transaction from a payload""" header, signature = make_transaction_header( payload=payload, signer_keypair=signer_keypair, batcher_public_key=batcher_public_key, ) return transaction_pb2.Transaction( payload=payload.SerializeToString(), header=header.SerializeToString(), header_signature=signature, )
def create_intkey_transaction(verb, name, value, deps, signer): """Creates a signed intkey transaction. Args: verb (str): the action the transaction takes, either 'set', 'inc', or 'dec' name (str): the variable name which is altered by verb and value value (int): the amount to set, increment, or decrement deps ([str]): a list of transaction header_signatures which are required dependencies which must be processed prior to processing this transaction signer (:obj:`Signer`): the cryptographic signer for signing the transaction Returns: transaction (transaction_pb2.Transaction): the signed intkey transaction """ payload = IntKeyPayload( verb=verb, name=name, value=value) # The prefix should eventually be looked up from the # validator's namespace registry. addr = make_intkey_address(name) header = transaction_pb2.TransactionHeader( signer_public_key=signer.get_public_key().as_hex(), family_name='intkey', family_version='1.0', inputs=[addr], outputs=[addr], dependencies=deps, payload_sha512=payload.sha512(), batcher_public_key=signer.get_public_key().as_hex(), nonce=time.time().hex().encode()) header_bytes = header.SerializeToString() signature = signer.sign(header_bytes) transaction = transaction_pb2.Transaction( header=header_bytes, payload=payload.to_cbor(), header_signature=signature) return transaction
def _create_proposal(self, block_header, pbft_enclave_module): """ proposal request """ public_key_hash = hashlib.sha256(block_header.signer_public_key.encode()).hexdigest() nonce = SignupInfo.block_id_to_nonce(block_header.previous_block_id) setting = 'sawtooth.consensus.pbft.max_log_size' if False: # try to set pbft params proposal = SettingProposal( setting=setting, value='1003', nonce=nonce) payload = SettingsPayload(data=proposal.SerializeToString(),action=SettingsPayload.PROPOSE) serialized = payload.SerializeToString() input_addresses = _config_inputs(setting) output_addresses = _config_outputs(setting) header = txn_pb.TransactionHeader( signer_public_key=block_header.signer_public_key, family_name='sawtooth_settings', family_version='1.0', inputs=input_addresses, outputs=output_addresses, dependencies=[], payload_sha512=hashlib.sha512(serialized).hexdigest(), batcher_public_key=block_header.signer_public_key, nonce=hex(random.randint(0, 2**64))).SerializeToString() signature = self._batch_publisher.identity_signer.sign(header) transaction = txn_pb.Transaction( header=header, payload=serialized, header_signature=signature) LOGGER.info('payload action=%s nonce=%s', payload.action, nonce) self._batch_publisher.send([transaction]) else: # get setting pass
def _create_txn_and_batch(self, txn_key, batch_key, inputs, outputs, payload): txn_header_bytes, signature = self._transaction_header( txn_key, batch_key, inputs, outputs, payload) txn = transaction_pb2.Transaction(header=txn_header_bytes, header_signature=signature, payload=payload.SerializeToString()) transactions = [txn] batch_header_bytes, signature = self._batch_header( batch_key, transactions) batch = batch_pb2.Batch(header=batch_header_bytes, header_signature=signature, transactions=transactions) return batch, signature
def assertValidTransaction(self, transaction, payload, signer_public_key): """Check a transaction is valid given a payload""" if isinstance(transaction, bytes): decoded = transaction_pb2.Transaction() decoded.ParseFromString(transaction) transaction = decoded self.assertIsInstance(transaction, transaction_pb2.Transaction) self.assertValidTransactionHeader( header=transaction.header, signature=transaction.header_signature, payload=payload, signer_public_key=signer_public_key, ) self.assertEqualPayload(payload1=transaction.payload, payload2=payload) message_type, message, _, _, _ = unmake_payload(payload) self.assertValidPayload( payload=transaction.payload, message=message, message_type=message_type )
def prepare_transaction(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)) return transaction.header_signature, transaction
def assertValidTransaction( self, transaction, message, message_type, inputs, outputs, signer_public_key ): if isinstance(transaction, bytes): decoded = transaction_pb2.Transaction() decoded.ParseFromString(transaction) transaction = decoded self.assertIsInstance(transaction, transaction_pb2.Transaction) self.assertValidTransactionHeader( header=transaction.header, signature=transaction.header_signature, message=message, message_type=message_type, inputs=inputs, outputs=outputs, signer_public_key=signer_public_key, )
def create_transaction(payload, addr, signer): header = transaction_pb2.TransactionHeader( signer_public_key=signer.get_public_key().as_hex(), family_name=get_family_name(), family_version=get_family_version(), inputs=[addr], outputs=[addr], dependencies=[], payload_sha512=payload.sha512(), batcher_public_key=signer.get_public_key().as_hex(), nonce=time.time().hex().encode()) header_bytes = header.SerializeToString() signature = signer.sign(header_bytes) transaction = transaction_pb2.Transaction(header=header_bytes, payload=payload.get_encrypted(), header_signature=signature) return transaction
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
def create_noop_transaction(signer): payload = NoopPayload() header = transaction_pb2.TransactionHeader( signer_public_key=signer.get_public_key().as_hex(), family_name='noop', family_version='1.0', inputs=[], outputs=[], dependencies=[], payload_sha512=payload.sha512(), batcher_public_key=signer.get_public_key().as_hex(), nonce=time.time().hex().encode()) header_bytes = header.SerializeToString() signature = signer.sign(header_bytes) transaction = transaction_pb2.Transaction(header=header_bytes, payload=payload.nonce, header_signature=signature) return transaction
def _register_signup_information(self, block_header, poet_enclave_module): # Create signup information for this validator, putting the block ID # of the block previous to the block referenced by block_header in the # nonce. Block ID is better than wait certificate ID for testing # freshness as we need to account for non-PoET blocks. public_key_hash = \ hashlib.sha256( block_header.signer_public_key.encode()).hexdigest() nonce = SignupInfo.block_id_to_nonce(block_header.previous_block_id) signup_info = \ SignupInfo.create_signup_info( poet_enclave_module=poet_enclave_module, originator_public_key_hash=public_key_hash, nonce=nonce) # Create the validator registry payload payload = \ vr_pb.ValidatorRegistryPayload( verb='register', name='validator-{}'.format(block_header.signer_public_key[:8]), id=block_header.signer_public_key, signup_info=vr_pb.SignUpInfo( poet_public_key=signup_info.poet_public_key, proof_data=signup_info.proof_data, anti_sybil_id=signup_info.anti_sybil_id, nonce=nonce), ) serialized = payload.SerializeToString() # Create the address that will be used to look up this validator # registry transaction. Seems like a potential for refactoring.. validator_entry_address = \ PoetBlockPublisher._validator_registry_namespace + \ hashlib.sha256(block_header.signer_public_key.encode()).hexdigest() # Create a transaction header and transaction for the validator # registry update amd then hand it off to the batch publisher to # send out. output_addresses = \ [validator_entry_address, PoetBlockPublisher._validator_map_address] input_addresses = \ output_addresses + \ [SettingsView.setting_address( 'sawtooth.poet.report_public_key_pem'), SettingsView.setting_address( 'sawtooth.poet.valid_enclave_measurements'), SettingsView.setting_address( 'sawtooth.poet.valid_enclave_basenames')] header = \ txn_pb.TransactionHeader( signer_public_key=block_header.signer_public_key, family_name='sawtooth_validator_registry', family_version='1.0', inputs=input_addresses, outputs=output_addresses, dependencies=[], payload_sha512=hashlib.sha512(serialized).hexdigest(), batcher_public_key=block_header.signer_public_key, nonce=time.time().hex().encode()).SerializeToString() signature = self._batch_publisher.identity_signer.sign(header) transaction = \ txn_pb.Transaction( header=header, payload=serialized, header_signature=signature) LOGGER.info( 'Register Validator Name=%s, ID=%s...%s, PoET public key=%s...%s, ' 'Nonce=%s', payload.name, payload.id[:8], payload.id[-8:], payload.signup_info.poet_public_key[:8], payload.signup_info.poet_public_key[-8:], nonce) self._batch_publisher.send([transaction]) # Store the key state so that we can look it up later if need be and # set the new key as our active key LOGGER.info('Save key state PPK=%s...%s => SSD=%s...%s', signup_info.poet_public_key[:8], signup_info.poet_public_key[-8:], signup_info.sealed_signup_data[:8], signup_info.sealed_signup_data[-8:]) self._poet_key_state_store[signup_info.poet_public_key] = \ PoetKeyState( sealed_signup_data=signup_info.sealed_signup_data, has_been_refreshed=False, signup_nonce=nonce) self._poet_key_state_store.active_key = signup_info.poet_public_key
def _register_signup_information(self, block_header, pbft_enclave_module=None): # Create signup information for this validator, putting the block ID # of the block previous to the block referenced by block_header in the # nonce. Block ID is better than wait certificate ID for testing # freshness as we need to account for non-BGT blocks. LOGGER.debug('_register_signup_information: TRY to REGISTER') public_key_hash = hashlib.sha256( block_header.signer_public_key.encode()).hexdigest() nonce = SignupInfo.block_id_to_nonce(block_header.previous_block_id) pbft_public_key = self._validator_id anti_sybil_id = hashlib.sha256(pbft_public_key.encode()).hexdigest() signup_data = { 'pbft_public_key': pbft_public_key, } sealed_signup_data = base64.b64encode( dict2json(signup_data).encode()).decode('utf-8') """ signup_info = SignupInfo.create_signup_info( pbft_enclave_module=pbft_enclave_module, originator_public_key_hash=public_key_hash, nonce=nonce) """ # Create the validator registry payload payload = vr_pb.BgxValidatorRegistryPayload( verb='register', name='validator-{}'.format(block_header.signer_public_key[:8]), id=block_header.signer_public_key, node=self._node, signup_info=vr_pb.BgxSignUpInfo( pbft_public_key=pbft_public_key, # signup_info.pbft_public_key, anti_sybil_id=anti_sybil_id, # signup_info.anti_sybil_id, nonce=nonce), ) serialized = payload.SerializeToString() # Create the address that will be used to look up this validator # registry transaction. Seems like a potential for refactoring.. validator_entry_address = PbftBlockPublisher._validator_registry_namespace + hashlib.sha256( block_header.signer_public_key.encode()).hexdigest() # Create a transaction header and transaction for the validator # registry update amd then hand it off to the batch publisher to # send out. output_addresses = [ validator_entry_address, PbftBlockPublisher._validator_map_address ] input_addresses = output_addresses + \ [SettingsView.setting_address('sawtooth.bgt.report_public_key_pem'), SettingsView.setting_address('sawtooth.bgt.valid_enclave_measurements'), SettingsView.setting_address('sawtooth.bgt.valid_enclave_basenames') ] header = txn_pb.TransactionHeader( signer_public_key=block_header.signer_public_key, family_name='bgx_validator_registry', family_version='1.0', inputs=input_addresses, outputs=output_addresses, dependencies=[], payload_sha512=hashlib.sha512(serialized).hexdigest(), batcher_public_key=block_header.signer_public_key, nonce=hex(random.randint(0, 2**64))).SerializeToString() signature = self._batch_publisher.identity_signer.sign(header) transaction = txn_pb.Transaction(header=header, payload=serialized, header_signature=signature) LOGGER.info('Register Validator Name=%s, ID=%s...%s,Nonce=%s', payload.name, payload.id[:8], payload.id[-8:], nonce) self._batch_publisher.send([transaction]) # Store the key state so that we can look it up later if need be and # set the new key as our active key self._pbft_key_state_store[pbft_public_key] = PbftKeyState( sealed_signup_data=sealed_signup_data, has_been_refreshed=False, signup_nonce=nonce) self._pbft_key_state_store.active_key = pbft_public_key LOGGER.debug('_register_signup_information: REGISTER DONE')
def do_create(args): """Executes the `poet registration` subcommand. This command generates a validator registry transaction and saves it to a file, whose location is determined by the args. The signup data, generated by the selected enclave, is also stored in a well-known location. """ signer = _read_signer(args.key) public_key = signer.get_public_key().as_hex() public_key_hash = sha256(public_key.encode()).hexdigest() nonce = SignupInfo.block_id_to_nonce(args.block) with PoetEnclaveModuleWrapper( enclave_module=args.enclave_module, config_dir=config.get_config_dir(), data_dir=config.get_data_dir()) as poet_enclave_module: signup_info = SignupInfo.create_signup_info( poet_enclave_module=poet_enclave_module, originator_public_key_hash=public_key_hash, nonce=nonce) print('Writing key state for PoET public key: {}...{}'.format( signup_info.poet_public_key[:8], signup_info.poet_public_key[-8:])) # Store the newly-created PoET key state, associating it with its # corresponding public key poet_key_state_store = \ PoetKeyStateStore( data_dir=config.get_data_dir(), validator_id=public_key) poet_key_state_store[signup_info.poet_public_key] = \ PoetKeyState( sealed_signup_data=signup_info.sealed_signup_data, has_been_refreshed=False, signup_nonce=nonce) # Create the validator registry payload payload = \ vr_pb.ValidatorRegistryPayload( verb='register', name='validator-{}'.format(public_key[:8]), id=public_key, signup_info=vr_pb.SignUpInfo( poet_public_key=signup_info.poet_public_key, proof_data=signup_info.proof_data, anti_sybil_id=signup_info.anti_sybil_id, nonce=SignupInfo.block_id_to_nonce(args.block))) serialized = payload.SerializeToString() # Create the address that will be used to look up this validator # registry transaction. Seems like a potential for refactoring.. validator_entry_address = \ VR_NAMESPACE + sha256(public_key.encode()).hexdigest() # Create a transaction header and transaction for the validator # registry update amd then hand it off to the batch publisher to # send out. output_addresses = [validator_entry_address, VALIDATOR_MAP_ADDRESS] input_addresses = \ output_addresses + \ [SettingsView.setting_address('sawtooth.poet.report_public_key_pem'), SettingsView.setting_address('sawtooth.poet.' 'valid_enclave_measurements'), SettingsView.setting_address('sawtooth.poet.valid_enclave_basenames')] header = \ txn_pb.TransactionHeader( signer_public_key=public_key, family_name='sawtooth_validator_registry', family_version='1.0', inputs=input_addresses, outputs=output_addresses, dependencies=[], payload_sha512=sha512(serialized).hexdigest(), batcher_public_key=public_key, nonce=time.time().hex().encode()).SerializeToString() signature = signer.sign(header) transaction = \ txn_pb.Transaction( header=header, payload=serialized, header_signature=signature) batch = _create_batch(signer, [transaction]) batch_list = batch_pb.BatchList(batches=[batch]) try: print('Generating {}'.format(args.output)) with open(args.output, 'wb') as batch_file: batch_file.write(batch_list.SerializeToString()) except IOError as e: raise CliException('Unable to write to batch file: {}'.format(str(e)))