Пример #1
0
def test_unsupported_condition_type():
    from bigchaindb.common import transaction
    from cryptoconditions.exceptions import UnsupportedTypeError

    with pytest.raises(UnsupportedTypeError):
        transaction._fulfillment_from_details({'type': 'a'})

    with pytest.raises(UnsupportedTypeError):
        transaction._fulfillment_to_details(MagicMock(type_name='a'))
Пример #2
0
def test_handle_threshold_overflow():
    from bigchaindb.common import transaction

    cond = {
        'type': 'ed25519-sha-256',
        'public_key': 'a' * 43,
    }
    for i in range(1000):
        cond = {
            'type': 'threshold-sha-256',
            'threshold': 1,
            'subconditions': [cond],
        }
    with pytest.raises(ThresholdTooDeep):
        transaction._fulfillment_from_details(cond)
Пример #3
0
def prepare_transfer_transaction(*, inputs, recipients, asset, metadata=None):
    """Prepares a ``"TRANSFER"`` transaction payload, ready to be
    fulfilled.

    Args:
        inputs (:obj:`dict` | :obj:`list` | :obj:`tuple`): One or more
            inputs holding the condition(s) that this transaction
            intends to fulfill. Each input is expected to be a
            :obj:`dict`.
        recipients (:obj:`str` | :obj:`list` | :obj:`tuple`): One or
            more public keys representing the new recipients(s) of the
            asset being transferred.
        asset (:obj:`dict`): A single-key dictionary holding the ``id``
            of the asset being transferred with this transaction.
        metadata (:obj:`dict`): Metadata associated with the
            transaction. Defaults to ``None``.

    Returns:
        dict: The prepared ``"TRANSFER"`` transaction.

    .. important::

        * ``asset`` MUST be in the form of::

            {
                'id': '<Asset ID (i.e. TX ID of its CREATE transaction)>'
            }

    Example:

        .. todo:: Replace this section with docs.

        In case it may not be clear what an input should look like, say
        Alice (public key: ``'3Cxh1eKZk3Wp9KGBWFS7iVde465UvqUKnEqTg2MW4wNf'``)
        wishes to transfer an asset over to Bob
        (public key: ``'EcRawy3Y22eAUSS94vLF8BVJi62wbqbD9iSUSUNU9wAA'``).
        Let the asset creation transaction payload be denoted by
        ``tx``::

            # noqa E501
            >>> tx
                {'asset': {'data': {'msg': 'Hello BigchainDB!'}},
                 'id': '9650055df2539223586d33d273cb8fd05bd6d485b1fef1caf7c8901a49464c87',
                 'inputs': [{'fulfillment': {'public_key': '3Cxh1eKZk3Wp9KGBWFS7iVde465UvqUKnEqTg2MW4wNf',
                                             'type': 'ed25519-sha-256'},
                             'fulfills': None,
                             'owners_before': ['3Cxh1eKZk3Wp9KGBWFS7iVde465UvqUKnEqTg2MW4wNf']}],
                 'metadata': None,
                 'operation': 'CREATE',
                 'outputs': [{'amount': '1',
                              'condition': {'details': {'public_key': '3Cxh1eKZk3Wp9KGBWFS7iVde465UvqUKnEqTg2MW4wNf',
                                                        'type': 'ed25519-sha-256'},
                                            'uri': 'ni:///sha-256;7ApQLsLLQgj5WOUipJg1txojmge68pctwFxvc3iOl54?fpt=ed25519-sha-256&cost=131072'},
                              'public_keys': ['3Cxh1eKZk3Wp9KGBWFS7iVde465UvqUKnEqTg2MW4wNf']}],
                 'version': '2.0'}

        Then, the input may be constructed in this way::

            output_index
            output = tx['transaction']['outputs'][output_index]
            input_ = {
                'fulfillment': output['condition']['details'],
                'input': {
                    'output_index': output_index,
                    'transaction_id': tx['id'],
                },
                'owners_before': output['owners_after'],
            }

        Displaying the input on the prompt would look like::

            >>> input_
            {'fulfillment': {
              'public_key': '3Cxh1eKZk3Wp9KGBWFS7iVde465UvqUKnEqTg2MW4wNf',
              'type': 'ed25519-sha-256'},
             'input': {'output_index': 0,
              'transaction_id': '9650055df2539223586d33d273cb8fd05bd6d485b1fef1caf7c8901a49464c87'},
             'owners_before': ['3Cxh1eKZk3Wp9KGBWFS7iVde465UvqUKnEqTg2MW4wNf']}


        To prepare the transfer:

        >>> prepare_transfer_transaction(
        ...     inputs=input_,
        ...     recipients='EcRawy3Y22eAUSS94vLF8BVJi62wbqbD9iSUSUNU9wAA',
        ...     asset=tx['transaction']['asset'],
        ... )

    """
    if not isinstance(inputs, (list, tuple)):
        inputs = (inputs, )
    if not isinstance(recipients, (list, tuple)):
        recipients = [([recipients], 1)]

    # NOTE: Needed for the time being. See
    # https://github.com/bigchaindb/bigchaindb/issues/797
    if isinstance(recipients, tuple):
        recipients = [(list(recipients), 1)]

    fulfillments = [
        Input(_fulfillment_from_details(input_['fulfillment']),
              input_['owners_before'],
              fulfills=TransactionLink(
                  txid=input_['fulfills']['transaction_id'],
                  output=input_['fulfills']['output_index']))
        for input_ in inputs
    ]

    transaction = Transaction.transfer(
        fulfillments,
        recipients,
        asset_id=asset['id'],
        metadata=metadata,
    )
    return transaction.to_dict()