Hợp đồng: hoạt động thế nào và vì sao
Toàn bộ tài sản và toàn bộ luật của FAIRDRUM nằm trong một chương trình trên mạng Solana — hợp đồng thông minh. Trang web chỉ gửi lệnh cho nó và hiển thị câu trả lời. Bên dưới: hợp đồng lưu những gì, hiểu những lệnh nào, kết quả được tính từ số ngẫu nhiên ra sao, và quản trị viên làm được gì, không làm được gì.
Hợp đồng là gì và nằm ở đâu
Hợp đồng thông minh là chương trình do các nút của mạng Solana thực thi, không chạy trên máy chủ của dự án. Mã của nó giống nhau với mọi người, và mỗi thao tác là một giao dịch công khai. Hợp đồng FAIRDRUM được viết bằng Rust với thư viện Anchor; mã nguồn của nó là mã mở.
Địa chỉ chương trình sẽ xuất hiện ở đây khi trang web được kết nối với hợp đồng.
Hệ quả quan trọng: nếu trang fairdrum.to biến mất, tài sản của người chơi vẫn nằm trong hợp đồng và có thể rút bằng bất kỳ chương trình nào gửi được lệnh rút kèm chữ ký ví của bạn.
Hợp đồng lưu những gì
- Két. Một tài khoản chứa wrapped SOL mà chỉ chính chương trình có quyền sử dụng. Mọi thứ nằm trong đó: số dư của người chơi, quỹ thưởng, các jackpot, quỹ dự trữ và phần của quản trị viên chưa được nhận.
- Tài khoản chung của trò chơi. Bản ghi về cách chia số tiền trong két: quỹ thưởng, jackpot, mini jackpot, siêu jackpot, quỹ dự trữ cho số tiền khởi điểm, phần của quản trị viên, số tiền khởi điểm của các jackpot, bộ đếm số vòng theo từng trò.
- Tài khoản người chơi. Được tạo bằng lệnh register mà trang web gửi cùng lần nạp đầu tiên, và gắn với địa chỉ ví: số dư trong game, thời điểm nạp gần nhất, vòng chưa hoàn tất, phần jackpot chưa được trả.
- Tài khoản phiên (nếu bật “chơi không cần chữ ký”): khóa tạm thời, thời hạn và hạn mức cược.
Sổ sách được xây dựng sao cho tổng mọi số dư và các hũ bằng đúng số tiền trong két. Một bài kiểm thử kiểm tra đẳng thức này sau mỗi thao tác trong hàng chục nghìn thao tác ngẫu nhiên.
Hợp đồng hiểu những lệnh nào
| Lệnh | Ai có thể gọi | Lệnh làm gì |
|---|---|---|
register | người chơi | Tạo tài khoản người chơi. Trang web gửi lệnh này cùng lần nạp đầu tiên. |
deposit | người chơi | Nạp vào số dư trong game. Ghi lại thời điểm: từ đó tính 12 giờ cho đến khi được rút. |
withdraw | người chơi | Rút về ví của chính mình. Bị từ chối khi chưa đủ 12 giờ kể từ lần nạp gần nhất. |
spin_commit | người chơi hoặc khóa phiên của họ | Đặt cược: trừ tiền vòng chơi khỏi số dư, ghi lại trò chơi và tỷ lệ đang áp dụng, yêu cầu oracle cấp số ngẫu nhiên. |
spin_settle | bất kỳ ai | Tính kết quả: đọc số của oracle, tính khoản chi trả và cộng cho người chơi. Ai cũng có thể gọi lệnh này — kết quả không phụ thuộc vào điều đó. |
spin_expire | bất kỳ ai | Đóng vòng chưa được tính kết quả trong 20 phút. Nếu oracle không phản hồi, tiền cược được hoàn lại toàn bộ cho người chơi. Nếu oracle đã phản hồi và vòng đã được chốt, hợp đồng trả các giải thường và không quay jackpot. |
spin_seal | bất kỳ ai | Chốt vòng: ghi lại hash của khối chứa lượt cược khi hash còn truy cập được (khoảng 3,5 phút). Chỉ cần đến khi oracle phản hồi lâu hơn thế; thường do dịch vụ trực gọi. Vòng không được tính kết quả và không được chốt kịp thời sẽ đóng mà không có kết quả. |
skip_nonce | người chơi | Dịch số thứ tự của yêu cầu ngẫu nhiên kế tiếp nếu địa chỉ của yêu cầu đã bị chiếm. |
session_open / session_close | người chơi | Cho phép một khóa tạm thời đặt cược trong phạm vi thời hạn và hạn mức; khóa này không thể rút cũng không thể nạp. |
donate | bất kỳ ai | Nạp SOL vào quỹ dự trữ cho số tiền khởi điểm của các jackpot. Không có lệnh ngược lại. |
set_jackpot_starts | quản trị viên | Ấn định số tiền khởi điểm mới cho jackpot và siêu jackpot; có hiệu lực sau 24 giờ. |
rescale_pools | quản trị viên | Chuyển một phần quỹ dự trữ cho số tiền khởi điểm sang quỹ thưởng của các trò. Chỉ theo chiều này; không thể chuyển vào các jackpot — chúng tự được bù từ quỹ dự trữ sau khi có người trúng. |
set_paused | quản trị viên | Tạm dừng hoặc mở lại việc nhận lượt cược mới — phòng khi oracle gặp sự cố. Các lượt cược đã đặt vẫn được tính kết quả; chi trả và rút vẫn hoạt động như thường. |
set_guardian / guard_pause | quản trị viên | Quản trị viên chỉ định người canh gác — khóa của dịch vụ trực, chỉ làm được một việc duy nhất: tạm dừng việc nhận lượt cược mới nếu oracle ngừng phản hồi. Chỉ quản trị viên mới có thể gỡ lệnh tạm dừng. |
propose_dev_authority / accept_dev_authority | quản trị viên | Chuyển quyền quản trị viên sang khóa khác qua hai bước: khóa hiện tại chỉ định khóa mới, khóa mới tự xác nhận. |
roll_epoch / checkin | bất kỳ ai | Các lệnh phụ trợ: cập nhật thống kê tuần và mốc ngày. Không di chuyển tài sản. |
claim_dev | quản trị viên | Nhận phần đã tích lũy của quản trị viên — và chỉ phần đó. |
initialize / fund_pools | quản trị viên | Khởi chạy một lần. initialize tạo các tài khoản (người nắm quyền nâng cấp chương trình ký); fund_pools ghi một lần duy nhất quỹ khởi đầu đã nạp vào các hũ, còn phần dư vượt quá số đó được ghi vào một dòng riêng mà quản trị viên có thể nhận bằng lệnh promo_pay. |
Trong mã không có lệnh nào chuyển quỹ thưởng, các jackpot hay số dư của người chơi cho quản trị viên.
Một vòng theo từng bước
- Đặt cược. Lệnh spin_commit trừ tiền vòng chơi khỏi số dư của bạn và, trong cùng giao dịch đó, tạo một yêu cầu số ngẫu nhiên tại oracle ORAO. Địa chỉ của yêu cầu được tính từ ví của bạn và số thứ tự của vòng, nên không thể đánh tráo bằng yêu cầu của người khác.
- Con số. Nhiều nút ORAO độc lập ký số ngẫu nhiên và ghi nó lên mạng. Trước khi nó được ghi, không ai biết nó: bạn không, dự án không, và từng nút riêng lẻ cũng không.
- Tính kết quả. Lệnh spin_settle đọc con số từ bản ghi của oracle, kiểm tra rằng đó đúng là yêu cầu của vòng bạn chơi, rồi tính khoản chi trả. Trang web tự gửi lệnh này; nếu trang đã đóng, chương trình trực của dự án sẽ làm việc đó, hoặc chính bạn ở lần truy cập sau.
- Hiển thị. Lá bài, mìn, tên lửa, viên đá là cách thể hiện khoản chi trả đã được tính xong. Các thao tác bấm trong trò chơi không ảnh hưởng đến nó.
Vì sao không thể biết trước và không thể làm giả kết quả. Con số cuối cùng của vòng là số của oracle được trộn với hash của khối ghi lượt cược. Tại thời điểm đặt cược, hash này chưa tồn tại, còn số của oracle đến sau và từ một bên thứ ba: không ai có thể tính trước kết cục — người chơi không, dự án không, và chính oracle cũng không. Trò chơi, số tiền khởi điểm của các jackpot và mức trần giải thưởng được ghi lại ngay lúc đặt cược; công thức tính nằm trong mã mở. Tính kết quả muộn không bao giờ có lợi hơn tính đúng hạn. Chỉ có thể thay đổi luật bằng cách thay mã chương trình, mà điều đó thì ai cũng thấy (xem phần về quản trị viên).
Kết quả được tính từ số ngẫu nhiên như thế nào
Một vòng gồm từ 1 đến 100 lượt cược, mỗi lượt 0,01 SOL (ở vòng quay là đến 1000). Số của oracle được triển khai thành một giá trị ngẫu nhiên độc lập cho từng lượt cược, và với mỗi lượt hợp đồng lần lượt trả lời các câu hỏi:
- Siêu jackpot, jackpot, mini jackpot? Xác suất trúng mỗi hũ bằng phần đóng góp của lượt cược vào hũ đó chia cho số tiền khởi điểm của hũ. Một hũ chỉ được quay khi trong đó có ít nhất 25% số tiền khởi điểm.
- Giải của trò chơi? Mỗi trò có xác suất trúng giải riêng và bảng riêng gồm sáu bậc có trọng số. Ví dụ, ở vòng quay giải rơi vào 10% số lượt cược. Bảng của mọi trò được hiển thị trên trang của chúng.
- “Quay thêm”? Với xác suất 11,6%, lượt cược được lặp lại miễn phí bằng tiền của quỹ thưởng.
- Nếu không thì lượt cược không có giải. Nó được chia giống mọi lượt cược khác: quỹ thưởng, các jackpot và phần của quản trị viên.
Bảng của các trò khác nhau, nhưng khoản chi trả kỳ vọng thì như nhau (chính xác đến phần trăm của một phần trăm; khi quỹ thưởng từ 40 SOL trở lên, lúc giải không chạm mức trần): khoảng 77,5% tiền cược dưới dạng giải thường, và tính cả các lượt lặp “Quay thêm” là khoảng 88% số cược đã trả tiền. Trình biên dịch kiểm tra sự bằng nhau này: nếu kỳ vọng của một trò nào đó cao hơn vòng quay, hoặc thấp hơn quá nửa phần trăm, chương trình sẽ không biên dịch được.
Hợp đồng đưa mỗi lượt cược vào đâu
| Đi đâu | Tỷ lệ trong lượt cược đã trả tiền | Để làm gì |
|---|---|---|
| Quỹ thưởng | ≈88% | giải thường của mọi trò |
| Jackpot, mini jackpot, siêu jackpot và số tiền khởi điểm | 2% | ba hũ chung |
| Quản trị viên | 10% | thu nhập của dự án; không có khoản nào khác |
Trong mã, các tỷ lệ được ghi trên mỗi lượt cược được thực hiện, kể cả các lượt lặp miễn phí, nên ở đó ghi 8,84% và 1,77%: quy về số cược đã trả tiền thì trung bình là 10% và 2%.
Các quy tắc giới hạn và lý do có chúng
- Một giải không quá một phần tư quỹ thưởng. Hợp đồng không thể hứa nhiều hơn số nó có, và một khoản thắng lớn không vét sạch quỹ của những người còn lại. Phần chưa trả đủ ở lại trong quỹ.
- Rút sau 12 giờ kể từ lần nạp gần nhất. Quy tắc này như nhau với mọi người và được ghi dưới dạng hằng số: chỉ có thể thay đổi bằng một phiên bản mới của chương trình.
- Số tiền khởi điểm của các jackpot thay đổi với độ trễ 24 giờ. Tỷ lệ của một vòng được chốt ngay lúc đặt cược, nên không thể thay đổi chúng “theo một lượt cược đã đặt”.
- 20 phút để tính kết quả. Nếu oracle không phản hồi, tiền cược được hoàn lại toàn bộ cho người chơi: khi chưa có con số thì không ai biết kết quả, nên không thể dùng cách này để tránh một lượt thua. Nếu oracle đã phản hồi nhưng việc tính kết quả bị trễ, các giải thường vẫn được trả, còn jackpot không được quay trong vòng này. Bảo vệ két. Trước mỗi lần chi trả và sau mỗi lần tính kết quả, hợp đồng kiểm tra rằng số tiền trong két không ít hơn số nó nợ người chơi và các hũ; nếu không, thao tác bị từ chối. Người canh gác. Nếu oracle ngừng phản hồi, việc nhận lượt cược mới tự động tạm dừng; việc tính kết quả và rút vẫn hoạt động.
- Jackpot được trả theo từng phần: người thắng được hưởng 95% hũ, trong đó 20% trả ngay và 8% mỗi tuần. Phần chưa trả được ghi vào tài khoản của người thắng.
- Mỗi người chơi chỉ có một vòng chưa hoàn tất. Khi vòng chưa được tính kết quả, lượt cược mới không được nhận.
Quản trị viên làm được gì và không làm được gì
Có thể
- nhận phần của mình — 10% số cược đã trả tiền;
- nạp SOL vào quỹ dự trữ và chuyển chúng từ quỹ dự trữ sang quỹ thưởng;
- nhận phần dư nằm trong két khi khởi chạy, vượt quá quỹ khởi đầu;
- thay đổi số tiền khởi điểm của các jackpot — có độ trễ và trong giới hạn định sẵn;
- tạm dừng việc nhận lượt cược mới nếu oracle không phản hồi, và chuyển quyền của mình sang khóa khác.
Không thể
- rút quỹ thưởng, các jackpot, quỹ dự trữ hay số dư của người chơi (với tư cách người chơi, quản trị viên thắng theo cùng điều kiện như mọi người);
- thay đổi bảng thưởng, xác suất trúng giải của các trò và các tỷ lệ chia tiền cược: đó là các hằng số trong mã;
- biết trước số ngẫu nhiên của một vòng trước khi đặt cược, hay chọn nó;
- dừng việc tính kết quả các lượt cược đã đặt hoặc việc rút: lệnh tạm dừng chỉ áp dụng cho lượt cược mới.
Lưu ý thẳng thắn. Chương trình có quyền nâng cấp: chừng nào quyền đó chưa bị thu hồi, người nắm quyền có thể thay mã bằng phiên bản mới, và khi đó mọi điều nói trên sẽ áp dụng cho mã mới. Trạng thái của quyền này và mọi lần nâng cấp đều xem được trong trình khám phá Solana. Hợp đồng chưa được kiểm toán độc lập.
Đã kiểm thử bằng gì
- Kiểm thử hợp đồng: phần của quản trị viên là 10% ở từng trò, tỷ lệ hoàn trả của mọi trò gần bằng nhau khi quỹ là 50 SOL, quy tắc một phần tư quỹ và mức trần giải thưởng tại thời điểm đặt cược, khóa rút tiền, thay đổi số tiền khởi điểm có độ trễ, tính kết quả muộn không có lợi hơn tính đúng hạn.
- Kiểm tra bảo toàn tài sản: hàng chục nghìn thao tác ngẫu nhiên, sau mỗi thao tác số tiền trong két được đối chiếu với tổng các số dư và các hũ.
- Các lần chạy dài: hai triệu lượt cược cho mỗi trò — đã trả cho người chơi bao nhiêu, quản trị viên nhận bao nhiêu.
- Giao dịch thật trên một nút Solana cục bộ: nạp tiền, từ chối rút trước hạn, nạp vào quỹ dự trữ, thay đổi số tiền khởi điểm.
- Kiểm thử trang web: trang web tính tỷ lệ bằng chính các công thức của hợp đồng và đối chiếu với các mẫu do hợp đồng ghi lại.
Những gì chưa được kiểm tra và chưa làm được liệt kê không tô vẽ trên trang “Vì sao FAIRDRUM”. Cách tự kiểm tra một vòng bất kỳ có trên trang “Kiểm tra vòng”.
Các tham số của hợp đồng trong một bảng
- Một lượt cược đơn vị
- 0,01 SOL
- Vòng
- đến 100 lượt cược ở các trò, đến 1.000 ở vòng quay
- Số trò (chế độ)
- 16
- Xác suất “Quay thêm”
- 11,6%
- Mức trần của một giải
- 1/4 quỹ thưởng
- Số tiền khởi điểm nhỏ nhất
- jackpot 0,2 SOL, siêu jackpot 2 SOL
- Mini jackpot
- bắt đầu từ 1/10 jackpot
- Cho người thắng jackpot
- 95% · 5% chuyển vào siêu jackpot
- Cho người thắng siêu jackpot
- 90%
- Khóa rút tiền
- 12 giờ sau lần nạp gần nhất
- Thời hạn tính kết quả vòng
- 3.000 slot của mạng, khoảng 20 phút
- Phí mạng và oracle
- 0,005 SOL mỗi vòng, không phải dự án thu