GM world rollup β
π Introduction β
This tutorial will guide you through building a sovereign gm-world
rollup (gm
stands for "good morning") using Rollkit. Unlike the quick start guide, this tutorial provides a more practical approach to understanding sovereign rollup development.
We will cover:
- Building and configuring a Cosmos-SDK application-specific rollup blockchain.
- Posting rollup data to a Data Availability (DA) network.
- Executing transactions (the end goal).
No prior understanding of the build process is required, just that it utilizes the Cosmos SDK for blockchain applications.
TIP
This tutorial explores Rollkit, currently in Alpha. If you encounter bugs, please report them via a GitHub issue ticket or reach out in our Telegram group.
π οΈ Dependencies β
If you followed the quick start guide, you should have the Rollkit CLI and Golang installed already. If not, here's the script for you:
curl -sSL https://rollkit.dev/install.sh | sh -s v0.13.4
π Running a local DA network β
Learn to run a local DA network, designed for educational purposes, on your machine.
To set up a local DA network node:
curl -sSL https://rollkit.dev/install-local-da.sh | bash -s v0.2.0
This script builds and runs the node, now listening on port 7980
.
ποΈ Building Your Sovereign Rollup β
With the local DA network running, letβs prepare your rollup blockchain.
To make it simple, we will download a repository with a gm-world
rollup that has all app chain config set up for you:
cd $HOME && bash -c "$(curl -sSL https://rollkit.dev/install-gm-rollup.sh)"
π§° Configuring your rollup β
Generate rollkit.toml file by running:
cd $HOME/gm && rollkit toml init
The output should be similar to this:
Found rollup entrypoint: /root/gm/cmd/gmd/main.go, adding to rollkit.toml
Could not find rollup config under gm. Please put the chain.config_dir in the rollkit.toml file manually.
Initialized rollkit.toml file in the current directory.
From the output, you can see that the rollup entrypoint is ~/gm/cmd/gmd/main.go
.
Open the rollkit.toml file and under the [chain]
section set config_dir
to the ./.gm
directory. Your rollkit.toml file should look like this:
entrypoint = "./cmd/gmd/main.go"
[chain]
config_dir = "./.gm"
π Starting your rollup β
Start the rollup, posting to the local DA network:
rollkit start --rollkit.aggregator --rollkit.da_address http://localhost:7980
Notice how we specified the DA network address. Now you should see the logs of the running node:
12:21PM INF starting node with ABCI CometBFT in-process module=server
12:21PM INF starting node with Rollkit in-process module=server
12:21PM INF service start impl=multiAppConn module=proxy msg="Starting multiAppConn service"
12:21PM INF service start connection=query impl=localClient module=abci-client msg="Starting localClient service"
12:21PM INF service start connection=snapshot impl=localClient module=abci-client msg="Starting localClient service"
12:21PM INF service start connection=mempool impl=localClient module=abci-client msg="Starting localClient service"
12:21PM INF service start connection=consensus impl=localClient module=abci-client msg="Starting localClient service"
12:21PM INF service start impl=EventBus module=events msg="Starting EventBus service"
12:21PM INF service start impl=PubSub module=pubsub msg="Starting PubSub service"
12:21PM INF Using default mempool ttl MempoolTTL=25 module=BlockManager
12:21PM INF service start impl=IndexerService module=txindex msg="Starting IndexerService service"
12:21PM INF service start impl=RPC module=server msg="Starting RPC service"
12:21PM INF service start impl=Node module=server msg="Starting Node service"
12:21PM INF starting P2P client module=server
12:21PM INF serving HTTP listen address=127.0.0.1:26657 module=server
12:21PM INF listening on address=/ip4/127.0.0.1/tcp/26656/p2p/12D3KooWSicdPmMTLf9fJbSSHZc9UVP1CbNqKPpbYVbgxHvbhAUY module=p2p
12:21PM INF listening on address=/ip4/163.172.162.109/tcp/26656/p2p/12D3KooWSicdPmMTLf9fJbSSHZc9UVP1CbNqKPpbYVbgxHvbhAUY module=p2p
12:21PM INF no seed nodes - only listening for connections module=p2p
12:21PM INF working in aggregator mode block time=1000 module=server
12:21PM INF Creating and publishing block height=22 module=BlockManager
12:21PM INF starting gRPC server... address=127.0.0.1:9290 module=grpc-server
12:21PM INF finalized block block_app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=22 module=BlockManager num_txs_res=0 num_val_updates=0
12:21PM INF executed block app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=22 module=BlockManager
12:21PM INF indexed block events height=22 module=txindex
...
Good work so far, we have a Rollup node, DA network node, now we can start submitting transactions.
πΈ Transactions β
First, list your keys:
rollkit keys list --keyring-backend test
You should see an output like the following
- address: gm17rpwv7lnk96ka00v93rphhvcqqztpn896q0dxx
name: alice
pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A5WPM5WzfNIPrGyha/TlHt0okdlzS1O4Gb1d1kU+xuG+"}'
type: local
- address: gm1r2udsh4za7r7sxvzy496qfazvjp04j4zgytve3
name: bob
pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A+jOX/CWInFer2IkqgXGo0da9j7Ubq+e1LJWzTMDjwdt"}'
type: local
For convenience we export two of our keys like this:
export KEY1=gm17rpwv7lnk96ka00v93rphhvcqqztpn896q0dxx
export KEY2=gm1r2udsh4za7r7sxvzy496qfazvjp04j4zgytve3
Now let's submit a transaction that sends coins from one account to another (don't worry about all the flags, for now, we just want to submit transaction from a high-level perspective):
rollkit tx bank send $KEY2 $KEY1 42069stake --keyring-backend test --chain-id gm --fees 5000stake
You'll be prompted to accept the transaction:
auth_info:
fee:
amount: []
gas_limit: "200000"
granter: ""
payer: ""
signer_infos: []
tip: null
body:
extension_options: []
memo: ""
messages:
- '@type': /cosmos.bank.v1beta1.MsgSend
amount:
- amount: "42069"
denom: stake
from_address: gm1r2udsh4za7r7sxvzy496qfazvjp04j4zgytve3
to_address: gm17rpwv7lnk96ka00v93rphhvcqqztpn896q0dxx
non_critical_extension_options: []
timeout_height: "0"
signatures: []
confirm transaction before signing and broadcasting [y/N]:
Confirm and sign the transaction as prompted. now you see the transaction hash at the output:
//...
txhash: 677CAF6C80B85ACEF6F9EC7906FB3CB021322AAC78B015FA07D5112F2F824BFF
βοΈ Checking Balances β
Query balances after the transaction:
rollkit query bank balances $KEY1
The receiverβs balance should show an increase.
balances:
- amount: "42069"
denom: stake
pagination:
next_key: null
total: "0"
For the senderβs balance:
rollkit query bank balances $KEY2
Output:
balances:
- amount: "99957931"
denom: stake
pagination:
next_key: null
total: "0"
π Next steps β
Congratulations! You've built a local rollup that posts to a local DA network. So far so good, keep diving deeper if you like it. Good luck!