signaturesecp256k1_sign

On-chain secp256k1 ECDSA signing

Sign messages on-chain using Mercury EVM's secp256k1 signing precompile.

Overview

secp256k1_sign() and async_secp256k1_sign() call the secp256k1 signing precompile at address 0x69 to create ECDSA signatures. The message is hashed with the EIP-191 personal-sign prefix before signing.

Signature

def secp256k1_sign(
    w3: Web3,
    *,
    sk: PrivateKey,
    message: str,
) -> HexBytes

async def async_secp256k1_sign(
    w3: AsyncWeb3,
    *,
    sk: PrivateKey,
    message: str,
) -> HexBytes

Parameters

Parameter
Type
Required
Description

w3

Web3 or AsyncWeb3

Yes

Web3 instance connected to a Seismic node

sk

Yes

32-byte secp256k1 private key

message

str

Yes

Message string to sign

Returns

Type
Description

HexBytes

ECDSA signature bytes (65 bytes: r + s + v)

Examples

Basic Usage

Async Usage

Sign Multiple Messages

Verify Signature Off-Chain

Extract Signature Components

Generate Private Key

Sign Transaction Hash

Compare On-Chain vs Off-Chain Signing

Sign with Message Context

How It Works

  1. Hash message - Applies EIP-191 personal-sign prefix and keccak256 hash:

  2. Encode parameters - ABI-encodes the private key and message hash

  3. Call precompile - Issues an eth_call to address 0x69 with 3000 gas

  4. Sign hash - Precompile performs ECDSA signing on secp256k1 curve

  5. Return signature - Returns 65-byte signature (r + s + v)

Gas Cost

Fixed gas cost: 3000 gas

The cost is constant regardless of message length (since the message is hashed before signing).

EIP-191 Message Hashing

The precompile follows EIP-191 personal-sign format, equivalent to:

This ensures compatibility with standard Ethereum message signing (e.g., MetaMask's personal_sign).

Signature Format

The returned signature is 65 bytes:

  • r (32 bytes): Signature component

  • s (32 bytes): Signature component

  • v (1 byte): Recovery ID (27 or 28)

This format is compatible with ecrecover and standard Ethereum signature verification.

Notes

  • Uses secp256k1 curve (same as Ethereum)

  • Message is automatically prefixed with EIP-191 header

  • Signatures are non-deterministic (random 'k' value)

  • Compatible with MetaMask and other Ethereum wallets

  • Can be verified on-chain using ecrecover precompile

Warnings

  • Private key security - Never expose or log private keys

  • Message format - Message is treated as UTF-8 string

  • Signature malleability - Standard ECDSA signatures are malleable (use EIP-2098 compact signatures if needed)

  • Non-deterministic - Multiple signatures of the same message will differ

See Also

Last updated