Created
February 23, 2023 17:03
-
-
Save xrchz/3cb122902ed66f11a6f56b96f534c3bc to your computer and use it in GitHub Desktop.
Vyper InvalidType error
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @version ^0.3.7 | |
# mental poker deck protocol | |
# | |
# Implements the paper | |
# A Fast Mental Poker Protocol by Tzer-Jen Wei & Lih-Chung Wang | |
# https://ia.cr/2009/439 | |
# using the alt-bn128's G1 (https://neuromancer.sk/std/bn/bn254) for G | |
# | |
# For discrete log equality non-interactive ZK proofs, we use the scheme | |
# described in Wallet Databases with Observers by David Chaum & Torben Pryds Pederson | |
# https://dx.doi.org/10.1007/3-540-48071-4_7 | |
# section 3.2 | |
GROUP_ORDER: constant(uint256) = 21888242871839275222246405745257275088696311157297823662689037894645226208583 | |
# arbitrary limits on deck size and number of players sharing a deck | |
# note: MAX_SIZE must be < GROUP_ORDER | |
# TODO: we inline these because of https://github.com/vyperlang/vyper/issues/3294 | |
MAX_SIZE: constant(uint256) = 9000 | |
MAX_PLAYERS: constant(uint256) = 8000 # to distinguish from MAX_SIZE when inlining | |
MAX_SECURITY: constant(uint256) = 256 | |
struct Proof: | |
# signature to confirm log_g(gx) = log_h(hx) | |
# s is a random secret scalar | |
gs: uint256[2] # g ** s | |
hs: uint256[2] # h ** s | |
scx: uint256 # s + cx (mod q), where c = hash(g, h, gx, hx, gs, hs) | |
struct CP: | |
# g and h are random points, x is a random secret scalar | |
g: uint256[2] | |
h: uint256[2] | |
gx: uint256[2] # g ** x | |
hx: uint256[2] # h ** x | |
p: Proof | |
struct DeckPrep: | |
cards: DynArray[CP, 9000] | |
struct DrawCard: | |
# successive decryptions | |
c: DynArray[uint256[2], 8000] | |
# 1 + index of player the card is initially drawn to (i.e. they skip decryption) | |
# note: a card can only be drawn to a single player | |
drawnTo: uint256 | |
# 1 + original index after reveal | |
opensAs: uint256 | |
struct Deck: | |
# authorised address for drawing cards and reshuffling | |
dealer: address | |
# authorised address for each player | |
addrs: DynArray[address, 8000] | |
# shuffle[0] is the unencrypted cards (including base card at index 0) | |
# shuffle[j+1] is the shuffled encrypted cards from player index j | |
shuffle: DynArray[DynArray[uint256[2], 9000], 8001] # 8000 + 1] <- another Vyper bug with importing | |
challengeReq: DynArray[uint256, 8000] | |
challengeRes: DynArray[DynArray[DynArray[uint256[2], 9000], 256], 8000] | |
challengeRnd: uint256 | |
# for decrypting shuffled cards | |
# note: cards[i] corresponds to shuffle[_][i+1] | |
cards: DynArray[DrawCard, 9000] | |
# data for deck preparation | |
prep: DynArray[DeckPrep, 8000] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @version ^0.3.7 | |
# no-limit hold'em sit-n-go single-table tournaments | |
# copied from Deck.vy because https://github.com/vyperlang/vyper/issues/2670 | |
MAX_SIZE: constant(uint256) = 9000 | |
MAX_PLAYERS: constant(uint256) = 8000 # to distinguish from MAX_SIZE when inlining | |
MAX_SECURITY: constant(uint256) = 256 | |
struct Proof: | |
# signature to confirm log_g(gx) = log_h(hx) | |
# s is a random secret scalar | |
gs: uint256[2] # g ** s | |
hs: uint256[2] # h ** s | |
scx: uint256 # s + cx (mod q), where c = hash(g, h, gx, hx, gs, hs) | |
struct CB: | |
# g and h are random points, x is a random secret scalar | |
g: uint256[2] | |
h: uint256[2] | |
gx: uint256[2] # g ** x | |
hx: uint256[2] # h ** x | |
p: Proof | |
struct DeckPrep: | |
cards: DynArray[CB, MAX_SIZE] | |
# end of copy | |
import Deck as DeckManager | |
# copied from Table.vy | |
MAX_SEATS: constant(uint256) = 9 # maximum seats per table | |
MAX_LEVELS: constant(uint256) = 100 # maximum number of levels in tournament structure | |
struct Config: | |
gameAddress: address # address of game manager | |
buyIn: uint256 # entry ticket price per player | |
bond: uint256 # liveness bond for each player | |
startsWith: uint256 # game can start when this many players are seated | |
untilLeft: uint256 # game ends when this many players are left | |
structure: uint256[MAX_LEVELS] # small blind levels (right-padded with blanks) | |
levelBlocks: uint256 # blocks between levels | |
verifRounds: uint256 # number of shuffle verifications required | |
prepBlocks: uint256 # blocks to submit deck preparation | |
shuffBlocks: uint256 # blocks to submit shuffle | |
verifBlocks: uint256 # blocks to submit shuffle verification | |
dealBlocks: uint256 # blocks to submit card decryptions | |
actBlocks: uint256 # blocks to act before folding can be triggered | |
Phase_JOIN: constant(uint256) = 0 # before the game has started, taking seats | |
Phase_PREP: constant(uint256) = 1 # all players seated, preparing the deck | |
Phase_SHUFFLE: constant(uint256) = 2 # submitting shuffles and verifications in order | |
Phase_DEAL: constant(uint256) = 3 # drawing and possibly opening cards as currently required | |
Phase_PLAY: constant(uint256) = 4 # betting; new card revelations may become required | |
Phase_SHOW: constant(uint256) = 5 # showdown TODO | |
# end copy | |
import Table as TableManager | |
T: immutable(TableManager) | |
@external | |
def __init__(tableAddress: address): | |
T = TableManager(tableAddress) | |
# TODO: add rake (rewards tabs for progress txns)? | |
# TODO: add penalties (instead of full abort on failure)? | |
struct Hand: | |
startBlock: uint256 # block number when game started | |
stack: uint256[MAX_SEATS] # stack at each seat (zero for eliminated or all-in players) | |
dealer: uint256 # seat index of current dealer | |
board: uint256[5] # board cards | |
bet: uint256[MAX_SEATS] # current round bet of each player | |
lastBet: uint256 # size of last bet or raise | |
live: bool[MAX_SEATS] # whether this player has a live hand | |
betIndex: uint256 # seat index of player who introduced the current bet | |
actionIndex: uint256 # seat index of currently active player | |
actionBlock: uint256 # block from which action was on the active player | |
pot: uint256 # pot for the hand (from previous rounds) | |
nextHandId: uint256 | |
hands: HashMap[uint256, Hand] | |
PENDING_REVEAL: constant(uint256) = 53 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @version ^0.3.7 | |
# copied from Deck.vy because https://github.com/vyperlang/vyper/issues/2670 | |
MAX_SIZE: constant(uint256) = 9000 | |
MAX_SECURITY: constant(uint256) = 256 | |
struct Proof: | |
# signature to confirm log_g(gx) = log_h(hx) | |
# s is a random secret scalar | |
gs: uint256[2] # g ** s | |
hs: uint256[2] # h ** s | |
scx: uint256 # s + cx (mod q), where c = hash(g, h, gx, hx, gs, hs) | |
struct CP: | |
# g and h are random points, x is a random secret scalar | |
g: uint256[2] | |
h: uint256[2] | |
gx: uint256[2] # g ** x | |
hx: uint256[2] # h ** x | |
p: Proof | |
struct DeckPrep: | |
cards: DynArray[CP, 9000] | |
# end of copy | |
import Deck as DeckManager | |
# player registry | |
nextPlayerId: public(uint256) | |
playerAddress: public(HashMap[uint256, address]) | |
pendingPlayerAddress: public(HashMap[uint256, address]) | |
@external | |
def register() -> uint256: | |
playerId: uint256 = self.nextPlayerId | |
self.playerAddress[playerId] = msg.sender | |
self.nextPlayerId = unsafe_add(playerId, 1) | |
return playerId | |
@external | |
def changePlayerAddress(_playerId: uint256, _newAddress: address): | |
assert self.playerAddress[_playerId] == msg.sender, "unauthorised" | |
self.pendingPlayerAddress[_playerId] = _newAddress | |
@external | |
def confirmChangePlayerAddress(_playerId: uint256): | |
assert self.pendingPlayerAddress[_playerId] == msg.sender, "unauthorised" | |
self.pendingPlayerAddress[_playerId] = empty(address) | |
self.playerAddress[_playerId] = msg.sender | |
MAX_SEATS: constant(uint256) = 9 # maximum seats per table | |
MAX_LEVELS: constant(uint256) = 100 # maximum number of levels in tournament structure | |
Req_DECK: constant(uint256) = 0 # not drawn | |
Req_HAND: constant(uint256) = 1 # drawn to hand | |
Req_MUCK: constant(uint256) = 2 # may be revealed, not required | |
Req_SHOW: constant(uint256) = 3 # must be shown | |
# not using Vyper enum because of this bug | |
# https://github.com/vyperlang/vyper/pull/3196/files#r1062141796 | |
Phase_JOIN: constant(uint256) = 0 # before the game has started, taking seats | |
Phase_PREP: constant(uint256) = 1 # all players seated, preparing the deck | |
Phase_SHUFFLE: constant(uint256) = 2 # submitting shuffles and verifications in order | |
Phase_DEAL: constant(uint256) = 3 # drawing and possibly opening cards as currently required | |
Phase_PLAY: constant(uint256) = 4 # betting; new card revelations may become required | |
Phase_SHOW: constant(uint256) = 5 # showdown TODO | |
struct Config: | |
gameAddress: address # address of game manager | |
buyIn: uint256 # entry ticket price per player | |
bond: uint256 # liveness bond for each player | |
startsWith: uint256 # game can start when this many players are seated | |
untilLeft: uint256 # game ends when this many players are left | |
structure: uint256[100] # small blind levels (right-padded with blanks) | |
levelBlocks: uint256 # blocks between levels | |
verifRounds: uint256 # number of shuffle verifications required | |
prepBlocks: uint256 # blocks to submit deck preparation | |
shuffBlocks: uint256 # blocks to submit shuffle | |
verifBlocks: uint256 # blocks to submit shuffle verification | |
dealBlocks: uint256 # blocks to submit card decryptions | |
actBlocks: uint256 # blocks to act before folding can be triggered | |
struct Table: | |
tableId: uint256 | |
config: Config | |
seats: uint256[9] # playerIds in seats as at the start of the game | |
deck: DeckManager # deck contract | |
deckId: uint256 # id of deck in deck contract | |
phase: uint256 | |
present: bool[9] # whether each player contributes to the current shuffle | |
handId: uint256 # id of hand in hand contract | |
commitBlock: uint256 # block from which new commitments were required | |
deckIndex: uint256 # index of next card in deck | |
drawIndex: uint256[26] # player the card is drawn to | |
requirement: uint256[26] # revelation requirement level |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment