added get_hash_data()

This commit is contained in:
diminator
2016-04-13 10:36:46 +02:00
parent b2fd909881
commit 8775e7e8d7
7 changed files with 41 additions and 27 deletions

View File

@@ -153,12 +153,7 @@ class BaseConsensusRules(AbstractConsensusRules):
'input `{}` was already spent'.format(fulfillment['input']))
# Check hash of the transaction
# remove the fulfillment messages (signatures)
transaction_data = copy.deepcopy(transaction)
for fulfillment in transaction_data['transaction']['fulfillments']:
fulfillment['fulfillment'] = None
calculated_hash = crypto.hash_data(util.serialize(transaction_data['transaction']))
calculated_hash = util.get_hash_data(transaction)
if calculated_hash != transaction['id']:
raise exceptions.InvalidHash()

View File

@@ -217,8 +217,7 @@ def create_tx(current_owners, new_owners, inputs, operation, payload=None):
}
# serialize and convert to bytes
tx_serialized = serialize(tx)
tx_hash = crypto.hash_data(tx_serialized)
tx_hash = get_hash_data(tx)
# create the transaction
transaction = {
@@ -268,7 +267,7 @@ def create_and_sign_tx(private_key, current_owner, new_owner, tx_input, operatio
def check_hash_and_signature(transaction):
# Check hash of the transaction
calculated_hash = crypto.hash_data(serialize(transaction['transaction']))
calculated_hash = get_hash_data(transaction)
if calculated_hash != transaction['id']:
raise exceptions.InvalidHash()
@@ -331,10 +330,22 @@ def get_fulfillment_message(transaction, fulfillment):
# 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['fid']]
fulfillment_message['condition'] = conditions[fulfillment['input']['cid']]
return fulfillment_message
def get_hash_data(transaction):
tx = copy.deepcopy(transaction)
if 'transaction' in tx:
tx = tx['transaction']
# remove the fulfillment messages (signatures)
for fulfillment in tx['fulfillments']:
fulfillment['fulfillment'] = None
return crypto.hash_data(serialize(tx))
def transform_create(tx):
"""Change the owner and signature for a ``CREATE`` transaction created by a node"""

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -114,11 +114,15 @@ tx_retrieved = b.get_transaction(tx_signed['id'])
```
The new owner of the digital asset is now `ACJyBLfeLNpCPrGWYoPYvnQ2MAC8BFukBko4hxtW9YoH`, which is the public key of `testuser1`.
The new owner of the digital asset is now `DTJCqP3sNkZcpoSA8bCtGwZ4ASfRLsMFXZDCmMHzCoeJ`, which is the public key of `testuser1`.
Note that the current owner with public key `3LQ5dTiddXymDhNzETB1rEkp4mA7fEV1Qeiu5ghHiJm9` refers to one of the federation nodes that actually created the asset and assigned it to `testuser1`.
## Transfer the Digital Asset
Now that `testuser1` has a digital asset assigned to him, he can transfer it to another user. Transfer transactions require an input. The input will be the transaction id of a digital asset that was assigned to `testuser1`, which in our case is `6539dded9479c47b3c83385ae569ecaa90bcf387240d1ee2ea3ae0f7986aeddd`.
Now that `testuser1` has a digital asset assigned to him, he can transfer it to another user. Transfer transactions require an input. The input will be the transaction id of a digital asset that was assigned to `testuser1`, which in our case is `cdb6331f26ecec0ee7e67e4d5dcd63734e7f75bbd1ebe40699fc6d2960ae4cb2`.
Since a transaction can have multiple outputs with each their own (crypto)condition, each transaction input should also refer to the condition index `cid`.
```python
# create a second testuser
@@ -203,13 +207,29 @@ b.validate_transaction(tx_transfer_signed2)
DoubleSpend: input `cdb6331f26ecec0ee7e67e4d5dcd63734e7f75bbd1ebe40699fc6d2960ae4cb2` was already spent
```
## Crypto Conditions
## Crypto-Conditions
BigchainDB makes use of the crypto-conditions library to both cryptographically lock and unlock transactions.
The locking script is refered to as a `condition` and a corresponding `fulfillment` unlocks the condition of the `input_tx`.
![BigchainDB transactions connecting fulfillments with conditions](./_static/tx_single_condition_single_fulfillment_v1.png)
### Introduction
Crypto-conditions provide a mechanism to describe a signed message such that multiple actors in a distributed system can all verify the same signed message and agree on whether it matches the description.
This provides a useful primitive for event-based systems that are distributed on the Internet since we can describe events in a standard deterministic manner (represented by signed messages) and therefore define generic authenticated event handlers.
Crypto-conditions are part of the Interledger protocol and the full specification can be found [here](https://interledger.org/five-bells-condition/spec.html).
Implementations of the crypto-conditions are available in [Python](https://github.com/bigchaindb/cryptoconditions) and [JavaScript](https://github.com/interledger/five-bells-condition).
### Threshold Signatures
MultiSig, m-of-n signatures
```python
import copy
import json

View File

@@ -940,14 +940,8 @@ class TestCryptoconditions(object):
'details': json.loads(first_tx_condition.serialize_json()),
'uri': first_tx_condition.condition.serialize_uri()
}
# conditions have been updated, so hash needs updating
transaction_data = copy.deepcopy(first_tx)
for fulfillment in transaction_data['transaction']['fulfillments']:
fulfillment['fulfillment'] = None
calculated_hash = crypto.hash_data(util.serialize(transaction_data['transaction']))
first_tx['id'] = calculated_hash
first_tx['id'] = util.get_hash_data(first_tx)
first_tx_signed = b.sign_transaction(first_tx, user_sk)
@@ -994,14 +988,8 @@ class TestCryptoconditions(object):
'details': json.loads(first_tx_condition.serialize_json()),
'uri': first_tx_condition.condition.serialize_uri()
}
# conditions have been updated, so hash needs updating
transaction_data = copy.deepcopy(first_tx)
for fulfillment in transaction_data['transaction']['fulfillments']:
fulfillment['fulfillment'] = None
calculated_hash = crypto.hash_data(util.serialize(transaction_data['transaction']))
first_tx['id'] = calculated_hash
first_tx['id'] = util.get_hash_data(first_tx)
first_tx_signed = b.sign_transaction(first_tx, user_sk)