CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Mục lục

Trang chủHướng dẫnHướng dẫn verify signatur...
Blockchain

Hướng dẫn verify signatures trong Solidity

3 phút đọc04/05/2025
CyStack Author
Đức Hacker

Senior Cybersecurity Expert

0 lượt xem
Reading Time: 3 minutes

Khi mình bắt đầu tập tành lập trình blockchain, việc verify signatures trong solidity khiến mình khá bối rối. Sau một thời gian tự mày mò, mình đã hiểu được cách hoạt động cũng như cách triển khai nó. Trong bài viết này, mình sẽ chia sẻ lại mọi thứ theo đúng hành trình học và “giác ngộ” của mình, để bạn nào mới tìm hiểu về cách verify signatures trong Solidity cũng có thể nắm bắt nhanh chóng!

verify signatures in solidity

Cách ký một message

Trước khi tìm hiểu cách verify signature Solidity, đầu tiên mình phải học cách ký (sign) một message.

Ở phía frontend (ví dụ như trên website), quá trình ký sẽ diễn ra như thế này:

javascript
CopyEdit
async function signMessage() {
    if (!window.ethereum) return alert("Please cài Metamask!");
// Kết nối tới ví
const accounts = await ethereum.request({ method: "eth_requestAccounts" });

// Message cần ký
const message = "hello";
console.log({ message });

// Hash message
const hashedMessage = Web3.utils.sha3(message);
console.log({ hashedMessage });

// Ký hashed message
const signature = await ethereum.request({
  method: "personal_sign",
  params: [hashedMessage, accounts[0]],
});
console.log({ signature });

// Tách signature ra thành r, s, v
const r = signature.slice(0, 66);
const s = "0x" + signature.slice(66, 130);
const v = parseInt(signature.slice(130, 132), 16);
console.log({ r, s, v });

}

💡 Một lưu ý nhỏ: Khi dùng personal_sign, Ethereum sẽ tự động thêm tiền tố “\\x19Ethereum Signed Message:\\n32” trước khi ký, để đảm bảo an toàn, tránh việc ai đó lừa bạn ký những giao dịch nguy hiểm.

Build Smart Contract để Verify

Sau khi đã có message đã được ký, việc tiếp theo là xây smart contract để verify signatures solidity.

Mình đã viết một contract mẫu đơn giản như sau:

solidity
CopyEdit
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Verify { function VerifyMessage(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) { bytes memory prefix = "\x19Ethereum Signed Message:\n32"; bytes32 prefixedHashMessage = keccak256(abi.encodePacked(prefix, _hashedMessage)); address signer = ecrecover(prefixedHashMessage, _v, _r, _s); return signer; } }

Một vài điểm quan trọng mình muốn nhấn mạnh:

  • Phải thêm prefix trước khi hash lại message.
  • Hàm ecrecover sẽ trả về địa chỉ Ethereum đã ký message đó.
  • Nếu address trả về đúng với người mà bạn mong đợi => signature hợp lệ.

Có thể bạn quan tâm: Quy trình 6 bước để tổ chức ICO token

Ứng dụng thực tế: Game Unity phát thưởng

Một ví dụ thực tế mà mình rất thích: sử dụng verify signature solidity trong game blockchain.

Giả sử bạn lập trình viên game:

  • Khi người chơi thắng, server game sẽ ký một message chứng nhận chiến thắng (giống như phát “phiếu thưởng”).
  • Người chơi gửi signature đó lên smart contract để claim phần thưởng.

Ví dụ contract:

solidity
CopyEdit
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Verify { address public owner = 0xdD4c825203f97984e7867F11eeCc813A036089D1; // Địa chỉ của server game

function claimPrize(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) public view returns (bool) {
    bytes memory prefix = "\\x19Ethereum Signed Message:\\n32";
    bytes32 prefixedHashMessage = keccak256(abi.encodePacked(prefix, _hashedMessage));
    address signer = ecrecover(prefixedHashMessage, _v, _r, _s);

    if (signer == owner) {
        return true; // Người chơi hợp lệ => thưởng
    }
    return false; // Không hợp lệ
}

}

Ở client side (ví dụ Unity), mình sẽ tách chữ ký ra như thế này:

csharp
CopyEdit
string signature = "0xb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c91c";
string r = signature.Substring(0, 66);
string s = "0x" + signature.Substring(66, 64);
int v = int.Parse(signature.Substring(130, 2), System.Globalization.NumberStyles.HexNumber);

Sau đó người chơi chỉ cần gửi _r, _s, _vhashedMessage vào contract để nhận thưởng.

Tổng kết

Việc verify signatures in Solidity thực ra không quá phức tạp, bạn chỉ cần lưu ý:

  • Hash message đúng chuẩn.
  • Thêm prefix "\\x19Ethereum Signed Message:\\n32" trước khi xác thực.
  • Dùng ecrecover để lấy địa chỉ người ký.

Nếu bạn đang muốn làm các dự án liên quan tới xác thực người dùng, phát coupon, kiểm tra quyền truy cập… thì việc phải master kỹ năng này là rất hữu ích đấy!

Bài viết liên quan:

Về tác giả

Đức Hacker
Đức HackerSenior Cybersecurity Expert

My passion is hunting down the latest attack trends—ransomware, APTs, you name it—while passing on knowledge to help businesses forge ironclad defenses. I’ve left my mark on data encryption projects and intrusion detection tools now widely used across Vietnam. I’m the shadow that strikes before the enemy does. @#@ Đam mê của tôi là nghiên cứu các xu hướng tấn công mới nhất như ransomware và APTs, đồng thời chia sẻ kiến thức để giúp doanh nghiệp xây dựng chiến lược phòng thủ hiệu quả. Tôi từng đóng góp vào các dự án mã hóa dữ liệu và phát triển công cụ phát hiện xâm nhập được sử dụng rộng rãi tại Việt Nam.

Cập nhật thông tin mới nhấtNhận các thông tin mới nhất về mối đe dọa, báo cáo an ninh mạng từ CyStack về hòm thư điện tử của bạn

Thảo luận (0)

Đăng nhập để thảo luận

Bài viết liên quan