Builders Guide
Sequencer Operations
Sequencer Node Setup

Running a Sequencer Node

This guide provides detailed instructions on how to join GOAT Network and run a sequencer node(validator).

For the sake of clarity and to prevent any confusion, a sequencer node serves as the validator in this tutorial. The term "validator" is employed from the perspective of the decentralized network, whereas "sequencer node" is utilized from the perspective of the Bitcoin Layer 2 (L2).

System Requirements

Hardware Configuration

  • CPU: Equivalent to c5.2xlarge or similar
  • Storage:
    • Root directory with at least 40 GiB of space
    • EBS gp3, 100 GiB, 3000 IOPS, mount it to /data, and ensure that you can extend the size.

Network Configuration

  • IPv4 Elastic IP (EIP) required

Security Group Rules

PortDescriptionProtocolSource
30303goat-geth p2pUDP0.0.0.0/0
30303goat-geth p2pTCP0.0.0.0/0
26656goat p2pTCP0.0.0.0/0

Ensure your server's firewall and network security settings allow inbound traffic on these ports.

Software Environment

Deployment Steps

Run the node

Fetch the docker-compose.yml from Gist (opens in a new tab) according to your network type,

Start the services:

docker-compose up -d

You must back up your validator key at path /data/goat/config/priv_validator_key.json

Check your node status by the following command,

docker-compose exec goat goatd status | jq

Wait for "catching_up": false to confirm full sync

Becoming a validator

⚠️

Please note, we don't have a website to participate right now. Before you do below operations, you need to have enough Solidity and Linux operation experience.

Locking Process

  1. Get creation proof on your instance
GOAT_VALIATOR_OWNER=0x # use your own address instead
GOAT_GETH_CHAIN_ID=`docker-compose exec geth geth attach --exec 'Number(eth.chainId())'`
docker-compose exec goat goatd modgen locking sign --owner $GOAT_VALIATOR_OWNER --eth-chain-id $GOAT_GETH_CHA
IN_ID

the GOAT_VALIATOR_OWNER variable is the node administrator's EVM address which is responsible for locking, redemption, and other operations.

After the last command, you'll get below result:

{
 "owner": "0x",
 "pubkey": "0x2b4a44d655b6d5882f58997417320f98b9fcb9b9fb563ce089d462928a1bd0569359880e97221e5a8a1a5c1b4f012e61f4f75fc0937189600671532bcdb7cf0e",
 "signature": "0xe8d37ae31e755021b8dd63d1723730057998204d29a9f36b9464d82d3e47830051bca27cae8dd0ecd23e724ed74b031d0e14d1be3b9995f5a984dba947b2c3ee00",
 "validator": "0x3d2cc0ff49145113a46d576a269d291898c5138a"
}
  1. Establish the contact with GOAT Network team to approve the new validator. This step is necessary in GOAT Alpha Mainnet.

  2. Check if you have sufficient assets

Call creationThreshold() method of the Locking contract get the minimal locking amounts and ensure your wallet holds sufficient assets. Take creationThreshold() invocation on mainnet for example:

cast call --json --rpc-url https://rpc.goat.network 0xbC10000000000000000000000000000000000004 'creationThreshold()((address,uint256)[])'
[
  "[(0x0000000000000000000000000000000000000000, 500000000000000000)]"
]

where 0xbC10000000000000000000000000000000000004 is the offical Locking (opens in a new tab) contract address. For other networks, use corresponding --rpc-url instead.

On the response, the 0x0000000000000000000000000000000000000000 represents native token(Bitcoin), and the 500000000000000000 represents the minimum amount to create a validator. if the token address is not the zero address, you should approve the locking contract to allow the Locking contract can spend it.

  1. Register your validator

Call create() method of the Locking contract to register your validator with the command below on mainnet, change the --rpc-url if necessary.

ETH_RPC_URL=https://rpc.goat.network

VALIDATOR_PUBKEY=0x2b4a44d655b6d5882f58997417320f98b9fcb9b9fb563ce089d462928a1bd0569359880e97221e5a8a1a5c1b4f012e61f4f75fc0937189600671532bcdb7cf0e
VALIDATOR_SIGNATURE=0xe8d37ae31e755021b8dd63d1723730057998204d29a9f36b9464d82d3e47830051bca27cae8dd0ecd23e724ed74b031d0e14d1be3b9995f5a984dba947b2c3ee00
GOAT_LOCKING_CONTRACT=0xbC10000000000000000000000000000000000004
SIG_V=${VALIDATOR_SIGNATURE: -2}
SIG_V=$((16#$SIG_V + 27))
SIG_V=$(printf "0x%02X" "$SIG_V")

BITCOIN_LOCKING_VALUE=`cast call --json $GOAT_LOCKING_CONTRACT 'tokens(address)(bool,uint64,uint256,uint256)' '0x0000000000000000000000000000000000000000' | jq -r '.[3]'`

cast send -v --interactive --value $BITCOIN_LOCKING_VALUE $GOAT_LOCKING_CONTRACT 'create(bytes32[2],bytes32,bytes32,uint8)' \
  "[0x${VALIDATOR_PUBKEY:2:64},0x${VALIDATOR_PUBKEY:66:64}]" "0x${VALIDATOR_SIGNATURE:2:64}" "0x${VALIDATOR_SIGNATURE:66:64}" "${SIG_V}"

Refer to step 2 for the VALIDATOR_PUBKEY and VALIDATOR_SIGNATURE.

The code snippet provided in code example (opens in a new tab) is also included to execute the aforementioned operations, assuming familiarity with the Hardhat (opens in a new tab).

Support Resources