Introduction

In blockchain and Web3 technologies, secure communication and identity verification are made possible by digital signatures. On Ethereum, one of the core tools for verifying these signatures is the built-in Solidity function ecrecover.

In this post, we’ll explore what ecrecover is, why we need the v, r, and s parameters, what they represent, and how digital signature verification works. We'll also walk through practical examples of both signing and verification.


Digital Signatures and Ethereum's Signing Process

Ethereum uses the ECDSA (Elliptic Curve Digital Signature Algorithm) over the secp256k1 curve to ensure the security of messages and transactions. Here's how it works:

  • A user signs the hash of a message with their private key.

  • The result is a digital signature composed of three parts:

    • r: A 32-byte value generated during the signing process.

    • s: Another 32-byte value.

    • v: A 1-byte recovery identifier used to determine the correct public key from the signature. In Ethereum, this is typically 27 or 28.

Together, these three values prove that the message was signed by someone in possession of the corresponding private key.


The ecrecover Function and Its Parameters

In Solidity, the ecrecover function is used as follows:

address signer = ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s);
  • hash: The keccak256 hash of the signed message.

  • v, r, and s: The three components of the digital signature.

This function returns the Ethereum address that created the signature, allowing you to verify the authenticity of the signer directly onchain.


Technical Breakdown of v, r, and s

  • r: First 32-byte value output from the ECDSA signing process.

  • s: Second 32-byte value of the signature.

  • v: Recovery parameter, helps choose the correct public key. Usually 27 or 28 in Ethereum.

The v value is necessary because the same r and s can produce two possible public keys. v tells us which one is valid.


Practical Example: Signing a Message in TypeScript

import { ethers } from "ethers";

async function signMessage() {
  const wallet = ethers.Wallet.createRandom(); 
  const message = "Hello Ethereum!"; 
  const signature = await wallet.signMessage(message); 
  const sig = ethers.Signature.from(signature); 

  console.log("Address:", wallet.address); 
  console.log("Message:", message); 
  console.log("v:", sig.v); 
  console.log("r:", sig.r); 
  console.log("s:", sig.s); 
} 
signMessage();

This script creates a random wallet, signs a message, and logs the v, r, and s values to the console.


Practical Example: Verifying a Signature in Solidity

pragma solidity ^0.8.0;

contract VerifySignature {
  function verify(
            bytes32 messageHash,
            uint8 v,
            bytes32 r,
            bytes32 s,
            address expectedSigner
         ) public pure returns (bool) { 
         return ecrecover(messageHash, v, r, s) == expectedSigner; 
         } 
}

This contract takes the messageHash and signature components, recovers the signer’s address, and checks if it matches the expected address.


Ecrecover Diagram

Ecrecover in Zero-Knowledge Circuits

Using ecrecover directly inside zero-knowledge proof (ZKP) circuits is computationally expensive. Instead, most ZK circuits accept the signer’s public key (split into x and y coordinates) as an input.

Here’s an example in Noir:

fn main(
  pub_key_x: [u8; 32],
  pub_key_y: [u8; 32],
  signature: [u8; 64],
  hashed_message: pub [u8; 32]
) -> pub Field {
  let address = ecrecover::ecrecover(pub_key_x, pub_key_y, signature, hashed_message);
address 
}

This approach avoids the cost of recovering the public key from the signature and makes the circuit more efficient.


Post-EIP-155: How v Changes

EIP-155 introduced a modification to the v parameter to include the chainId as a protection against replay attacks.

The formula is:

v = CHAIN_ID * 2 + 35 or CHAIN_ID * 2 + 36

Examples:

  • On Ethereum Mainnet (chainId = 1), possible v values are 37 and 38.

  • On Polygon (chainId = 137), possible values are 309 and 310.

This ensures that the same signature cannot be reused across multiple chains.


Security Notes & Tips

  • While v is typically 27 or 28, EIP-155 allows it to take other values.

  • Always validate the v value correctly during signature verification.

  • Always check that the address returned by ecrecover matches the expected signer.

  • To prevent replay attacks, include a nonce or chainId in the message being signed.


Conclusion

Ethereum’s ecrecover function is a foundational tool for verifying digital signatures on-chain. Understanding how it works including the role of v, r, and s is critical for writing secure smart contracts.

As zero-knowledge technologies evolve, verifying signatures efficiently off-chain and inside ZK circuits becomes more practical but at the core, it all starts with understanding how signature recovery works.

Mirror文章信息

Mirror原文:查看原文

作者地址:0xBa10d1C045Fca9470AC81755062A97df524C2569

内容类型:application/json

应用名称:MirrorXYZ

内容摘要:J-YVp5iZSlQUoy9TBOpZkK1dYnljBuawEX7cNmj3lyI

原始内容摘要:ukRj20g9Q9ZPM2M8bNkvq_XNN3JdbBxEX7T4_FCCXNw

区块高度:1715105

发布时间:2025-07-19 23:05:32