From 1e866a120790b9565f53fcce662fdc40d8f42cbb Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Mon, 24 Apr 2017 13:37:50 +0200 Subject: [PATCH] signature payload is serialized transaction --- bigchaindb/common/transaction.py | 9 +++------ docs/server/source/data-models/transaction-model.rst | 2 +- tests/common/test_transaction.py | 8 +++----- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/bigchaindb/common/transaction.py b/bigchaindb/common/transaction.py index 285272c5..d0b24dbb 100644 --- a/bigchaindb/common/transaction.py +++ b/bigchaindb/common/transaction.py @@ -690,8 +690,7 @@ class Transaction(object): tx_dict = Transaction._remove_signatures(tx_dict) tx_serialized = Transaction._to_str(tx_dict) for i, input_ in enumerate(self.inputs): - message = '%s:%s' % (i, tx_serialized) - self.inputs[i] = self._sign_input(input_, message, key_pairs) + self.inputs[i] = self._sign_input(input_, tx_serialized, key_pairs) return self @classmethod @@ -843,10 +842,8 @@ class Transaction(object): def validate(i, output_condition_uri=None): """ Validate input against output condition URI """ - message = '%s:%s' % (i, tx_serialized) - - return self._input_valid(self.inputs[i], self.operation, message, - output_condition_uri) + return self._input_valid(self.inputs[i], self.operation, + tx_serialized, output_condition_uri) return all(validate(i, cond) for i, cond in enumerate(output_condition_uris)) diff --git a/docs/server/source/data-models/transaction-model.rst b/docs/server/source/data-models/transaction-model.rst index 3610d1fe..cc548aa9 100644 --- a/docs/server/source/data-models/transaction-model.rst +++ b/docs/server/source/data-models/transaction-model.rst @@ -49,4 +49,4 @@ Here's some explanation of the contents of a :ref:`transaction `: Later, when we get to the models for the block and the vote, we'll see that both include a signature (from the node which created it). You may wonder why transactions don't have signatures... The answer is that they do! They're just hidden inside the ``fulfillment`` string of each input. A creation transaction is signed by whoever created it. A transfer transaction is signed by whoever currently controls or owns it. -What gets signed? For each input in the transaction, the "fullfillment message" that gets signed includes the JSON serialized body of the transaction, minus any fulfillment strings, and with "n:" prepended where n is the index of the input being signed. The computed signature goes into creating the ``fulfillment`` string of the input. +What gets signed? For each input in the transaction, the "fullfillment message" that gets signed includes the JSON serialized body of the transaction, minus any fulfillment strings. The computed signature goes into creating the ``fulfillment`` string of the input. diff --git a/tests/common/test_transaction.py b/tests/common/test_transaction.py index adc6e60d..205009ac 100644 --- a/tests/common/test_transaction.py +++ b/tests/common/test_transaction.py @@ -510,7 +510,7 @@ def test_validate_tx_simple_create_signature(user_input, user_output, user_priv, tx = Transaction(Transaction.CREATE, asset_definition, [user_input], [user_output]) expected = deepcopy(user_output) - message = ('0:' + str(tx)).encode() + message = str(tx).encode() expected.fulfillment.sign(message, PrivateKey(user_priv)) tx.sign([user_priv]) @@ -574,7 +574,7 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input, tx = Transaction(Transaction.CREATE, asset_definition, [user_user2_threshold_input], [user_user2_threshold_output]) - message = ('0:' + str(tx)).encode() + message = str(tx).encode() expected = deepcopy(user_user2_threshold_output) expected.fulfillment.subconditions[0]['body'].sign(message, PrivateKey(user_priv)) @@ -589,8 +589,6 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input, validate_transaction_model(tx) -import pytest -@pytest.mark.skip() def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv, asset_definition): from copy import deepcopy @@ -877,7 +875,7 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub, expected_input = deepcopy(inputs[0]) expected['id'] = transfer_tx['id'] - expected_input.fulfillment.sign(('0:' + serialize(expected)).encode(), + expected_input.fulfillment.sign(serialize(expected).encode(), PrivateKey(user_priv)) expected_ffill = expected_input.fulfillment.serialize_uri() transfer_ffill = transfer_tx['inputs'][0]['fulfillment']