Example #1
0
def threshold_it():

    #gets input data
    data = request.get_json(force=True)
    txID = data['txID']
    cid = int(data['cid'])
    pubKeys = data['pubKeys']
    privKeys = data['privKeys']
    newPubKeys = data['newPubKeys']
    N = int(data['N'])

    #formats input data
    pubKeys = pubKeys.split("_")
    privKeys = privKeys.split("_")
    newPubKeys = newPubKeys.split("_")

    #format retrieved_id
    txn = {"cid": cid, "txid": txID}

    #makes the base template
    threshold_tx = b.create_transaction(pubKeys, newPubKeys, txn, 'TRANSFER')
    #implements the threshold condition
    threshold_condition = cc.ThresholdSha256Fulfillment(threshold=(N))
    for i in range(len(newPubKeys)):
        threshold_condition.add_subfulfillment(
            cc.Ed25519Fulfillment(public_key=newPubKeys[i]))

    #Update the condition in the newly created transaction
    threshold_tx['transaction']['conditions'][0]['condition'] = {
        'details': json.loads(threshold_condition.serialize_json()),
        'uri': threshold_condition.condition.serialize_uri()
    }

    #Now update the transaction hash (ID)
    threshold_tx['id'] = util.get_hash_data(threshold_tx)

    #Sign the transaction
    threshold_tx_signed = b.sign_transaction(threshold_tx, privKeys)

    #Write the transaction
    b.write_transaction(threshold_tx_signed)

    #Return the signed transaction
    return flask.jsonify(**threshold_tx_signed)
Example #2
0
def create_tx(current_owners, new_owners, inputs, operation, payload=None):
    """Create a new transaction

    A transaction in the bigchain is a transfer of a digital asset between two entities represented
    by public keys.

    Currently the bigchain supports two types of operations:

        `CREATE` - Only federation nodes are allowed to use this operation. In a create operation
        a federation node creates a digital asset in the bigchain and assigns that asset to a public
        key. The owner of the private key can then decided to transfer this digital asset by using the
        `transaction id` of the transaction as an input in a `TRANSFER` transaction.

        `TRANSFER` - A transfer operation allows for a transfer of the digital assets between entities.

    Args:
        current_owners (list): base58 encoded public key of the current owners of the asset.
        new_owners (list): base58 encoded public key of the new owners of the digital asset.
        inputs (list): id of the transaction to use as input.
        operation (str): Either `CREATE` or `TRANSFER` operation.
        payload (Optional[dict]): dictionary with information about asset.

    Returns:
        dict: unsigned transaction.


    Raises:
        TypeError: if the optional ``payload`` argument is not a ``dict``.

    Reference:
        {
            "id": "<sha3 hash>",
            "version": "transaction version number",
            "transaction": {
                "fulfillments": [
                        {
                            "current_owners": ["list of <pub-keys>"],
                            "input": {
                                "txid": "<sha3 hash>",
                                "cid": "condition index"
                            },
                            "fulfillment": "fulfillement of condition cid",
                            "fid": "fulfillment index"
                        }
                    ],
                "conditions": [
                        {
                            "new_owners": ["list of <pub-keys>"],
                            "condition": "condition to be met",
                            "cid": "condition index (1-to-1 mapping with fid)"
                        }
                    ],
                "operation": "<string>",
                "timestamp": "<timestamp from client>",
                "data": {
                    "hash": "<SHA3-256 hash hexdigest of payload>",
                    "payload": {
                        "title": "The Winds of Plast",
                        "creator": "Johnathan Plunkett",
                        "IPFS_key": "QmfQ5QAjvg4GtA3wg3adpnDJug8ktA1BxurVqBD8rtgVjP"
                    }
                }
            },
        }
    """
    # validate arguments (owners and inputs should be lists or None)

    # The None case appears on fulfilling a hashlock
    if current_owners is None:
        current_owners = []
    if not isinstance(current_owners, list):
        current_owners = [current_owners]

    # The None case appears on assigning a hashlock
    if new_owners is None:
        new_owners = []
    if not isinstance(new_owners, list):
        new_owners = [new_owners]

    if not isinstance(inputs, list):
        inputs = [inputs]

    # handle payload
    if payload is not None and not isinstance(payload, dict):
        raise TypeError('`payload` must be an dict instance or None')

    data = {'uuid': str(uuid.uuid4()), 'payload': payload}

    # handle inputs
    fulfillments = []

    # transfer
    if inputs:
        for fid, tx_input in enumerate(inputs):
            fulfillments.append({
                'current_owners': current_owners,
                'input': tx_input,
                'fulfillment': None,
                'fid': fid
            })
    # create
    else:
        fulfillments.append({
            'current_owners': current_owners,
            'input': None,
            'fulfillment': None,
            'fid': 0
        })

    # handle outputs
    conditions = []
    for fulfillment in fulfillments:

        # threshold condition
        if len(new_owners) > 1:
            condition = cc.ThresholdSha256Fulfillment(
                threshold=len(new_owners))
            for new_owner in new_owners:
                condition.add_subfulfillment(
                    cc.Ed25519Fulfillment(public_key=new_owner))

        # simple signature condition
        elif len(new_owners) == 1:
            condition = cc.Ed25519Fulfillment(public_key=new_owners[0])

        # to be added later (hashlock conditions)
        else:
            condition = None

        if condition:
            conditions.append({
                'new_owners': new_owners,
                'condition': {
                    'details': condition.to_dict(),
                    'uri': condition.condition_uri
                },
                'cid': fulfillment['fid']
            })

    tx = {
        'fulfillments': fulfillments,
        'conditions': conditions,
        'operation': operation,
        'timestamp': timestamp(),
        'data': data
    }

    # serialize and convert to bytes
    tx_hash = get_hash_data(tx)

    # create the transaction
    transaction = {'id': tx_hash, 'version': 1, 'transaction': tx}

    return transaction
Example #3
0
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(bigchaindb.util.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'] = bigchaindb.util.get_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
import cryptoconditions as cc

SPACER = '*' * 40

# Create some keys and a message to sign
sk1, vk1 = cc.crypto.ed25519_generate_key_pair()
sk2, vk2 = cc.crypto.ed25519_generate_key_pair()
message = 'Hello World! I am a message to sign!'

##############################################################
# Create a Threshold fulfillment and
# add subfulfillments and subconditions as an object or by URI
##############################################################
# Create a 1-of-4 threshold condition (OR gate)
threshold_fulfillment = cc.ThresholdSha256Fulfillment(threshold=1)
# Add a hashlock fulfillment
threshold_fulfillment.add_subfulfillment(
    cc.PreimageSha256Fulfillment(b'much secret'))
# Add a signature condition
threshold_fulfillment.add_subcondition(
    cc.Ed25519Fulfillment(public_key=vk1).condition)
# Add a fulfillment URI
threshold_fulfillment.add_subfulfillment_uri('cf:0:')
# Add a condition URI
threshold_fulfillment.add_subcondition_uri(
    'cc:0:3:47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU:0')
print(SPACER)
print('Condition URI: {}'.format(threshold_fulfillment.condition_uri))
print('Threshold: {}'.format(threshold_fulfillment.threshold))
print('Is valid fulfillment? {}'.format(
# signature_treshold = 2

# Create some new testusers
thresholduser1_priv, thresholduser1_pub = crypto.generate_key_pair()
thresholduser2_priv, thresholduser2_pub = crypto.generate_key_pair()

# Retrieve the last transaction of testuser2
tx_retrieved_id = b.get_owned_ids(testuser2_pub).pop()

# Create a base template for a 1-input/2-output transaction
threshold_tx = b.create_transaction(testuser2_pub,
                                    [thresholduser1_pub, thresholduser2_pub],
                                    tx_retrieved_id, 'TRANSFER')

# Create a Threshold Cryptocondition
threshold_condition = cc.ThresholdSha256Fulfillment(
    threshold=signature_treshold)
threshold_condition.add_subfulfillment(
    cc.Ed25519Fulfillment(public_key=thresholduser1_pub))
threshold_condition.add_subfulfillment(
    cc.Ed25519Fulfillment(public_key=thresholduser2_pub))

# Update the condition in the newly created transaction
threshold_tx['transaction']['conditions'][0]['condition'] = {
    'details': json.loads(threshold_condition.serialize_json()),
    'uri': threshold_condition.condition.serialize_uri()
}

# Conditions have been updated, so the transaction hash (ID) needs updating
threshold_tx['id'] = util.get_hash_data(threshold_tx)

# Sign the transaction