Skip to content
On this page

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:

bash
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:

bash
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:

bash
cd $HOME && bash -c "$(curl -sSL https://rollkit.dev/install-gm-rollup.sh)"

🧰 Configuring your rollup ​

Generate rollkit.toml file by running:

bash
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:

bash
entrypoint = "./cmd/gmd/main.go"

[chain]
  config_dir = "./.gm"

πŸš€ Starting your rollup ​

Start the rollup, posting to the local DA network:

bash
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:

bash
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:

bash
rollkit keys list --keyring-backend test

You should see an output like the following

bash
- 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:

bash
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):

bash
rollkit tx bank send $KEY2 $KEY1 42069stake --keyring-backend test --chain-id gm --fees 5000stake

You'll be prompted to accept the transaction:

bash
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:

bash
//...

txhash: 677CAF6C80B85ACEF6F9EC7906FB3CB021322AAC78B015FA07D5112F2F824BFF

βš–οΈ Checking Balances ​

Query balances after the transaction:

bash
rollkit query bank balances $KEY1

The receiver’s balance should show an increase.

bash
balances: 
- amount: "42069" 
  denom: stake
pagination:
  next_key: null
  total: "0"

For the sender’s balance:

bash
rollkit query bank balances $KEY2

Output:

bash
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!

Released under the APACHE-2.0 License