Skip to content

Karma và trọng số

Đây là trang giải thích thứ dễ gây bối rối nhất: vì sao một bài có 14 phiếu mà karma lại âm tới −602.

Một câu

Số phiếu thô đếm số người. Karma cộng trọng số của từng người. Trọng số của một người phụ thuộc vào karma của chính người đó.

Hai con số khác nhau ở hai chỗ

Trên giao diện, hai con số này xuất hiện cạnh nhau và không cùng đơn vị:

Chỗ hiển thịCon sốNghĩa
Cạnh nút vote trên cardhiệu thô likeCount − dislikeCountBao nhiêu người hơn nhau
Cạnh tên tác giảauthorKarmaTổng có trọng số trên toàn bộ tài khoản
Ô Karma ở trang cá nhânkarmaOf đọc thẳng từ chainCùng con số authorKarma

Vì vậy "14 downvote" (thô) và "−602 karma" (có trọng số) có thể cùng mô tả một chuyện, chỉ khác đơn vị.

Đơn vị: 100 điểm = một phiếu trọn vẹn

Solidity không có số thập phân, nhưng hệ thống cần nói được cả "0,05 phiếu" lẫn "1,25 phiếu". Nên chọn một đơn vị nhỏ:

100 điểm karma = 1 phiếu trọn vẹn. Giống 1 đồng = 100 xu.

weight là số "xu" một phiếu đáng. karma là tổng số "xu" một tài khoản đã nhận được. Mọi thuật toán xếp hạng chia weightedLikes / 100 trước khi áp công thức Reddit, vì công thức của Reddit tính bằng số phiếu nguyên.

Trọng số đến từ đâu

Trọng số của một người suy trực tiếp từ karma của chính người đó, theo bậc:

KarmaTrọng sốNghĩa
< 00Bị tắt tiếng — phiếu không còn giá trị
01Ví mới: 0,01 phiếu
1 … 950,05 phiếu
10 … 49250,25 phiếu
50 … 199100Tròn một phiếu
200 … 9991251,25 phiếu
1000 … 49991501,5 phiếu
≥ 5000200Trần: 2 phiếu

Cùng một bảng này, trong hợp đồng:

solidity
function weightOf(address account) public view returns (uint32) {
    int256 k = karmaOf[account];
    if (k >= 5000) return 200;
    if (k >= 1000) return 150;
    if (k >= 200)  return 125;
    if (k >= 50)   return 100;
    if (k >= 10)   return 25;
    if (k >= 1)    return 5;
    if (k >= 0)    return 1;
    return 0;
}

Ví dụ 1 — một tài khoản leo bậc

  1. Ví mới A có karmaOf(A) = 0weightOf(A) = 1. Phiếu của A đáng 0,01.
  2. B (cũng mới, trọng số 1) like bài của A. Vì B ≠ A nên hợp lệ.
    • karmaOf(A) : 0 → 1
    • weightOf(A) : 1 → 5 (vì 1 karma rơi vào bậc 1…9)
  3. A được 50 tài khoản khác nhau upvote → karmaOf(A) = 50weightOf(A) = 100. Từ giờ một like của A đáng trọn một phiếu.
  4. A lên 5000 karma → weightOf(A) = 200 (trần 2 phiếu).
  5. A bị downvote về âm → weightOf(A) = 0. Phiếu của A không còn giá trị cho tới khi được upvote trở lại trên 0.

Ví dụ 2 — vì sao 14 người mà −602

Lấy dữ liệu demo thật. Một tài khoản có hai bài bị dislike nhiều:

BàiLike thôDislike thôNet thôweightedLikesweightedDislikesNet có trọng số
1819−85466−461
1617−61142−141
Tổng216−146608−602

Đọc bảng:

  • Card hiện −8−6 — đó là số người hơn nhau. Tổng thô là −14.
  • Nhưng 9 người dislike bài 18 không phải ai cũng "đáng 1". Họ đã có karma, nên 466 điểm chia cho 9 phiếu ≈ 52 điểm/người. Bài 16: 142 / 7 ≈ 20 điểm/người.
  • Hai cái like duy nhất chỉ đáng 51, vì người like có karma rất thấp.
  • Karma là tổng toàn tài khoản, không phải của riêng một bài: 6 − 608 = −602.

Nên: 14−602 không mâu thuẫn. Một cái đếm người, một cái cộng uy tín.

Đừng so net thô với karma

Nếu muốn một con số khớp với karma, hãy cộng weightedLikes − weightedDislikes. Hiệu thô chỉ là số đầu người.

Vì sao karma âm bị tắt tiếng

Trước đây bậc sàn là 1: ai bị downvote nặng vẫn giữ một tiếng nói nhỏ. Hiện tại karma âm trả về 0. Lý do:

  • Một tài khoản bị cả phòng downvote không nên còn có thể tự "cứu" mình bằng cách đi vote người khác.
  • không bị khoá vĩnh viễn: người khác vẫn upvote được, và khi karma lên lại trên 0 thì trọng số hồi về ngay.
  • Karma đúng bằng 0 vẫn được trọng số 1, nên một ví hoàn toàn mới không bị câm.

Vì sao thiết kế này chống clone

Nếu ví mới đáng 1 phiếu nguyên thì 2 ví clone = 1 người thường. Ở đây ví mới đáng 0,01 phiếu:

  • Một ring cần ~100 ví mới bằng một phiếu thường.
  • Muốn một thành viên đạt trọng số 100, ring phải upvote chéo cho nó tới 50 karma — tức thêm ~50 ví nữa chỉ để nâng một người.

Không khoá tuyệt đối, nhưng nâng cái giá lên hai bậc độ lớn. Đổi lại, hệ thống giữ được tính fair: ai cũng vote được ngay từ ngày đầu.

Đọc thẳng trên chain

Karma và trọng số không cần tin indexer. Kiểm tra bằng cast:

bash
POST_REGISTRY=0xaC74A6AF7Ec96e28F2885916673EF3B9aACF10F5

cast call $POST_REGISTRY "karmaOf(address)(int256)" 0xYourAddress \
  --rpc-url https://testnet-rpc.monad.xyz

cast call $POST_REGISTRY "weightOf(address)(uint32)" 0xYourAddress \
  --rpc-url https://testnet-rpc.monad.xyz

Tài liệu cho Monad testnet. Nội dung mô tả đúng những gì đang chạy.