Live testing in Seoulnet: baking with tz4 consensus keys

As the Seoul protocol upgrade proposal advances through the Tezos L1 governance process, we invite bakers to test and experiment with its new features, notably Aggregated Attestations.

This new feature of the Tezos protocol opens the door for significant improvements to L1’s performance and security. Achieving them requires bakers to adopt tz4 consensus and DAL companion keys (BLS signature scheme) for signing consensus operations and blocks.

In this post, we will set up BLS consensus keys and DAL companion keys for a Seoulnet test baker, and explore how attestation aggregation is reflected on the network.

We assume here you do have a baker running on Seoulnet. We will fiddle with Germán’s (one of our TechRel team members) today. That said, we are always looking for new testnet bakers :wink: All it takes is an idle old machine gaining dust somewhere, and a bit of time to follow this tutorial.

If we haven’t convinced you…You can still follow these steps, and retrace their outcome using tzkt.io Seoulnet’s deployment.

Preliminaries: An Octez baker up and running smoothly on Seoulnet (no aggregation).

Protocol test networks like Seoulnet offer a perfect environment for testing early how upcoming protocol proposals would affect our baking setups.

In the next section, we assume we have already:

  • Installed Octez v23.0, and configured the node to join Seoulnet.
  • Set up a baking key, and correctly deployed a DAL node and a baker.

You can follow the steps in this tutorial to get you to this point.

Indeed, let’s double check we are ready to go:

:white_check_mark: We are using the right version of Octez:

~ $ octez-node --version
dc9bed35 (2025-08-21 14:02:20 +0200) (Octez 23.0)

:white_check_mark: Our baking key is active, and has been given baking rights:

The easiest way to check when/if the baker has been given consensus rights is using a block explorer: the Schedule and Rewards tabs for a baker should show that you have rights 2 cycles into the future.

Otherwise, we can always follow the information provided by the delegates RPC endpoint.

~ $ octez-client rpc get /chains/main/blocks/head/context/delegates/tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb

Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

{ "deactivated": false, "is_forbidden": false,
  "participation":
    { "expected_cycle_activity": 50886, "minimal_cycle_activity": 33924,
      "missed_slots": 0, "missed_levels": 0,
      "remaining_allowed_missed_slots": 16962,
      "expected_attesting_rewards": "4417210116" },

# Cutting the rest here...

The baker is indeed not deactivated nor forbidden to participate in consensus. In the participation field, we can see it has been assigned attesting rights (a global number of total slots). As a bonus, we haven’t missed any attestation so far this cycle :flexed_biceps:

:white_check_mark: The DAL node has been configured correctly, with our baking key listed as attester-profiles , it is well connected and receiving allocated shards.

The attester profile can be asserted by checking the DAL node or, alternatively, by verifying the DAL node is being run with such parameter):

~ $ cat /opt/tezos/.tezos-dal-node/config.json 
{ "data-dir": "/opt/tezos/.tezos-dal-node", "public-addr": "127.0.0.1:11732",
  "endpoint": "http://127.0.0.1:8732",
  "profiles":
    { "kind": "controller",
      "controller_profile":
        { "kind": "controller",
          "controller_profiles":
            { "attesters": [ "tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb" ] } } },
  "version": 2 }

As there is a DAL producer pushing data to the DAL regularly on Seoulnet, we should see messages like this in our logs.

Aug 20 09:24:39.378 NOTICE │ Finalized block BKksUjyztJtox3bqgWuWBXoo5XGobf9zPcKmYQ1yvUyQtbvm1DD at level 861793, round 0
Aug 20 09:24:43.322 NOTICE │ For slots 0 published at level 861790, tz1TGKSrZrBpN got all its shards.
Aug 20 09:24:43.466 NOTICE │ tz1TGKSrZrBpN attested slot(s) 0 at attested level 861794.
Aug 20 09:24:43.467 NOTICE │ Finalized block BLdJcueZR1xF9vVKsSnyhUqq1PQn3REPrThL1WnsYbGqczE5zC2 at level 861794, round 0
Aug 20 09:24:43.941 NOTICE │ For slots 0 published at level 861788, tz1TGKSrZrBpN got all its shards.
Aug 20 09:24:43.943 NOTICE │ For slots 0 published at level 861789, tz1TGKSrZrBpN got all its shards.
Aug 20 09:24:43.971 NOTICE │ For slots 0 published at level 861790, tz1TGKSrZrBpN got all its shards.
Aug 20 09:24:47.267 NOTICE │ For slots 0 published at level 861791, tz1TGKSrZrBpN got all its shards.
Aug 20 09:24:47.283 NOTICE │ For slots 0 published at level 861791, tz1TGKSrZrBpN got all its shards.
Aug 20 09:24:47.382 NOTICE │ tz1TGKSrZrBpN attested slot(s) 0 at attested level 861795.

:white_check_mark: Baker is injecting attestations (with DAL payload) correctly:

Aug 20 09:15:23.484 NOTICE │ injected attestation (with DAL) for level 861656, round 0 for delegate
Aug 20 09:15:23.484 NOTICE │ 'ledger_german' (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb) with consensus key
Aug 20 09:15:23.484 NOTICE │ 'ledger_german' (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb)
Aug 20 09:15:23.484 NOTICE │ (operation hash: ooTv6okJ3yBpZRBDoEBye4x29DpaMaHcDP22cg3xqjrteyXqD58)
Aug 20 09:15:27.264 NOTICE │ received new proposal BMY2nkMS3ebN2updh9jKykdaDYnTuiNQiNVEJXzWxhP4mgBE7gK at
Aug 20 09:15:27.264 NOTICE │ level 861657, round 0
Aug 20 09:15:27.289 NOTICE │ ready to attach DAL attestation for level 861657, round 0, with bitset 1 for
Aug 20 09:15:27.289 NOTICE │ tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb to attest slots published at level
Aug 20 09:15:27.289 NOTICE │ 861650
Aug 20 09:15:27.298 NOTICE │ injected preattestation for level 861657, round 0 for delegate
Aug 20 09:15:27.298 NOTICE │ 'ledger_german' (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb) with consensus key
Aug 20 09:15:27.298 NOTICE │ 'ledger_german' (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb)
Aug 20 09:15:27.298 NOTICE │ (operation hash: ooSPRDJ3AJoRWugdqEMGD24WJzwWU3Cq35CiYc6Gsm3ENE2cTYX)

:white_check_mark: One last holistic check: verifying the dal_participation endpoint

At this point, we are pretty sure the baker is configuring correctly. Still, scrolling further down on the result of the participation endpoint query we used before, we find the dal_participation field.

We can also query this field alone with:

~ octez-client rpc get /chains/main/blocks/head/context/delegates/tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb/dal_participation
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

{ "expected_assigned_shards_per_slot": 3721,
  "delegate_attested_dal_slots": 182, "delegate_attestable_dal_slots": 182,
  "expected_dal_rewards": "981439797", "sufficient_dal_participation": true,
  "denounced": false } 

This provides a summary of the baker’s DAL attesting activity so far in the current cycle. We had insofar been assigned 182 attestable, and we have included the correct DAL payload in all of them. We also see that we currently qualify for being allowed the expected_dal_rewards at the end of the cycle—provided we keep up the good work.

Troubleshooting point: if your baker is not correctly submitting DAL attestations (for instance, if the bitset is 0 in the baker log output above), or the DAL logs reports missed shards… don’t hesitate to go through common pitfalls in this troubleshooting guide.

All systems are green. Let’s go!

Setting up tz4 consensus and DAL companion keys

Aggregated Attestations is a new feature included in the Seoul protocol proposal, which enables significant efficiency gains by allowing individual attestations in a block to be summarized into a single operation, instead of having one operation per attesting baker.

However, this feature relies on properties of the BLS cryptographic scheme, so only attestations signed with tz4 addresses can be aggregated. Existing bakers whose baking keys are powered by a different curve, like Germán’s `tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb`, can set up a tz4 address as a consensus key to take advantage of the feature.

In this article our baker will use 2 distinct fresh tz4 addresses that we will need to generate. As this is a testnet setup, we are (somewhat) comfortable with using hot, unencrypted keys, stored in the Octez CLI wallet—Please don’t do this on mainnet.

The 2 tz4 addresses will serve different purposes:

  • One will serve as the baker’s consensus key. Consensus keys are used to sign consensus operations (preattestations and attestations) and blocks on behalf of the baker. By default, the manager (or baking key) of the baker is also its consensus key. Setting up a separate consensus key allows for better separation of concerns, and increases the security of baking deployments: consensus key cannot stake/unstake, transfer funds, or participate in governance—these capabilities are limited to the manager key. Consensus keys also enable adopting new operational features, such as Aggregated Attestations, without needing to migrate the baking key.

  • The other will serve as its DAL companion key. This is a new type of auxiliary key, introduced by the Seoul protocol proposal. It serves to sign the DAL attestation payload for bakers actively participating in the Tezos DAL, when a baker is using a tz4 address to sign consensus operations and blocks. Bakers using tz1/tz2/tz3 addresses as consensus do not need to define a DAL companion key. If declared, the DAL companion key must be different from the consensus key.

Setting up a tz4 consensus key

We start by generating a fresh tz4 address, and save it as consensus_key as follows:

~ $ octez-client gen keys consensus_key -s bls

This results in a new key being generated, whose address we assess immediately

~ $ octez-client show address consensus_key
Warning:

             `This is NOT the Tezos Mainnet.`  

       `Do NOT use your fundraiser keys on this network.`

Hash: tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7
Public Key: BLpk1wiReQSN3PzrwQafTtFD4szTnszesNPSaro3q2myQETj2BH1HUUA76VytNqD8YczqX1DyX8t

The next step is to set the key as the consensus key, this can be done with the command line as follows:

~ $ octez-client set consensus key for ledger_german to consensus_key
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

Node is bootstrapped.
Estimated gas: 1744.502 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'opAfoU8pQT3oE1J2rMRYmjYGBBtxArnpvC9gJCq3eLdizaTC464'
Waiting for the operation to be included...
Operation found in block: BLmEq1Jm77aaxFdyGRkqsopZ6gKks9HUHfnaSxB8RzJih3j3nzK (pass: 3, offset: 0)
This sequence of operations was run:
  Manager signed operations:
    From: tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb
    Fee to the baker: ꜩ0.000559
    Expected counter: 12
    Gas limit: 1845
    Storage limit: 0 bytes
    Balance updates:
      tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb ... -ꜩ0.000559
      payload fees(the block proposer) ....... +ꜩ0.000559
    Update_consensus_key:
      Public key hash: tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7
      Proof of possession: BLsig9xscHaxrAhMnaS9uhWFXbwDZxi6MvAXMpZ5XjYmu7gfCznYxduDnPkmuz99LAk2xdbYwe3zw9MMJhVdLJ1DbdXETtzZ9nVTqJNsDHnTid1QwjKws32tpU6SEipWA687uJp2kuKNth
      This consensus key update was successfully applied
      Consumed gas: 1744.436

The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
  octez-client wait for opAfoU8pQT3oE1J2rMRYmjYGBBtxArnpvC9gJCq3eLdizaTC464 to be included --confirmations 1 --branch BMCbMZ1fM8gmNt8rErCBk62FVinERAJFdtrpNm6r1ZaaY2fjpBi
and/or an external block explorer.

While the operation was immediately included in the blockchain, it still needs a few cycles to take effect, and the baking key or any previous consensus key, will be active for the current cycle and all other cycles for which consensus rights have already been computed. In Seoulnet and mainnet, this means it will become active in 3 cycles—Here, on cycle 3322.

We can verify this using the consensus key RPC endpoint:

~ $ octez-client rpc get /chains/main/blocks/head/context/delegates/tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb/consensus_key
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

{ "active":
    { "pkh": "tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb",
      "pk": "edpkvG8RpyhnPi3ugWWvavsKwR79rb7iMvedeFNxBdyCvenTDZeC9n" },
  "pendings":
    [ { "cycle": 3322, "pkh": "tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7",
        "pk":
          "BLpk1wiReQSN3PzrwQafTtFD4szTnszesNPSaro3q2myQETj2BH1HUUA76VytNqD8YczqX1DyX8t" } ] }

Setting up a tz4 DAL companion key

Now, we repeat the process from the previous section and generate a fresh tz4 address, dal_companion, to be used as the DAL companion key:

~ $ octez-client gen keys dal_companion -s bls
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

~ $ octez-client show address dal_companion
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

Hash: tz4CJsoQMDZVvAcEQEFjFcBU5hZuoeVz2aLd
Public Key: BLpk1vF6GZqiqdAwA78upao7AYNuyJcKQbTJ6FXYp97bAjKPRrcVT9LZebacVMpg2tkgEow4k1K4

Starting with v23.0, the Octez client implements a new command allowing the declaration of DAL companion keys, in a similar way to consensus keys:

~ $ octez-client set companion key for ledger-german to dal_companion
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

Node is bootstrapped.
Estimated gas: 1744.502 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'ooPWA9tV8gz9PqEjgmiZ5QHUDS5WbvCZzdLXwFxaZu9cbR4uZsg'
Waiting for the operation to be included...
Operation found in block: BMd8nGTTQ4VrcKvdTazmrmQmyZ8MDGDWAdJtCnmePRzUJdtp15W (pass: 3, offset: 0)
This sequence of operations was run:
  Manager signed operations:
    From: tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb
    Fee to the baker: ꜩ0.000559
    Expected counter: 13
    Gas limit: 1845
    Storage limit: 0 bytes
    Balance updates:
      tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb ... -ꜩ0.000559
      payload fees(the block proposer) ....... +ꜩ0.000559
    Update_companion_key:
      Public key hash: tz4CJsoQMDZVvAcEQEFjFcBU5hZuoeVz2aLd
      Proof of possession: BLsig9df5P5Rg3TJxEGuBYrUXuDHfLDUnd1MY3ahdPvaPX47pjv8vutXGAzZLQswLDncqGJTxnZYRU5q8WAF3G34Ypxb4mz28QNFTStgRKcze2Uehm275AXaQjMYnSo58qL26fQm7xm997
      This companion key update was successfully applied
      Consumed gas: 1744.436

The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
  octez-client wait for ooPWA9tV8gz9PqEjgmiZ5QHUDS5WbvCZzdLXwFxaZu9cbR4uZsg to be included --confirmations 1 --branch BLsgfqNXgWgRU4WX5hUQ6ZLSUtqraCv3AvDoxL3Gx4hbUtuvi1m
and/or an external block explorer.

Indeed, the DAL companion key has the same delay as the consensus key in terms of becoming active. We can check the expected activation cycle on the block explorer, or using the companion_key RPC endpoint:

~ $ octez-client rpc get /chains/main/blocks/head/context/delegates/tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb/companion_key
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

{ "pendings":
    [ { "cycle": 3323, "pkh": "tz4CJsoQMDZVvAcEQEFjFcBU5hZuoeVz2aLd",
        "pk":
          "BLpk1vF6GZqiqdAwA78upao7AYNuyJcKQbTJ6FXYp97bAjKPRrcVT9LZebacVMpg2tkgEow4k1K4" } ] }

:warning: At this point, we need to make sure that we update our baking deployment to take the new keys into account, and restart the baking binary. For instance, by adapting our baker binary run command to take the new keys.

octez-baker run with local node /opt/tezos/.tezos-node --liquidity-baking-toggle-vote on --adaptive-issuance-vote on --dal-node http://127.0.0.1:10732 ledger_german consensus_key dal_companion

Note that the baking key ledger_german will be the active consensus keys for a few more cycles, so we need to keep it as well. There is no risk of double signing involved by supplying both ledger_german and consensus_key, as only one key can be the active consensus key in a cycle. The same restriction is enforced for DAL companion keys.

Aside. One should also notice we are using the new protocol-independent baker binary :slightly_smiling_face: This is a new addition to the Octez suite, released with v23.0. The protocol-independent baker and accuser binaries simplify baking operations, as we don’t need to modify deployments to select the protocol-specific clients. It also reduces the need to deploy both current and next protocol binaries around protocol activations. Instead, the protocol-independent binaries track the active protocol and react appropriately!

Aggregated attestations at work

A few cycles later, our changes have kicked in. Indeed the baker logs show that we are signing blocks, preattestations, and attestations with the consensus and dal companion keys:

Aug 26 15:54:29.620 NOTICE │ injected attestation (with DAL) for level 997041, round 0 for delegate 'ledger_german' (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb) with consensus key
Aug 26 15:54:29.620 NOTICE │   'consensus_key' (tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7) and companion key 'dal_companion' (tz4CJsoQMDZVvAcEQEFjFcBU5hZuoeVz2aLd)
Aug 26 15:54:29.620 NOTICE │   (operation hash: ooGuXnhSq8H73pjvRZDCtHFq6V4MjNurhAENU9EUyp2bodoHpvU)
Aug 26 15:54:32.410 NOTICE │ Voting on for liquidity baking toggle vote
Aug 26 15:54:32.411 NOTICE │ Voting pass for adaptive issuance vote
Aug 26 15:54:33.002 NOTICE │ block BLYvpjZNzktevGcnxoWJ5DEnoWKrpVkV9pFxHWv4mQDdH9uUh7R at level 997042, round 0 injected for delegate 'ledger_german' (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb) with consensus key
Aug 26 15:54:33.002 NOTICE │   'consensus_key' (tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7)
Aug 26 15:54:33.025 NOTICE │ received new proposal BLYvpjZNzktevGcnxoWJ5DEnoWKrpVkV9pFxHWv4mQDdH9uUh7R at level 997042, round 0
Aug 26 15:54:33.040 NOTICE │ ready to attach DAL attestation for level 997042, round 0, with bitset 1 for tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb to attest slots published at level 997035
Aug 26 15:54:33.061 NOTICE │ injected preattestation for level 997042, round 0 for delegate 'ledger_german' (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb) with consensus key
Aug 26 15:54:33.061 NOTICE │   'consensus_key' (tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7) (operation hash: ooi9pFRXeJq5UfEYyGsEQmnkDybHMP6MLUSeFfaSB82sUZJ7eZ8)
Aug 26 15:54:33.112 NOTICE │ received new head BLYvpjZNzktevGcnxoWJ5DEnoWKrpVkV9pFxHWv4mQDdH9uUh7R at level 997042, round 0
Aug 26 15:54:33.132 NOTICE │ new block (BLYvpjZNzktevGcnxoWJ5DEnoWKrpVkV9pFxHWv4mQDdH9uUh7R) on proposal period (remaining period duration 158)

Indeed, we can again use the participation and dal_participation RPC endpoints to check we are attesting correctly:

~ $ octez-client rpc get /chains/main/blocks/head/context/delegates/tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb/participation
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

{ "expected_cycle_activity": 52552, "minimal_cycle_activity": 35034,
  "missed_slots": 0, "missed_levels": 0,
  "remaining_allowed_missed_slots": 17518,
  "expected_attesting_rewards": "4569606608" }
~ $ octez-client rpc get /chains/main/blocks/head/context/delegates/tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb/dal_participation
Warning:
  
                 This is NOT the Tezos Mainnet.
  
           Do NOT use your fundraiser keys on this network.

{ "expected_assigned_shards_per_slot": 3843,
  "delegate_attested_dal_slots": 37, "delegate_attestable_dal_slots": 38,
  "expected_dal_rewards": "1015347501", "sufficient_dal_participation": true,
  "denounced": false }

The migration to tz4 consensus and DAL companion keys was indeed successful :flexed_biceps:

So what’s different now?

With Seoul, attestations signed by tz4 addresses are propagated as other attestations in the mempools and network, but they should be aggregated in blocks – blocks with non-aggregated attestations signed by tz4 addresses are not valid!

The designated baker will collect attestations like ooGuXnhSq8H73pjvRZDCtHFq6V4MjNurhAENU9EUyp2bodoHpvU above, and aggregate them into a single aggregated attestation, opYQQ8gro6MxxvDWCMykBQ2bDeSQSdrECKfkZGFE7X59pj92z6a, when producing the block. The JSON for the aggregated attestation results:

    { "protocol": "PtSeouLouXkxhg39oWzjxDWaCydNfR3RxCUrNe4Q9Ro8BTehcbh",
      "chain_id": "NetXd56aBs1aeW3",
      "hash": "opYQQ8gro6MxxvDWCMykBQ2bDeSQSdrECKfkZGFE7X59pj92z6a",
      "branch": "BKtgbwebgB7JFD5EzTG8Khdm5cM2PLD9XcE3vdbonbcFbgvyEA8",
      "contents":
        [ { "kind": "attestations_aggregate",
            "consensus_content":
              { "level": 997040, "round": 0,
                "block_payload_hash":
                  "vh1w1LEnfcESyNgJaeUbvWNps6uEeAq67dyvpkKZ36T8UVujHar7" },
            "committee":
              [ { "slot": 4, "dal_attestation": "1" },
                { "slot": 8, "dal_attestation": "1" }, { "slot": 23 },
                { "slot": 27, "dal_attestation": "1" },
                { "slot": 51, "dal_attestation": "1" },
                { "slot": 57, "dal_attestation": "1" },
                { "slot": 378, "dal_attestation": "1" }, { "slot": 1411 },
                { "slot": 3682 } ],
            "metadata":
              { "committee":
                  [ { "delegate": "tz1Zt8QQ9aBznYNk5LUBjtME9DuExomw9YRs",
                      "consensus_pkh": "tz4XbGtqxNZDq6CJNVbxktoqSTu9Db6aXQHL",
                      "consensus_power": 2022 },
                    { "delegate": "tz3PgFHdYvEGEbUo1pUJmuNH8fgc8cwARKfC",
                      "consensus_pkh": "tz4EWkmNN93yE7HrjaRR6mGh22rUgSYJG1Sj",
                      "consensus_power": 887 },
                    { "delegate": "tz4MvCEiLgK6vYRSkug9Nz64UNTbT4McNq8m",
                      "consensus_pkh": "tz4MvCEiLgK6vYRSkug9Nz64UNTbT4McNq8m",
                      "consensus_power": 756 },
                    { "delegate": "tz1NNT9EERmcKekRq2vdv6e8TL3WQpY8AXSF",
                      "consensus_pkh": "tz4X5GCfEHQCUnrBy9Qo1PSsmExYHXxiEkvp",
                      "consensus_power": 596 },
                    { "delegate": "tz4HG14YMihpZxynRXu7tK72hoz3mnnXZGzm",
                      "consensus_pkh": "tz4HG14YMihpZxynRXu7tK72hoz3mnnXZGzm",
                      "consensus_power": 77 },
                    { "delegate": "tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb",
                      "consensus_pkh": "tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7",
                      "consensus_power": 181 },
                    { "delegate": "tz1QU72xcAVpv4qntQZ3tgBHSwNomktKDnsV",
                      "consensus_pkh": "tz4HRf3jYhfo8W3D4ppUCWjAi2rw7jPSZ234",
                      "consensus_power": 12 },
                    { "delegate": "tz4GVPvRjU74WK6PvZrvb9jrSnqDykyj7eHc",
                      "consensus_pkh": "tz4GVPvRjU74WK6PvZrvb9jrSnqDykyj7eHc",
                      "consensus_power": 17 },
                    { "delegate": "tz4DLnQQ9XvmgrVGFZ72JFAckPcozpUWarXc",
                      "consensus_pkh": "tz4DLnQQ9XvmgrVGFZ72JFAckPcozpUWarXc",
                      "consensus_power": 1 } ],
                "total_consensus_power": 4549 } } ],
      "signature":
        "BLsigAzBSt6HvJZbXQSNpqF6ntyNqTJYS2WXZuiHv51hXfb543Fx349maNRDpFJKEhqa9CFv7nRV9spqGKsN9oSyU1v3QdSVV7ZXfDwrsJFH3hQVuHZ4ry1Qun2hw75QNFZ3gctYfG8ooe" } ],

Looking at the contents, we identify that:

  • The operation is indeed an aggregated attestation for level 997040.
  • It aggregates the attestations from nine bakers, listing their tz4 consensus address, consensus power (the number of consensus slots attested), and index slot (the first slot they attest at that level).
  • For seven out of the nine bakers, it also includes a dal_attestation payload. This means that the remaining two bakers either haven’t deployed a DAL node, or haven’t configured their DAL companion key correctly.
  • The operation JSON also includes the total consensus power of the aggregated attestation, here: 4549/7000. This is equivalent to roughly 65% of consensus power compressed into a single attestation.

Finally, we can assert that our attestation ooGuXnhSq8H73pjvRZDCtHFq6V4MjNurhAENU9EUyp2bodoHpvU was included in the aggregate; that Germán (tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb) was correctly included in the committee; and that the DAL payload, signed using dal_companion, was correctly included:

{ "delegate": "tz1TGKSrZrBpND3PELJ43nVdyadoeiM1WMzb",
                      "consensus_pkh": "tz4Hgy9DDhKJzBDe5kg3VW1no766scaz7nU7",
                      "consensus_power": 181 }


{ "slot": 57, "dal_attestation": "1" },

Here, we used the chains/main/blocks/997040/helpers/attestation_rights RPC endpoint to identify the baker’s attestation index slot (57) at the attested level.

The dal_attestation payload is a bitset encoding the attested slots. As we saw earlier, here we are attesting only the DAL slot 0 which is the only one that was in use in the network at the moment… Hence, the value of 1.

Take home

In this post, we explored how to set up tz4 addresses as consensus and DAL companion keys with the Seoul protocol, and took a look at how aggregation works under the hood.

We hope this article helps clear any doubts bakers might have as to how this new feature of the Seoul protocol would affect baking operations.

Now it’s your turn. We invite you all to continue testing your baking setups on Seoulnet—and don’t hesitate to reach out in the thread below with more questions.

Looking forward to seeing your attestations aggregated!

5 Likes