Bạn đã bao giờ tự hỏi, tại sao một chiếc NFT được quảng cáo là "mint ngẫu nhiên 100%" lại có kết quả trùng hợp đến kỳ lạ? Có người mint 10 lần, cả 10 lần đều trúng cùng một cấp độ hiếm. Có người mint 1 lần, lại trúng ngay cái hiếm nhất.
Tôi từng audit một dự án GameFi nhỏ vào năm 2022. Team của họ khoe rằng họ có "hệ thống random cực kỳ an toàn". Khi tôi hỏi họ dùng thuật toán gì, họ trả lời: "Chúng tôi dùng Math.random() của JavaScript, rất an toàn vì chạy trên máy chủ".
Tôi ngồi im mất 5 giây.
Nếu bạn đã từng đọc qua một bài báo khoa học phổ thông về blockchain, chắc bạn biết rằng blockchain không thể chạy một hàm random thông thường. Nhưng điều tôi sắp kể cho bạn nghe hôm nay không chỉ là kiến thức cơ bản. Đó là một câu chuyện về cách mà cả một ngành công nghiệp, từ những dự án triệu đô đến những startup nhỏ lẻ, đang mắc cùng một sai lầm. Và sai lầm đó không nằm ở code, mà nằm ở cách họ hiểu về "ngẫu nhiên".
Hãy bắt đầu với một câu hỏi đơn giản: Trong một thế giới mà mọi thứ đều có thể được dự đoán, làm thế nào để tạo ra thứ không thể dự đoán?
Bối cảnh: Tại sao blockchain không có Math.random()?
Hãy tưởng tượng bạn đang chơi một trò chơi tung đồng xu. Nhưng thay vì tung đồng xu thật, bạn và tôi cùng nhìn vào một chiếc máy tính. Máy tính đó chạy một chương trình. Mỗi lần bạn bấm nút, nó sẽ hiện ra "Mặt ngửa" hoặc "Mặt sấp".
Bạn có tin rằng kết quả là ngẫu nhiên không?
Tất nhiên là không. Bởi vì bạn biết rằng máy tính chỉ đang chạy một thuật toán. Nếu biết chính xác thời điểm bạn bấm nút, tôi có thể dự đoán kết quả. Đó chính là bản chất của hàm pseudo-random (giả ngẫu nhiên) trong lập trình. Nó là một chuỗi số có vẻ ngẫu nhiên, nhưng thực chất là hoàn toàn xác định.
Bây giờ, hãy đặt chiếc máy tính đó lên một blockchain. Bạn biết gì về blockchain? Nó là một cỗ máy trạng thái xác định. Mọi node trên mạng lưới, khi chạy cùng một giao dịch với cùng một dữ liệu đầu vào, sẽ cho ra cùng một kết quả. Đó là tính chất cốt lõi để đảm bảo sự đồng thuận.
Vậy, nếu bạn gọi Math.random() trong một smart contract, điều gì sẽ xảy ra?
- Trường hợp 1: Hàm đó lấy entropy từ một nguồn không xác định. Mỗi node sẽ có một kết quả khác nhau. Mạng lưới sẽ không bao giờ đạt được đồng thuận. Giao dịch sẽ bị từ chối.
- Trường hợp 2: Hàm đó lấy entropy từ một nguồn xác định, ví dụ như
block.timestamp(thời gian của block). Kết quả sẽ giống nhau trên mọi node. Nhưng vấn đề là: người đào (miner) hoặc người xác thực (validator) của block đó có thể thao túng thời gian tạo block. Họ có thể chọn một timestamp có lợi cho họ, hoặc từ chối tạo block nếu timestamp đó cho ra kết quả không mong muốn. Đây là một lỗ hổng bảo mật kinh điển trong các ứng dụng đánh bạc trên blockchain.
Đó là lý do tại sao [thông tin 1] trong phân tích đã chỉ ra: Blockchain không thể sử dụng bộ tạo số ngẫu nhiên thông thường. Đây không phải là một giới hạn kỹ thuật, mà là một hệ quả tất yếu từ triết lý thiết kế của blockchain. Nó hy sinh tính ngẫu nhiên để đổi lấy tính xác định và đồng thuận.
Phần cốt lõi: Các giải pháp "có vẻ" ngẫu nhiên
Vậy làm thế nào để tạo ra một thứ "có vẻ" ngẫu nhiên trên một hệ thống "hoàn toàn" xác định? Các nhà mật mã học đã nghĩ ra một vài cách. Và [thông tin 2] cho biết: Ethereum và các mạng lưới khác dựa vào các phương pháp mật mã để tạo ra tính ngẫu nhiên có thể xác minh.
Tôi sẽ không đi sâu vào từng thuật toán, nhưng tôi muốn kể cho bạn nghe về một cuộc gặp gỡ thú vị.
Năm 2020, tôi có cơ hội nói chuyện với một trong những người đóng góp chính cho RANDAO – một giao thức tạo số ngẫu nhiên trên Ethereum. Tôi hỏi anh ấy: "Điều gì khiến RANDAO khác biệt so với việc dùng blockhash?"
Anh ấy cười và nói: "Blockhash là một bức ảnh chụp nhanh. Nó đã có sẵn. RANDAO là một quá trình. Nó là một giao thức mà nhiều người chơi cùng nhau đóng góp entropy, và không ai có thể biết trước kết quả cho đến khi vòng cuối cùng kết thúc."
Điều đó có nghĩa là gì?
Hãy tưởng tượng 100 người cùng viết một con số bí mật vào một tờ giấy, rồi bỏ vào một cái hộp. Sau đó, tất cả cùng mở tờ giấy ra. Con số cuối cùng là tổng của tất cả các con số đó. Một người duy nhất không thể thao túng kết quả, vì anh ta không biết những người khác đã viết gì. Nhưng nếu có 51 người thông đồng với nhau, họ có thể kiểm soát kết quả.
Đó là điểm yếu của RANDAO. Nó an toàn trong điều kiện lý tưởng, nhưng không hoàn hảo trong thế giới thực, nơi có những kẻ tấn công có tổ chức.

Còn một giải pháp khác, được gọi là VRF (Verifiable Random Function – Hàm ngẫu nhiên có thể xác minh). Đây là một công cụ mạnh mẽ hơn. Nó cho phép một người dùng (hoặc một oracle) tạo ra một số ngẫu nhiên, và kèm theo một "bằng chứng" (proof) để bất kỳ ai cũng có thể xác minh rằng số đó thực sự được tạo ra từ một quy trình mật mã, chứ không phải do ai đó tự bịa ra. Chainlink VRF là một ví dụ điển hình.
Theo kinh nghiệm audit của tôi, VRF là giải pháp an toàn hơn cho các ứng dụng yêu cầu tính công bằng cao, như xổ số hoặc game có thưởng. Nhưng nó cũng có một nhược điểm: nó phụ thuộc vào một oracle tập trung hoặc bán tập trung. Nếu oracle đó bị tấn công hoặc thao túng, tính ngẫu nhiên cũng sẽ bị ảnh hưởng.
Tôi từng thấy một dự án NFT sử dụng Chainlink VRF, nhưng họ lại lưu trữ seed của VRF trên một máy chủ web2. Khi máy chủ đó bị hack, kẻ tấn công có thể dự đoán được tất cả các kết quả NFT trong tương lai. Đây là một ví dụ điển hình về việc "công nghệ đúng" nhưng "kiến trúc sai".
Góc nhìn phản trực giác: Khi sự "ngẫu nhiên" trở thành gánh nặng
Bây giờ, tôi muốn bạn hãy nghĩ khác đi một chút. Điều gì sẽ xảy ra nếu chúng ta không cần sự ngẫu nhiên?
Nghe có vẻ điên rồ, nhưng hãy suy ngẫm. Hầu hết các ứng dụng blockchain đều đang cố gắng "mô phỏng" sự ngẫu nhiên để tạo ra sự khan hiếm hoặc sự bất ngờ. Một NFT hiếm, một phần thưởng bất ngờ, một người chiến thắng may mắn. Nhưng liệu sự ngẫu nhiên có thực sự cần thiết cho giá trị của ứng dụng?

Tôi từng chứng kiến một dự án game "phi tập trung" nhưng họ lại dùng một hệ thống trung tâm để quyết định việc rơi vật phẩm. Họ nói: "Chúng tôi không thể tin tưởng vào bất kỳ giải pháp on-chain nào vì chúng quá chậm và đắt." Kết quả là, người chơi không bao giờ tin tưởng vào sự công bằng của trò chơi. Dự án đó đã chết sau 3 tháng.
Đây là góc nhìn phản trực giác của tôi: Sự theo đuổi "ngẫu nhiên" tuyệt đối on-chain đang khiến các dự án trở nên phức tạp và kém hiệu quả. Thay vào đó, họ nên tập trung vào việc thiết kế một hệ thống mà "kết quả" có thể được dự đoán một phần, nhưng không thể bị thao túng bởi một thực thể duy nhất.
Ví dụ, thay vì một hệ thống xổ số ngẫu nhiên, hãy thiết kế một hệ thống đấu giá. Thay vì một vật phẩm hiếm ngẫu nhiên, hãy thiết kế một hệ thống mà người chơi có thể chọn vật phẩm hiếm nhưng phải trả một cái giá (ví dụ: thời gian, công sức, token).
Hay nói cách khác: hãy chấp nhận rằng blockchain không phải là một công cụ tạo ra sự ngẫu nhiên, mà là một công cụ tạo ra sự minh bạch và có thể kiểm chứng. Sự ngẫu nhiên chỉ là một phần nhỏ của bức tranh lớn hơn.
Takeaway: Tương lai của tính ngẫu nhiên
Tôi tin rằng, trong tương lai, các giao thức sẽ không còn phải "vật lộn" với việc tạo ra số ngẫu nhiên nữa. Các Layer 1 và Layer 2 sẽ tích hợp sẵn các giải pháp VRF hoặc RANDAO mạnh mẽ và rẻ hơn. Điều này sẽ giống như việc các trình duyệt web hiện đại có sẵn một API crypto.getRandomValues() thay vì Math.random(). Nó sẽ trở thành một tính năng cơ bản của hạ tầng.
Nhưng trước khi điều đó xảy ra, câu hỏi dành cho bạn, những người đang xây dựng trên blockchain, là: Bạn có hiểu rõ ràng về "sự ngẫu nhiên" mà bạn đang sử dụng không? Hay bạn chỉ đang copy-paste một đoạn code từ một bài báo, và hy vọng nó sẽ hoạt động?
Hãy nhớ, trong thế giới blockchain, không có gì là thực sự ngẫu nhiên. Chỉ có những thứ mà chúng ta chưa thể dự đoán. Và ranh giới giữa "ngẫu nhiên" và "có thể thao túng" là ranh giới giữa sự tin tưởng và sự sụp đổ.