ethsig

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2026 License: MIT Imports: 18 Imported by: 0

README

ethsig

A comprehensive Ethereum signature library for Go, providing secure signing operations with whitelist-based access control and parameter validation.

Features

  • Multiple Signer Types

    • Private key-based signing (EthPrivateKeySigner)
    • Keystore file-based signing (KeystoreSigner)
    • Configurable scrypt parameters for keystore encryption
  • Signing Standards Support

    • Personal sign (EIP-191 version 0x45)
    • EIP-191 signed messages
    • EIP-712 typed structured data
    • Ethereum transaction signing
  • Security Features

    • Secure memory handling for sensitive data
    • Configurable encryption strength
    • Fine-grained access control
    • Comprehensive validation

Installation

go get github.com/ivanzzeth/ethsig

Quick Start

Basic Signing with Private Key

See examples/basic_privatekey/main.go for a complete example.

Using Keystore Signer

See examples/keystore_signer/main.go for a complete example.

Custom Scrypt Configuration

See examples/custom_scrypt_config/main.go for a complete example.

Signing Operations

Personal Sign (EIP-191)

See examples/personal_sign/main.go for a complete example.

EIP-712 Typed Data Signing

See examples/eip712_signing/main.go for a complete example.

Transaction Signing

See examples/transaction_signing/main.go for a complete example.

Interfaces

The library provides several interfaces for flexibility:

// AddressGetter provides address retrieval
type AddressGetter interface {
    GetAddress() common.Address
}

// RawMessageSigner signs raw messages without hashing
type RawMessageSigner interface {
    SignRawMessage(raw []byte) ([]byte, error)
}

// HashSigner signs raw hashes
type HashSigner interface {
    SignHash(hashedData common.Hash) ([]byte, error)
}

// EIP191Signer signs EIP-191 formatted messages
type EIP191Signer interface {
    SignEIP191Message(message string) ([]byte, error)
}

// PersonalSigner signs personal messages
type PersonalSigner interface {
    PersonalSign(data string) ([]byte, error)
}

// TypedDataSigner signs EIP-712 typed data
type TypedDataSigner interface {
    SignTypedData(typedData eip712.TypedData) ([]byte, error)
}

// TransactionSigner signs transactions
type TransactionSigner interface {
    SignTransactionWithChainID(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)
}

// Signer combines all signing capabilities
type Signer interface {
    AddressGetter
    RawMessageSigner
    HashSigner
    EIP191Signer
    PersonalSigner
    TypedDataSigner
    TransactionSigner
}

Security Best Practices

  1. Always close signers when done to clear sensitive data from memory:

    defer signer.Close()
    
  2. Use StandardScryptConfig for production keystore files:

    signer, err := ethsig.NewKeystoreSigner(path, password, &ethsig.StandardScryptConfig)
    
  3. Use LightScryptConfig for testing to avoid timeouts:

    signer, err := ethsig.NewKeystoreSigner(path, password, nil) // nil = LightScryptConfig
    
  4. Validate parameter and field values using constraints to prevent unauthorized operations

  5. Store keystore files securely with appropriate file permissions (0600)

  6. Never log or expose private keys - use keystore files instead

Testing

Run the test suite:

# Run all tests
go test ./...

# Run with timeout
go test ./... -timeout 30s

# Run specific package tests
go test -v ./... -run TestKeystore

# Run with race detection
go test -race ./...

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues and questions, please open an issue on GitHub.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Signature errors
	ErrInvalidSignatureLen        = errors.New("invalid signature length")
	ErrInvalidEIP191MessagePrefix = errors.New("invalid EIP191 message prefix")
	ErrSignatureValidationFailed  = errors.New("signature validation failed")
	ErrSignatureRecoveryFailed    = errors.New("signature recovery failed")

	// Signer errors
	ErrSignerNotImplemented  = errors.New("signer does not implement required interface")
	ErrSignerNotFound        = errors.New("signer not found")
	ErrSignerInvalidType     = errors.New("invalid signer type")
	ErrSignerAddressMismatch = errors.New("address mismatch in signer")

	// Transaction errors
	ErrTransactionNil        = errors.New("transaction is nil")
	ErrChainIDNil            = errors.New("chainID is nil")
	ErrTransactionSignFailed = errors.New("transaction signing failed")
	ErrTransactionInvalid    = errors.New("invalid transaction")

	// Keystore errors
	ErrKeystorePathEmpty          = errors.New("keystore path cannot be empty")
	ErrKeystoreNotFound           = errors.New("keystore file not found")
	ErrKeystoreDecryptFailed      = errors.New("keystore decryption failed")
	ErrKeystoreImportFailed       = errors.New("keystore import failed")
	ErrKeystoreDirectoryEmpty     = errors.New("keystore directory cannot be empty")
	ErrKeystoreNoFilesFound       = errors.New("no keystore files found in directory")
	ErrKeystoreCreateFailed       = errors.New("failed to create keystore")
	ErrKeystoreExportNotSupported = errors.New("private key export not supported with keystore-based implementation")

	// Validation errors
	ErrAddressZero      = errors.New("address is zero address")
	ErrAddressInvalid   = errors.New("invalid Ethereum address format")
	ErrChainIDInvalid   = errors.New("chainID must be positive")
	ErrMessageInvalid   = errors.New("invalid message format")
	ErrTypedDataInvalid = errors.New("invalid typed data structure")

	// Cryptographic errors
	ErrCryptoOperationFailed = errors.New("cryptographic operation failed")
	ErrPrivateKeyInvalid     = errors.New("invalid private key")
	ErrPublicKeyInvalid      = errors.New("invalid public key")
	ErrHashFailed            = errors.New("hash operation failed")

	// Security errors
	ErrSecurityViolation = errors.New("security violation detected")
	ErrMemorySafety      = errors.New("memory safety violation")
	ErrTimingAttack      = errors.New("potential timing attack detected")

	// EIP-712 errors
	ErrEIP712DomainUndefined  = errors.New("domain is undefined")
	ErrEIP712HashFailed       = errors.New("failed to hash EIP-712 data")
	ErrEIP712TypeNotFound     = errors.New("EIP-712 type not found")
	ErrEIP712InvalidStructure = errors.New("invalid EIP-712 structure")

	// Authorization errors
	ErrNotAuthorized    = errors.New("not authorized to perform operation")
	ErrPermissionDenied = errors.New("permission denied")

	// Configuration errors
	ErrConfigurationInvalid = errors.New("invalid configuration")
	ErrParameterMissing     = errors.New("required parameter missing")
	ErrParameterInvalid     = errors.New("invalid parameter value")

	// HD wallet errors
	ErrHDWalletAlreadyExists  = errors.New("HD wallet already exists")
	ErrHDWalletNotFound       = errors.New("HD wallet file not found")
	ErrHDWalletDecryptFailed  = errors.New("HD wallet decryption failed")
	ErrHDWalletInvalidVersion = errors.New("unsupported HD wallet version")
	ErrMnemonicInvalid        = errors.New("invalid BIP-39 mnemonic")
	ErrHDWalletClosed         = errors.New("HD wallet is closed")
	ErrHDDerivationFailed     = errors.New("HD key derivation failed")
	ErrInvalidDerivationRange = errors.New("invalid derivation range: start must be less than end")
)

Common errors used throughout the package

View Source
var (
	// StandardScryptConfig uses standard scrypt parameters (high security, slower)
	StandardScryptConfig = KeystoreScryptConfig{
		N: keystore.StandardScryptN,
		P: keystore.StandardScryptP,
	}

	// LightScryptConfig uses light scrypt parameters (lower security, faster - suitable for testing)
	LightScryptConfig = KeystoreScryptConfig{
		N: keystore.LightScryptN,
		P: keystore.LightScryptP,
	}
)

Default scrypt configurations

Functions

func ConvertRSV2SigBytes

func ConvertRSV2SigBytes(r [32]byte, s [32]byte, v uint8) []byte

ConvertRSV2SigBytes converts R, S, V components to a signature byte slice This is the reverse operation of ConvertSigBytes2RSV

Example: Input:

R: 0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f
S: 0x797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f244
V: 28

Output: 0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f2441c

func ConvertRSV2SigHex

func ConvertRSV2SigHex(r [32]byte, s [32]byte, v uint8) string

ConvertRSV2SigHex converts R, S, V components to a hex-encoded signature string with "0x" prefix

Example: Input:

R: 0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f
S: 0x797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f244
V: 28

Output: "0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f2441c"

func ConvertSigBytes2RSV

func ConvertSigBytes2RSV(sig []byte) (r [32]byte, s [32]byte, v uint8, err error)

ConvertSigBytes2RSV converts a signature byte slice to R, S, V components Input: 65-byte signature (R: 32 bytes, S: 32 bytes, V: 1 byte) Output: R, S, V components

Example: Input: 0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f2441c Output:

R: 0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f
S: 0x797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f244
V: 28

func ConvertSigHex2RSV

func ConvertSigHex2RSV(sigHex string) (r [32]byte, s [32]byte, v uint8, err error)

ConvertSigHex2RSV converts a hex-encoded signature string to R, S, V components The hex string should be 130 characters (65 bytes * 2) with optional "0x" prefix

Example: Input: "0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f2441c" Output:

R: 0x4fde044566e1288a60cebbc94458b2da86940d78ea2a92a993232726fb2ce78f
S: 0x797aef5eb003a2ca56ffec9e9cefe28f5666c352da36306c8ab807ac02d2f244
V: 28

func DenormalizeSignatureV

func DenormalizeSignatureV(signature []byte) []byte

DenormalizeSignatureV converts V from 27/28 to 0/1 format in a signature This function safely handles the signature and returns a denormalized copy

func DenormalizeV

func DenormalizeV(v uint8) uint8

DenormalizeV converts V from 27/28 to 0/1 format This is useful for some contract interactions that expect 0/1

func FormatSignatureHex

func FormatSignatureHex(r [32]byte, s [32]byte, v uint8) string

FormatSignatureHex formats R, S, V components as a pretty-printed string

func GetAddress

func GetAddress(signer any) (common.Address, error)

GetAddress flexibly returns the address associated with a signer It accepts any signer type and automatically chooses the best implementation: - If signer implements AddressGetter, use GetAddress directly This allows for maximum flexibility and future extensibility

func GetAddressWithExactGetter

func GetAddressWithExactGetter(getter AddressGetter) common.Address

GetAddressWithExactGetter is a helper function that returns the address associated with an AddressGetter

func IsAuthorizationError

func IsAuthorizationError(err error) bool

IsAuthorizationError checks if an error is authorization-related

func IsConfigurationError

func IsConfigurationError(err error) bool

IsConfigurationError checks if an error is configuration-related

func IsEIP712Error

func IsEIP712Error(err error) bool

IsEIP712Error checks if an error is EIP-712 related

func IsHDWalletError added in v0.4.0

func IsHDWalletError(err error) bool

IsHDWalletError checks if an error is HD wallet-related

func IsKeystoreError

func IsKeystoreError(err error) bool

IsKeystoreError checks if an error is keystore-related

func IsSecurityError

func IsSecurityError(err error) bool

IsSecurityError checks if an error is security-related

func IsSignatureError

func IsSignatureError(err error) bool

IsSignatureError checks if an error is signature-related

func IsSignerError

func IsSignerError(err error) bool

IsSignerError checks if an error is signer-related

func IsTransactionError

func IsTransactionError(err error) bool

IsTransactionError checks if an error is transaction-related

func IsValidationError

func IsValidationError(err error) bool

IsValidationError checks if an error is validation-related

func NewBindSignerFn

func NewBindSignerFn(txSigner any, chainID *big.Int) (bind.SignerFn, error)

NewBindSignerFn creates a bind.SignerFn from a TransactionSigner This function is used to convert our custom signer interface into the SignerFn type required by bind.TransactOpts

Parameters:

  • txSigner: The signer implementation (must implement both TransactionSigner/HashSigner and AddressGetter)
  • chainID: The chain ID to use for signing (e.g., 137 for Polygon)

Returns a bind.SignerFn that can be assigned to bind.TransactOpts.Signer

Example usage:

signerFn, err := signer.NewBindSignerFn(mySigner, big.NewInt(137))
if err != nil {
    return err
}
opts := &bind.TransactOpts{
    From: signer.GetAddress(mySigner),
    Signer: signerFn,
}

func NormalizeSignatureV

func NormalizeSignatureV(signature []byte) []byte

NormalizeSignatureV normalizes the V value in a signature to the standard format (27 or 28) This function safely handles the signature and returns a normalized copy

func NormalizeV

func NormalizeV(v uint8) uint8

NormalizeV normalizes the V value to the standard format (27 or 28) Some implementations use 0/1, this converts them to 27/28

func ParseSignatureComponents

func ParseSignatureComponents(sig []byte) (r *big.Int, s *big.Int, v uint8, err error)

ParseSignatureComponents parses a signature into its components and returns them as big.Int and uint8 This is useful for contract interactions that require *big.Int types

func PersonalSign

func PersonalSign(signer any, data string) ([]byte, error)

PersonalSign flexibly signs data using the most appropriate method based on signer type It accepts any signer type and automatically chooses the best implementation: - If signer implements PersonalSigner, use PersonalSign directly - If signer implements EIP191Signer, use PersonalSignWithEIP191 - If signer implements HashSigner, use PersonalSignWithHash This allows for maximum flexibility and automatic optimization

func PersonalSignWithEIP191

func PersonalSignWithEIP191(signer EIP191Signer, data string) ([]byte, error)

PersonalSignWithEIP191 implements personal_sign using an EIP191Signer This is a composable version that builds on top of SignEIP191Message

func PersonalSignWithExactSigner

func PersonalSignWithExactSigner(signer PersonalSigner, data string) ([]byte, error)

PersonalSignWithExactSigner is a helper function that signs data using personal_sign (EIP-191 0x45)

func PersonalSignWithHash

func PersonalSignWithHash(signer HashSigner, data string) ([]byte, error)

PersonalSignWithHash implements personal_sign using a HashSigner (hash-based approach) This is a composable version that builds on top of SignHash

func SecureZeroize

func SecureZeroize(data []byte)

SecureZeroize securely zeroizes a byte slice

func SecureZeroizeString

func SecureZeroizeString(str *string)

SecureZeroizeString securely zeroizes a string by converting to bytes and zeroizing Note: This function is deprecated and should not be used due to string immutability in Go. Use SecureBytes for sensitive data instead.

func SignEIP191Message

func SignEIP191Message(signer any, message string) ([]byte, error)

SignEIP191Message flexibly signs an EIP-191 formatted message using the most appropriate method based on signer type It accepts any signer type and automatically chooses the best implementation: - If signer implements EIP191Signer, use SignEIP191Message directly This allows for maximum flexibility and future extensibility

func SignEIP191MessageWithExactSigner

func SignEIP191MessageWithExactSigner(signer EIP191Signer, message string) ([]byte, error)

SignEIP191MessageWithExactSigner is a helper function that signs an EIP-191 formatted message

func SignEIP191MessageWithRawMessageSigner

func SignEIP191MessageWithRawMessageSigner(signer RawMessageSigner, message string) ([]byte, error)

func SignHash

func SignHash(signer any, hashedData common.Hash) ([]byte, error)

SignHash flexibly signs hashed data using the most appropriate method based on signer type It accepts any signer type and automatically chooses the best implementation: - If signer implements HashSigner, use SignHash directly - If signer implements RawMessageSigner, use SignHashWithRawMessageSigner This allows for maximum flexibility and automatic optimization

func SignHashWithExactSigner

func SignHashWithExactSigner(signer HashSigner, hashedData common.Hash) ([]byte, error)

SignHashWithExactSigner is a helper function that signs hashed data using a HashSigner

func SignHashWithRawMessageSigner

func SignHashWithRawMessageSigner(signer RawMessageSigner, hashedData common.Hash) ([]byte, error)

SignHashWithRawMessageSigner implements hash signing using a RawMessageSigner This is a composable version that builds on top of SignRawMessage

func SignRawMessage

func SignRawMessage(signer any, raw []byte) ([]byte, error)

SignRawMessage flexibly signs raw message data using the most appropriate method based on signer type It accepts any signer type and automatically chooses the best implementation: - If signer implements RawMessageSigner, use SignRawMessage directly - If signer implements HashSigner, use SignRawMessageWithHashSigner This allows for maximum flexibility and automatic optimization

func SignRawMessageWithHashSigner

func SignRawMessageWithHashSigner(signer HashSigner, raw []byte) ([]byte, error)

func SignTransaction

func SignTransaction(signer any, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

SignTransaction flexibly signs an Ethereum transaction using the most appropriate method based on signer type It accepts any signer type and automatically chooses the best implementation: - If signer implements TransactionSigner, use SignTransactionWithChainID directly - If signer implements HashSigner, use SignTransactionWithHashSigner This allows for maximum flexibility and automatic optimization IMPORTANT: Always provide explicit chainID to ensure correct signing

func SignTransactionWithExactSigner

func SignTransactionWithExactSigner(signer TransactionSigner, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

SignTransactionWithExactSigner is a helper function that signs an Ethereum transaction It requires explicit chainID to ensure correct signing

func SignTransactionWithHashSigner

func SignTransactionWithHashSigner(signer HashSigner, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

SignTransactionWithHashSigner implements transaction signing using a HashSigner This is a composable version that builds on top of SignHash It follows the same logic as types.SignTx but uses the HashSigner interface IMPORTANT: Always uses the provided chainID for signing, NOT tx.ChainId()

func SignTypedData

func SignTypedData(signer any, typedData eip712.TypedData) ([]byte, error)

SignTypedData flexibly signs EIP-712 typed data using the most appropriate method based on signer type It accepts any signer type and automatically chooses the best implementation: - If signer implements TypedDataSigner, use SignTypedData directly - If signer implements EIP191Signer, use SignTypedDataWithEIP191 - If signer implements HashSigner, use SignTypedDataWithHash This allows for maximum flexibility and automatic optimization

func SignTypedDataWithEIP191

func SignTypedDataWithEIP191(signer EIP191Signer, typedData eip712.TypedData) ([]byte, error)

SignTypedDataWithEIP191 implements EIP-712 signing using an EIP191Signer This is a composable version that builds on top of SignEIP191Message

func SignTypedDataWithExactSigner

func SignTypedDataWithExactSigner(signer TypedDataSigner, typedData eip712.TypedData) ([]byte, error)

SignTypedDataWithExactSigner is a helper function that signs EIP-712 typed data

func SignTypedDataWithHash

func SignTypedDataWithHash(signer HashSigner, typedData eip712.TypedData) ([]byte, error)

SignTypedDataWithHash implements EIP-712 signing using a HashSigner This is a composable version that builds on top of SignHash

func StructToRSV

func StructToRSV(rsv RSV) (r [32]byte, s [32]byte, v uint8)

StructToRSV extracts R, S, V from an RSV struct

func ValidateAddress

func ValidateAddress(address common.Address) error

ValidateAddress validates that an address is a valid Ethereum address

func ValidateChainID

func ValidateChainID(chainID *big.Int) error

ValidateChainID validates that a chain ID is valid

func ValidateEIP191Message

func ValidateEIP191Message(message []byte) error

func ValidateSignature

func ValidateSignature(signer common.Address, hashedData common.Hash, signature []byte) (bool, error)

func ValidateSignatureLength

func ValidateSignatureLength(signature []byte) error

ValidateSignatureLength validates that a signature has the correct length

Types

type AddressGetter

type AddressGetter interface {
	// GetAddress returns the address associated with this signer
	GetAddress() common.Address
}

type EIP191Signer

type EIP191Signer interface {
	SignEIP191Message(message string) ([]byte, error)
}

type ErrorType

type ErrorType int

Error types for better error categorization

const (
	ErrorTypeSignature ErrorType = iota
	ErrorTypeSigner
	ErrorTypeTransaction
	ErrorTypeKeystore
	ErrorTypeValidation
	ErrorTypeCryptographic
	ErrorTypeSecurity
	ErrorTypeEIP712
	ErrorTypeAuthorization
	ErrorTypeConfiguration
	ErrorTypeHDWallet
)

type EthPrivateKeySigner

type EthPrivateKeySigner struct {
	// contains filtered or unexported fields
}

EthPrivateKeySigner implements Signer using an Ethereum private key

func NewEthPrivateKeySigner

func NewEthPrivateKeySigner(privateKey *ecdsa.PrivateKey) *EthPrivateKeySigner

NewEthPrivateKeySigner creates a new EthPrivateKeySigner instance

func NewEthPrivateKeySignerFromPrivateKeyHex

func NewEthPrivateKeySignerFromPrivateKeyHex(privateKeyHex string) (*EthPrivateKeySigner, error)

func (*EthPrivateKeySigner) GetAddress

func (s *EthPrivateKeySigner) GetAddress() common.Address

GetAddress returns the Ethereum address associated with the private key Implements AddressGetter interface

func (*EthPrivateKeySigner) PersonalSign

func (s *EthPrivateKeySigner) PersonalSign(data string) ([]byte, error)

PersonalSign implements personal_sign (EIP-191 version 0x45) It prepends "\x19Ethereum Signed Message:\n" + len(message) to the message before signing This implementation uses the composable PersonalSignWithHash helper

func (*EthPrivateKeySigner) SignEIP191Message

func (s *EthPrivateKeySigner) SignEIP191Message(message string) ([]byte, error)

func (*EthPrivateKeySigner) SignHash

func (s *EthPrivateKeySigner) SignHash(hashedData common.Hash) ([]byte, error)

Sign signs the hashed data using the private key

func (*EthPrivateKeySigner) SignRawMessage

func (s *EthPrivateKeySigner) SignRawMessage(raw []byte) ([]byte, error)

func (*EthPrivateKeySigner) SignTransactionWithChainID

func (s *EthPrivateKeySigner) SignTransactionWithChainID(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

SignTransactionWithChainID signs an Ethereum transaction with the private key Implements TransactionSigner interface IMPORTANT: Always uses the provided chainID for signing, NOT tx.ChainId() This ensures correct signing even when tx.ChainId() returns unexpected values (e.g., MaxUint64 for unsigned legacy transactions)

Parameters:

  • tx: The transaction to sign (must have nonce, gas, gasPrice, etc. set)
  • chainID: The explicit chain ID to use for signing (e.g., 137 for Polygon)

func (*EthPrivateKeySigner) SignTypedData

func (s *EthPrivateKeySigner) SignTypedData(typedData eip712.TypedData) ([]byte, error)

SignTypedData implements EIP-712 typed data signing This implementation uses the composable SignTypedDataWithHash helper

type HDWalletSigner added in v0.4.0

type HDWalletSigner struct {
	// contains filtered or unexported fields
}

HDWalletSigner implements Signer using a key derived from an HD wallet at a specific derivation index. The private key is derived once at construction and held in memory until Close is called.

func NewHDWalletSigner added in v0.4.0

func NewHDWalletSigner(wallet *keystore.HDWallet, index uint32) (*HDWalletSigner, error)

NewHDWalletSigner creates a new signer for the given HD wallet at the specified derivation index. The private key is derived immediately.

func (*HDWalletSigner) Close added in v0.4.0

func (s *HDWalletSigner) Close() error

Close zeroizes the derived private key. The signer is unusable after this call.

func (*HDWalletSigner) GetAddress added in v0.4.0

func (s *HDWalletSigner) GetAddress() common.Address

GetAddress returns the Ethereum address derived at this signer's index.

func (*HDWalletSigner) PersonalSign added in v0.4.0

func (s *HDWalletSigner) PersonalSign(data string) ([]byte, error)

PersonalSign implements personal_sign (EIP-191 version 0x45).

func (*HDWalletSigner) SignEIP191Message added in v0.4.0

func (s *HDWalletSigner) SignEIP191Message(message string) ([]byte, error)

SignEIP191Message signs an EIP-191 formatted message.

func (*HDWalletSigner) SignHash added in v0.4.0

func (s *HDWalletSigner) SignHash(hashedData common.Hash) ([]byte, error)

SignHash signs the hashed data using the derived private key.

func (*HDWalletSigner) SignRawMessage added in v0.4.0

func (s *HDWalletSigner) SignRawMessage(raw []byte) ([]byte, error)

SignRawMessage signs raw message bytes by hashing them first.

func (*HDWalletSigner) SignTransactionWithChainID added in v0.4.0

func (s *HDWalletSigner) SignTransactionWithChainID(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

SignTransactionWithChainID signs an Ethereum transaction with the derived key.

func (*HDWalletSigner) SignTypedData added in v0.4.0

func (s *HDWalletSigner) SignTypedData(typedData eip712.TypedData) ([]byte, error)

SignTypedData implements EIP-712 typed data signing.

type HashSigner

type HashSigner interface {
	// SignHash signs the hashed data and returns the signature
	SignHash(hashedData common.Hash) ([]byte, error)
}

type KeystoreScryptConfig

type KeystoreScryptConfig struct {
	N int // CPU/memory cost parameter
	P int // Parallelization parameter
}

KeystoreScryptConfig holds the scrypt parameters for keystore encryption/decryption

type KeystoreSigner

type KeystoreSigner struct {
	// contains filtered or unexported fields
}

KeystoreSigner implements Signer using an Ethereum keystore It delegates all signing operations to the keystore's signing methods This allows external code to manage the KeyStore and create signers for specific addresses

func NewKeystoreSigner

func NewKeystoreSigner(ks *keystore.KeyStore, address common.Address, password string) (*KeystoreSigner, error)

NewKeystoreSigner creates a new KeystoreSigner from an existing KeyStore and address This is the recommended way to create KeystoreSigners when managing multiple accounts, as it allows external code to manage the KeyStore lifecycle and create signers for specific addresses.

Parameters:

  • ks: An existing KeyStore instance (managed by caller)
  • address: The address to sign with (must exist in the KeyStore)
  • password: Password to unlock the account

Returns:

  • *KeystoreSigner: The initialized keystore signer
  • error: Any error that occurred during account lookup or password validation

Example:

// Create a single KeyStore for all accounts
ks := keystore.NewKeyStore("/path/to/keystore", keystore.StandardScryptN, keystore.StandardScryptP)

// Create signers for different addresses from the same KeyStore
addr1 := common.HexToAddress("0x1234...")
signer1, _ := ethsig.NewKeystoreSigner(ks, addr1, "password1")

addr2 := common.HexToAddress("0x5678...")
signer2, _ := ethsig.NewKeystoreSigner(ks, addr2, "password2")

func NewKeystoreSignerFromDirectory

func NewKeystoreSignerFromDirectory(keystoreDir string, address common.Address, password string, scryptConfig *KeystoreScryptConfig) (*KeystoreSigner, error)

NewKeystoreSignerFromDirectory creates a KeystoreSigner from a directory and address This is a convenience wrapper around NewKeystoreSignerFromPath.

Parameters:

  • keystoreDir: Directory containing keystore files
  • address: The address to sign with
  • password: Password to unlock the account
  • scryptConfig: Scrypt configuration (use nil for LightScryptConfig default)

Returns:

  • *KeystoreSigner: The initialized keystore signer
  • error: Any error that occurred

Example:

addr := common.HexToAddress("0x1234...")
signer, err := ethsig.NewKeystoreSignerFromDirectory("/path/to/keystore", addr, "password", nil)

func NewKeystoreSignerFromFile

func NewKeystoreSignerFromFile(keystoreFile string, address common.Address, password string, scryptConfig *KeystoreScryptConfig) (*KeystoreSigner, error)

NewKeystoreSignerFromFile creates a KeystoreSigner from a specific keystore file and address This is a convenience wrapper around NewKeystoreSignerFromPath that validates the file exists.

Parameters:

  • keystoreFile: Path to a specific keystore file
  • address: The address to sign with (must match the file's address)
  • password: Password to unlock the account
  • scryptConfig: Scrypt configuration (use nil for LightScryptConfig default)

Returns:

  • *KeystoreSigner: The initialized keystore signer
  • error: Any error that occurred

Example:

addr := common.HexToAddress("0x1234...")
signer, err := ethsig.NewKeystoreSignerFromFile("/path/to/keystore/UTC--2024...", addr, "password", nil)

func NewKeystoreSignerFromPath

func NewKeystoreSignerFromPath(keystorePath string, address common.Address, password string, scryptConfig *KeystoreScryptConfig) (*KeystoreSigner, error)

NewKeystoreSignerFromPath creates a KeystoreSigner from a keystore directory/file path This is a convenience function that creates a new KeyStore internally.

Parameters:

  • keystorePath: Path to the keystore directory or file
  • address: The address to sign with
  • password: Password to unlock the account
  • scryptConfig: Scrypt configuration (use nil for LightScryptConfig default)

Returns:

  • *KeystoreSigner: The initialized keystore signer
  • error: Any error that occurred

Example:

addr := common.HexToAddress("0x1234...")
signer, err := ethsig.NewKeystoreSignerFromPath("/path/to/keystore", addr, "password", nil)

func (*KeystoreSigner) Close

func (s *KeystoreSigner) Close() error

Close securely cleans up sensitive data from memory This should be called when the signer is no longer needed

func (*KeystoreSigner) GetAddress

func (s *KeystoreSigner) GetAddress() common.Address

GetAddress returns the Ethereum address associated with the private key Implements AddressGetter interface

func (*KeystoreSigner) PersonalSign

func (s *KeystoreSigner) PersonalSign(data string) ([]byte, error)

PersonalSign implements personal_sign (EIP-191 version 0x45) It prepends "\x19Ethereum Signed Message:\n" + len(message) to the message before signing

func (*KeystoreSigner) SignEIP191Message

func (s *KeystoreSigner) SignEIP191Message(message string) ([]byte, error)

SignEIP191Message signs an EIP-191 formatted message

func (*KeystoreSigner) SignHash

func (s *KeystoreSigner) SignHash(hashedData common.Hash) ([]byte, error)

SignHash signs the hashed data using the private key

func (*KeystoreSigner) SignRawMessage

func (s *KeystoreSigner) SignRawMessage(raw []byte) ([]byte, error)

SignRawMessage signs raw message bytes

func (*KeystoreSigner) SignTransactionWithChainID

func (s *KeystoreSigner) SignTransactionWithChainID(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

SignTransactionWithChainID signs an Ethereum transaction with the private key Implements TransactionSigner interface IMPORTANT: Always uses the provided chainID for signing, NOT tx.ChainId()

func (*KeystoreSigner) SignTypedData

func (s *KeystoreSigner) SignTypedData(typedData eip712.TypedData) ([]byte, error)

SignTypedData implements EIP-712 typed data signing

type PersonalSigner

type PersonalSigner interface {
	PersonalSign(data string) ([]byte, error)
}

type RSV

type RSV struct {
	R [32]byte // R component
	S [32]byte // S component
	V uint8    // V component (recovery ID)
}

RSV represents the R, S, V components of an Ethereum signature

func RSVToStruct

func RSVToStruct(r [32]byte, s [32]byte, v uint8) RSV

RSVToStruct converts R, S, V byte arrays to an RSV struct

type RawMessageSigner

type RawMessageSigner interface {
	SignRawMessage(raw []byte) ([]byte, error)
}

type SecureBytes

type SecureBytes struct {
	// contains filtered or unexported fields
}

SecureBytes provides secure handling of sensitive byte data It automatically zeroizes memory when no longer needed

func NewSecureBytes

func NewSecureBytes(data []byte) *SecureBytes

NewSecureBytes creates a new SecureBytes instance

func NewSecureBytesFromString

func NewSecureBytesFromString(data string) *SecureBytes

NewSecureBytesFromString creates a new SecureBytes instance from a string

func (*SecureBytes) Bytes

func (sb *SecureBytes) Bytes() []byte

Bytes returns a copy of the secure bytes

func (*SecureBytes) ConstantTimeCompare

func (sb *SecureBytes) ConstantTimeCompare(other *SecureBytes) bool

ConstantTimeCompare compares two SecureBytes in constant time

func (*SecureBytes) IsZeroized

func (sb *SecureBytes) IsZeroized() bool

IsZeroized checks if the secure bytes have been zeroized

func (*SecureBytes) Len

func (sb *SecureBytes) Len() int

Len returns the length of the secure bytes

func (*SecureBytes) String

func (sb *SecureBytes) String() string

String returns the secure bytes as a string (use with caution)

func (*SecureBytes) Zeroize

func (sb *SecureBytes) Zeroize()

Zeroize securely erases the sensitive data from memory

type Signer

type Signer struct {
	// contains filtered or unexported fields
}

Signer is a flexible wrapper that accepts any underlying signer implementation and provides a unified interface for all signing operations. It automatically delegates to the most appropriate method based on what the underlying signer supports.

func NewSigner

func NewSigner(signer any) *Signer

NewSigner creates a new Signer instance wrapping any underlying signer

func (*Signer) Close

func (s *Signer) Close() error

Close securely cleans up sensitive data from memory This method checks if the underlying signer implements a Close() method and calls it It should be called when the signer is no longer needed

func (*Signer) GetAddress

func (s *Signer) GetAddress() common.Address

GetAddress returns the address associated with this signer Implements AddressGetter interface NOTE: If not supported by the underlying signer, ZERO address will be returned.

func (*Signer) PersonalSign

func (s *Signer) PersonalSign(data string) ([]byte, error)

PersonalSign signs data using personal_sign (EIP-191 0x45) Implements PersonalSigner interface

func (*Signer) SafeGetAddress

func (s *Signer) SafeGetAddress() (common.Address, error)

SafeGetAddress returns the address associated with this signer with error handling

func (*Signer) SignEIP191Message

func (s *Signer) SignEIP191Message(message string) ([]byte, error)

SignEIP191Message signs an EIP-191 formatted message Implements EIP191Signer interface

func (*Signer) SignHash

func (s *Signer) SignHash(hashedData common.Hash) ([]byte, error)

SignHash signs hashed data Implements HashSigner interface

func (*Signer) SignRawMessage

func (s *Signer) SignRawMessage(raw []byte) ([]byte, error)

SignRawMessage signs raw message bytes Implements RawMessageSigner interface

func (*Signer) SignTransactionWithChainID

func (s *Signer) SignTransactionWithChainID(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

SignTransactionWithChainID signs an Ethereum transaction with explicit chainID Implements TransactionSigner interface

func (*Signer) SignTypedData

func (s *Signer) SignTypedData(typedData eip712.TypedData) ([]byte, error)

SignTypedData signs EIP-712 typed data Implements TypedDataSigner interface

type TransactionSigner

type TransactionSigner interface {
	SignTransactionWithChainID(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)
}

type TypedDataSigner

type TypedDataSigner interface {
	SignTypedData(typedData eip712.TypedData) ([]byte, error)
}

TypedDataSigner is an interface for signing typed data

type TypedError

type TypedError struct {
	Type    ErrorType
	Message string
	Cause   error
}

TypedError represents a categorized error with additional context

func NewAuthorizationError

func NewAuthorizationError(message string, cause error) *TypedError

NewAuthorizationError creates an authorization-related error

func NewConfigurationError

func NewConfigurationError(message string, cause error) *TypedError

NewConfigurationError creates a configuration-related error

func NewEIP712Error

func NewEIP712Error(message string, cause error) *TypedError

NewEIP712Error creates an EIP-712 related error

func NewHDWalletError added in v0.4.0

func NewHDWalletError(message string, cause error) *TypedError

NewHDWalletError creates an HD wallet-related error

func NewKeystoreError

func NewKeystoreError(message string, cause error) *TypedError

NewKeystoreError creates a keystore-related error

func NewSecurityError

func NewSecurityError(message string, cause error) *TypedError

NewSecurityError creates a security-related error

func NewSignatureError

func NewSignatureError(message string, cause error) *TypedError

NewSignatureError creates a signature-related error

func NewSignerError

func NewSignerError(message string, cause error) *TypedError

NewSignerError creates a signer-related error

func NewTransactionError

func NewTransactionError(message string, cause error) *TypedError

NewTransactionError creates a transaction-related error

func NewTypedError

func NewTypedError(errorType ErrorType, message string, cause error) *TypedError

NewTypedError creates a new typed error

func NewValidationError

func NewValidationError(message string, cause error) *TypedError

NewValidationError creates a validation-related error

func (*TypedError) Error

func (e *TypedError) Error() string

Error implements the error interface

func (*TypedError) Unwrap

func (e *TypedError) Unwrap() error

Unwrap returns the underlying error

Directories

Path Synopsis
cmd
keystore command
examples
eip712_signing command
keystore_signer command
personal_sign command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL