def test_cat_tx_fields_double(self): # Version number version = 1 # Arbitrary 32 byte previous transaction hash prev_tx_hash = hash_SHA('0'.encode()) # Arbritrary 32 byte previous recipient prev_recipient = hash_SHA('1'.encode()) # Arbritrary 32 byte recipient recipient = hash_SHA('2'.encode()) # Value of 100 for output value1 = 100 value2 = 300 # Inputs generated from above elements, with output_index of 0, 1 input1 = cat_input_fields(prev_tx_hash, 0, prev_recipient) input2 = cat_input_fields(prev_tx_hash, 1, prev_recipient) # Output genereated from above elements output1 = create_output(value1, recipient) output2 = create_output(value2, recipient) # Input list inputs = [input1, input2] # Output list outputs = [output1, output2] # Manually generates expected output from above elements expected = int_to_bytes(version) expected += short_to_bytes(len(inputs)) expected += input1 expected += input2 expected += short_to_bytes(len(outputs)) expected += output1 expected += output2 # Actual output generated from cat_tx_fields actual = cat_tx_fields(version, inputs, outputs) self.assertEqual(expected, actual)
def cat_tx_fields(version, inputs, outputs): """ takes in a version, a list of inputs, and a list of outputs convert the version to integer byte form, get the num_inputs and num_outputs from the len of the inputs and outputs` respectively convert these to shorts in byte form concatenate the parameters in the following order: version number + # inputs + input 0...input n + # outputs + output 0... output n :param1 version: integer representing the version of the software :param2 inputs: a list of inputs :param3 outputs: a list of outputs :return: byte string, concatonation of version number + # inputs + input 0...input n + # outputs + output 0... output n """ # Adds version number bytes to output byte string return_bstr = int_to_bytes(version) # Adds number of inputs in short byte form to output byte string return_bstr += short_to_bytes(len(inputs)) # Adds each input to output byte string for inp in inputs: return_bstr += inp # Adds number of outputs in short byte form to output byte string return_bstr += short_to_bytes(len(outputs)) # Adds each output to output byte string for out in outputs: return_bstr += out # Returns output byte string return return_bstr
def test_create_tx_single(self): # Version number version = 1 # Arbitrary 32 byte previous transaction hash prev_tx_hash = hash_SHA('0'.encode()) # Arbritrary 32 byte previous recipient prev_recipient = hash_SHA('1'.encode()) # Arbritrary 32 byte recipient recipient = hash_SHA('2'.encode()) # Value of 100 for output value = 100 # Input generated from above elements, with output_index of 0 input1 = cat_input_fields(prev_tx_hash, 0, prev_recipient) # Output genereated from above elements output1 = create_output(value, recipient) # Input list unsigned_inputs = [input1] # Output list outputs = [output1] key_set1 = generate_key_set() private_key = key_set1["private_key"] public_key = key_set1["public_key"] unsigned_tx = cat_tx_fields(version, unsigned_inputs, outputs) signature = sign_transaction(unsigned_tx, private_key) signed_input = cat_input_fields(prev_tx_hash, 0, signature + public_key) signed_inputs = [signed_input] # creating a verification key verifying_key = ecdsa.VerifyingKey.from_string(public_key, ecdsa.SECP256k1) actual = create_tx(version, unsigned_inputs, outputs, private_key) #Checks if version number is correct self.assertEqual(actual[0:4], int_to_bytes(version)) #Checks input info #Checks if number of inputs is correct self.assertEqual(actual[4:6], short_to_bytes(1)) #Checks if previous transaction hash is correct of input1 self.assertEqual(actual[6:38], prev_tx_hash) #Checks if output index of input1 is correct self.assertEqual(actual[38:40], short_to_bytes(0)) #Checks if signature of input1 is valid self.assertTrue(verifying_key.verify(actual[40:104], hash_SHA(unsigned_tx))) #Checks ouptut info #Checks if the number of outputs is correct self.assertEqual(actual[6 + len(signed_input):6 + len(signed_input) + 2], short_to_bytes(1)) #Checks if output1 is correct self.assertEqual(actual[6 + len(signed_input) + 2:6 + len(signed_input) + 2 + len(output1)], output1)
def test_cat_input_fields(self): prev_hash = hash_SHA('previous'.encode()) output_index = 128 prev_recipient = hash_SHA('recipient'.encode()) actualResults = cat_input_fields(prev_hash, output_index, prev_recipient) expectedResults = prev_hash + short_to_bytes(output_index) + prev_recipient self.assertEqual(actualResults, expectedResults)
def cat_input_fields(prev_tx_hash, output_index, prev_recipient): """ converts output_index to short in byte form and concatenates parameters in order :params prev_tx_hash, output_index, prev_recipient :return: concatentation of prev_tx_has, output_index (in byte form), prev_recipient """ return prev_tx_hash + short_to_bytes(output_index) + prev_recipient
def create_input(previous_tx_hash, index, signature, public_key): """ Creates transation input :param previous_tx_hash: hash of the previous transaction :param index: Index of output :param signature: signature of the transaction hash :param public_key: users public key :return: concatenation of parameters with the index changed to a short """ unlocking_script = signature + public_key index_short = short_to_bytes(index) return previous_tx_hash + index_short + unlocking_script
def test_create_input(self): # Create key set key_dict = generate_key_set() priv_key = key_dict["private_key"] public_key = key_dict["public_key"] # Create transaction signature previous_tx_hash = hash_SHA('previous'.encode()) prev_tx_locking_script = create_output(30000000, hash_SHA('recipient'.encode())) new_tx_output = hash_SHA('new_output'.encode()) signature = sign_transaction(priv_key, previous_tx_hash, prev_tx_locking_script, new_tx_output) # Create index value index = 2 # Concatenate values together unlocking_script = signature + public_key index_short = short_to_bytes(index) expected = previous_tx_hash + index_short + unlocking_script # Run same values through function actual = create_input(previous_tx_hash, index, signature, public_key) # Check if function equals the concatenation of the values self.assertEqual(expected, actual)