Skip to content

Commit

Permalink
DevEx improvements (#547) (#548)
Browse files Browse the repository at this point in the history
* fixes failing tests in game entropy library
* updates readme to be consistent with latest contract
* updates repo to use starkli instead of legacy starknet
* adds script to automate starkli account setup
* adds script to automate contract deployment
* adds DockerFile
  • Loading branch information
loothero authored Feb 18, 2024
1 parent f57e125 commit 760fa5f
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 105 deletions.
21 changes: 21 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Use Debian Bookworm as a base image
FROM debian:bookworm-slim

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

# Update the package list and install minimal utilities
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl \
git \
ca-certificates \
unzip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | bash -s -- -v 2.5.4
RUN curl https://get.starkli.sh | bash
RUN /root/.starkli/bin/starkliup
# Specify the command to run on container start
CMD ["bash"]
10 changes: 7 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
{
"name": "Rust",
"image": "mcr.microsoft.com/devcontainers/rust:0-1-bullseye",
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"starkware.cairo1"
"starkware.cairo1",
"github.copilot"
]
}
},
Expand All @@ -14,5 +17,6 @@
"CAIRO_COMPILER_DIR":"~/.cairo/target/release/",
"CAIRO_COMPILER_ARGS":"--add-pythonic-hints"
},
"postCreateCommand":"curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | bash -s -- -v 0.7.0 && curl https://pyenv.run | bash && echo 'export PATH=\"$HOME/.pyenv/bin:$PATH\"' >> ~/.bashrc && echo 'eval \"$(pyenv init -)\"' >> ~/.bashrc && echo 'eval \"$(pyenv virtualenv-init -)\"' >> ~/.bashrc && $HOME/.pyenv/bin/pyenv install 3.9.0 && $HOME/.pyenv/bin/pyenv virtualenv 3.9.0 cairo_venv && echo 'pyenv activate cairo_venv' >> ~/.bashrc && echo 'pip install cairo-lang 2> /dev/null' >> ~/.bashrc"
"postCreateCommand": "git config --global core.editor \"code --wait\" && bash scripts/starkli_setup.sh",
"postStartCommand": "cd contracts && scarb build && scarb test"
}
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
market,
obstacles,
combat,
# game_entropy,
# game_snapshot,
game_entropy,
game_snapshot,
]
steps:
- uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ contracts/game_entropy/target/CACHEDIR.TAG
contracts/game_entropy/target/dev/game_entropy.sierra

scripts/stress_test.py
.env
115 changes: 29 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,127 +148,70 @@ Loot Survivor is an onchain game, designed to be immutable and permanently hoste

### Deploying

#### Set up env

Follow instructions here: `https://docs.starknet.io/documentation/getting_started/environment_setup/`


```
source ~/cairo_venv/bin/activate
```

```bash
export STARKNET_NETWORK=alpha-goerli
export STARKNET_WALLET=starkware.starknet.wallets.open_zeppelin.OpenZeppelinAccount
export CAIRO_COMPILER_DIR=~/.cairo/target/release/
export CAIRO_COMPILER_ARGS=--add-pythonic-hints

# you will have an account from the Starknet ENV setup
export ACCOUNT_NAME=INSERT_YOUR_ACCOUNT_NAME_HERE
export ADVENTURER_ID=INSERT_YOUR_ADVENTURER_ID_HERE
export STRENGTH=0
export DEXTERITY=1
export VITALITY=2
export INTELLIGENCE=4
export CHARISMA=5

export LORDS_ADDRESS=0x059dac5df32cbce17b081399e97d90be5fba726f97f00638f838613d088e5a47
export DAO_ADDRESS=0x020b96923a9e60f63a1829d440a03cf680768cadbc8fe737f71380258817d85b

# nav to dir
cd contracts/game

# build
scarb build

# declare
starknet declare --contract target/dev/game_Game.sierra.json --account $ACCOUNT_NAME

# deploy
# <classhash> will be in the output of the previous command
starknet deploy --class_hash 0x2958304935054101c0aeab16cf6507adda1c98b4d977af40d59c2ae75f05767 --max_fee 100000000000000000 --input $LORDS_ADDRESS $DAO_ADDRESS --account $ACCOUNT_NAME
```
#### Setup Starkli Account

```bash
# set contract address
export CONTRACT_ADDRESS=0x06ee32da9f22c736c4ef049719c0021380c302e5d449fbc8acf97489e16a9d05
bash scripts/starkli_setup.sh
```

#### Deploy Contract
```bash
starknet invoke --function mint --address $LORDS_ADDRESS --input 0x1feb9c05d31b70a1506decf52a809d57493bfcd5cc85d6a3e9fd54a12d64389 1000000000000000000000 0 --max_fee 10000000000000000 --account $ACCOUNT_NAME

starknet invoke --function approve --address $LORDS_ADDRESS --input $CONTRACT_ADDRESS 1000000000000000000000 0 --max_fee 10000000000000000 --account $ACCOUNT_NAME
bash scripts/deploy.sh.sh
```

### Game Actions
### Play

#### Start
#### Mint $lords and approve LS to spend
```bash
starknet invoke --function start --address $CONTRACT_ADDRESS --input 0x020b96923a9e60f63a1829d440a03cf680768cadbc8fe737f71380258817d85b 12 123 0 0 0 --max_fee 10000000000000000 --account $ACCOUNT_NAME
source "/workspaces/loot-survivor/.env"
starkli invoke $LORDS_ADDRESS mint 0x1feb9c05d31b70a1506decf52a809d57493bfcd5cc85d6a3e9fd54a12d64389 1000000000000000000000 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
starkli invoke $LORDS_ADDRESS approve $CONTRACT_ADDRESS 1000000000000000000000 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

#### Explore
#### Start New Game
```bash
starknet invoke --function explore --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --max_fee 10000000000000000 --account $ACCOUNT_NAME
starkli invoke $CONTRACT_ADDRESS new_game 0x020b96923a9e60f63a1829d440a03cf680768cadbc8fe737f71380258817d85b 12 123 0 0 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

#### Attack
#### Explore
```bash
starknet invoke --function attack --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --max_fee 10000000000000000 --account $ACCOUNT_NAME
starkli invoke $CONTRACT_ADDRESS explore $ADVENTURER_ID 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

#### Flee
#### Attack Starter Beast
```bash
starknet invoke --function flee --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --max_fee 10000000000000000 --account $ACCOUNT_NAME
starkli invoke $CONTRACT_ADDRESS attack $ADVENTURER_ID 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

#### Upgrade Stat (Charisma x 1)
#### Upgrade Adventurer
```bash
starknet invoke --function upgrade_stat --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 $CHARISMA 1 --max_fee 10000000000000000 --account $ACCOUNT_NAME
starkli invoke $CONTRACT_ADDRESS upgrade $ADVENTURER_ID 0 $CHARISMA 1 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```


### Checking On Your Adventurer
### View Adventurer Details

##### Get full adventurer state
##### Adventurer State
```bash
starknet call --function get_adventurer --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --account $ACCOUNT_NAME
starkli call --watch $CONTRACT_ADDRESS get_adventurer $ADVENTURER_ID 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

##### Get adventurer health
##### Get Adventurer Health
```bash
starknet call --function get_health --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --account $ACCOUNT_NAME
starkli call --watch $CONTRACT_ADDRESS get_health $ADVENTURER_ID 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

##### Get adventurer gold
##### Get Adventurer Gold
```bash
starknet call --function get_gold --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --account $ACCOUNT_NAME
starkli call --watch $CONTRACT_ADDRESS get_gold $ADVENTURER_ID 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

##### Get adventurer xp
##### Get Adventurer XP
```bash
starknet call --function get_xp --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --account $ACCOUNT_NAME
starkli call --watch $CONTRACT_ADDRESS get_xp $ADVENTURER_ID 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```

##### Get upgradable stat points
##### Get number of stat upgrades available
```bash
starknet call --function get_stat_upgrades_available --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --account $ACCOUNT_NAME
```

##### Get base charisma stat (doesn't include boost from items)
```bash
starknet call --function get_base_charisma --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --account $ACCOUNT_NAME
```

##### Get charisma stat including item boosts
```bash
starknet call --function get_charisma --address $CONTRACT_ADDRESS --input $ADVENTURER_ID 0 --account $ACCOUNT_NAME
```


# Starkli Deploy


starkli declare /contracts/game/target/dev/game_Game.sierra.json --account ./account --keystore ./keys --max-fee 0.01

starkli deploy 0x00cccbd15bf27792e7635bd89da237de68b13d29ec01b5cae1da786b276be8a4 $LORDS_ADDRESS $DAO_ADDRESS 0x06fe9215a0f193431f30043e612d921b62331946529ebf5f258949a4b34aa799 --account ./account --keystore ./keys
starkli call --watch $CONTRACT_ADDRESS get_stat_upgrades_available $ADVENTURER_ID 0 --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
```
16 changes: 8 additions & 8 deletions contracts/game_entropy/src/game_entropy.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl ImplGameEntropy of IGameEntropy {
block_number_diff * 3600 / block_timestamp_diff
}

/// @notice Calculate the current rate of blocks produced per hour, based on a ten-minute window.
/// @notice Calculate the current rate of blocks produced per hour, based on a thirty minute window.
/// @return The number of blocks produced per hour.
#[inline(always)]
fn current_blocks_per_hour(self: GameEntropy) -> u64 {
Expand Down Expand Up @@ -179,17 +179,17 @@ mod tests {
let hash = 0x123;
let last_updated_block = 282360;
let last_updated_time = 1696209920;
let next_update_block = 282364;
let next_update_block = 282380;

let game_entropy = GameEntropy {
hash, last_updated_block, last_updated_time, next_update_block,
};

let adventurer_idle_blocks = 3;
let adventurer_idle_blocks = 4;
let is_idle = game_entropy.is_adventurer_idle(adventurer_idle_blocks);
assert(!is_idle, 'should not be idle');

let adventurer_idle_blocks = 4;
let adventurer_idle_blocks = 6;
let is_idle = game_entropy.is_adventurer_idle(adventurer_idle_blocks);
assert(is_idle, 'should be idle');
}
Expand All @@ -208,15 +208,15 @@ mod tests {

// next entropy rotation is in 3 blocks which is 10 minutes
// at 1 block per 3mins (20 blocks per hour)
assert(next_entropy_rotation == 4, 'wrong rotation, slow speed');
assert(next_entropy_rotation == 11, 'wrong rotation, slow speed');

// starknet expects to eventually be producing blocks every 30s (2 per min, 120 per hour)
let blocks_per_hour = 120;
let next_entropy_rotation = ImplGameEntropy::calculate_next_update_block(
current_block, blocks_per_hour
);
// after this blockspeed, ten minutes is now 20 blocks in the future
assert(next_entropy_rotation == 21, 'wrong rotation, fast speed');
assert(next_entropy_rotation == 61, 'wrong rotation, fast speed');
}

#[test]
Expand All @@ -229,9 +229,9 @@ mod tests {
next_update_block: 282481,
};
let blocks_per_hour = game_entropy.current_blocks_per_hour();
assert(blocks_per_hour == 96, 'wrong blocks per hour')
assert(blocks_per_hour == 32, 'wrong blocks per hour')
}

#[test]
#[available_gas(29280)]
fn test_calculate_blocks_per_hour() {
Expand Down
14 changes: 8 additions & 6 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/bin/bash

export STARKNET_NETWORK=alpha-goerli
export STARKNET_WALLET=starkware.starknet.wallets.open_zeppelin.OpenZeppelinAccount
export CAIRO_COMPILER_DIR=~/.cairo/target/release/
export CAIRO_COMPILER_ARGS=--add-pythonic-hints
# Source env vars
ENV_FILE="/workspaces/loot-survivor/.env"
source $ENV_FILE

scarb contracts/game/build
# build game contract
cd /workspaces/loot-survivor/contracts/
scarb build

starknet declare --contract contracts/game/target/dev/game_Game.sierra.json --account deployer_4
# declare game contract
starkli declare --watch /workspaces/loot-survivor/target/dev/game_Game.contract_class.json --account $STARKNET_ACCOUNT --private-key $PRIVATE_KEY
64 changes: 64 additions & 0 deletions scripts/starkli_setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
ENV_FILE="/workspaces/loot-survivor/.env"

# If there is already an account in .env, skip that
if grep -q "^ACCOUNT_ADDRESS=" "$ENV_FILE"; then
echo "Account already setup, exiting"
exit
fi

echo "LORDS_ADDRESS=0x059dac5df32cbce17b081399e97d90be5fba726f97f00638f838613d088e5a47" > $ENV_FILE
echo "DAO_ADDRESS=0x059dac5df32cbce17b081399e97d90be5fba726f97f00638f838613d088e5a47" >> $ENV_FILE

# these are mainnet contracts. If you are running on testnet, please update these to right contracts
echo "GOLDEN_TOKEN_ADDRESS=0x04f5e296c805126637552cf3930e857f380e7c078e8f00696de4fc8545356b1d" >> $ENV_FILE
echo "BEASTS_ADDRESS=0x0158160018d590d93528995b340260e65aedd76d28a686e9daa5c4e8fad0c5dd" >> $ENV_FILE

echo "ADVENTURER_ID=1" >> $ENV_FILE

echo "STRENGTH=0" >> $ENV_FILE
echo "DEXTERITY=1" >> $ENV_FILE
echo "VITALITY=2" >> $ENV_FILE
echo "WISDOM=3" >> $ENV_FILE
echo "INTELLIGENCE=4" >> $ENV_FILE
echo "CHARISMA=5" >> $ENV_FILE


# initialize starknet directories
mkdir -p $HOME/.starknet
STARKNET_ACCOUNT=$HOME/.starknet/account
STARKNET_KEYSTORE=$HOME/.starknet/keystore

# Change directory to starkli
cd /root/.starkli/bin/

# Generate keypair
output=$(./starkli signer gen-keypair)

# Store keys as vars so we can use them and later write to .bashrc
private_key=$(echo "$output" | awk '/Private key/ {print $4}')
public_key=$(echo "$output" | awk '/Public key/ {print $4}')

# Initialize OZ account and save output
account_output=$(./starkli account oz init $STARKNET_ACCOUNT --private-key $private_key 2>&1)
account_address=$(echo "$account_output" | grep -oE '0x[0-9a-fA-F]+')

# Deploy Account
./starkli account deploy $STARKNET_ACCOUNT --private-key $private_key

# Output key and account info
echo "Private Key: $private_key"
echo "Public Key: $public_key"
echo "Account: $account_address"

# Add keys and account to .bashrc as env vars for easy access in shell
echo "PRIVATE_KEY=\"$private_key\"" >> $ENV_FILE
echo "PUBLIC_KEY=\"$public_key\"" >> $ENV_FILE
echo "ACCOUNT_ADDRESS=\"$account_address\"" >> $ENV_FILE
echo "STARKNET_ACCOUNT=$STARKNET_ACCOUNT" >> $ENV_FILE
echo "STARKNET_KEYSTORE=$STARKNET_KEYSTORE" >> $ENV_FILE

echo "set -o allexport" >> ~/.bashrc
echo "source $ENV_FILE" >> ~/.bashrc
echo "set +o allexport" >> ~/.bashrc

source ~/.bashrc

0 comments on commit 760fa5f

Please sign in to comment.