def test_generate(self): merkle_tree_generator = MerkleTreeGenerator() merkle_tree_generator.populate(get_test_data_generator()) byte_array = merkle_tree_generator.get_blockchain_data() self.assertEqual( b2h(byte_array), '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')
def instantiate_blockchain_handlers(app_config, file_mode=True): issuing_address = app_config.issuing_address chain = app_config.chain secret_manager = initialize_signer(app_config) if file_mode: certificate_batch_handler = CertificateBatchHandler( secret_manager=secret_manager, certificate_handler=CertificateV2Handler(), merkle_tree=MerkleTreeGenerator()) else: certificate_batch_handler = CertificateBatchWebHandler( secret_manager=secret_manager, certificate_handler=CertificateWebV2Handler(), merkle_tree=MerkleTreeGenerator()) if chain == Chain.mockchain: transaction_handler = MockTransactionHandler() else: cost_constants = BitcoinTransactionCostConstants( app_config.tx_fee, app_config.dust_threshold, app_config.satoshi_per_byte) connector = BitcoinServiceProviderConnector(chain, app_config.bitcoind) transaction_handler = BitcoinTransactionHandler( connector, cost_constants, secret_manager, issuing_address=issuing_address) return certificate_batch_handler, transaction_handler, connector
def test_proofs(self): merkle_tree_generator = MerkleTreeGenerator() merkle_tree_generator.populate(get_test_data_generator()) _ = merkle_tree_generator.get_blockchain_data() gen = merkle_tree_generator.get_proof_generator( '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', Chain.mainnet) p1 = next(gen) _ = next(gen) p3 = next(gen) p1_expected = {'type': ['MerkleProof2017', 'Extension'], 'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044', 'targetHash': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b', 'proof': [{'right': 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35'}, {'right': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'}], 'anchors': [ {'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', 'type': 'BTCOpReturn'}]} p3_expected = {'type': ['MerkleProof2017', 'Extension'], 'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044', 'targetHash': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce', 'proof': [{'left': '4295f72eeb1e3507b8461e240e3b8d18c1e7bd2f1122b11fc9ec40a65894031a'}], 'anchors': [{'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', 'type': 'BTCOpReturn'}]} self.assertEqual(p1, p1_expected) self.assertEqual(p3, p3_expected)
class SimplifiedCertificateBatchIssuer: """ Class to issue blockcerts without relying on filesystem usage. Please note that it currently only supports anchoring to Ethereum. """ def __init__(self, config: 'AttrDict', unsigned_certs: dict): # 1- Prepare config and unsigned certs (These come from my latest changes in cert-tools self.config = config self.config.original_chain = self.config.chain self.config.chain = Chain.parse_from_chain(self.config.chain) self.path_to_secret = os.path.join(config.usb_name, config.key_file) self.unsigned_certs = unsigned_certs self.cert_generator = self._create_cert_generator() # 2- Calculate Merkle Tree and Root self.merkle_tree_generator = MerkleTreeGenerator() self.merkle_tree_generator.populate(self.cert_generator) self.merkle_root = self.merkle_tree_generator.get_blockchain_data() def issue(self) -> Tuple[str, Dict]: """Anchor the merkle root in a blockchain transaction and add the tx id and merkle proof to each cert.""" tx_id = self._broadcast_transaction() signed_certs = self._add_proof_to_certs(tx_id) return tx_id, signed_certs def _add_proof_to_certs(self, tx_id) -> Dict: """Add merkle proof to the JSON of the certificates.""" proof_generator = self.merkle_tree_generator.get_proof_generator( tx_id, self.config.chain) signed_certs = copy.deepcopy(self.unsigned_certs) for _, cert in signed_certs.items(): proof = next(proof_generator) cert['signature'] = proof return signed_certs def _broadcast_transaction(self) -> str: """Broadcast the tx used to anchor a merkle root to a given blockchain.""" self.transaction_handler = SimplifiedEthereumTransactionHandler( chain=self.config.original_chain.split('_')[1], path_to_secret=self.path_to_secret, private_key=self.config.get('eth_private_key'), recommended_max_cost=self.config.gas_price * self.config.gas_limit, account_from=self.config.get('eth_public_key') or self.config.issuing_address, ) tx_id = self.transaction_handler.issue_transaction(self.merkle_root) return tx_id def _create_cert_generator(self) -> Generator: """Return a generator of jsonld-normalized unsigned certs.""" for uid, cert in self.unsigned_certs.items(): normalized = normalize_jsonld(cert, detect_unmapped_fields=False) yield normalized.encode('utf-8')
def __init__(self, config: 'AttrDict', unsigned_certs: dict): # 1- Prepare config and unsigned certs (These come from my latest changes in cert-tools self.config = config self.config.original_chain = self.config.chain self.config.chain = Chain.parse_from_chain(self.config.chain) self.path_to_secret = os.path.join(config.usb_name, config.key_file) self.unsigned_certs = unsigned_certs self.cert_generator = self._create_cert_generator() # 2- Calculate Merkle Tree and Root self.merkle_tree_generator = MerkleTreeGenerator() self.merkle_tree_generator.populate(self.cert_generator) self.merkle_root = self.merkle_tree_generator.get_blockchain_data()
def instantiate_blockchain_handlers(app_config): check_necessary_arguments(app_config) issuing_address = app_config.issuing_address chain = app_config.chain secret_manager = initialize_signer(app_config) certificate_batch_handler = CertificateBatchHandler( secret_manager=secret_manager, certificate_handler=CertificateV3Handler(), merkle_tree=MerkleTreeGenerator(), config=app_config) if chain == Chain.mockchain: transaction_handler = MockTransactionHandler() # ethereum chains elif chain == Chain.ethereum_mainnet or chain == Chain.ethereum_bloxberg: cost_constants = EthereumTransactionCostConstants( app_config.gas_price, app_config.gas_limit) connector = instantiate_connector(app_config, cost_constants) transaction_handler = EthereumSCTransactionHandler( connector, cost_constants, secret_manager, issuing_address=issuing_address) return certificate_batch_handler, transaction_handler, connector
def main(app_config): issuing_address = app_config.issuing_address chain = app_config.chain secret_manager = signer_helper.initialize_signer(app_config) certificate_batch_handler = CertificateBatchHandler( secret_manager=secret_manager, certificate_handler=CertificateV2Handler(), merkle_tree=MerkleTreeGenerator()) if chain == Chain.mockchain: transaction_handler = MockTransactionHandler() # ethereum chains elif chain == Chain.ethereum_mainnet or chain == Chain.ethereum_ropsten or chain == Chain.ethereum_testnet: cost_constants = EthereumTransactionCostConstants( app_config.gas_price, app_config.gas_limit) connector = EthereumServiceProviderConnector(chain, app_config.api_token) transaction_handler = EthereumTransactionHandler( connector, cost_constants, secret_manager, issuing_address=issuing_address) else: cost_constants = BitcoinTransactionCostConstants( app_config.tx_fee, app_config.dust_threshold, app_config.satoshi_per_byte) connector = BitcoinServiceProviderConnector(chain, app_config.bitcoind) transaction_handler = BitcoinTransactionHandler( connector, cost_constants, secret_manager, issuing_address=issuing_address) return issue(app_config, certificate_batch_handler, transaction_handler)
def do_test_signature(self, chain, display_chain, type): merkle_tree_generator = MerkleTreeGenerator() merkle_tree_generator.populate(get_test_data_generator()) _ = merkle_tree_generator.get_blockchain_data() gen = merkle_tree_generator.get_proof_generator( '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', chain) p1 = next(gen) _ = next(gen) p3 = next(gen) p1_expected = {'type': ['MerkleProof2017', 'Extension'], 'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044', 'targetHash': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b', 'proof': [{'right': 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35'}, {'right': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'}], 'anchors': [ {'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', 'type': type, 'chain': display_chain}]} p3_expected = {'type': ['MerkleProof2017', 'Extension'], 'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044', 'targetHash': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce', 'proof': [{'left': '4295f72eeb1e3507b8461e240e3b8d18c1e7bd2f1122b11fc9ec40a65894031a'}], 'anchors': [{'sourceId': '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', 'type': type, 'chain': display_chain}]} self.assertEqual(p1, p1_expected) self.assertEqual(p3, p3_expected)
def _get_certificate_batch_handler(self): secret_manager = mock.Mock() certificates_to_issue = dict() certificates_to_issue['1'] = mock.Mock() certificates_to_issue['2'] = mock.Mock() certificates_to_issue['3'] = mock.Mock() handler = CertificateBatchHandler( secret_manager=secret_manager, certificate_handler=DummyCertificateHandler(), merkle_tree=MerkleTreeGenerator()) return handler, certificates_to_issue
def test_prepare_batch(self): secret_manager = mock.Mock() certificates_to_issue = dict() certificates_to_issue['1'] = mock.Mock() certificates_to_issue['2'] = mock.Mock() certificates_to_issue['3'] = mock.Mock() certificate_batch_handler = CertificateBatchHandler(secret_manager=secret_manager, certificate_handler=DummyCertificateHandler(), merkle_tree=MerkleTreeGenerator()) certificate_batch_handler.set_certificates_in_batch(certificates_to_issue) result = certificate_batch_handler.prepare_batch() self.assertEqual(b2h(result), '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')
def instantiate_blockchain_handlers(app_config): issuing_address = app_config.issuing_address chain = app_config.chain secret_manager = initialize_signer(app_config) certificate_batch_handler = CertificateBatchHandler(secret_manager=secret_manager, certificate_handler=CertificateV2Handler(), merkle_tree=MerkleTreeGenerator()) if chain == Chain.mockchain: transaction_handler = MockTransactionHandler() # ethereum chains elif chain == Chain.ethereum_mainnet or chain == Chain.ethereum_ropsten: cost_constants = EthereumTransactionCostConstants(app_config.gas_price, app_config.gas_limit) connector = EthereumServiceProviderConnector(chain, app_config.api_token) transaction_handler = EthereumTransactionHandler(connector, cost_constants, secret_manager, issuing_address=issuing_address) return certificate_batch_handler, transaction_handler, connector
def _get_certificate_batch_handler(self): secret_manager = mock.Mock() certificates_to_issue = dict() certificates_to_issue['1'] = mock.Mock() certificates_to_issue['2'] = mock.Mock() certificates_to_issue['3'] = mock.Mock() config = mock.Mock() config.issuing_address = "http://example.com" handler = CertificateBatchHandler( secret_manager=secret_manager, certificate_handler=DummyCertificateHandler(), merkle_tree=MerkleTreeGenerator(), config=config) return handler, certificates_to_issue
def main(app_config): issuing_address = app_config.issuing_address chain = app_config.bitcoin_chain secret_manager = signer_helper.initialize_signer(app_config) certificate_batch_handler = CertificateBatchHandler( secret_manager=secret_manager, certificate_handler=CertificateV2Handler(), merkle_tree=MerkleTreeGenerator()) if chain == Chain.mocknet: transaction_handler = MockTransactionHandler() else: cost_constants = TransactionCostConstants(app_config.tx_fee, app_config.dust_threshold, app_config.satoshi_per_byte) connector = ServiceProviderConnector(chain, app_config.bitcoind) transaction_handler = BitcoinTransactionHandler( connector, cost_constants, secret_manager, issuing_address=issuing_address) return issue(app_config, certificate_batch_handler, transaction_handler)
def test_generate(self): merkle_tree_generator = MerkleTreeGenerator() merkle_tree_generator.populate(get_test_data_generator()) byte_array = merkle_tree_generator.get_blockchain_data() self.assertEqual(b2h(byte_array), '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')
def do_test_signature(self, chain, display_chain, type): self.maxDiff = None app_config = mock.Mock() app_config.issuing_method = "transaction" merkle_tree_generator = MerkleTreeGenerator() merkle_tree_generator.populate(get_test_data_generator()) _ = merkle_tree_generator.get_blockchain_data() gen = merkle_tree_generator.get_proof_generator( '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582', 'http://example.com', chain) p1 = next(gen) _ = next(gen) p3 = next(gen) p1_json_proof = { 'path': [{ 'right': 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35' }, { 'right': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' }], 'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044', 'targetHash': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b', 'anchors': [ helpers.tx_to_blink( chain, '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582' ) ] } mp2019 = MerkleProof2019() proof_value = mp2019.encode(p1_json_proof) p1_expected = { "type": "MerkleProof2019", "created": p1['created'], "proofValue": proof_value.decode('utf8'), "proofPurpose": "assertionMethod", "verificationMethod": "http://example.com" } p3_json_proof = { 'path': [{ 'left': '4295f72eeb1e3507b8461e240e3b8d18c1e7bd2f1122b11fc9ec40a65894031a' }], 'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044', 'targetHash': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce', 'anchors': [ helpers.tx_to_blink( chain, '8087c03e7b7bc9ca7b355de9d9d8165cc5c76307f337f0deb8a204d002c8e582' ) ] } mp2019 = MerkleProof2019() proof_value = mp2019.encode(p3_json_proof) p3_expected = { "type": "MerkleProof2019", "created": p3['created'], "proofValue": proof_value.decode('utf8'), "proofPurpose": "assertionMethod", "verificationMethod": "http://example.com" } self.assertEqual(p1, p1_expected) self.assertEqual(p3, p3_expected)