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)
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
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