Digital Signatures on Ethereum Blockchain

A step-by-step guide to building one

Overview

In today's digital world, where information is transmitted and exchanged across networks and devices, ensuring the authenticity and integrity of electronic documents is crucial. Digital signatures are one such mechanism that provides this security and authenticity for electronic documents.

Ethereum on its own is a decentralized blockchain platform that enables the creation and execution of smart contracts and Decentralized Applications (DApps). One of the key features that make Ethereum a secure and trustworthy platform is digital signatures. In this blog, we will explore what Ethereum digital signatures are, how they are made, how they work, and their significance to the Ethereum ecosystem.

What are Digital Signatures?

Digital signatures are cryptographic tools that allow users to verify the authenticity and integrity of digital documents, messages, and transactions. They are based on public-key cryptography, which uses a pair of keys: a public key and a private key. The private key is used to sign a message, while the public key is used to verify the signature. Digital signatures are essential for secure communication, online transactions, and electronic contracts.

Digital Signatures in Ethereum

Ethereum uses digital signatures to verify the identity of users and to authenticate transactions on its blockchain. Suppose Dami creates a transaction on the Ethereum network, he has to use his private key to sign the transaction to prove that he is the rightful owner of the private key and that the transaction is legitimate . The transaction is then broadcasted to the network, and his signature is verified by other nodes on the network using his public key(address in layman's terms).

Ethereum uses a specific type of digital signature called the Elliptic Curve Digital Signature Algorithm (ECDSA), which is based on the mathematics of elliptic curves. ECDSA is a widely used digital signature algorithm that is known for its efficiency and security. It is used in many blockchain platforms, including Bitcoin and Ethereum.

ECDSA signatures consist of two numbers (integers): r and s. Ethereum also uses an additional v (recovery identifier) variable. The signature can be notated as {r, s, v}. We will understand more about it as we go on.

How to make a Digital Signature

Here, we are going to be using Solidity to show how digital signatures are made.

For you to learn about Solidity you can check it out here. Generally, Solidity is an object-oriented, high-level language for implementing smart contracts.

So we dive straight into it.

Step 1: Create a new file in your RemixIDE

Create a new file digitalSignature.sol and since I'll be using a compiler version of 0.7 and above I'll enter the following.

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

Step 2: Create a contract

contract digitalSignature{

}

Step 3: Create a function to Verify Signatures

function verifySig(address signer, string memory message, bytes memory sig)
    external pure returns (bool){
        bytes32 messageHash = getMessageHash(message);
        bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash);
        return recover(ethSignedMessageHash, sig) == signer;
    }

Note: We still have to make a getMessageHash , ethSignedMessageHash recover functions to hash whatever message we enter and get a signed message and recover whatever signed message.

Step 4: Write the getMessageHash function to hash the message

 function getMessageHash(string memory message)
     public pure returns(bytes32){
         return keccak256(abi.encodePacked(message));
     }

Step 5: Write the recover function

function recover(bytes32 ethSignedMessageHash, bytes memory sig)
     public pure returns(address){
         (bytes32 r, bytes32 s, uint8 v) = _split(sig);
         return ecrecover(ethSignedMessageHash,v,r,s);
     }

To verify a message, we need the original message, the address of the private key it was signed with, and the signature {r, s, v} itself

From the recover function, we have a _split function that uses assembly

 function _split(bytes memory sig)
     internal pure returns(bytes32 r, bytes32 s, uint8 v){
         require(sig.length == 65, "invalid signature length");
         assembly{
             r:=mload(add(sig,32))
             s:=mload(add(sig,64))
             v:=byte(0,mload(add(sig,96)))
         }

In assembly, the First 32 bytes store the length of the signature add(sig, 32) = pointer of sig + 32 effectively, skips the first 32 bytes of signature mload(p) loads the next 32 bytes starting at the memory address p into memory.

Step 6: We compile our deploy it

Deployment

Now to deploy our code,

Step 1: We enter a message and get the hash

Step 2: Open the console and enable Ethereum by using the ethereum.enable

Step 3: We need to get our Account public key using the code

await ethereum.request({
    method: 'eth_requestAccounts',
  })

Then we get the public key and save it in a notepad

Step 4: We then save the account and message hash as constants

account = "0x----"
hash = ""

Step 5: Enter the code which returns a promise

ethereum.request({method:"personal_sign", params:[account, hash]})

This also returns a request to sign the message

Now, you have signed your message, you can now go on to recover the hashes and verify that you posted the message.

Conclusion

Digital signatures are an essential component of the Ethereum platform. They provide security, privacy, and trust for users and enable decentralized transactions and smart contracts. Understanding how digital signatures work and their significance for the Ethereum ecosystem is essential for anyone interested in the blockchain and cryptocurrency space. As Ethereum continues to grow and evolve, digital signatures will remain a critical tool for ensuring the security and integrity of the platform.