Example #1
0
def test_multiple_input_validation_of_transfer_tx(user_input, user_output,
                                                  user_priv, user2_pub,
                                                  user2_priv, user3_pub,
                                                  user3_priv,
                                                  asset_definition):
    from bigchaindb.common.transaction import (Transaction, TransactionLink,
                                               Input, Output)
    from cryptoconditions import Ed25519Sha256
    from .utils import validate_transaction_model

    tx = Transaction(Transaction.CREATE, asset_definition, [user_input],
                     [user_output, deepcopy(user_output)])
    tx.sign([user_priv])

    inputs = [
        Input(cond.fulfillment, cond.public_keys,
              TransactionLink(tx.id, index))
        for index, cond in enumerate(tx.outputs)
    ]
    outputs = [
        Output(Ed25519Sha256(public_key=b58decode(user3_pub)), [user3_pub]),
        Output(Ed25519Sha256(public_key=b58decode(user3_pub)), [user3_pub])
    ]
    transfer_tx = Transaction('TRANSFER', {'id': tx.id}, inputs, outputs)
    transfer_tx = transfer_tx.sign([user_priv])

    assert transfer_tx.inputs_valid(tx.outputs) is True

    validate_transaction_model(tx)
Example #2
0
def test_output_from_dict_invalid_amount(user_output):
    from bigchaindb.common.transaction import Output
    from bigchaindb.common.exceptions import AmountError

    out = user_output.to_dict()
    out['amount'] = 'a'
    with raises(AmountError):
        Output.from_dict(out)
Example #3
0
def test_invalid_output_initialization(cond_uri, user_pub):
    from bigchaindb.common.transaction import Output
    from bigchaindb.common.exceptions import AmountError

    with raises(TypeError):
        Output(cond_uri, user_pub)
    with raises(TypeError):
        Output(cond_uri, [user_pub], 'amount')
    with raises(AmountError):
        Output(cond_uri, [user_pub], 0)
Example #4
0
def test_generate_output_invalid_parameters(user_pub, user2_pub, user3_pub):
    from bigchaindb.common.transaction import Output
    from bigchaindb.common.exceptions import AmountError

    with raises(ValueError):
        Output.generate([], 1)
    with raises(TypeError):
        Output.generate('not a list', 1)
    with raises(ValueError):
        Output.generate([[user_pub, [user2_pub, [user3_pub]]]], 1)
    with raises(ValueError):
        Output.generate([[user_pub]], 1)
    with raises(AmountError):
        Output.generate([[user_pub]], -1)
Example #5
0
def create_asset(vw_sk, vw_pk, vehicle_id, data, metadata):
    # Create asset VW -> [VW, TEL]
    # Custom crypto condition multisig 1-2
    threshold_fulfillment = ThresholdSha256Fulfillment(threshold=1)

    vw_fulfillment = Ed25519Fulfillment(public_key=vw_pk)
    tel_fulfillment = Ed25519Fulfillment(public_key=vehicle_id)

    threshold_fulfillment.add_subfulfillment(vw_fulfillment)
    threshold_fulfillment.add_subfulfillment(tel_fulfillment)

    output = {
        'amount': 1,
        'condition': {
            'details': threshold_fulfillment.to_dict(),
            'uri': threshold_fulfillment.condition.serialize_uri()
        },
        'public_keys': [vw_pk, vehicle_id]
    }

    # Create the transaction
    tx_create = Transaction.create([vw_pk], [([vw_pk, vehicle_id], 1)],
                                   asset=data,
                                   metadata=metadata)
    # Override the condition we our custom build one
    tx_create.outputs[0] = Output.from_dict(output)

    # Sign the transaction
    tx_create_signed = tx_create.sign([vw_sk])

    return tx_create_signed
def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv,
                                             asset_definition):
    from cryptoconditions import Ed25519Sha256, ThresholdSha256
    from bigchaindb.common.transaction import Input, Output, Transaction

    threshold = ThresholdSha256(threshold=2)
    threshold.add_subfulfillment(Ed25519Sha256(public_key=b58decode(user_pub)))
    threshold.add_subfulfillment(Ed25519Sha256(public_key=b58decode(user_pub)))

    threshold_input = Input(threshold, [user_pub, user_pub])
    threshold_output = Output(threshold, [user_pub, user_pub])

    tx = Transaction(Transaction.CREATE, asset_definition, [threshold_input],
                     [threshold_output])
    expected = deepcopy(threshold_input)
    expected.fulfillment.subconditions[0]['body'].sign(
        str(tx).encode(), b58decode(user_priv))
    expected.fulfillment.subconditions[1]['body'].sign(
        str(tx).encode(), b58decode(user_priv))

    tx.sign([user_priv, user_priv])

    subconditions = tx.inputs[0].fulfillment.subconditions
    expected_subconditions = expected.fulfillment.subconditions
    assert subconditions[0]['body'].to_dict()['signature'] == \
        expected_subconditions[0]['body'].to_dict()['signature']
    assert subconditions[1]['body'].to_dict()['signature'] == \
        expected_subconditions[1]['body'].to_dict()['signature']

    assert tx.inputs[0].to_dict()['fulfillment'] == \
        expected.fulfillment.serialize_uri()
    assert tx.inputs_valid() is True
Example #7
0
def test_generate_output_single_owner_with_output(user_pub):
    from bigchaindb.common.transaction import Output
    from cryptoconditions import Ed25519Sha256

    expected = Ed25519Sha256(public_key=b58decode(user_pub))
    cond = Output.generate([expected], 1)

    assert cond.fulfillment.to_dict() == expected.to_dict()
Example #8
0
def test_output_hashlock_serialization():
    from bigchaindb.common.transaction import Output
    from cryptoconditions import PreimageSha256

    secret = b'wow much secret'
    hashlock = PreimageSha256(preimage=secret).condition_uri

    expected = {
        'condition': {
            'uri': hashlock,
        },
        'public_keys': None,
        'amount': '1',
    }
    cond = Output(hashlock, amount=1)

    assert cond.to_dict() == expected
Example #9
0
def prepare_transfer(inputs, outputs, metadata=None):
    """Create an instance of a :class:`~.Output`.

    Args:
        inputs (list of
                    (dict):
                        {
                            'tx': <(bigchaindb.common.transactionTransaction):
                                    input transaction, can differ but must have same asset id>,
                            'output': <(int): output index of tx>
                        }
                )
        outputs (list of
                    (dict):
                        {
                            'condition': <(cryptoconditions.Condition): output condition>,
                            'public_keys': <(optional list of base58): for indexing defaults to `None`>,
                            'amount': <(int): defaults to `1`>
                        }
                )
        metadata (dict)
    Raises:
        TypeError: if `public_keys` is not instance of `list`.
            """
    from bigchaindb.common.transaction import (Input, Output, TransactionLink)

    from bigchaindb.models import Transaction

    from cryptoconditions import (Fulfillment, Condition)

    asset = inputs[0]['tx']['asset']
    asset = {'id': asset['id'] if 'id' in asset else inputs[0]['tx']['id']}

    _inputs, _outputs = [], []

    for _input in inputs:

        _output = _input['tx']['outputs'][_input['output']]
        _inputs.append(
            Input(fulfillment=Condition.from_uri(_output['condition']['uri']),
                  owners_before=_output['public_keys'],
                  fulfills=TransactionLink(txid=_input['tx']['id'],
                                           output=_input['output'])))

    for output in outputs:
        _outputs.append(
            Output(fulfillment=output['condition'],
                   public_keys=output['public_keys']
                   if "public_keys" in output else [],
                   amount=output['amount'] if "amount" in output else 1))

    return Transaction(
        operation='TRANSFER',
        asset=asset,
        inputs=_inputs,
        outputs=_outputs,
        metadata=metadata,
    )
Example #10
0
def test_output_serialization(user_Ed25519, user_pub):
    from bigchaindb.common.transaction import Output

    expected = {
        'condition': {
            'uri': user_Ed25519.condition_uri,
            'details': {
                'type': 'ed25519-sha-256',
                'public_key': b58encode(user_Ed25519.public_key).decode(),
            },
        },
        'public_keys': [user_pub],
        'amount': '1',
    }

    cond = Output(user_Ed25519, [user_pub], 1)

    assert cond.to_dict() == expected
Example #11
0
def generate_output(amount, owner_after):
    """
    Generate cryptooutputs from keys.

    Generates a Ed25119 output from a OWNER_AFTER or a ThresholdSha256
    Output from more than one OWNER_AFTER.
    """
    output = Output.generate(list(owner_after), amount=amount)
    click.echo(json.dumps(output.to_dict()))
Example #12
0
def test_validate_inputs_of_transfer_tx_with_invalid_params(
        transfer_tx, cond_uri, utx, user2_pub, user_priv, ffill_uri):
    from bigchaindb.common.transaction import Output
    from cryptoconditions import Ed25519Sha256

    invalid_out = Output(Ed25519Sha256.from_uri(ffill_uri), ['invalid'])
    assert transfer_tx.inputs_valid([invalid_out]) is False
    invalid_out = utx.outputs[0]
    invalid_out.public_key = 'invalid'
    assert transfer_tx.inputs_valid([invalid_out]) is True

    with raises(TypeError):
        assert transfer_tx.inputs_valid(None) is False
    with raises(AttributeError):
        transfer_tx.inputs_valid('not a list')
    with raises(ValueError):
        transfer_tx.inputs_valid([])
    with raises(TypeError):
        transfer_tx.operation = "Operation that doesn't exist"
        transfer_tx.inputs_valid([utx.outputs[0]])
Example #13
0
def create(owner_before, outputs, metadata, asset_data):
    """
    Generate a CREATE transaction.

    The CREATE transaction creates a new asset.
    """
    input_ = Input.generate([owner_before])
    outputs = [Output.from_dict(c) for c in listify(outputs)]
    tx = Transaction(Transaction.CREATE, {'data': asset_data}, [input_],
                     outputs, metadata)
    tx = Transaction._to_str(tx.to_dict())
    click.echo(tx)
Example #14
0
def transfer(inputs, outputs, asset, metadata):
    """
    Generate a TRANSFER transaction.

    The TRANSFER transaction transfers ownership of a given asset.
    """
    inputs = [Input.from_dict(i) for i in listify(inputs)]
    outputs = [Output.from_dict(i) for i in listify(outputs)]
    tx = Transaction(Transaction.TRANSFER,
                     asset=asset,
                     inputs=inputs,
                     outputs=outputs,
                     metadata=metadata)
    click.echo(Transaction._to_str(tx.to_dict()))
Example #15
0
def test_generate_outputs_flat_ownage(user_pub, user2_pub, user3_pub):
    from bigchaindb.common.transaction import Output
    from cryptoconditions import Ed25519Sha256, ThresholdSha256

    expected_simple1 = Ed25519Sha256(public_key=b58decode(user_pub))
    expected_simple2 = Ed25519Sha256(public_key=b58decode(user2_pub))
    expected_simple3 = Ed25519Sha256(public_key=b58decode(user3_pub))

    expected = ThresholdSha256(threshold=3)
    expected.add_subfulfillment(expected_simple1)
    expected.add_subfulfillment(expected_simple2)
    expected.add_subfulfillment(expected_simple3)

    cond = Output.generate([user_pub, user2_pub, expected_simple3], 1)
    assert cond.fulfillment.to_dict() == expected.to_dict()
Example #16
0
def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv,
                                             asset_definition):
    from cryptoconditions import Ed25519Sha256, ThresholdSha256
    from bigchaindb.common.transaction import Input, Output, Transaction

    threshold = ThresholdSha256(threshold=2)
    threshold.add_subfulfillment(Ed25519Sha256(public_key=b58decode(user_pub)))
    threshold.add_subfulfillment(Ed25519Sha256(public_key=b58decode(user_pub)))

    threshold_input = Input(threshold, [user_pub, user_pub])
    threshold_output = Output(threshold, [user_pub, user_pub])

    tx = Transaction(Transaction.CREATE, asset_definition, [threshold_input],
                     [threshold_output])

    tx_dict = tx.to_dict()
    tx_dict['inputs'][0]['fulfillment'] = None
    serialized_tx = json.dumps(tx_dict,
                               sort_keys=True,
                               separators=(',', ':'),
                               ensure_ascii=True)
    message = sha3_256(serialized_tx.encode()).digest()

    expected = deepcopy(threshold_input)
    expected.fulfillment.subconditions[0]['body'].sign(message,
                                                       b58decode(user_priv))
    expected.fulfillment.subconditions[1]['body'].sign(message,
                                                       b58decode(user_priv))

    tx.sign([user_priv, user_priv])

    subconditions = tx.inputs[0].fulfillment.subconditions
    expected_subconditions = expected.fulfillment.subconditions
    assert subconditions[0]['body'].to_dict()['signature'] == \
        expected_subconditions[0]['body'].to_dict()['signature']
    assert subconditions[1]['body'].to_dict()['signature'] == \
        expected_subconditions[1]['body'].to_dict()['signature']

    assert tx.inputs[0].to_dict()['fulfillment'] == \
        expected.fulfillment.serialize_uri()
    assert tx.inputs_valid() is True
Example #17
0
def user2_output(user2_Ed25519, user2_pub):
    from bigchaindb.common.transaction import Output
    return Output(user2_Ed25519, [user2_pub])
Example #18
0
def user_user2_threshold_output(user_user2_threshold, user_pub, user2_pub):
    from bigchaindb.common.transaction import Output
    return Output(user_user2_threshold, [user_pub, user2_pub])