def to_dict(self): """Transform the Block to a Python dictionary. Returns: dict: The Block as a dict. Raises: ValueError: If the Block doesn't contain any transactions. """ if len(self.transactions) == 0: raise ValueError('Empty block creation is not allowed') block = { 'timestamp': self.timestamp, 'transactions': [tx.to_dict() for tx in self.transactions], 'node_pubkey': self.node_pubkey, 'voters': self.voters, } block_serialized = serialize(block) block_id = hash_data(block_serialized) return { 'id': block_id, 'block': block, 'signature': self.signature, }
def to_dict(self): """Transform the Block to a Python dictionary. Returns: dict: The Block as a dict. Raises: OperationError: If the Block doesn't contain any transactions. """ if len(self.transactions) == 0: raise OperationError('Empty block creation is not allowed') block = { 'timestamp': self.timestamp, 'transactions': [tx.to_dict() for tx in self.transactions], 'node_pubkey': self.node_pubkey, 'voters': self.voters, } block_serialized = serialize(block) block_id = hash_data(block_serialized) return { 'id': block_id, 'block': block, 'signature': self.signature, }
def from_dict(cls, block_body): """Transform a Python dictionary to a Block object. Args: block_body (dict): A block dictionary to be transformed. Returns: :class:`~Block` Raises: InvalidHash: If the block's id is not corresponding to its data. """ # Validate block id block = block_body['block'] block_serialized = serialize(block) block_id = hash_data(block_serialized) if block_id != block_body['id']: raise InvalidHash() transactions = [Transaction.from_dict(tx) for tx in block['transactions']] signature = block_body.get('signature') return cls(transactions, block['node_pubkey'], block['timestamp'], block['voters'], signature)
def create_asset_hashlock(bigchain, payload, secret): # Create a hash-locked asset without any new_owners hashlock_tx = bigchain.create_transaction(bigchain.me, None, None, 'CREATE', payload=payload) hashlock_tx_condition = cc.PreimageSha256Fulfillment( preimage=secret.encode()) # The conditions list is empty, so we need to append a new condition hashlock_tx['transaction']['conditions'].append({ 'condition': { 'details': hashlock_tx_condition.to_dict(), 'uri': hashlock_tx_condition.condition.serialize_uri() }, 'cid': 0, 'new_owners': None }) # Conditions have been updated, so hash needs updating hashlock_tx['id'] = crypto.hash_data(hashlock_tx) # The asset needs to be signed by the current_owner hashlock_tx_signed = bigchain.sign_transaction(hashlock_tx, bigchain.me_private) bigchain.validate_transaction(hashlock_tx_signed) # write the transaction to the bigchain bigchain.write_transaction(hashlock_tx_signed) return hashlock_tx_signed
def test_block_invalid_signature(self, b, alice): from bigchaindb.common.crypto import hash_data from bigchaindb.common.exceptions import InvalidSignature from bigchaindb.common.utils import gen_timestamp, serialize from bigchaindb.models import Block, Transaction transaction = Transaction.create([alice.public_key], [([alice.public_key], 1)]) transaction.sign([alice.private_key]) timestamp = gen_timestamp() block = { 'timestamp': timestamp, 'transactions': [transaction.to_dict()], 'node_pubkey': alice.public_key, } block_body = { 'id': hash_data(serialize(block)), 'block': block, 'signature': 'an invalid signature', } with raises(InvalidSignature): Block.from_dict(block_body).validate(b)
def from_dict(cls, block_body): block = block_body['block'] block_serialized = serialize(block) block_id = hash_data(block_serialized) verifying_key = VerifyingKey(block['node_pubkey']) try: signature = block_body['signature'] except KeyError: signature = None if block_id != block_body['id']: raise InvalidHash() if signature is not None: # NOTE: CC throws a `ValueError` on some wrong signatures # https://github.com/bigchaindb/cryptoconditions/issues/27 try: signature_valid = verifying_key\ .verify(block_serialized.encode(), signature) except ValueError: signature_valid = False if signature_valid is False: raise InvalidSignature('Invalid block signature') transactions = [ Transaction.from_dict(tx) for tx in block['transactions'] ] return cls(transactions, block['node_pubkey'], block['timestamp'], block['voters'], signature)
def from_dict(cls, block_body): """Transform a Python dictionary to a Block object. Args: block_body (dict): A block dictionary to be transformed. Returns: :class:`~Block` Raises: InvalidHash: If the block's id is not corresponding to its data. """ # Validate block id block = block_body['block'] block_serialized = serialize(block) block_id = hash_data(block_serialized) if block_id != block_body['id']: raise InvalidHash() transactions = [ Transaction.from_dict(tx) for tx in block['transactions'] ] signature = block_body.get('signature') return cls(transactions, block['node_pubkey'], block['timestamp'], block['voters'], signature)
def test_block_deserialization(self, b): from bigchaindb.common.crypto import hash_data from bigchaindb.common.utils import gen_timestamp, serialize from bigchaindb.models import Block, Transaction transaction = Transaction.create([b.me], [([b.me], 1)]) transaction.sign([b.me_private]) timestamp = gen_timestamp() voters = ['Qaaa', 'Qbbb'] expected = Block([transaction], b.me, timestamp, voters) block = { 'timestamp': timestamp, 'transactions': [transaction.to_dict()], 'node_pubkey': b.me, 'voters': voters, } block_body = { 'id': hash_data(serialize(block)), 'block': block, 'signature': None, } assert expected == Block.from_dict(block_body)
def test_block_serialization(self, b, alice): from bigchaindb.common.crypto import hash_data from bigchaindb.common.utils import gen_timestamp, serialize from bigchaindb.models import Block, Transaction transactions = [ Transaction.create([alice.public_key], [([alice.public_key], 1)]) ] timestamp = gen_timestamp() voters = ['Qaaa', 'Qbbb'] expected_block = { 'timestamp': timestamp, 'transactions': [tx.to_dict() for tx in transactions], 'node_pubkey': alice.public_key, 'voters': voters, } expected = { 'id': hash_data(serialize(expected_block)), 'block': expected_block, 'signature': None, } block = Block(transactions, alice.public_key, timestamp, voters) assert block.to_dict() == expected
def from_dict(cls, block_body): """Transform a Python dictionary to a Block object. Args: block_body (dict): A block dictionary to be transformed. Returns: :class:`~Block` Raises: InvalidHash: If the block's id is not corresponding to its data. InvalidSignature: If the block's signature is not corresponding to it's data or `node_pubkey`. """ # TODO: Reuse `is_signature_valid` method here. block = block_body['block'] block_serialized = serialize(block) block_id = hash_data(block_serialized) public_key = PublicKey(block['node_pubkey']) try: signature = block_body['signature'] except KeyError: signature = None if block_id != block_body['id']: raise InvalidHash() if signature is not None: # NOTE: CC throws a `ValueError` on some wrong signatures # https://github.com/bigchaindb/cryptoconditions/issues/27 try: signature_valid = public_key\ .verify(block_serialized.encode(), signature) except ValueError: signature_valid = False if signature_valid is False: raise InvalidSignature('Invalid block signature') transactions = [ Transaction.from_dict(tx) for tx in block['transactions'] ] return cls(transactions, block['node_pubkey'], block['timestamp'], block['voters'], signature)
def from_dict(cls, block_body): """Transform a Python dictionary to a Block object. Args: block_body (dict): A block dictionary to be transformed. Returns: :class:`~Block` Raises: InvalidHash: If the block's id is not corresponding to its data. InvalidSignature: If the block's signature is not corresponding to it's data or `node_pubkey`. """ # TODO: Reuse `is_signature_valid` method here. block = block_body['block'] block_serialized = serialize(block) block_id = hash_data(block_serialized) public_key = PublicKey(block['node_pubkey']) try: signature = block_body['signature'] except KeyError: signature = None if block_id != block_body['id']: raise InvalidHash() if signature is not None: # NOTE: CC throws a `ValueError` on some wrong signatures # https://github.com/bigchaindb/cryptoconditions/issues/27 try: signature_valid = public_key\ .verify(block_serialized.encode(), signature) except ValueError: signature_valid = False if signature_valid is False: raise InvalidSignature('Invalid block signature') transactions = [Transaction.from_dict(tx) for tx in block['transactions']] return cls(transactions, block['node_pubkey'], block['timestamp'], block['voters'], signature)
def to_dict(self): if len(self.transactions) == 0: raise OperationError('Empty block creation is not allowed') block = { 'timestamp': self.timestamp, 'transactions': [tx.to_dict() for tx in self.transactions], 'node_pubkey': self.node_pubkey, 'voters': self.voters, } block_serialized = serialize(block) block_id = hash_data(block_serialized) return { 'id': block_id, 'block': block, 'signature': self.signature, }
def test_block_deserialization(self, b, alice): from bigchaindb.common.crypto import hash_data from bigchaindb.common.utils import gen_timestamp, serialize from bigchaindb.models import Block, Transaction transaction = Transaction.create([alice.public_key], [([alice.public_key], 1)]) transaction.sign([alice.private_key]) timestamp = gen_timestamp() expected = Block([transaction], alice.public_key, timestamp) block = { 'timestamp': timestamp, 'transactions': [transaction.to_dict()], 'node_pubkey': alice.public_key, } block_body = { 'id': hash_data(serialize(block)), 'block': block, 'signature': None, } assert expected == Block.from_dict(block_body)
def test_block_invalid_signature(self, b): from bigchaindb.common.crypto import hash_data from bigchaindb.common.exceptions import InvalidSignature from bigchaindb.common.utils import gen_timestamp, serialize from bigchaindb.models import Block, Transaction transactions = [Transaction.create([b.me], [([b.me], 1)])] timestamp = gen_timestamp() block = { 'timestamp': timestamp, 'transactions': [tx.to_dict() for tx in transactions], 'node_pubkey': b.me, 'voters': list(b.federation), } block_body = { 'id': hash_data(serialize(block)), 'block': block, 'signature': 'an invalid signature', } with raises(InvalidSignature): Block.from_dict(block_body).validate(b)
def _hash(self): self._id = hash_data(self.serialized)
def _to_hash(value): return hash_data(value)
def get_hash_str(self, p_str): return hash_data(p_str)
def escrow_asset(bigchain, source, to, asset_id, sk, expires_at=None, ilp_header=None, execution_condition=None): asset = bigchain.get_transaction(asset_id['txid']) payload = asset['transaction']['data']['payload'].copy() if ilp_header: payload.update({'ilp_header': ilp_header}) # Create escrow template with the execute and abort address asset_escrow = bigchain.create_transaction(source, [source, to], asset_id, 'TRANSFER', payload=payload) if not expires_at: # Set expiry time (100 secs from now) time_sleep = 100 expires_at = float(gen_timestamp()) + time_sleep # Create escrow and timeout condition condition_escrow = cc.ThresholdSha256Fulfillment(threshold=1) # OR Gate condition_timeout = cc.TimeoutFulfillment( expire_time=str(expires_at)) # only valid if now() <= time_expire condition_timeout_inverted = cc.InvertedThresholdSha256Fulfillment( threshold=1) condition_timeout_inverted.add_subfulfillment(condition_timeout) # Create execute branch execution_threshold = 3 if execution_condition else 2 condition_execute = cc.ThresholdSha256Fulfillment( threshold=execution_threshold) # AND gate condition_execute.add_subfulfillment( cc.Ed25519Fulfillment(public_key=to)) # execute address condition_execute.add_subfulfillment( condition_timeout) # federation checks on expiry if execution_condition: condition_execute.add_subcondition_uri(execution_condition) condition_escrow.add_subfulfillment(condition_execute) # Create abort branch condition_abort = cc.ThresholdSha256Fulfillment(threshold=2) # AND gate condition_abort.add_subfulfillment( cc.Ed25519Fulfillment(public_key=source)) # abort address condition_abort.add_subfulfillment(condition_timeout_inverted) condition_escrow.add_subfulfillment(condition_abort) # Update the condition in the newly created transaction asset_escrow['transaction']['conditions'][0]['condition'] = { 'details': condition_escrow.to_dict(), 'uri': condition_escrow.condition.serialize_uri() } # conditions have been updated, so hash needs updating asset_escrow['id'] = crypto.hash_data(asset_escrow) # sign transaction asset_escrow_signed = bigchaindb.util.sign_tx(asset_escrow, sk, bigchain=bigchain) bigchain.write_transaction(asset_escrow_signed) return asset_escrow_signed