Khi hệ thống “InferenceChain” vừa huy động 150 triệu USD từ BlackRock và người dùng lao vào farm token, phản ứng đầu tiên của tôi không phải là kiểm tra APY. Không phải quan sát TVL. Tôi lặng lẽ fork repo của họ.
Bạn thấy đấy, với tư cách là một DeFi Security Auditor 42 tuổi ở Stockholm, tôi có một thói quen kỳ lạ: trước khi bất kỳ ai có thể khoe về tính năng “AI xác thực dữ liệu on-chain”, tôi muốn xem thử code của cái “xác thực” đó có thực sự xác thực được thứ gì không.
Và tôi đã tìm thấy nó. Một lỗi trong hàm tạo số ngẫu nhiên (randomness) dành cho kết quả đầu ra của AI. Nó không phải là một lỗi phức tạp. Nó cổ điển đến mức nhàm chán. Một hàm vrf dựa trên block.timestamp. Kẻ tấn công biết trước kết quả của oracle AI trong một block, và có thể front-run giao dịch xác nhận dữ liệu.
Bài viết này không phải để chỉ trích InferenceChain. “An toàn” không phải là trạng thái có thể mua được bằng tiền. Nó là một lựa chọn thiết kế. Và bài viết này sẽ mổ xẻ lý do tại sao việc ghép “AI” và “Blockchain” lại tạo ra một lớp lỗ hổng mới mà 99% dự án đang cố tình hoặc vô tình bỏ qua.
Context: Ảo tưởng “Decentralized Oracle”
Cốt lõi của “InferenceChain” và các dự án tương tự là một mạng lưới oracle phi tập trung dùng AI để xác thực dữ liệu off-chain. Nghe có vẻ thông minh. “AI + Crypto” là từ khóa hot nhất 2025. Nhưng hãy nhìn vào kiến trúc kỹ thuật:
- Mô hình AI (Off-chain): Huấn luyện trên một tập dữ liệu lớn, đưa ra xác suất cho một sự kiện.
- Mạng lưới Oracle (On-chain): Các node chạy mô hình AI, gửi kết quả lên hợp đồng thông minh.
- Hợp đồng tổng hợp (Aggregation Contract): Nhận đầu ra từ các node, tổng hợp để đưa ra quyết định cuối cùng.
Vấn đề nằm ở điểm 3. Khi một mô hình AI đưa ra kết quả “không xác định” (uncertainty cao), hợp đồng thông minh cần một cơ chế dự phòng. Và cơ chế dự phòng đó thường là... một hàm random “an toàn”.
Core: Vết nứt trong “Hộp đen” AI
Tôi đã đọc mã nguồn của InferenceChainAggregator.sol. Logic chính như sau:
function processInference(bytes32 requestId, uint256[] memory scores) external onlyOracle {
// ... some checks ...
uint256 highestScoreIndex = getHighestScoreIndex(scores);
if (scores[highestScoreIndex] > certainThreshold) {
// AI is certain, execute the action
executeAction(requestId, highestScoreIndex);
} else {
// AI is uncertain, fallback to random selection
uint256 randomIndex = _getRandomIndex();
executeAction(requestId, randomIndex);
}
}
Nhìn _getRandomIndex của họ:
function _getRandomIndex() internal view returns (uint256) {
return uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % NUMBER_OF_OUTCOMES;
}
}
Bạn có thấy lỗi không? Một auditor mới vào nghề cũng biết block.timestamp và block.prevrandao (hoặc block.difficulty cũ) là các giá trị có thể bị thao túng ở một mức độ nhất định bởi miner/validator. Nhưng đây không chỉ là vấn đề “có thể thao túng”.
Đây là vấn đề tính tiên tri (predictability). Trong một mạng lưới mà node oracle gửi giao dịch có thể nhìn thấy trong mempool, một kẻ tấn công có thể:
- Xác định block mà giao dịch của một node oracle cụ thể sẽ được đưa vào.
- Tính toán
block.timestampcho block đó (dễ dàng dự đoán hoặc chờ đợi). - Tính toán
block.prevrandao(cũng có thể đoán được từ block trước đó trong một số tình huống). - Tính trước
randomIndex.
Khi đó, một kết quả “không xác định” từ AI trở thành một kết quả “do kẻ tấn công chọn”. Họ có thể chọn index có lợi nhất cho mình.
Tôi đã sửa lỗi này bằng cách kết hợp block.timestamp với một nonce từ oracle và một hàm VRF (Verifiable Random Function) thực thụ. Nhưng điểm mấu chốt không phải là một dòng code sai.
Điểm mấu chốt là: Người thiết kế tin rằng “AI có thể thay thế cơ chế đồng thuận”. Và khi AI thất bại, họ lại dùng một cơ chế ngẫu nhiên giả để thay thế. Đây là một tư duy thiết kế thiếu nhất quán, và trong bảo mật, sự thiếu nhất quán luôn dẫn đến lỗ hổng.
Contrarian: Điểm mù của “Kỹ thuật dịch chuyển niềm tin”
Đa số mọi người cho rằng rủi ro của AI + Blockchain nằm ở mô hình AI bị tấn công dữ liệu (adversarial attack). Họ phân tích thuật toán, xem xét dữ liệu huấn luyện, kiểm tra độ chính xác...
Tôi cho rằng điều ngược lại mới là rủi ro thực sự: Rủi ro không đến từ AI, mà đến từ chính lớp “blockchain” bao bọc nó. Vấn đề là sự dịch chuyển niềm tin: người dùng tin tưởng vào tính “phi tập trung” và “không thể gian lận” của blockchain, vì vậy họ mặc nhiên tin tưởng vào bất kỳ thứ gì được đặt trên nó, bao gồm cả một mô hình AI không hoàn hảo.
Khi một oracle AI đưa ra kết quả, nó được ghi vào block. Nó trở thành “sự thật on-chain”. Nhưng “sự thật on-chain” không đồng nghĩa với “sự thật ngoài đời thực”. Nó chỉ là kết quả của một phép tính. Và nếu phép tính đó bị lỗi (do code yếu), thì “sự thật on-chain” đó là một lời nói dối được lưu trữ vĩnh viễn.
Chúng ta đang tạo ra một hệ thống mà một lỗi logic đơn giản trong code Solidity có thể khuếch đại sức ảnh hưởng của một mô hình AI thiếu chính xác, và làm cho hàng triệu USD bị mất dưới cái vỏ bọc “code is law”.
Takeaway: “an toàn” là một chuỗi, không phải một nút
Trong báo cáo audit dài 50 trang của tôi cho InferenceChain, tôi không chỉ đơn thuần chỉ ra lỗi _getRandomIndex. Tôi thiết kế một framework “kiểm chứng ba lớp” cho các hệ thống lai AI-Blockchain:
- Lớp Code (Solidity): Kiểm tra các lỗ hổng kinh điển (re-entrancy, oracle manipulation, randomness).
- Lớp Mô hình (AI): Kiểm tra độ chính xác và khả năng chống lại các cuộc tấn công đối nghịch.
- Lớp Logic Ngoại vi (Peripheral): Kiểm tra cách mà Lớp 1 và Lớp 2 tương tác với nhau. Chính xác là nơi tôi tìm ra lỗi.
Khi thị trường tăng và ai cũng FOMO, hãy nhìn vào nơi mà các lớp này giao nhau. Đó là nơi mà những kẻ tấn công sẽ chờ đợi. Và nếu bạn không thể tái tạo được “sự an toàn” đó trên một testnet, thì đó chỉ là một lời hứa được viết trên blog.
Bạn có dám fork code của “dự án AI thế hệ tiếp theo” trước khi nhấn “mint” không?
