-
-
Save ezesundayeze/05b1dadead9ce13332985b76ad4a0c7d to your computer and use it in GitHub Desktop.
Signature Method Comparison
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Signature Comparison: Raw vs EIP-191 vs EIP-712</title> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| h2 { | |
| color: #333; | |
| text-align: center; | |
| } | |
| .button-group { | |
| display: flex; | |
| gap: 10px; | |
| margin-bottom: 20px; | |
| flex-wrap: wrap; | |
| } | |
| button { | |
| padding: 10px 15px; | |
| border: none; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| font-weight: bold; | |
| flex: 1; | |
| min-width: 200px; | |
| } | |
| #signRaw { | |
| background-color: #ffcccc; | |
| } | |
| #signEIP191 { | |
| background-color: #ccffcc; | |
| } | |
| #signEIP712 { | |
| background-color: #ccffff; | |
| } | |
| pre { | |
| background-color: #f5f5f5; | |
| padding: 15px; | |
| border-radius: 5px; | |
| white-space: pre-wrap; | |
| word-wrap: break-word; | |
| min-height: 180px; | |
| } | |
| .signature-type { | |
| font-weight: bold; | |
| margin-bottom: 5px; | |
| } | |
| .danger { | |
| color: #d32f2f; | |
| } | |
| .safe { | |
| color: #388e3c; | |
| } | |
| .enhanced { | |
| color: #0288d1; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h2>Signature Method Comparison</h2> | |
| <div class="button-group"> | |
| <button id="signRaw" onclick="signWithoutEIP191()"> | |
| ⚠️ Sign Raw Hash | |
| </button> | |
| <button id="signEIP191" onclick="signWithEIP191()"> | |
| ✅ Sign with EIP-191 | |
| </button> | |
| <button id="signEIP712" onclick="signWithEIP712()"> | |
| ✨ Sign with EIP-712 | |
| </button> | |
| </div> | |
| <pre id="output"></pre> | |
| <script src="https://cdn.jsdelivr.net/npm/ethers@5.7.2/dist/ethers.umd.min.js"></script> | |
| <script> | |
| const output = document.getElementById("output"); | |
| async function getConnectedAccount() { | |
| if (!window.ethereum) { | |
| throw new Error("MetaMask is not installed."); | |
| } | |
| const accounts = await window.ethereum.request({ | |
| method: "eth_requestAccounts" | |
| }); | |
| const account = accounts[0]; | |
| if (!account) { | |
| throw new Error("No MetaMask account is connected."); | |
| } | |
| return account; | |
| } | |
| async function signWithoutEIP191() { | |
| try { | |
| const account = await getConnectedAccount(); | |
| const message = "Withdraw 1 ETH from treasury"; | |
| const messageHash = ethers.utils.keccak256( | |
| ethers.utils.toUtf8Bytes(message) | |
| ); | |
| const signature = await window.ethereum.request({ | |
| method: "personal_sign", | |
| params: [messageHash, account] | |
| }); | |
| output.innerHTML = `<div class="signature-type danger">⚠️ Raw Hash Signature via personal_sign</div> | |
| Original message: | |
| "${message}" | |
| Keccak-256 hash (signed directly): | |
| ${messageHash} | |
| Signature: | |
| ${signature} | |
| This signs the raw hash using personal_sign. | |
| eth_sign was deprecated by MetaMask — it allowed signing arbitrary hashes with no user-readable context. | |
| personal_sign still lets you sign a hash directly, but MetaMask will show a warning.`; | |
| } catch (err) { | |
| output.textContent = `Error: ${err.message}`; | |
| } | |
| } | |
| async function signWithEIP191() { | |
| try { | |
| const account = await getConnectedAccount(); | |
| const message = "Withdraw 1 ETH from treasury"; | |
| const messageHex = ethers.utils.hexlify( | |
| ethers.utils.toUtf8Bytes(message) | |
| ); | |
| const signature = await window.ethereum.request({ | |
| method: "personal_sign", | |
| params: [messageHex, account] | |
| }); | |
| output.innerHTML = `<div class="signature-type safe">✅ EIP-191 Signed Message via personal_sign</div> | |
| Message: | |
| "${message}" | |
| Hex-encoded message sent to MetaMask: | |
| ${messageHex} | |
| Signature: | |
| ${signature} | |
| personal_sign applies the EIP-191 prefix before hashing and signing. | |
| MetaMask can also display the readable message to the user.`; | |
| } catch (err) { | |
| output.textContent = `Error: ${err.message}`; | |
| } | |
| } | |
| async function signWithEIP712() { | |
| try { | |
| const account = await getConnectedAccount(); | |
| const chainIdHex = await window.ethereum.request({ | |
| method: "eth_chainId" | |
| }); | |
| const chainId = Number.parseInt(chainIdHex, 16); | |
| const typedData = { | |
| domain: { | |
| name: "SignatureDemo", | |
| version: "1", | |
| chainId, | |
| verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | |
| }, | |
| primaryType: "Transaction", | |
| types: { | |
| EIP712Domain: [ | |
| { name: "name", type: "string" }, | |
| { name: "version", type: "string" }, | |
| { name: "chainId", type: "uint256" }, | |
| { name: "verifyingContract", type: "address" } | |
| ], | |
| Transaction: [ | |
| { name: "action", type: "string" }, | |
| { name: "amount", type: "uint256" }, | |
| { name: "currency", type: "string" }, | |
| { name: "recipient", type: "address" } | |
| ] | |
| }, | |
| message: { | |
| action: "Withdraw", | |
| amount: ethers.utils.parseEther("1").toString(), | |
| currency: "ETH", | |
| recipient: account | |
| } | |
| }; | |
| const signature = await window.ethereum.request({ | |
| method: "eth_signTypedData_v4", | |
| params: [account, JSON.stringify(typedData)] | |
| }); | |
| output.innerHTML = `<div class="signature-type enhanced">✨ EIP-712 Structured Signature</div> | |
| Typed data: | |
| ${JSON.stringify(typedData, null, 2)} | |
| Signature: | |
| ${signature} | |
| EIP-712 signs structured typed data. | |
| MetaMask can display the action, amount, recipient, and signing domain more clearly.`; | |
| } catch (err) { | |
| output.textContent = `Error: ${err.message}`; | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment