| story version | geth version |
|---|---|
| v1.5.2-stable | 1.2.1-stable |
Overview
Story Protocol (Story Network) is a purpose-built Layer-1 blockchain for intellectual property (IP), designed to make IP registration, licensing, and royalty distribution enforceable through smart contracts. The network is EVM-equivalent and built with the Cosmos SDK, with execution-level optimizations for working with graph-like relationship data (e.g., original works and their derivatives) so these relationships can be stored, traversed, and queried efficiently.
At the protocol level, IP is represented as an IP Asset implemented as an ERC-721 NFT. When an IP Asset is registered, it is paired with an IP Account based on a modified ERC-6551 (token-bound account) design. This account acts as the programmable container for the asset’s permissions and economic logic-such as licensing terms, royalty configuration, and links to derivative works.
Core protocol modules typically include:
-
A Licensing module that attaches a programmable license (commonly referred to as a Programmable IP License / PIL) to an IP Asset and enables issuance of License Tokens (ERC-721) to grant usage rights under defined terms.
-
A Derivative workflow where creating or registering a derivative can require consuming/burning the relevant License Token, establishing parent–child relationships on-chain.
-
A Royalty module that automates revenue sharing across related IP assets according to the configured rules.
-
A Dispute module (and supporting components) for handling challenges/flags and related governance processes.
In practice, Story Protocol positions itself as an IP-native L1 where ownership records, licensing permissions, derivative relationships, and royalties are managed on-chain through standardized assets and protocol modules-reducing reliance on manual, off-chain enforcement for these workflows.
Public Endpoints
| Type | Endpoint | Link |
|---|---|---|
| RPC | https://story-testnet-cosmos-rpc.crouton.digital/ | |
| API | https://story-testnet-cosmos-rest.crouton.digital/ | |
| Websocket | wss://story-testnet-cosmos-ws.crouton.digital | |
| peer | [email protected]:52656 | |
| JSON-RPC | https://story-testnet-evm-rpc.crouton.digital | |
| Websocket | wss://story-testnet-evm-ws.crouton.digital |
Hardware requirements
Recommended server specs for a Story Protocol validator: 32 GB RAM, 8 dedicated CPU cores, and at least 500 GB of NVMe storage.
Prepare
Update and install packages
sudo apt update && sudo apt upgrade -y && \ sudo apt install -y curl git wget jq make gcc clang tmux screen htop ncdu unzip tar lz4 bc build-essential pkg-config libssl-dev libleveldb-dev bsdmainutils fail2ban
Installing Go
VER="1.22.5" && \ cd $HOME && \ wget "https://golang.org/dl/go$VER.linux-amd64.tar.gz" && \ sudo rm -rf /usr/local/go && \ sudo tar -C /usr/local -xzf "go$VER.linux-amd64.tar.gz" && \ rm "go$VER.linux-amd64.tar.gz" && \ mkdir -p $HOME/go/bin && \ grep -qxF 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' $HOME/.bash_profile || echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> $HOME/.bash_profile && \ source $HOME/.bash_profile && \ go version
Binary
Download prebuilt binary
cd $HOME && \ rm -rf story-geth && \ mkdir -p $HOME/go/bin && \ wget -O story-geth https://github.com/piplabs/story-geth/releases/download/v1.2.1/geth-linux-amd64 && \ chmod +x $HOME/story-geth && \ mv $HOME/story-geth $HOME/go/bin/ && \ mkdir -p $HOME/.story/story $HOME/.story/geth && \ $HOME/go/bin/story-geth version
Building from source
cd $HOME && \ rm -rf story && \ git clone https://github.com/piplabs/story.git && \ cd story && \ git checkout v1.5.2 && \ go build -o story ./client && \ mkdir -p $HOME/go/bin && \ mv $HOME/story/story $HOME/go/bin/
Initialization
Initialize the node and create the default configuration files
story init --moniker MONIKER --network story
Replace MONIKER with your own validator name. This name will be used as your node’s identifier on the network.
Genesis
Download genesis
wget -O $HOME/.story/story/config/genesis.json https://storage.crouton.digital/mainnet/story/files/genesis.json
Addrbook
Download addrbook
wget -O $HOME/.story/story/config/addrbook.json https://storage.crouton.digital/mainnet/story/files/addrbook.json
Set the correct Story network name and execution engine endpoint in story.toml to ensure the consensus client connects properly to the local story-geth instance.
sed -i 's/^network *= *.*/network = "story"/' $HOME/.story/story/config/story.toml sed -i 's|^engine-endpoint *= .*|engine-endpoint = "http://localhost:26551"|' $HOME/.story/story/config/story.toml sed -i '/^\[api\]/,/^\[/{s/^enable *=.*/enable = true/}' $HOME/.story/story/config/story.toml
Services
Сreate geth service file
sudo tee /etc/systemd/system/story-geth.service > /dev/null <<EOF [Unit] Description=Story Geth daemon After=network-online.target [Service] User=root WorkingDirectory=/root/.story/geth ExecStart=/root/go/bin/story-geth --story --syncmode full \ --datadir /root/.story/geth \ --http --http.api eth,net,web3,engine --http.vhosts '*' \ --http.addr 0.0.0.0 --http.port 26545 \ --authrpc.port 26551 \ --ws --ws.api eth,web3,net,txpool \ --ws.addr 0.0.0.0 --ws.port 26546 \ --port 26303 Restart=on-failure RestartSec=3 LimitNOFILE=65535 [Install] WantedBy=multi-user.target EOF
Сreate story service file
sudo tee /etc/systemd/system/story.service > /dev/null <<EOF [Unit] Description=Story Service After=network.target [Service] Type=simple User=root WorkingDirectory=/root/.story/story ExecStart=/root/go/bin/story run \ --engine-endpoint http://localhost:26551 \ --engine-jwt-file /root/.story/geth/geth/jwtsecret \ --api-enable \ --api-address 0.0.0.0:1317 Restart=on-failure RestartSec=5 LimitNOFILE=65535 [Install] WantedBy=multi-user.target EOF
Restore node from snapshot
sudo apt install -y lz4 && \ sudo systemctl stop story story-geth && \ cp $HOME/.story/story/data/priv_validator_state.json $HOME/.story/story/priv_validator_state.json.backup && \ rm -rf $HOME/.story/story/data && \ curl -L https://storage.crouton.digital/mainnet/story/snapshots/story_latest.tar.lz4 | lz4 -dc - | tar -xf - -C $HOME/.story/story && \ mv $HOME/.story/story/priv_validator_state.json.backup $HOME/.story/story/data/priv_validator_state.json && \ rm -rf $HOME/.story/geth/story/geth/chaindata && \ mkdir -p $HOME/.story/geth/story/geth && \ curl -L https://storage.crouton.digital/mainnet/story/snapshots/geth_story_latest.tar.lz4 | lz4 -dc - | tar -xf - -C $HOME/.story/geth/story/geth
Enable and start geth-story
sudo systemctl daemon-reload && \ sudo systemctl enable story story-geth && \ sudo systemctl restart story-geth && \ sleep 5 && \ sudo systemctl restart story && \ sudo journalctl -u story -u story-geth -f -o cat
Create validator
View your validator key
story validator export
Export EVM private key
story validator export --export-evm-key
View EVM private key and make a key backup
cat $HOME/.story/story/config/private_key.txt
After importing your private key into a wallet such as MetaMask or Phantom, add the Story mainnet network and fund your wallet with IP tokens. Then copy your EVM address, send IP to it from an exchange or another wallet, and use the balance to pay for transactions and other on-chain operations.
Before creating a validator, wait for your node to get fully synced. Once "catching_up" is "false", move on to the next step
curl localhost:$(sed -n '/\[rpc\]/,/laddr/ { /laddr/ {s/.*://; s/".*//; p} }' $HOME/.story/story/config/config.toml)/status | jq
Create a secure directory for Story environment variables and open a protected story.env file to store your private key.
mkdir -p /root/.config/story chmod 700 /root/.config/story nano /root/.config/story/story.env
Add your private key to the story.env file.
PRIVATE_KEY=your_private_key
Secure the story.env file, load the private key into the current shell session, and verify that the PRIVATE_KEY variable is available.
chmod 600 /root/.config/story/story.env && \ set -a && \ source /root/.config/story/story.env && \ set +a && \ [ -n "$PRIVATE_KEY" ] && echo "PRIVATE_KEY is set" || echo "PRIVATE_KEY is empty"
story validator create \ --stake 1024000000000000000000 \ --moniker "MONIKER" \ --chain-id 1514 \ --story-api "http://localhost:1317" \ --unlocked=false
To create a validator, your wallet must hold at least 1024 IP for the required self-stake, plus a small additional amount of IP to cover transaction fees.


