- vừa được xem lúc

🔐 Understanding Ethereum ECDSA, EIP-712 and Its Role in Permit Functionality 🧾

0 0 2

Người đăng: Truong Phung

Theo Viblo Asia

1. ECDSA

In Ethereum and Solidity, digital signatures are generated using the Elliptic Curve Digital Signature Algorithm (ECDSA). This algorithm is used to verify the authenticity of a message signed by a private key. The signature is typically broken into three components: v, r, and s. Let's explore these components in more detail:

1. ECDSA Signature Basics

When someone signs a message using their private key (off-chain), they produce a signature consisting of two main values, r and s, plus a recovery identifier v. This signature proves that the message was signed by the owner of a particular private key without revealing the private key itself.

  • r and s: These are the two components of the actual signature, representing points on the elliptic curve.
    • r: A random integer generated during the signing process, part of the elliptic curve calculations.
    • s: The second half of the signature, derived from the private key and the message being signed.
  • v: The recovery identifier, which is used to recover the signer's public key from the signature.

2. Understanding v, r, and s

  • r (32 bytes):
    • A point on the elliptic curve generated during the signature creation process.
    • It is deterministic but varies with each signature, even if the same message is signed multiple times.
  • s (32 bytes): The second part of the signature, calculated using the private key, the message hash, and r. There are two possible values for s (high and low). By convention, the "low" value is used to prevent signature malleability attacks (i.e., changing the signature without changing the underlying message).
  • v (1 byte):
    • The recovery identifier, also known as the "recovery id". It is a single byte that can be either 27 or 28 on Ethereum.
    • v helps the ecrecover function (used to recover the public key from the signature) determine which of two possible public keys corresponds to the signature. Without v, there would be ambiguity about which public key was used to sign the message.

3. How the Signature is Created

Here’s how the signing process typically works off-chain:

  1. Hash the Message: The message is hashed using the Keccak-256 hashing algorithm. This produces a unique hash of the message that is used for signing.
    messageHash = keccak256(abi.encodePacked(...));
    
  2. Sign the Hash: The private key signs the hash of the message, producing the signature. The signing process yields three values: r, s, and v.
    • The elliptic curve algorithm computes the points r and s based on the private key and the message hash.
    • v is derived from the signing process and tells us which public key can be used to verify the signature.
  3. Provide the Signature: The resulting signature, composed of r, s, and v, is then sent alongside the message. The contract will later use these values to verify that the signature is valid and corresponds to the correct address (public key).

4. How the Signature is Verified On-Chain

In Solidity, the function used to verify an ECDSA signature is ecrecover. This function takes four parameters: digest, v, r, and s. It recovers the public key of the signer (which is derived from the signer's Ethereum address) and checks whether it matches the expected signer.

Here’s how this works:

address recoveredAddress = ecrecover(digest, v, r, s);
  • digest: The hash of the message, which was signed off-chain.
  • v: The recovery identifier (helps in resolving which key to use).
  • r and s: The signature values generated during the signing process. The ecrecover function returns the address corresponding to the public key of the signer. The contract compares this address with the expected owner address:
    require(recoveredAddress != address(0) && recoveredAddress == owner, 'INVALID_SIGNATURE');
    

If the recovered address matches the owner's address and is not the zero address, the signature is valid.

5. Use Case in the permit Function

In the context of the permit function (ERC-2612):

  • The user (owner) signs a permit off-chain, which contains the information about the spender, the value, nonce, and deadline.
  • This produces the v, r, and s values.
  • The spender or a third party submits the signed permit (with the v, r, and s values) to the blockchain, where it is validated using ecrecover.

The contract then:

  1. Hashes the permit message using the same parameters.
  2. Uses ecrecover to recover the address of the signer from the signature components (v, r, s).
  3. Ensures that the recovered address matches the owner's address to confirm the validity of the signature.

6. Signature Verification Example in Practice

Here’s a simplified example of how the signing and recovery process works:

1. Off-Chain Signature Creation (using a wallet):

The wallet signs the hashed message (permit details) with the private key. This generates r, s, and v.

2. On-Chain Signature Verification:
bytes32 digest = keccak256( abi.encodePacked( '\x19\x01', // EIP-712 prefix DOMAIN_SEPARATOR, // Contract domain separator keccak256(abi.encode( // Hash of the permit data PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline )) )
);
address recoveredAddress = ecrecover(digest, v, r, s);
  • ecrecover(digest, v, r, s) uses the digest (hashed message) and the v, r, s signature components to recover the signer’s address.
  • If the recovered address matches the expected owner, the signature is valid.

Summary of v, r, s in ECDSA

  • r and s: The signature components representing points on the elliptic curve. These are used to verify that the message was signed by the private key corresponding to the signer's address.
  • v: The recovery id, which helps resolve which of the two possible public keys (from elliptic curve math) was used to sign the message.

The combination of these values ensures secure, verifiable signatures in Ethereum smart contracts, allowing off-chain signature generation and on-chain verification.

2. Understanding EIP-712 and Its Role in Permit Functionality

When working with Ethereum and Solidity, secure off-chain data signing is a critical requirement for many applications, especially those involving token approvals and meta-transactions. EIP-712, a standard for "Typed Structured Data Hashing and Signing," plays a pivotal role in enabling these functionalities seamlessly and securely.

What is EIP-712?

EIP-712 standardizes how structured data is encoded, hashed, and signed, ensuring compatibility between off-chain systems and Ethereum smart contracts. It provides:

  • Human-Readable Messages: Makes it easier for users to verify the content of the data being signed.
  • Security: Includes domain-specific details like chain ID and contract address to prevent signature reuse (replay attacks) across different domains or contracts.

EIP-712Domain in Solidity

The EIP712Domain is a structured hash that uniquely identifies a contract and its context. It includes fields such as:

  • name: The name of the contract (e.g., "MyToken").
  • version: The version of the contract (e.g., "1").
  • chainId: The blockchain ID, ensuring signatures are valid only on the intended chain.
  • verifyingContract: The contract address.

The DOMAIN_SEPARATOR is the hash of this domain and is a key element used in the final signature verification process. Example of constructing the DOMAIN_SEPARATOR in Solidity:

bytes32 public DOMAIN_SEPARATOR; constructor() { DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes("MyToken")), keccak256(bytes("1")), block.chainid, address(this) ) );
}

Permit: Gasless Approvals with ERC-2612

The permit function, introduced in ERC-2612, leverages EIP-712 to allow users to approve token allowances using off-chain signatures instead of on-chain transactions. This eliminates the need for an approve transaction, saving gas and streamlining user interactions.

How Permit Works:

  1. User Signs a Permit: Off-chain, the user signs a message containing details like the spender address, amount, nonce, and deadline.
  2. Submit the Permit On-Chain: The spender submits the signed message to the contract via the permit function.
  3. Verify the Signature: The smart contract uses EIP-712 hashing and signature recovery (via ecrecover) to ensure that:
  • The signature is valid.
  • It was signed by the token owner.
  • The nonce is unique, and the deadline has not expired.

Example of the permit function in Solidity:

function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s
) external { require(deadline >= block.timestamp, "Permit: expired"); bytes32 structHash = keccak256( abi.encode( keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"), owner, spender, value, nonces[owner]++, deadline ) ); bytes32 digest = keccak256( abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, structHash) ); address signer = ecrecover(digest, v, r, s); require(signer == owner, "Permit: invalid signature"); _approve(owner, spender, value);
}

Why Use EIP-712 and Permit?

  • User Convenience: Users no longer need to perform multiple transactions (e.g., approve and transfer), reducing friction.
  • Gas Savings: Permit eliminates the need for an approve transaction, significantly saving gas fees.
  • Security: With EIP-712, signatures are tied to the contract and chain, preventing replay attacks.

EIP-712 and Permit are foundational technologies for building user-friendly and efficient decentralized applications, especially in the context of DeFi and tokenized ecosystems.

Bình luận

Bài viết tương tự

- vừa được xem lúc

[Blockchain] Road to Bitcoin

. Chắc mọi người hẳn đã không còn xa lạ gì với anh chàng tỷ phú đã ném vỡ cửa kính ô tô nhà mình cùng với siêu năng lực điều khiển vật giá chỉ bằng lời nói, người đã đẩy định giá Bitcoin trên thị trường vượt ngưỡng 50K dolar/coin với những bài twitter để đời . .

0 0 61

- vừa được xem lúc

Khi Ethereum có chi phí giao dịch quá đắt đỏ - Tương lai cho layer2 ?

Với sự phát triển như vũ bão của Blockchain, ETH dường như đang quá tải và hệ quả là chi phí Gas đã lên đến 1000Gwei, phí để tạo những transaction phức tạp đã xấp xỉ 500$ . Và một giải pháp cứu cánh cho các sản phẩm Defi trên ETH chính là Layer2, và trong nhiệm vụ lần này Matic đang thể hiện khả năn

0 0 89

- vừa được xem lúc

Blockchain với Java - Tại sao không?

Cuộc cách mạng công nghiệp 4.0 ra đời kéo theo nhiều sự thay đổi và xu hướng mới được hình thành. Riêng đối với lĩnh vực CNTT cũng không nằm ngoài vùng ảnh hưởng mạnh mẽ. Chính làn sóng 4.

0 0 92

- vừa được xem lúc

Phân loại và tầm quan trọng của các node trong mạng blockchain

Trước khi đi vào phân loại và nêu rõ được tầm quan trọng của các node trọng mạng blockchain thì mình xin được trích dẫn khái niệm về blockchain từ Wikipedia như sau:. .

0 1 65

- vừa được xem lúc

Code Smart Contract bằng Assembly ?

Introduction. Hồi còn học trong ghế nhà trường bộ môn lập trình tốn nhiều não nhất của mình là code assembly. Nôm na thì bất cứ ngôn ngữ bậc cao nào như C , Go, Java,... được sinh ra để người dễ hiểu và dễ code , tuy nhiên chúng đều sẽ được compiled down xuống assembly một ngôn ngữ bậc thấp để máy h

0 0 58

- vừa được xem lúc

Dextool - Công cụ phân tích Decentralized Exchange tuyệt vời

. Trend Defi mặc dù đã bớt nhiệt nhưng những sản phẩm nổi bật của làn sóng này mang lại thì vẫn rất được người dùng ưa chuộng. Đặc biệt là các nền tảng Decentralized Exchange, tiêu biểu là Uniswap, SushiSwap, 1inch Exchange, FalconSwap,... Nhưng khi đã sử dụng các nền tảng DEx này mà không biết đến

0 0 106