Signatures in transaction
Digital signatures are used in transactions due to their properties that ensure the integrity of the transaction contents and non-repudiation of any events in the transaction. A transaction embedded into the block will contain a certain action that is being signed by someone who possesses the private key. Owning the private key thus proves the identity of the signer.
The following code shows a simple transaction with transaction id, signature, and public key. The transaction can only be signed by the owner of the corresponding private key of the public key. The transactions of Bitcoin and other blockchain platforms have several fields in the transaction to perform value transfer, while transactions of cryptocurrency are covered in greater detail in Chapter 5, Cryptocurrency:
class Transaction: def __init__(self, public_key): self.id = randint(1, 10**5) self.signature = None self.public_key = public_key
A signature is then created by signing the hashed content of the transaction with the private key of the corresponding public key:
def sign(self, private_key): data_to_sign = SHA256.new(str(self.id).encode()).digest() sk = SigningKey.from_string(bytes.fromhex(private_key),
curve=SECP256k1) self.signature =
binascii.b2a_hex(sk.sign(data_to_sign)).decode()
The transaction is then verified with the help of only the transaction contents, created signature, and the public key. Verification will only fail if the signature or the transaction contents were modified. This operation also verifies the integrity of the transaction:
def verify(self): vk = VerifyingKey.from_string(bytes.fromhex(self.public_key),
curve=SECP256k1) try: vk.verify(bytes.fromhex(self.signature),
SHA256.new(str(self.id).encode()).digest()) except keys.BadSignatureError: print('invalid transaction signature') return False return True
A transaction can be successfully verified every time as long as the signature or data is not altered. The following code generates a signature and successfully verifies it:
tx = Transaction(account.public_key) tx.sign(account.private_key) print("Generated signature: %s" % tx.signature) tx.verify() Generated signature:
943ed91d7ceb2a57d4e972845acda7ea818b994a840d3101d192ebe33a7c1f4d68
55e50ed7b882cd4d372d540187f52f2d5b3a6144a58fc20098095f1726849f
When the transaction contents are modified or, in this case, the transaction ID is, then the verification fails:
tx.id = '1234' tx.verify()
The transaction constructed in this section demonstrates the basic signing and verification process. An actual transaction can be used to transfer value from one user to other. In the next section, we'll cover the basic asset management that can be performed using the transactions.