Một blockchain có thể viết lại luật của chính nó. Với Bittensor, việc đó xảy ra 23 lần trong 61 ngày gần nhất, và cả 23 lần đều đi qua đúng một cánh cửa: một ví chung cần hai trong ba chữ ký. Không lần nào đi qua một cuộc bỏ phiếu — và ở block đọc hôm nay, chain không còn phần mã nào để tổ chức một cuộc bỏ phiếu như vậy.
Câu đáng hỏi trước tiên không phải "ai ký", mà là "đổi luật" ở đây to tới đâu.
Luật của chain nằm trong một file, và có một lệnh để thay file đó
Bittensor dựng trên Substrate. Ở đó luật của chain không nằm rải rác trong nhiều hợp đồng như trên Ethereum — nó nằm gọn trong một file chương trình, được cất trong chính bộ nhớ của chain. Phát hành bao nhiêu TAO mỗi block, chia cho ai, ai được làm gì: tất cả ở trong file đó.
Thay file ấy là thay luật. Lệnh thay tên là set_code, và lần thay gần nhất mang theo 2.541.439 byte mã mới.
Nên câu hỏi "ai duyệt một lần set_code" không phải câu hỏi kỹ thuật. Nó là câu hỏi ai viết lại được quy tắc của thứ bạn đang giữ.
Phần mã để bỏ phiếu không còn trong runtime
Bản chương trình đang chạy tự khai danh sách các phần cấu thành nó — Substrate gọi mỗi phần là một pallet. Đây không phải tài liệu: nó là thứ chính chain trả về khi được hỏi, và hỏi được tại từng block trong quá khứ.
Điểm mấu chốt nằm ở chỗ mỗi pallet có một số thứ tự, và số đó không bao giờ được cấp lại cho pallet khác. Gỡ một pallet đi thì số của nó để trống vĩnh viễn. Chỗ trống là thứ đọc được — đó là lý do câu chuyện này đo được thay vì phải tin.
So ba lượt đọc. Tại block 5.020.351, runtime khai ba pallet mang tên bộ máy biểu quyết: Triumvirate ở số 8, TriumvirateMembers ở số 9, SenateMembers ở số 10. Tại block 8.667.736, cả ba không còn, và dãy số thủng đúng ba chỗ đó. Tại block 9.107.775 — lượt đọc hôm nay — vẫn thủng đúng ba chỗ ấy.
Mốc gỡ đọc được tới từng block: file chương trình mới được ghi ở block 6.811.690, tức 05/11/2025 giờ VN, và nó có hiệu lực ngay block kế tiếp. Độ lệch một block này là cố ý, không phải sai số: lệnh chạy trong block trước, bản mới bắt đầu có hiệu lực ở block sau — nên mỗi lần thay luật luôn có hai số block đi cùng nhau.
Còn một khả năng phải loại trừ: có thể bộ máy biểu quyết chỉ đổi tên. Tại block 8.667.736, quét cả danh sách pallet, 288 call và 227 ô dữ liệu của pallet chính SubtensorModule cho các chữ vote · referendum · senate · triumvirate · council · collective · democracy ra 0 khớp.
Một phép quét trả về 0 có thể vì không có gì, cũng có thể vì nó hỏng. Nên cùng lượt chạy đó phải tìm thấy những thứ chắc chắn có mặt — và nó tìm thấy: 89 call thuộc họ sudo, 7 call họ schedule, 10 call họ force, cùng các pallet Sudo, Multisig, Scheduler, Proxy. Công cụ nhìn thấy pallet bình thường. Nó chỉ không thấy pallet bỏ phiếu.
Một bẫy phải nói trước, vì ai tự chạy phép quét này ở lượt đọc hôm nay sẽ gặp: có đúng một cái tên khớp chữ collective — RandomnessCollectiveFlip. Đó là pallet sinh số ngẫu nhiên, không phải hội đồng biểu quyết; nó khớp vì trùng chuỗi con, cùng kiểu với chữ tip nằm trong multiplier. Khớp theo tên là để khoanh vùng, kết luận thì phải mở pallet ra xem.
23 lần thay luật, 23 lần cùng một cánh cửa
Phần trên mới nói chain không có chỗ bỏ phiếu. Nó chưa nói cái gì đang được dùng thay vào đó. Phần này đọc từng lần một.
Mọi lần thay luật trong cửa sổ được tìm bằng cách chia đôi liên tục trên ô ghi "runtime hiện tại là bản nào" — 300 lượt đọc thay cho việc quét 440.039 block. Mỗi lần tìm ra, lệnh ở block đó được dịch lại bằng từ điển của chính bản runtime đã thi hành nó, không phải bằng bản hôm nay; hai bản khác nhau thì cùng một chuỗi byte dịch ra hai thứ khác nhau.
Từ block 8.667.736 tới block 9.107.775, kết quả là 23 lần, và chúng rơi vào đúng hai hình dạng:
| đường đi của lệnh, đọc từ chain | số lần |
|---|---|
ví chung 2-of-3 → ví chung 2-of-2 → uỷ quyền → quyền sudo → set_code | 19 |
ví chung 2-of-3 → quyền sudo → set_code | 4 |
| qua một cuộc bỏ phiếu on-chain | 0 |
Hai dòng đầu khác nhau ở lối đi, không khác nhau ở quyền dùng. Lớp ngoài cùng — ví chung 2-of-3 — là một ở cả 23 lần; đó là ví giữ quyền sudo. Ở 19 lần dòng trên, ví ấy không tự bấm nút cuối: nó ký vào một ví chung thứ hai, gồm chính nó cộng một khoá tự động của quy trình phát hành, và ví thứ hai đó mới gọi lệnh thay mặt nó. Ở 4 lần dòng dưới, ví 2-of-3 gọi thẳng, không qua lớp nào. Cả 23 lần đều kết thúc ở cùng một chỗ, và cửa vào cũng là một.
Còn "hai trong ba chữ ký" thì không phải chuyện suy ra. Trên Substrate, địa chỉ của một ví chung được tính ra từ danh sách người ký cộng với ngưỡng — cùng danh sách, cùng ngưỡng thì luôn ra cùng một địa chỉ, và đổi một người ký thì ra địa chỉ khác hẳn. Bản thân lệnh mang sẵn ngưỡng và danh sách người ký còn lại, nên tính ngược ra địa chỉ rồi so với ví đang giữ quyền sudo tại chính block đó là một phép so có thể sai. Phép so này chạy trên lớp ngoài cùng của từng lần — lớp 2-of-3 — nên nó trả lời đúng câu đang hỏi: ai mở cửa. Nó khớp 23/23. Và phép thử ngược — bỏ một người ký ra khỏi danh sách — cho ra địa chỉ khác ở cả 23 lần, nên phép so này phân biệt được chứ không phải lúc nào cũng gật.
Lần gần nhất là tối thứ Sáu vừa rồi
Lần thay luật cuối cùng trong cửa sổ đưa chain lên bản 467, thi hành ở block 9.095.776 lúc 23h38 ngày 18/09/2026 giờ VN — hai ngày trước lượt đọc này. Cùng cánh cửa.
Ở đầu kia của cửa sổ, lần thay luật đầu tiên rơi vào block 8.679.056, rạng sáng 23/07 giờ VN — tức hai đầu dải cách nhau gần hai tháng, và suốt quãng đó cánh cửa không đổi.
Điều đáng chú ý là thứ không đổi. So danh sách pallet ở hai đầu cửa sổ: thêm 0, bớt 0 — vẫn 28 pallet, ba pallet biểu quyết không quay lại, không pallet nào mới thế chỗ. Ví giữ quyền sudo tại block 9.107.775 vẫn đúng địa chỉ đã dùng cho các lần thay luật trong cửa sổ, và quyền đó chưa được gỡ.
Nói cách khác: qua 23 lần viết lại luật, phần luật nói ai được viết lại luật là phần đứng yên.
Điều này đổi cách đọc gì
Khi một dự án được mô tả là "có governance", người mua token thường đọc câu đó thành tôi giữ một phần quyền quyết định. Với Bittensor, câu đó kiểm được — và trong 61 ngày đã đo, không lần thay luật nào đi qua một lá phiếu on-chain. Ở cả hai lượt đọc, đầu và cuối cửa sổ, chain cũng không khai phần mã nào để tổ chức một lá phiếu như vậy.
Chỗ này quan trọng với người định giá TAO, vì những thứ quyết định giá trị của một token mạng — phát hành mỗi block, cách chia phần thưởng — là tham số nằm trong chính file đã bị thay 23 lần trong 61 ngày. Điều đó không phải suy đoán: cùng bản runtime ấy khai một pallet tên AdminUtils với 82 call, gần như toàn bộ mang tiền tố sudo_set_, tức những nút để đặt lại tham số. Rủi ro cần định giá không phải "phiếu của tôi nhỏ so với cá voi", mà là: 23 lần thay luật đã đo đều đi qua một ngưỡng hai chữ ký, và không lần nào đi qua một lá phiếu.
Cái này cắt cả hai chiều, và nên nói thẳng chiều còn lại: một chain đổi luật được nhanh cũng là một chain vá lỗi được nhanh. Tối 14/09 có ba lần thay luật liên tiếp trong chưa tới hai giờ, hình dạng quen thuộc của một chuỗi vá gấp — nhưng hồ sơ không đo được mục đích của từng lần, chỉ đo đường đi. Sudo giữ lại trong giai đoạn đầu cũng là lựa chọn phổ biến, không phải dấu hiệu xấu tự động.
Điều bài này không nói
Bài không nói rằng chỉ cánh cửa ấy mới thay được luật. Nó đọc đường đã dùng trong 61 ngày, không đọc toàn bộ tập đường được phép: trong 28 pallet của runtime có 23 pallet khai lệnh gọi; hồ sơ mới đọc quyền gọi của 2 pallet do chính dự án viết, còn 21 pallet kia — những pallet dùng chung của Substrate — thì chưa. Đó là giới hạn thật, và nó nằm đúng chỗ người đọc muốn kết luận mạnh nhất.
Bài cũng không nói một người kiểm soát Bittensor. Ngưỡng đọc được là hai trên ba. Và đây là thiết kế được công bố: tài liệu phát hành của chính dự án gọi thẳng khoá đó là sudo multisig, rồi mô tả cả quy trình hai chữ ký dùng để đưa một bản runtime mới lên chain.
Ba địa chỉ người ký thì không được đặt tên ở đây. Chain cho biết bao nhiêu, không cho biết ai, và không có nguồn công khai nào được kiểm để nối địa chỉ với một pháp nhân. Địa chỉ giữ quyền sudo cũng không phải vật cố định — trước đây nó từng là một địa chỉ khác với một bộ ba người ký khác — nên bài nói về nó theo từng block đã đọc, không nói như một vật cố định.
Cuối cùng, 23 lần là đầy đủ trong cửa sổ 61 ngày này, không phải toàn bộ lịch sử chain. Cộng những lần đã đọc trước đó, hồ sơ mới đọc 27 lần; khoảng giữa vẫn còn trống và bài không nói gì về nó.
Phần kiểm chứng — cách tự kiểm
Mọi lệnh dưới chạy với một node archive của Bittensor, không cần khoá riêng, không đổi gì.
Phần trên gọi mọi thứ bằng tiếng Việt, phần này gọi bằng tên máy — đây là bảng nối hai bên: file chương trình là :code: · ô ghi runtime hiện tại là bản nào là System.LastRuntimeUpgrade · ví chung là Multisig.as_multi · ví giữ quyền sudo là Sudo.Key · tính địa chỉ ví chung từ danh sách người ký là multi_account_id · danh sách pallet là kết quả của state_getMetadata.
Danh sách pallet. Gọi state_getMetadata tại block 9.107.775 và tại block 5.020.351, rồi lấy danh sách pallet. Bản cũ phải có Triumvirate, TriumvirateMembers, SenateMembers ở số 8, 9, 10; bản mới phải thiếu đúng ba cái đó và dãy số phải thủng đúng ba vị trí ấy. Nếu bản mới vẫn còn một trong ba, hoặc dãy số liền mạch, thì phần đầu bài sai.
Mốc gỡ. Đọc metadata tại block 6.811.690 và block 6.811.689: hai bản phải khác sha256 nhau. Ô System.LastRuntimeUpgrade phải đổi từ bản 326 sang bản 334 ở block 6.811.691 — tức một block SAU khi file mới được ghi. Độ lệch một block này là cố ý, không phải sai số: lệnh chạy trong block trước, bản mới có hiệu lực ở block sau.
Đường đi của một lần thay luật. Lấy lần gần nhất: LastRuntimeUpgrade tại block 9.095.777 phải là 467, tại block 9.095.775 phải nhỏ hơn. Lấy block 9.095.776 bằng chain_getBlock, rồi giải mã các lệnh trong đó bằng metadata tại block 9.095.775. Phải có đúng một lệnh mang set_code, và bóc lớp của nó phải gặp Multisig.as_multi với ngưỡng bằng 2 trước khi tới set_code.
Danh sách người ký. Từ lệnh as_multi lấy ngưỡng cùng danh sách người ký còn lại, cộng người đã ký giao dịch, rồi tính multi_account_id và so với ô Sudo.Key đọc tại chính block đó — phải khớp. Bỏ một người ký khỏi danh sách rồi tính lại: phải ra địa chỉ khác. Nếu vẫn ra địa chỉ cũ thì phép tính này không phân biệt được gì, và mọi kết luận về ngưỡng phải rút.
Phép thử đắt nhất, chạy trước khi tin dải 23 lần. Chạy đúng quy trình trên cho lần thay luật lên bản 432 — lần đã được đo trước đây bằng một công cụ khác. Nó phải ra đúng block thi hành 8.636.190, đúng chuỗi lớp, và đúng sha256 của file chương trình, bắt đầu bằng 63854f0a. Không tái lập được lần cũ thì mọi con số của 23 lần mới là rác, bất kể chúng trông hợp lý tới đâu.
Điều bác bỏ. Kết luận của bài sai nếu, tại các block đã nêu: metadata ở lượt đọc hôm nay khai một pallet chở việc biểu quyết; hoặc một trong 23 lần có set_code khởi phát từ một quyền không phải Sudo; hoặc ô Sudo.Key tại block 9.107.775 trả về rỗng, tức quyền đã được gỡ; hoặc danh sách người ký tính ra không khớp Sudo.Key ở dù chỉ một lần. Bất kỳ điều nào đúng thì câu tương ứng ở trên phải rút.
Không phải lời khuyên đầu tư.