Skip to content

Commit

Permalink
Only "real" ideal dices.
Browse files Browse the repository at this point in the history
  • Loading branch information
cusma committed Nov 8, 2022
1 parent a4897dd commit 6312e74
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 14 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Let's roll your dices on Algorand!

## Overview
[AlgoDices](https://testnet.algoexplorer.io/application/120974808) application
[AlgoDices](https://testnet.algoexplorer.io/application/121287966) application
let players **roll dices on-chain** (TestNet), thanks the [*Randomness Beacon Application*](https://developer.algorand.org/articles/usage-and-best-practices-for-randomness-beacon/).

Starting from AVM 7, Algorand enables [turstless randomness on chain](https://developer.algorand.org/articles/randomness-on-algorand),
Expand Down Expand Up @@ -55,9 +55,9 @@ mandate `future_round` to be greater than current round plus `N`.
the previous booked randomness is unused.

### Let's roll a die!
Once the booked randomness is available, players can roll a die of **any number
of faces** (e.g. usally `d4`, `d6`, `d8`, `d10`, `d12`, `d20`, `d100` are
common dices in board games).
Once the booked randomness is available, players can roll a die with a *"real"
number of faces* (`d4`, `d6`, `d8`, `d10`, `d12`, `d20`, are common dices in
board games).

⚠️ Players should wait at least for `future_round + 8` round to be sure that
their booked randomness is available in the Randomness Beacon App.
Expand All @@ -74,7 +74,7 @@ their booked randomness is available in the Randomness Beacon App.
{
"type": "uint64",
"name": "faces",
"desc": "Number of faces (e.g. 2, 4, 6, 8, 10, 12, 20, 100, ...)"
"desc": "Number of faces (2, 4, 6, 8, 10, 12, 20)"
}
],
"returns": {
Expand All @@ -90,6 +90,13 @@ AlgoDice `die_roll` returns an array containing:
2. Die's faces;
3. The result.

## 🎰 Games
On-chain games can _call_ AlgoDices imposing their own rules, for example:
a `GameApp` calls `roll_die` two times (on behalf of players Alice and Bob
participating in the game thourgh proxy Contract Accounts controlled by
GameApp) as Inner Transactions executed in the same GameApp Call, requiring
`faces = 6`. The highest result wins the match.

## CLI
You can easily roll a die with the Python 🎲 AlgoDices CLI.

Expand Down
6 changes: 5 additions & 1 deletion algodices.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@

from algodices_dapp import AlgoDices

ALGO_DICES_APP_ID = 120974808
ALGO_DICES_APP_ID = 121287966
RANDOMNESS_BEACON_DELAY = 8
FACES = [2, 4, 6, 8, 10, 12, 20]


def args_types(args: dict) -> dict:
Expand Down Expand Up @@ -87,6 +88,9 @@ def main():
return print(f" --- Result can be revealed from round: {reveal_round}")

elif args["roll"]:
if args["<faces>"] not in FACES:
quit(f"\n⚠️ Number of faces must be either: {FACES}")

current_round = testnet.algod().status()["last-round"]
booked_round = algo_dices.get_account_state(user_address)[
AlgoDices.randomness_round.key.byte_str[1:-1]
Expand Down
15 changes: 14 additions & 1 deletion algodices_dapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,32 @@ def roll_die(
Args:
randomness_beacon: Randomness Beacon App ID (110096026)
faces: Number of faces (e.g. 2, 4, 6, 8, 10, 12, 20, 100, ...)
faces: Number of faces (2, 4, 6, 8, 10, 12, 20)
Returns:
Die roll: (booked_round, faces, result)
"""
randomness = Btoi(
Extract(string=self.get_randomness(), start=Int(0), length=Int(8))
)
is_valid_faces = Or(
faces.get() == Int(2),
faces.get() == Int(4),
faces.get() == Int(6),
faces.get() == Int(8),
faces.get() == Int(10),
faces.get() == Int(12),
faces.get() == Int(20),
)
return Seq(
Assert(
randomness_beacon.application_id() == self.beacon_app_id,
comment="Randomness Beacon App ID must be correct.",
),
Assert(
is_valid_faces,
comment="Number of faces must be equal to real ideal dices.",
),
(booked_round := abi.Uint64()).set(self.randomness_round[Txn.sender()]),
(result := abi.Uint64()).set(randomness % faces.get() + Int(1)),
self.randomness_round[Txn.sender()].set_default(),
Expand Down
6 changes: 3 additions & 3 deletions artifacts/application.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"hints": {},
"source": {
"approval": "I3ByYWdtYSB2ZXJzaW9uIDcKaW50Y2Jsb2NrIDAgMQpieXRlY2Jsb2NrIDB4NzI2MTZlNjQ2ZjZkNmU2NTczNzM1ZjcyNmY3NTZlNjQgMHg2MjY1NjE2MzZmNmU1ZjYxNzA3MDVmNjk2NAp0eG4gTnVtQXBwQXJncwppbnRjXzAgLy8gMAo9PQpibnogbWFpbl9sNgp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweGQ0YjE3OWNjIC8vICJib29rX2RpZV9yb2xsKHVpbnQ2NCl2b2lkIgo9PQpibnogbWFpbl9sNQp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweDZhMTYzNGQzIC8vICJyb2xsX2RpZShhcHBsaWNhdGlvbix1aW50NjQpdWludDY0WzNdIgo9PQpibnogbWFpbl9sNAplcnIKbWFpbl9sNDoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQppbnRjXzAgLy8gMApnZXRieXRlCnN0b3JlIDIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgpidG9pCnN0b3JlIDMKbG9hZCAyCmxvYWQgMwpjYWxsc3ViIHJvbGxkaWVfNApzdG9yZSA0CnB1c2hieXRlcyAweDE1MWY3Yzc1IC8vIDB4MTUxZjdjNzUKbG9hZCA0CmNvbmNhdApsb2cKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDU6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CnR4bmEgQXBwbGljYXRpb25BcmdzIDEKYnRvaQpjYWxsc3ViIGJvb2tkaWVyb2xsXzMKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDY6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KYm56IG1haW5fbDEwCnR4biBPbkNvbXBsZXRpb24KaW50Y18xIC8vIE9wdEluCj09CmJueiBtYWluX2w5CmVycgptYWluX2w5Ogp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQphc3NlcnQKY2FsbHN1YiBvcHRpbl8xCmludGNfMSAvLyAxCnJldHVybgptYWluX2wxMDoKdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKPT0KYXNzZXJ0CmNhbGxzdWIgY3JlYXRlXzAKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBjcmVhdGUKY3JlYXRlXzA6CmludGNfMCAvLyAwCmJ5dGVjXzEgLy8gImJlYWNvbl9hcHBfaWQiCmFwcF9nbG9iYWxfZ2V0X2V4CnN0b3JlIDEKc3RvcmUgMApsb2FkIDEKIQphc3NlcnQKYnl0ZWNfMSAvLyAiYmVhY29uX2FwcF9pZCIKcHVzaGludCAxMTAwOTYwMjYgLy8gMTEwMDk2MDI2CmFwcF9nbG9iYWxfcHV0CnJldHN1YgoKLy8gb3B0X2luCm9wdGluXzE6CnR4biBTZW5kZXIKYnl0ZWNfMCAvLyAicmFuZG9tbmVzc19yb3VuZCIKaW50Y18wIC8vIDAKYXBwX2xvY2FsX3B1dApyZXRzdWIKCi8vIGdldF9yYW5kb21uZXNzCmdldHJhbmRvbW5lc3NfMjoKdHhuIFNlbmRlcgpieXRlY18wIC8vICJyYW5kb21uZXNzX3JvdW5kIgphcHBfbG9jYWxfZ2V0CnN0b3JlIDkKdHhuIFNlbmRlcgpzdG9yZSAxMApsb2FkIDEwCmxlbgppdG9iCmV4dHJhY3QgNiAwCmxvYWQgMTAKY29uY2F0CnN0b3JlIDEwCml0eG5fYmVnaW4KcHVzaGludCA2IC8vIGFwcGwKaXR4bl9maWVsZCBUeXBlRW51bQpieXRlY18xIC8vICJiZWFjb25fYXBwX2lkIgphcHBfZ2xvYmFsX2dldAppdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKcHVzaGJ5dGVzIDB4NDdjMjBjMjMgLy8gIm11c3RfZ2V0KHVpbnQ2NCxieXRlW10pYnl0ZVtdIgppdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwpsb2FkIDkKaXRvYgppdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwpsb2FkIDEwCml0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCmludGNfMCAvLyAwCml0eG5fZmllbGQgRmVlCml0eG5fc3VibWl0Cml0eG4gTGFzdExvZwpleHRyYWN0IDQgMApyZXRzdWIKCi8vIGJvb2tfZGllX3JvbGwKYm9va2RpZXJvbGxfMzoKc3RvcmUgOApsb2FkIDgKZ2xvYmFsIFJvdW5kCj4KLy8gRGllIHJvbGwgcm91bmQgbXVzdCBiZSBpbiB0aGUgZnV0dXJlLgphc3NlcnQKdHhuIFNlbmRlcgpieXRlY18wIC8vICJyYW5kb21uZXNzX3JvdW5kIgpsb2FkIDgKYXBwX2xvY2FsX3B1dApyZXRzdWIKCi8vIHJvbGxfZGllCnJvbGxkaWVfNDoKc3RvcmUgNQp0eG5hcyBBcHBsaWNhdGlvbnMKYnl0ZWNfMSAvLyAiYmVhY29uX2FwcF9pZCIKYXBwX2dsb2JhbF9nZXQKPT0KLy8gUmFuZG9tbmVzcyBCZWFjb24gQXBwIElEIG11c3QgYmUgY29ycmVjdC4KYXNzZXJ0CnR4biBTZW5kZXIKYnl0ZWNfMCAvLyAicmFuZG9tbmVzc19yb3VuZCIKYXBwX2xvY2FsX2dldApzdG9yZSA2CmNhbGxzdWIgZ2V0cmFuZG9tbmVzc18yCmV4dHJhY3QgMCA4CmJ0b2kKbG9hZCA1CiUKaW50Y18xIC8vIDEKKwpzdG9yZSA3CnR4biBTZW5kZXIKYnl0ZWNfMCAvLyAicmFuZG9tbmVzc19yb3VuZCIKaW50Y18wIC8vIDAKYXBwX2xvY2FsX3B1dApsb2FkIDYKaXRvYgpsb2FkIDUKaXRvYgpjb25jYXQKbG9hZCA3Cml0b2IKY29uY2F0CnJldHN1Yg==",
"approval": "I3ByYWdtYSB2ZXJzaW9uIDcKaW50Y2Jsb2NrIDAgMSA2CmJ5dGVjYmxvY2sgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzVmNzI2Zjc1NmU2NCAweDYyNjU2MTYzNmY2ZTVmNjE3MDcwNWY2OTY0CnR4biBOdW1BcHBBcmdzCmludGNfMCAvLyAwCj09CmJueiBtYWluX2w2CnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4ZDRiMTc5Y2MgLy8gImJvb2tfZGllX3JvbGwodWludDY0KXZvaWQiCj09CmJueiBtYWluX2w1CnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4NmExNjM0ZDMgLy8gInJvbGxfZGllKGFwcGxpY2F0aW9uLHVpbnQ2NCl1aW50NjRbM10iCj09CmJueiBtYWluX2w0CmVycgptYWluX2w0Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CiYmCmFzc2VydAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCmludGNfMCAvLyAwCmdldGJ5dGUKc3RvcmUgMgp0eG5hIEFwcGxpY2F0aW9uQXJncyAyCmJ0b2kKc3RvcmUgMwpsb2FkIDIKbG9hZCAzCmNhbGxzdWIgcm9sbGRpZV80CnN0b3JlIDQKcHVzaGJ5dGVzIDB4MTUxZjdjNzUgLy8gMHgxNTFmN2M3NQpsb2FkIDQKY29uY2F0CmxvZwppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sNToKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpidG9pCmNhbGxzdWIgYm9va2RpZXJvbGxfMwppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sNjoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQpibnogbWFpbl9sMTAKdHhuIE9uQ29tcGxldGlvbgppbnRjXzEgLy8gT3B0SW4KPT0KYm56IG1haW5fbDkKZXJyCm1haW5fbDk6CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CmFzc2VydApjYWxsc3ViIG9wdGluXzEKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDEwOgp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAo9PQphc3NlcnQKY2FsbHN1YiBjcmVhdGVfMAppbnRjXzEgLy8gMQpyZXR1cm4KCi8vIGNyZWF0ZQpjcmVhdGVfMDoKaW50Y18wIC8vIDAKYnl0ZWNfMSAvLyAiYmVhY29uX2FwcF9pZCIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMQpzdG9yZSAwCmxvYWQgMQohCmFzc2VydApieXRlY18xIC8vICJiZWFjb25fYXBwX2lkIgpwdXNoaW50IDExMDA5NjAyNiAvLyAxMTAwOTYwMjYKYXBwX2dsb2JhbF9wdXQKcmV0c3ViCgovLyBvcHRfaW4Kb3B0aW5fMToKdHhuIFNlbmRlcgpieXRlY18wIC8vICJyYW5kb21uZXNzX3JvdW5kIgppbnRjXzAgLy8gMAphcHBfbG9jYWxfcHV0CnJldHN1YgoKLy8gZ2V0X3JhbmRvbW5lc3MKZ2V0cmFuZG9tbmVzc18yOgp0eG4gU2VuZGVyCmJ5dGVjXzAgLy8gInJhbmRvbW5lc3Nfcm91bmQiCmFwcF9sb2NhbF9nZXQKc3RvcmUgOQp0eG4gU2VuZGVyCnN0b3JlIDEwCmxvYWQgMTAKbGVuCml0b2IKZXh0cmFjdCA2IDAKbG9hZCAxMApjb25jYXQKc3RvcmUgMTAKaXR4bl9iZWdpbgppbnRjXzIgLy8gYXBwbAppdHhuX2ZpZWxkIFR5cGVFbnVtCmJ5dGVjXzEgLy8gImJlYWNvbl9hcHBfaWQiCmFwcF9nbG9iYWxfZ2V0Cml0eG5fZmllbGQgQXBwbGljYXRpb25JRApwdXNoYnl0ZXMgMHg0N2MyMGMyMyAvLyAibXVzdF9nZXQodWludDY0LGJ5dGVbXSlieXRlW10iCml0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCmxvYWQgOQppdG9iCml0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCmxvYWQgMTAKaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKaW50Y18wIC8vIDAKaXR4bl9maWVsZCBGZWUKaXR4bl9zdWJtaXQKaXR4biBMYXN0TG9nCmV4dHJhY3QgNCAwCnJldHN1YgoKLy8gYm9va19kaWVfcm9sbApib29rZGllcm9sbF8zOgpzdG9yZSA4CmxvYWQgOApnbG9iYWwgUm91bmQKPgovLyBEaWUgcm9sbCByb3VuZCBtdXN0IGJlIGluIHRoZSBmdXR1cmUuCmFzc2VydAp0eG4gU2VuZGVyCmJ5dGVjXzAgLy8gInJhbmRvbW5lc3Nfcm91bmQiCmxvYWQgOAphcHBfbG9jYWxfcHV0CnJldHN1YgoKLy8gcm9sbF9kaWUKcm9sbGRpZV80OgpzdG9yZSA1CnR4bmFzIEFwcGxpY2F0aW9ucwpieXRlY18xIC8vICJiZWFjb25fYXBwX2lkIgphcHBfZ2xvYmFsX2dldAo9PQovLyBSYW5kb21uZXNzIEJlYWNvbiBBcHAgSUQgbXVzdCBiZSBjb3JyZWN0Lgphc3NlcnQKbG9hZCA1CnB1c2hpbnQgMiAvLyAyCj09CmxvYWQgNQpwdXNoaW50IDQgLy8gNAo9PQp8fApsb2FkIDUKaW50Y18yIC8vIDYKPT0KfHwKbG9hZCA1CnB1c2hpbnQgOCAvLyA4Cj09Cnx8CmxvYWQgNQpwdXNoaW50IDEwIC8vIDEwCj09Cnx8CmxvYWQgNQpwdXNoaW50IDEyIC8vIDEyCj09Cnx8CmxvYWQgNQpwdXNoaW50IDIwIC8vIDIwCj09Cnx8Ci8vIE51bWJlciBvZiBmYWNlcyBtdXN0IGJlIGVxdWFsIHRvIHJlYWwgaWRlYWwgZGljZXMuCmFzc2VydAp0eG4gU2VuZGVyCmJ5dGVjXzAgLy8gInJhbmRvbW5lc3Nfcm91bmQiCmFwcF9sb2NhbF9nZXQKc3RvcmUgNgpjYWxsc3ViIGdldHJhbmRvbW5lc3NfMgpleHRyYWN0IDAgOApidG9pCmxvYWQgNQolCmludGNfMSAvLyAxCisKc3RvcmUgNwp0eG4gU2VuZGVyCmJ5dGVjXzAgLy8gInJhbmRvbW5lc3Nfcm91bmQiCmludGNfMCAvLyAwCmFwcF9sb2NhbF9wdXQKbG9hZCA2Cml0b2IKbG9hZCA1Cml0b2IKY29uY2F0CmxvYWQgNwppdG9iCmNvbmNhdApyZXRzdWI=",
"clear": "I3ByYWdtYSB2ZXJzaW9uIDcKcHVzaGludCAwIC8vIDAKcmV0dXJu"
},
"schema": {
Expand Down Expand Up @@ -54,7 +54,7 @@
{
"type": "uint64",
"name": "faces",
"desc": "Number of faces (e.g. 2, 4, 6, 8, 10, 12, 20, 100, ...)"
"desc": "Number of faces (2, 4, 6, 8, 10, 12, 20)"
}
],
"returns": {
Expand All @@ -65,7 +65,7 @@
}
],
"networks": {
"SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=": { "appID": 120974808 }
"SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=": { "appID": 121287966 }
},
"desc": "Algorand Dices Application"
}
Expand Down
33 changes: 31 additions & 2 deletions artifacts/approval.teal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma version 7
intcblock 0 1
intcblock 0 1 6
bytecblock 0x72616e646f6d6e6573735f726f756e64 0x626561636f6e5f6170705f6964
txn NumAppArgs
intc_0 // 0
Expand Down Expand Up @@ -120,7 +120,7 @@ load 10
concat
store 10
itxn_begin
pushint 6 // appl
intc_2 // appl
itxn_field TypeEnum
bytec_1 // "beacon_app_id"
app_global_get
Expand Down Expand Up @@ -162,6 +162,35 @@ app_global_get
==
// Randomness Beacon App ID must be correct.
assert
load 5
pushint 2 // 2
==
load 5
pushint 4 // 4
==
||
load 5
intc_2 // 6
==
||
load 5
pushint 8 // 8
==
||
load 5
pushint 10 // 10
==
||
load 5
pushint 12 // 12
==
||
load 5
pushint 20 // 20
==
||
// Number of faces must be equal to real ideal dices.
assert
txn Sender
bytec_0 // "randomness_round"
app_local_get
Expand Down
4 changes: 2 additions & 2 deletions artifacts/contract.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
{
"type": "uint64",
"name": "faces",
"desc": "Number of faces (e.g. 2, 4, 6, 8, 10, 12, 20, 100, ...)"
"desc": "Number of faces (2, 4, 6, 8, 10, 12, 20)"
}
],
"returns": {
Expand All @@ -37,7 +37,7 @@
}
],
"networks": {
"SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=": { "appID": 120974808 }
"SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=": { "appID": 121287966 }
},
"desc": "Algorand Dices Application"
}

0 comments on commit 6312e74

Please sign in to comment.