From 342d58df9b0c8d7ce2b98172ef3fee53bed675de Mon Sep 17 00:00:00 2001 From: Tyler <48813565+technicallyty@users.noreply.github.com> Date: Fri, 15 Aug 2025 11:03:33 -0700 Subject: [PATCH 1/5] upgrade script --- local_node.sh | 403 +++++++++++++++++++++++++++----------------------- 1 file changed, 222 insertions(+), 181 deletions(-) mode change 100755 => 100644 local_node.sh diff --git a/local_node.sh b/local_node.sh old mode 100755 new mode 100644 index 7ccfa247a..7c3420ff2 --- a/local_node.sh +++ b/local_node.sh @@ -2,19 +2,14 @@ CHAINID="${CHAIN_ID:-9001}" MONIKER="localtestnet" -# Remember to change to other types of keyring like 'file' in-case exposing to outside world, -# otherwise your balance will be wiped quickly -# The keyring test does not require private key to steal tokens from you KEYRING="test" KEYALGO="eth_secp256k1" LOGLEVEL="info" -# Set dedicated home directory for the evmd instance CHAINDIR="$HOME/.evmd" BASEFEE=10000000 -# Path variables CONFIG_TOML=$CHAINDIR/config/config.toml APP_TOML=$CHAINDIR/config/app.toml GENESIS=$CHAINDIR/config/genesis.json @@ -22,201 +17,247 @@ TMP_GENESIS=$CHAINDIR/config/tmp_genesis.json # validate dependencies are installed command -v jq >/dev/null 2>&1 || { - echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/" - exit 1 + echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/" + exit 1 } -# used to exit on first error (any non-zero exit code) set -e -# Parse input flags +# ------------- Flags ------------- install=true overwrite="" BUILD_FOR_DEBUG=false +ADDITIONAL_USERS=0 +MNEMONIC_FILE="" # default later to $CHAINDIR/mnemonics.yaml + +usage() { + cat < Overwriting the previous chain data." - overwrite="y" - shift # Move past the flag - ;; - -n) - echo "Flag -n passed -> Not overwriting the previous chain data." - overwrite="n" - shift # Move past the argument - ;; - --no-install) - echo "Flag --no-install passed -> Skipping installation of the evmd binary." - install=false - shift # Move past the flag - ;; - --remote-debugging) - echo "Flag --remote-debugging passed -> Building with remote debugging options." - BUILD_FOR_DEBUG=true - shift # Move past the flag - ;; - *) - echo "Unknown flag passed: $key -> Exiting script!" - exit 1 - ;; - esac + key="$1" + case $key in + -y) + echo "Flag -y passed -> Overwriting the previous chain data." + overwrite="y"; shift + ;; + -n) + echo "Flag -n passed -> Not overwriting the previous chain data." + overwrite="n"; shift + ;; + --no-install) + echo "Flag --no-install passed -> Skipping installation of the evmd binary." + install=false; shift + ;; + --remote-debugging) + echo "Flag --remote-debugging passed -> Building with remote debugging options." + BUILD_FOR_DEBUG=true; shift + ;; + --additional-users) + if [[ -z "${2:-}" || "$2" =~ ^- ]]; then + echo "Error: --additional-users requires a number."; usage; exit 1 + fi + ADDITIONAL_USERS="$2"; shift 2 + ;; + --mnemonic-file) + if [[ -z "${2:-}" || "$2" =~ ^- ]]; then + echo "Error: --mnemonic-file requires a path."; usage; exit 1 + fi + MNEMONIC_FILE="$2"; shift 2 + ;; + -h|--help) + usage; exit 0 + ;; + *) + echo "Unknown flag passed: $key -> Aborting"; usage; exit 1 + ;; + esac done if [[ $install == true ]]; then - if [[ $BUILD_FOR_DEBUG == true ]]; then - # for remote debugging the optimization should be disabled and the debug info should not be stripped - make install COSMOS_BUILD_OPTIONS=nooptimization,nostrip - else - make install - fi + if [[ $BUILD_FOR_DEBUG == true ]]; then + make install COSMOS_BUILD_OPTIONS=nooptimization,nostrip + else + make install + fi fi -# User prompt if neither -y nor -n was passed as a flag -# and an existing local node configuration is found. +# Prompt if -y was not passed to original invocation if [[ $overwrite = "" ]]; then - if [ -d "$CHAINDIR" ]; then - printf "\nAn existing folder at '%s' was found. You can choose to delete this folder and start a new local node with new keys from genesis. When declined, the existing local node is started. \n" "$CHAINDIR" - echo "Overwrite the existing configuration and start a new local node? [y/n]" - read -r overwrite - else - overwrite="y" - fi + if [ -d "$CHAINDIR" ]; then + printf "\nAn existing folder at '%s' was found. You can choose to delete this folder and start a new local node with new keys from genesis. When declined, the existing local node is started. \n" "$CHAINDIR" + echo "Overwrite the existing configuration and start a new local node? [y/n]" + read -r overwrite + else + overwrite="y" + fi fi -# Setup local node if overwrite is set to Yes, otherwise skip setup -if [[ $overwrite == "y" || $overwrite == "Y" ]]; then - # Remove the previous folder - rm -rf "$CHAINDIR" - - # Set client config - evmd config set client chain-id "$CHAINID" --home "$CHAINDIR" - evmd config set client keyring-backend "$KEYRING" --home "$CHAINDIR" - - # myKey address 0x7cb61d4117ae31a12e393a1cfa3bac666481d02e | cosmos10jmp6sgh4cc6zt3e8gw05wavvejgr5pwjnpcky - # myKey's private key: 0xe9b1d63e8acd7fe676acb43afb390d4b0202dab61abec9cf2a561e4becb147de # gitleaks:allow - VAL_KEY="mykey" - VAL_MNEMONIC="gesture inject test cycle original hollow east ridge hen combine junk child bacon zero hope comfort vacuum milk pitch cage oppose unhappy lunar seat" - - # dev0 address 0xC6Fe5D33615a1C52c08018c47E8Bc53646A0E101 | cosmos1cml96vmptgw99syqrrz8az79xer2pcgp84pdun - # dev0's private key: 0x88cbead91aee890d27bf06e003ade3d4e952427e88f88d31d61d3ef5e5d54305 # gitleaks:allow - USER1_KEY="dev0" - USER1_MNEMONIC="copper push brief egg scan entry inform record adjust fossil boss egg comic alien upon aspect dry avoid interest fury window hint race symptom" - - # dev1 address 0x963EBDf2e1f8DB8707D05FC75bfeFFBa1B5BaC17 | cosmos1jcltmuhplrdcwp7stlr4hlhlhgd4htqh3a79sq - # dev1's private key: 0x741de4f8988ea941d3ff0287911ca4074e62b7d45c991a51186455366f10b544 # gitleaks:allow - USER2_KEY="dev1" - USER2_MNEMONIC="maximum display century economy unlock van census kite error heart snow filter midnight usage egg venture cash kick motor survey drastic edge muffin visual" - - # dev2 address 0x40a0cb1C63e026A81B55EE1308586E21eec1eFa9 | cosmos1gzsvk8rruqn2sx64acfsskrwy8hvrmafqkaze8 - # dev2's private key: 0x3b7955d25189c99a7468192fcbc6429205c158834053ebe3f78f4512ab432db9 # gitleaks:allow - USER3_KEY="dev2" - USER3_MNEMONIC="will wear settle write dance topic tape sea glory hotel oppose rebel client problem era video gossip glide during yard balance cancel file rose" - - # dev3 address 0x498B5AeC5D439b733dC2F58AB489783A23FB26dA | cosmos1fx944mzagwdhx0wz7k9tfztc8g3lkfk6rrgv6l - # dev3's private key: 0x8a36c69d940a92fcea94b36d0f2928c7a0ee19a90073eda769693298dfa9603b # gitleaks:allow - USER4_KEY="dev3" - USER4_MNEMONIC="doll midnight silk carpet brush boring pluck office gown inquiry duck chief aim exit gain never tennis crime fragile ship cloud surface exotic patch" - - # Import keys from mnemonics - echo "$VAL_MNEMONIC" | evmd keys add "$VAL_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" - echo "$USER1_MNEMONIC" | evmd keys add "$USER1_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" - echo "$USER2_MNEMONIC" | evmd keys add "$USER2_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" - echo "$USER3_MNEMONIC" | evmd keys add "$USER3_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" - echo "$USER4_MNEMONIC" | evmd keys add "$USER4_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" - - # Set moniker and chain-id for the example chain (Moniker can be anything, chain-id must be an integer) - echo "$VAL_MNEMONIC" | evmd init $MONIKER -o --chain-id "$CHAINID" --home "$CHAINDIR" --recover - - # Change parameter token denominations to desired value - jq '.app_state["staking"]["params"]["bond_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state["gov"]["params"]["min_deposit"][0]["denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state["gov"]["params"]["expedited_min_deposit"][0]["denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state["evm"]["params"]["evm_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state["mint"]["params"]["mint_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - - # Add default token metadata to genesis - jq '.app_state["bank"]["denom_metadata"]=[{"description":"The native staking token for evmd.","denom_units":[{"denom":"atest","exponent":0,"aliases":["attotest"]},{"denom":"test","exponent":18,"aliases":[]}],"base":"atest","display":"test","name":"Test Token","symbol":"TEST","uri":"","uri_hash":""}]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - - # Enable precompiles in EVM params - jq '.app_state["evm"]["params"]["active_static_precompiles"]=["0x0000000000000000000000000000000000000100","0x0000000000000000000000000000000000000400","0x0000000000000000000000000000000000000800","0x0000000000000000000000000000000000000801","0x0000000000000000000000000000000000000802","0x0000000000000000000000000000000000000803","0x0000000000000000000000000000000000000804","0x0000000000000000000000000000000000000805", "0x0000000000000000000000000000000000000806", "0x0000000000000000000000000000000000000807"]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - - # Set EVM config - jq '.app_state["evm"]["params"]["evm_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - - # Enable native denomination as a token pair for STRv2 - jq '.app_state.erc20.native_precompiles=["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state.erc20.token_pairs=[{contract_owner:1,erc20_address:"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",denom:"atest",enabled:true}]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - - # Set gas limit in genesis - jq '.consensus.params.block.max_gas="10000000"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' 's/timeout_propose = "3s"/timeout_propose = "2s"/g' "$CONFIG_TOML" - sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "200ms"/g' "$CONFIG_TOML" - sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "500ms"/g' "$CONFIG_TOML" - sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "200ms"/g' "$CONFIG_TOML" - sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "500ms"/g' "$CONFIG_TOML" - sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "200ms"/g' "$CONFIG_TOML" - sed -i '' 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$CONFIG_TOML" - sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "5s"/g' "$CONFIG_TOML" - else - sed -i 's/timeout_propose = "3s"/timeout_propose = "2s"/g' "$CONFIG_TOML" - sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "200ms"/g' "$CONFIG_TOML" - sed -i 's/timeout_prevote = "1s"/timeout_prevote = "500ms"/g' "$CONFIG_TOML" - sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "200ms"/g' "$CONFIG_TOML" - sed -i 's/timeout_precommit = "1s"/timeout_precommit = "500ms"/g' "$CONFIG_TOML" - sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "200ms"/g' "$CONFIG_TOML" - sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$CONFIG_TOML" - sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "5s"/g' "$CONFIG_TOML" - fi +# ---------- YAML writer ---------- +write_mnemonics_yaml() { + local file_path="$1"; shift + local -a mns=("$@") + mkdir -p "$(dirname "$file_path")" + { + echo "mnemonics:" + for m in "${mns[@]}"; do + printf ' - "%s"\n' "$m" + done + } > "$file_path" + echo "Wrote mnemonics to $file_path" +} - # enable prometheus metrics and all APIs for dev node - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' 's/prometheus = false/prometheus = true/' "$CONFIG_TOML" - sed -i '' 's/prometheus-retention-time = 0/prometheus-retention-time = 1000000000000/g' "$APP_TOML" - sed -i '' 's/enabled = false/enabled = true/g' "$APP_TOML" - sed -i '' 's/enable = false/enable = true/g' "$APP_TOML" - else - sed -i 's/prometheus = false/prometheus = true/' "$CONFIG_TOML" - sed -i 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML" - sed -i 's/enabled = false/enabled = true/g' "$APP_TOML" - sed -i 's/enable = false/enable = true/g' "$APP_TOML" - fi +# ---------- Add funded account ---------- +add_genesis_funds() { + local keyname="$1" + evmd genesis add-genesis-account "$keyname" 1000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" +} - # Change proposal periods to pass within a reasonable time for local testing - sed -i.bak 's/"max_deposit_period": "172800s"/"max_deposit_period": "30s"/g' "$GENESIS" - sed -i.bak 's/"voting_period": "172800s"/"voting_period": "30s"/g' "$GENESIS" - sed -i.bak 's/"expedited_voting_period": "86400s"/"expedited_voting_period": "15s"/g' "$GENESIS" - - # set custom pruning settings - sed -i.bak 's/pruning = "default"/pruning = "custom"/g' "$APP_TOML" - sed -i.bak 's/pruning-keep-recent = "0"/pruning-keep-recent = "100"/g' "$APP_TOML" - sed -i.bak 's/pruning-interval = "0"/pruning-interval = "10"/g' "$APP_TOML" - - # Allocate genesis accounts (cosmos formatted addresses) - evmd genesis add-genesis-account "$VAL_KEY" 100000000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" - evmd genesis add-genesis-account "$USER1_KEY" 1000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" - evmd genesis add-genesis-account "$USER2_KEY" 1000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" - evmd genesis add-genesis-account "$USER3_KEY" 1000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" - evmd genesis add-genesis-account "$USER4_KEY" 1000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" - - # Sign genesis transaction - evmd genesis gentx "$VAL_KEY" 1000000000000000000000atest --gas-prices ${BASEFEE}atest --keyring-backend "$KEYRING" --chain-id "$CHAINID" --home "$CHAINDIR" - ## In case you want to create multiple validators at genesis - ## 1. Back to `evmd keys add` step, init more keys - ## 2. Back to `evmd add-genesis-account` step, add balance for those - ## 3. Clone this ~/.evmd home directory into some others, let's say `~/.clonedOsd` - ## 4. Run `gentx` in each of those folders - ## 5. Copy the `gentx-*` folders under `~/.clonedOsd/config/gentx/` folders into the original `~/.evmd/config/gentx` - - # Collect genesis tx - evmd genesis collect-gentxs --home "$CHAINDIR" - - # Run this to ensure everything worked and that the genesis file is setup correctly - evmd genesis validate-genesis --home "$CHAINDIR" +# Setup local node if overwrite is set to Yes, otherwise skip setup +if [[ $overwrite == "y" || $overwrite == "Y" ]]; then + rm -rf "$CHAINDIR" + + evmd config set client chain-id "$CHAINID" --home "$CHAINDIR" + evmd config set client keyring-backend "$KEYRING" --home "$CHAINDIR" + + # ---------------- Validator key ---------------- + VAL_KEY="mykey" + VAL_MNEMONIC="gesture inject test cycle original hollow east ridge hen combine junk child bacon zero hope comfort vacuum milk pitch cage oppose unhappy lunar seat" + echo "$VAL_MNEMONIC" | evmd keys add "$VAL_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" + + # ---------------- Default dev keys ---------------- + USER1_KEY="dev0" + USER2_KEY="dev1" + USER3_KEY="dev2" + USER4_KEY="dev3" + + default_mnemonics=( + "copper push brief egg scan entry inform record adjust fossil boss egg comic alien upon aspect dry avoid interest fury window hint race symptom" # dev0 + "maximum display century economy unlock van census kite error heart snow filter midnight usage egg venture cash kick motor survey drastic edge muffin visual" # dev1 + "will wear settle write dance topic tape sea glory hotel oppose rebel client problem era video gossip glide during yard balance cancel file rose" # dev2 + "doll midnight silk carpet brush boring pluck office gown inquiry duck chief aim exit gain never tennis crime fragile ship cloud surface exotic patch" # dev3 + ) + + # Import default dev keys + echo "${default_mnemonics[0]}" | evmd keys add "$USER1_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" + echo "${default_mnemonics[1]}" | evmd keys add "$USER2_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" + echo "${default_mnemonics[2]}" | evmd keys add "$USER3_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" + echo "${default_mnemonics[3]}" | evmd keys add "$USER4_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" + + echo "$VAL_MNEMONIC" | evmd init $MONIKER -o --chain-id "$CHAINID" --home "$CHAINDIR" --recover + + # ---------- Genesis customizations ---------- + jq '.app_state["staking"]["params"]["bond_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + jq '.app_state["gov"]["params"]["min_deposit"][0]["denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + jq '.app_state["gov"]["params"]["expedited_min_deposit"][0]["denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + jq '.app_state["evm"]["params"]["evm_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + jq '.app_state["mint"]["params"]["mint_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + + jq '.app_state["bank"]["denom_metadata"]=[{"description":"The native staking token for evmd.","denom_units":[{"denom":"atest","exponent":0,"aliases":["attotest"]},{"denom":"test","exponent":18,"aliases":[]}],"base":"atest","display":"test","name":"Test Token","symbol":"TEST","uri":"","uri_hash":""}]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + + jq '.app_state["evm"]["params"]["active_static_precompiles"]=["0x0000000000000000000000000000000000000100","0x0000000000000000000000000000000000000400","0x0000000000000000000000000000000000000800","0x0000000000000000000000000000000000000801","0x0000000000000000000000000000000000000802","0x0000000000000000000000000000000000000803","0x0000000000000000000000000000000000000804","0x0000000000000000000000000000000000000805", "0x0000000000000000000000000000000000000806", "0x0000000000000000000000000000000000000807"]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + + jq '.app_state["evm"]["params"]["evm_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + + jq '.app_state.erc20.native_precompiles=["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + jq '.app_state.erc20.token_pairs=[{contract_owner:1,erc20_address:"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",denom:"atest",enabled:true}]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + + jq '.consensus.params.block.max_gas="10000000"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" + + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' 's/timeout_propose = "3s"/timeout_propose = "2s"/g' "$CONFIG_TOML" + sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "200ms"/g' "$CONFIG_TOML" + sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "500ms"/g' "$CONFIG_TOML" + sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "200ms"/g' "$CONFIG_TOML" + sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "500ms"/g' "$CONFIG_TOML" + sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "200ms"/g' "$CONFIG_TOML" + sed -i '' 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$CONFIG_TOML" + sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "5s"/g' "$CONFIG_TOML" + else + sed -i 's/timeout_propose = "3s"/timeout_propose = "2s"/g' "$CONFIG_TOML" + sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "200ms"/g' "$CONFIG_TOML" + sed -i 's/timeout_prevote = "1s"/timeout_prevote = "500ms"/g' "$CONFIG_TOML" + sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "200ms"/g' "$CONFIG_TOML" + sed -i 's/timeout_precommit = "1s"/timeout_precommit = "500ms"/g' "$CONFIG_TOML" + sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "200ms"/g' "$CONFIG_TOML" + sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$CONFIG_TOML" + sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "5s"/g' "$CONFIG_TOML" + fi + + # enable prometheus metrics and all APIs for dev node + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' 's/prometheus = false/prometheus = true/' "$CONFIG_TOML" + sed -i '' 's/prometheus-retention-time = 0/prometheus-retention-time = 1000000000000/g' "$APP_TOML" + sed -i '' 's/enabled = false/enabled = true/g' "$APP_TOML" + sed -i '' 's/enable = false/enable = true/g' "$APP_TOML" + else + sed -i 's/prometheus = false/prometheus = true/' "$CONFIG_TOML" + sed -i 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML" + sed -i 's/enabled = false/enabled = true/g' "$APP_TOML" + sed -i 's/enable = false/enable = true/g' "$APP_TOML" + fi + + # Change proposal periods + sed -i.bak 's/"max_deposit_period": "172800s"/"max_deposit_period": "30s"/g' "$GENESIS" + sed -i.bak 's/"voting_period": "172800s"/"voting_period": "30s"/g' "$GENESIS" + sed -i.bak 's/"expedited_voting_period": "86400s"/"expedited_voting_period": "15s"/g' "$GENESIS" + + # pruning + sed -i.bak 's/pruning = "default"/pruning = "custom"/g' "$APP_TOML" + sed -i.bak 's/pruning-keep-recent = "0"/pruning-keep-recent = "100"/g' "$APP_TOML" + sed -i.bak 's/pruning-interval = "0"/pruning-interval = "10"/g' "$APP_TOML" + + # Allocate genesis accounts for validator and default users + evmd genesis add-genesis-account "$VAL_KEY" 100000000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" + add_genesis_funds "$USER1_KEY" + add_genesis_funds "$USER2_KEY" + add_genesis_funds "$USER3_KEY" + add_genesis_funds "$USER4_KEY" + + # --------- Generate additional users if requested --------- + # final_mnemonics starts with defaults; we append generated ones next + final_mnemonics=("${default_mnemonics[@]}") + + if [[ -z "$MNEMONIC_FILE" ]]; then + MNEMONIC_FILE="$CHAINDIR/mnemonics.yaml" + fi + + if [[ "$ADDITIONAL_USERS" -gt 0 ]]; then + START_INDEX=4 # dev0..dev3 already exist + for ((i=0; i&1) + USER_MNEMONIC=$(echo "$MNEMONIC_OUTPUT" | grep -E '^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+' | tail -1) + if [[ -z "$USER_MNEMONIC" ]]; then + echo "Failed to capture mnemonic for $KEYNAME"; exit 1 + fi + + final_mnemonics+=("$USER_MNEMONIC") + add_genesis_funds "$KEYNAME" + echo "Created $KEYNAME" + done + fi + + # --------- Finalize genesis --------- + evmd genesis gentx "$VAL_KEY" 1000000000000000000000atest --gas-prices ${BASEFEE}atest --keyring-backend "$KEYRING" --chain-id "$CHAINID" --home "$CHAINDIR" + evmd genesis collect-gentxs --home "$CHAINDIR" + evmd genesis validate-genesis --home "$CHAINDIR" + + # --------- Write YAML with mnemonics (defaults + generated) --------- + write_mnemonics_yaml "$MNEMONIC_FILE" "${final_mnemonics[@]}" if [[ $1 == "pending" ]]; then echo "pending mode is on, please wait for the first block committed." From 069e6c52f35512d8444b1ae44bb615b9a58a44fa Mon Sep 17 00:00:00 2001 From: Tyler <48813565+technicallyty@users.noreply.github.com> Date: Fri, 15 Aug 2025 11:07:25 -0700 Subject: [PATCH 2/5] some comments --- local_node.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/local_node.sh b/local_node.sh index 7c3420ff2..8395ac3da 100644 --- a/local_node.sh +++ b/local_node.sh @@ -2,14 +2,19 @@ CHAINID="${CHAIN_ID:-9001}" MONIKER="localtestnet" +# Remember to change to other types of keyring like 'file' in-case exposing to outside world, +# otherwise your balance will be wiped quickly +# The keyring test does not require private key to steal tokens from you KEYRING="test" KEYALGO="eth_secp256k1" LOGLEVEL="info" +# Set dedicated home directory for the evmd instance CHAINDIR="$HOME/.evmd" BASEFEE=10000000 +# Path variables CONFIG_TOML=$CHAINDIR/config/config.toml APP_TOML=$CHAINDIR/config/app.toml GENESIS=$CHAINDIR/config/genesis.json @@ -21,6 +26,7 @@ command -v jq >/dev/null 2>&1 || { exit 1 } +# used to exit on first error (any non-zero exit code) set -e # ------------- Flags ------------- @@ -86,13 +92,15 @@ done if [[ $install == true ]]; then if [[ $BUILD_FOR_DEBUG == true ]]; then + # for remote debugging the optimization should be disabled and the debug info should not be stripped make install COSMOS_BUILD_OPTIONS=nooptimization,nostrip else make install fi fi -# Prompt if -y was not passed to original invocation +# User prompt if neither -y nor -n was passed as a flag +# and an existing local node configuration is found. if [[ $overwrite = "" ]]; then if [ -d "$CHAINDIR" ]; then printf "\nAn existing folder at '%s' was found. You can choose to delete this folder and start a new local node with new keys from genesis. When declined, the existing local node is started. \n" "$CHAINDIR" From c1aac612fcefdfd755fc61937a595cb330b4c91c Mon Sep 17 00:00:00 2001 From: Tyler <48813565+technicallyty@users.noreply.github.com> Date: Fri, 15 Aug 2025 14:27:33 -0700 Subject: [PATCH 3/5] allow mnemonics file input --- local_node.sh | 129 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 38 deletions(-) mode change 100644 => 100755 local_node.sh diff --git a/local_node.sh b/local_node.sh old mode 100644 new mode 100755 index 8395ac3da..54c798065 --- a/local_node.sh +++ b/local_node.sh @@ -34,7 +34,8 @@ install=true overwrite="" BUILD_FOR_DEBUG=false ADDITIONAL_USERS=0 -MNEMONIC_FILE="" # default later to $CHAINDIR/mnemonics.yaml +MNEMONIC_FILE="" # output file (defaults later to $CHAINDIR/mnemonics.yaml) +MNEMONICS_INPUT="" # input yaml to prefill dev keys usage() { cat < "$tmpfile" + + while IFS= read -r line; do + [[ -z "$line" ]] && continue + provided_mnemonics+=( "$line" ) + done < "$tmpfile" + rm -f "$tmpfile" + if [[ ${#provided_mnemonics[@]} -eq 0 ]]; then + echo "no mnemonics found in $MNEMONICS_INPUT (expected a list under 'mnemonics:')"; exit 1 + fi + fi + + # choose base list: prefer provided over defaults + if [[ ${#provided_mnemonics[@]} -gt 0 ]]; then + dev_mnemonics=("${provided_mnemonics[@]}") + else + dev_mnemonics=("${default_mnemonics[@]}") + fi + + # init chain w/ validator mnemonic echo "$VAL_MNEMONIC" | evmd init $MONIKER -o --chain-id "$CHAINID" --home "$CHAINDIR" --recover # ---------- Genesis customizations ---------- @@ -226,36 +273,40 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then sed -i.bak 's/pruning-keep-recent = "0"/pruning-keep-recent = "100"/g' "$APP_TOML" sed -i.bak 's/pruning-interval = "0"/pruning-interval = "10"/g' "$APP_TOML" - # Allocate genesis accounts for validator and default users - evmd genesis add-genesis-account "$VAL_KEY" 100000000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" - add_genesis_funds "$USER1_KEY" - add_genesis_funds "$USER2_KEY" - add_genesis_funds "$USER3_KEY" - add_genesis_funds "$USER4_KEY" + # fund validator (devs already funded in the loop) + evmd genesis add-genesis-account "$VAL_KEY" 100000000000000000000000000atest --keyring-backend "$KEYRING" --home "$CHAINDIR" - # --------- Generate additional users if requested --------- - # final_mnemonics starts with defaults; we append generated ones next - final_mnemonics=("${default_mnemonics[@]}") + # --------- maybe generate additional users --------- + # start with provided/default list + final_mnemonics=("${dev_mnemonics[@]}") + # default output path if not set if [[ -z "$MNEMONIC_FILE" ]]; then MNEMONIC_FILE="$CHAINDIR/mnemonics.yaml" fi if [[ "$ADDITIONAL_USERS" -gt 0 ]]; then - START_INDEX=4 # dev0..dev3 already exist + start_index=${#dev_mnemonics[@]} # continue after last provided/default entry for ((i=0; i&1)" + # try to grab a line that looks like a seed phrase (>=12 words), else last line + user_mnemonic="$(echo "$mnemonic_out" | grep -E '([[:alpha:]]+[[:space:]]+){11,}[[:alpha:]]+$' | tail -1)" + if [[ -z "$user_mnemonic" ]]; then + user_mnemonic="$(echo "$mnemonic_out" | tail -n 1)" + fi + user_mnemonic="$(echo "$user_mnemonic" | tr -d '\r')" - MNEMONIC_OUTPUT=$(evmd keys add "$KEYNAME" --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" 2>&1) - USER_MNEMONIC=$(echo "$MNEMONIC_OUTPUT" | grep -E '^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+' | tail -1) - if [[ -z "$USER_MNEMONIC" ]]; then - echo "Failed to capture mnemonic for $KEYNAME"; exit 1 - fi + if [[ -z "$user_mnemonic" ]]; then + echo "failed to capture mnemonic for $keyname"; exit 1 + fi - final_mnemonics+=("$USER_MNEMONIC") - add_genesis_funds "$KEYNAME" - echo "Created $KEYNAME" + final_mnemonics+=("$user_mnemonic") + add_genesis_funds "$keyname" + echo "created $keyname" done fi @@ -264,12 +315,14 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then evmd genesis collect-gentxs --home "$CHAINDIR" evmd genesis validate-genesis --home "$CHAINDIR" - # --------- Write YAML with mnemonics (defaults + generated) --------- - write_mnemonics_yaml "$MNEMONIC_FILE" "${final_mnemonics[@]}" + # --------- Write YAML with mnemonics if the user specified more --------- + if [[ "$ADDITIONAL_USERS" -gt 0 ]]; then + write_mnemonics_yaml "$MNEMONIC_FILE" "${final_mnemonics[@]}" + fi - if [[ $1 == "pending" ]]; then - echo "pending mode is on, please wait for the first block committed." - fi + if [[ $1 == "pending" ]]; then + echo "pending mode is on, please wait for the first block committed." + fi fi # Start the node From fbc3107b7e2c9febf178400ba4fcc269a9fedc82 Mon Sep 17 00:00:00 2001 From: Tyler <48813565+technicallyty@users.noreply.github.com> Date: Fri, 15 Aug 2025 17:27:03 -0700 Subject: [PATCH 4/5] fix script --- local_node.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/local_node.sh b/local_node.sh index 54c798065..7475535a4 100755 --- a/local_node.sh +++ b/local_node.sh @@ -98,6 +98,12 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -n "$MNEMONICS_INPUT" && "$ADDITIONAL_USERS" -gt 0 ]]; then + echo "Error: --mnemonics-input and --additional-users cannot be used together." + echo "Use --mnemonics-input to provide all dev account mnemonics, or use --additional-users to generate extra accounts." + exit 1 +fi + if [[ $install == true ]]; then if [[ $BUILD_FOR_DEBUG == true ]]; then # for remote debugging the optimization should be disabled and the debug info should not be stripped @@ -203,8 +209,10 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then # choose base list: prefer provided over defaults if [[ ${#provided_mnemonics[@]} -gt 0 ]]; then + echo "using provided mnemonics" dev_mnemonics=("${provided_mnemonics[@]}") else + echo "using default mnemonics" dev_mnemonics=("${default_mnemonics[@]}") fi @@ -285,6 +293,21 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then MNEMONIC_FILE="$CHAINDIR/mnemonics.yaml" fi + # Process all dev mnemonics (provided or default) + for ((i=0; i<${#dev_mnemonics[@]}; i++)); do + + keyname="dev${i}" + mnemonic="${dev_mnemonics[i]}" + + echo "adding key for $keyname" + + # Add key to keyring using the mnemonic + echo "$mnemonic" | evmd keys add "$keyname" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" + + # Fund the account in genesis + add_genesis_funds "$keyname" + done + if [[ "$ADDITIONAL_USERS" -gt 0 ]]; then start_index=${#dev_mnemonics[@]} # continue after last provided/default entry for ((i=0; i Date: Fri, 15 Aug 2025 17:50:46 -0700 Subject: [PATCH 5/5] add in the dev0-dev3s info --- local_node.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/local_node.sh b/local_node.sh index 7475535a4..f4376a26e 100755 --- a/local_node.sh +++ b/local_node.sh @@ -180,6 +180,17 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then echo "$VAL_MNEMONIC" | evmd keys add "$VAL_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$CHAINDIR" # ---------------- dev mnemonics source ---------------- + # dev0 address 0xC6Fe5D33615a1C52c08018c47E8Bc53646A0E101 | cosmos1cml96vmptgw99syqrrz8az79xer2pcgp84pdun + # dev0's private key: 0x88cbead91aee890d27bf06e003ade3d4e952427e88f88d31d61d3ef5e5d54305 # gitleaks:allow + + # dev1 address 0x963EBDf2e1f8DB8707D05FC75bfeFFBa1B5BaC17 | cosmos1jcltmuhplrdcwp7stlr4hlhlhgd4htqh3a79sq + # dev1's private key: 0x741de4f8988ea941d3ff0287911ca4074e62b7d45c991a51186455366f10b544 # gitleaks:allow + + # dev2 address 0x40a0cb1C63e026A81B55EE1308586E21eec1eFa9 | cosmos1gzsvk8rruqn2sx64acfsskrwy8hvrmafqkaze8 + # dev2's private key: 0x3b7955d25189c99a7468192fcbc6429205c158834053ebe3f78f4512ab432db9 # gitleaks:allow + + # dev3 address 0x498B5AeC5D439b733dC2F58AB489783A23FB26dA | cosmos1fx944mzagwdhx0wz7k9tfztc8g3lkfk6rrgv6l + # dev3's private key: 0x8a36c69d940a92fcea94b36d0f2928c7a0ee19a90073eda769693298dfa9603b # gitleaks:allow default_mnemonics=( "copper push brief egg scan entry inform record adjust fossil boss egg comic alien upon aspect dry avoid interest fury window hint race symptom" # dev0 "maximum display century economy unlock van census kite error heart snow filter midnight usage egg venture cash kick motor survey drastic edge muffin visual" # dev1