예제 #1
0
def get_input_condition(bigchain, fulfillment):
    """

    Args:
        bigchain:
        fulfillment:
    Returns:
    """
    input_tx = fulfillment['input']
    # if `TRANSFER` transaction
    if input_tx:
        # get previous condition
        previous_tx = bigchain.get_transaction(input_tx['txid'])
        conditions = sorted(previous_tx['transaction']['conditions'],
                            key=lambda d: d['cid'])
        return conditions[input_tx['cid']]

    # if `CREATE` transaction
    # there is no previous transaction so we need to create one on the fly
    else:
        current_owner = fulfillment['current_owners'][0]
        condition = cc.Ed25519Fulfillment(public_key=current_owner)

        return {
            'condition': {
                'details': condition.to_dict(),
                'uri': condition.condition_uri
            }
        }
예제 #2
0
def get_fulfillment_message(transaction, fulfillment, serialized=False):
    """Get the fulfillment message for signing a specific fulfillment in a transaction

    Args:
        transaction (dict): a transaction
        fulfillment (dict): a specific fulfillment (for a condition index) within the transaction
        serialized (Optional[bool]): False returns a dict, True returns a serialized string

    Returns:
        str|dict: fulfillment message
    """
    b = bigchaindb.Bigchain()

    # data to sign contains common transaction data
    fulfillment_message = {
        'operation': transaction['transaction']['operation'],
        'timestamp': transaction['transaction']['timestamp'],
        'data': transaction['transaction']['data'],
        'version': transaction['version'],
        'id': transaction['_id']
    }
    # and the condition which needs to be retrieved from the output of a previous transaction
    # or created on the fly it this is a `CREATE` transaction
    fulfillment_message.update({
        'input': fulfillment['input'],
        'condition': None,
    })

    # if `TRANSFER` transaction
    if fulfillment['input']:
        # get previous condition
        previous_tx = b.get_transaction(fulfillment['input']['txid'])
        conditions = sorted(previous_tx['transaction']['conditions'],
                            key=lambda d: d['cid'])
        fulfillment_message['condition'] = conditions[fulfillment['input']
                                                      ['cid']]
    # if `CREATE` transaction
    # there is no previous transaction so we need to create one on the fly
    else:
        current_owner = transaction['transaction']['fulfillments'][0][
            'current_owners'][0]
        condition = json.loads(
            cc.Ed25519Fulfillment(public_key=current_owner).serialize_json())
        fulfillment_message['condition'] = {
            'condition': {
                'details': condition
            }
        }
    if serialized:
        return serialize(fulfillment_message)
    return fulfillment_message
예제 #3
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)
예제 #4
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
예제 #5
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
예제 #6
0
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(
    threshold_fulfillment.validate(message)))
if threshold_fulfillment.validate():
    print('Fulfillment URI {}'.format(threshold_fulfillment.serialize_uri()))
print('Dict representation:')
print(
    json.dumps(threshold_fulfillment.to_dict(),
예제 #7
0
import binascii
import base58

import cryptoconditions as cc
from cryptoconditions.crypto import Ed25519SigningKey as SigningKey

message = 'Hello World! Conditions are here!'
sk_b58 = base58.b58encode(binascii.unhexlify('833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42'))
sk = SigningKey(sk_b58)

ed25519_fulfillment = cc.Ed25519Fulfillment()
ed25519_fulfillment.sign(message, sk)

print(ed25519_fulfillment.condition_uri)
# prints 'cc:4:20:7Bcrk61eVjv0kyxw4SRQNMNUZ-8u_U1k6_gZaDRn4r8:96'
print(ed25519_fulfillment.serialize_uri())
# prints 'cf:4:7Bcrk61eVjv0kyxw4SRQNMNUZ-8u_U1k6_gZaDRn4r-2IpH62UMvjymLnEpIldvik_b_2hpo2t8Mze9fR6DHISpf6jzal6P0wD6p8ui
#        'sHOyGpR1FISer26CdG28zHAcK'

fulfillment_uri = 'cf:4:7Bcrk61eVjv0kyxw4SRQNMNUZ-8u_U1k6_gZaDRn4r-2IpH62UMvjymLnEpIldvik_b_2hpo2t8Mze9fR6DHISpf6jzal' \
                  '6P0wD6p8uisHOyGpR1FISer26CdG28zHAcK'
condition_uri = 'cc:4:20:7Bcrk61eVjv0kyxw4SRQNMNUZ-8u_U1k6_gZaDRn4r8:96'

fulfillment = cc.Fulfillment.from_uri(fulfillment_uri)

result = fulfillment.validate(message) and condition_uri == fulfillment.condition_uri
print(result)


sk_b58 = base58.b58encode(binascii.unhexlify('1a3ab1a87f000348f391613930cc49529652ecf2d2c7cadfd96e87a7f6de948a'))
sk = SigningKey(sk_b58)
예제 #8
0
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
threshold_tx_signed = b.sign_transaction(threshold_tx, testuser2_priv)