GitHub Logo HIP-991: Permissionless revenue-generating Topic Ids for Topic Operators

Author Michael Kantor, Ty Smith
Working Group Michael Heinrichs
Requested By TierBot
Discussions-To https://github.com/hashgraph/hedera-improvement-proposal/pull/991
Status Accepted
Needs Council Approval Yes
Review period ends Wed, 24 Jul 2024 07:00:00 +0000
Type Standards Track
Category Core
Created 2024-06-14
Updated 2024-12-05

Abstract

This document outlines the development of a fixed fee system for the submission of topic messages on the Hedera network. It addresses the need for improved economic scalability and aims to enhance resource allocation and revenue distribution mechanisms for topic operators. It also seeks to simplify engineering complexity for dApp developers on the Hedera network.

Background and Motivation

Problems to Solve:

  • Dynamic Restriction of Access to Topic Writing: Users currently face difficulties when creating new topic IDs because they must choose between making the topic publicly writable for a very low cost or implementing a complex web architecture to manage access through the submit key. This complexity can hinder user experience and development efficiency.
  • Ease of Monetization: Developers and businesses find it challenging to charge users for submitting information to a topic due to the lack of a native fee structure. A built-in payment system would streamline monetization, allowing developers to easily charge for topic submissions, which can enhance the financial viability of their applications.
  • Resource Allocation: The current low fee of $0.0001 per message makes it difficult for topic operators to manage and predict the economic impact of high-traffic topics. Users can suffer from spam and unexpected messages that operators have to handle, potentially degrading the quality of service.
  • Token and HBAR Utilization: There is an opportunity to expand the utility of various tokens within the Hedera ecosystem. By allowing fees to be paid in tokens other than HBAR, such as those required by DAOs, users can leverage their token holdings for topic submissions, enhancing the ecosystem’s flexibility and user engagement.

Feature Summary:

  • HCS topics can have an optional fee for submitting messages. Fees can be set in HBAR or HTS fungible tokens.
  • HCS topics have now a new Fee Schedule Key. This key can manage fee updates. The key can be set at creation time and updated later (similarly to HTS tokens). If the HCS topic was created without a Fee Schedule Key, it cannot be added later.
  • Topic fees can be distributed similarly to fixed fees on the HTS, supporting multiple wallets and Fungible tokens in addition to HBAR.
  • HCS topics can have a list of keys that are allowed to send free messages.
  • Security measures to prevent unauthorized access to fee configurations and distributions.
  • Security measures to prevent users from being induced to pay unforeseen charges.
  • Distribution of collected fees akin to fixed fees on tokens, with support for distribution to multiple account IDs.

Benefits:

  • Provides predictable revenue per message for topic operators.
  • Enables new products and business models on HCS.
  • Increases node revenue for network fees tied to new HCS transactions/topic creations with fixed fees.
  • Enhances the utility of HCS within Hedera.
  • Increases revenue streams for node operators.
  • Enables simple facilitation of holding and spending tokens to document new information on a topic.

Related Requests:

This enhancement is in response to community feedback (Tier Bot) requesting more versatile and predictable economic models within topic IDs on the Hedera network.

User personas and stories

User Personas:

  • Topic Operator: Entities or individuals who manage and operate topics, interested in stable revenue and easy management of topic-related transactions.
  • Topic Operator: Entities or individuals who manage and operate topics, interested in reducing the noise of public topic IDs/making it more difficult to spam an open topic.
  • Regular User: End users who interact with topics, adding paid methods of interaction and submission to topics.

User Stories:

  • As a Topic Operator, I want to set a fixed fee for submitting messages to my topic, so that I can ensure a consistent revenue stream and manage my topic effectively.
  • As a Regular User, I want to know the exact cost of interacting with a topic.

Specification

Overview

We propose adding a fixed fee mechanism to the Hedera Consensus Service (HCS) for topic messages, similar to the custom fee structures in the Hedera Token Service (HTS). This will involve creating new protocol buffers (protobuf) messages and modifying existing ones to accommodate fixed fees for topics.

Requirements and Scope

Main

  • Topics may have fees for submitting messages.

Fees Definition

  • Fees are defined as a list of custom fee.
  • The list of custom fees can contain a maximum of MAX_CUSTOM_FEE_ENTRIES_FOR_TOPICS entries.
  • A custom fee is defined leveraging the HTS’s FixedFee data structure (see ConsensusCustomFee).
  • A custom fee can be set in HBAR or HTS fungible tokens and must have an accountID as the receiver.

Fee Management

  • Fees can be set at creation time.
  • Fees can be changed (updated or removed) in a topic with an update topic transaction signed by the Fee Schedule Key.
  • Topics can have a Fee Schedule Key set at creation time.
  • The Fee Schedule Key can manage fee updates for the topic.
  • The Fee Schedule Key can be updated according to the same rules that currently apply to the Submit key. In addition, to update the Fee Schedule Key, the new key must sign the transaction.
  • If the topic was created without a Fee Schedule Key, the key cannot be added later.

Fee Payment

  • A ConsensusSubmitMessageTransactionBody will include a new optional field max_custom_fee that a user can set to limit the paid custom fees.
  • The account submitting a message to the topic will cover network transaction fees, and if necessary, a custom fee. The topic initiates the transfer of the custom fee to the fee collector using a synthetic CryptoTransfer, moving funds from the message sender’s account to the designated fee collector.
  • If the fee of submitting a message exceeds the max_custom_fee, the transaction will fail with an appropriate error. The sender still pays node and network fees for failed transactions.
  • No balance will be held by the topic itself. Funds remain in the sender’s account, and insufficient funds will result in the message submission failing with an appropriate error. The sender still pays node and network fees for failed transactions.

Fee Exclusions

  • Topics can have a Fee Exempt Key List
  • The Fee Exempt Key List can be set at creation time
  • The Fee Exempt Key List can be updated with a ConsensusUpdateTopicTransaction signed by the topic’s Admin Key
  • The Fee Exempt Key List has a maximum of MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST entries.
  • If a TopicMessageSubmitTransaction is submitted to the network and it contains a signature from a key included in the Fee Exempt Key List, no fees will be charged for that message.
Handling Duplicates

If the Fee Exempt Key List contains duplicate keys, the ConsensusCreateTopicTransaction, respectively ConsensusUpdateTopicTransaction, will fail with a FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS error. This ensures that duplicate entries are not silently ignored, preventing potential bugs or issues in the calling code.

Signatures for Invalid/Inactive/Deleted Accounts

The Fee Exempt Key List will only require keys to be formally valid as per protobuf specifications, meaning they must be correctly formatted key structures. These are keys, not accounts. Even if an account associated with a key is inactive, deleted, or non-existent, the key itself can still be added to the Fee Exempt Key List.

Threshold Keys

Threshold keys are supported in the Fee Exempt Key List. To avoid paying custom fees, the threshold must be met, meaning that the number of required signatures from the Fee Exempt Key List must be satisfied for a message submission. Any valid threshold key configuration will be processed normally.

Pre-Filled Keys in Fee Exempt Key List

When creating a topic, the Fee Exempt Key List is independent and must be explicitly populated. By default, the Fee Exempt Key List will not include the Admin Key, Submit Key, or Fee Schedule Key, unless explicitly provided in the creation or update transaction. The SDK might suggest default behavior, but the HIP doesn’t enforce automatic inclusion of these keys in the Fee Exempt Key List.

HIP Parameters

The HIP parameters are defined as follow:

  • MAX_CUSTOM_FEE_ENTRIES_FOR_TOPICS = 10
  • MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST = 10

User Flows and Interaction

  • Users will specify the fee settings during the topic creation process through a simple interface in their Hedera client (refer to the creation of token custom fees/fixed fee for reference).
  • When submitting a message to a topic with custom fees through an application or wallet interface, users must set the maximum fee for the message. Alternatively, users can add a flag to accept all custom fees from a topic id. If the topic has no custom fees, neither is required.
  • In case of user wallets, applications show the custom fees to the user before submitting the message.
  • Operators will get fee collections and distributions automatically through the custom fees just like they do in the token service currently.

New and Modified Protobuf Messages

The following is a list of modifications to the protobuf messages structure to comply with the above requirements.

ConsensusCustomFee

The ConsensusCustomFee message defines the type of fee and the account ID receiving the fee assessed during a message submission to the associated topic. A custom fee may only be a FixedFee and must specify a fee collector account to receive the assessed fees. FixedFee is an existing protobuf message and it must not be modified.

message ConsensusCustomFee {
  /**
  * Fixed fee to be charged
  */
  FixedFee fixed_fee = 1;

  /**
  * The account to receive the custom fee
  */
  AccountID fee_collector_account_id = 2;
}

ConsensusCreateTopicTransactionBody

The ConsensusCreateTopicTransactionBody message is updated to include the optional Fee Schedule Key, the optional Fee Exempt Key List, and the custom_fees property for specifying fixed fees during topic creation.

message ConsensusCreateTopicTransactionBody {
  [...]

  /**
    * Access control for update/delete of custom fees. Null if there is no key.
    */
  Key fee_schedule_key = 8;

  /**
    * If the transaction contains a signer from this list, no custom fees are applied.
    */
  repeated Key fee_exempt_key_list = 9;

  /**
    * The custom fee to be assessed during a message submission to this topic. Empty if no custom fees are applied.
    */
  repeated ConsensusCustomFee custom_fees = 10;
}

ConsensusUpdateTopicTransactionBody

The ConsensusUpdateTopicTransactionBody message is updated to include the optional Fee Schedule Key, the optional Fee Exempt Key List, and the custom_fees property for specifying fixed fees during topic update.

message ConsensusUpdateTopicTransactionBody {
  [..]
  /**
    * Access control for update/delete of custom fees. Null if the key should not be updated.
    */
  Key fee_schedule_key = 10;

  /**
    * If the transaction contains a signer from this list, no custom fees are applied. Null if the list should not be updated.
    */
  FeeExemptKeyList fee_exempt_key_list = 11;

  /*
   * The custom fee to be assessed during a message submission to this topic. Null if the fees should not be updated.
   */
  ConsensusCustomFeeList custom_fees = 12;

}

message FeeExemptKeyList {
  repeated Key keys = 1;
}

message ConsensusCustomFeeList {
  repeated ConsensusCustomFee fees = 1;
}

ConsensusSubmitMessageTransactionBody

The ConsensusSubmitMessageTransactionBody message is updated to include the optional max_custom_fees property for specifying the maximum fee that the user is willing to pay for the message.

message ConsensusSubmitMessageTransactionBody {
  [..]
  /**
    * The maximum custom fee that the user is willing to pay for the message. This field will be ignored if `accept_all_custom_fees` is set to `true`.
    */
  repeated FixedFee max_custom_fees = 4;
  
  /**
   * If set to true, the transaction will accept all custom fees from the topic id
   */
  bool accept_all_custom_fees = 5;
}

ConsensusTopicInfo

The ConsensusTopicInfo message is updated to include the Fee Schedule Key and the current list of custom fixed fees associated with the topic.

message ConsensusTopicInfo {
  [...]
  /**
    * Access control for update/delete of custom fees. Null if there is no key.
    */
  Key fee_schedule_key = 10;

  /**
    * If the transaction contains a signer from this list, no custom fees are applied.
    */
  repeated Key fee_exempt_key_list = 11;

  /*
   * The custom fee to be assessed during a message submission to this topic
   */
  repeated ConsensusCustomFee custom_fees = 12;
}

Mirror Node

To comply with this HIP, the Mirror Node provides the following features:

  • Support for querying a topic’s custom fees via REST APIs.
  • Custom fees should be able to be queried by topic, in the same structure as custom fees exist and can be queried on token entities.

REST API changes

  • /api/v1/topics/{topicId}
    • Changes to the body of the response. The response should include three new fields: fee_schedule_key, fee_exempt_key_list, and custom_fee. The fields will expose any data defined in their corresponding protobuffer definition. A sample response payload follows.
    {
      "admin_key": {
        "_type": "ProtobufEncoded",
        "key": "421050820e1485acdd59726088e0e4a2130ebbbb70009f640ad95c78dd5a7b38"
      },
      "auto_renew_account": "0.0.2",
      "auto_renew_period": 7776000,
      "created_timestamp": "1586567700.453054000",
      "custom_fees": {
        "created_timestamp": "1234567890.000000001",
        "fixed_fees": [
          {
            "amount": 100,
            "collector_account_id": "0.1.5",
            "denominating_token_id": "0.10.8"
          }
        ]
      },
      "deleted": false,
      "fee_exempt_key_list": [
        {
          "_type": "ProtobufEncoded",
          "key": "421050820e1485acdd59726088e0e4a2130ebbbb70009f640ad95c78dd5a7b38"
        },
        {
          "_type": "ProtobufEncoded",
          "key": "421050820e1485acdd59726088e0e4a2130ebbbb70009f640ad95c78dd5a7b39"
        }
      ],
      "fee_schedule_key": {
        "_type": "ProtobufEncoded",
        "key": "421050820e1485acdd59726088e0e4a2130ebbbb70009f640ad95c78dd5a7b38"
      },
      "memo": "topic memo",
      "submit_key": {
        "_type": "ProtobufEncoded",
        "key": "421050820e1485acdd59726088e0e4a2130ebbbb70009f640ad95c78dd5a7b38"
      },
      "timestamp": {
        "from": "1586567700.453054000",
        "to": "1586567700.453054000"
      },
      "topic_id": "0.0.2"
    }
    

SDKs

This document does not include the details of the implementation updates required by the SDKs to comply with the HIP-991 specifications. However, a suggested example for the JavaScript SDK is described in the SDK Reference Implementation section.

Backwards Compatibility

The HIP introduces new features while ensuring compatibility and integration with existing Hedera network protocols and services. New topics with custom fees will require appropriate updates to the Hedera SDKs, mirror nodes, and applications to support the new fee structures. There are no known backward compatibility issues. Existing topics without custom fees will continue to function as they currently do.

Security Implications

The introduction of custom fees adds another layer of economic control, but also introduces potential vectors for abuse, such as fee manipulation. To address these issues, this HIP adheres to current security requirements regarding the authorization of moving user funds. In particular, the user can set a maximum charge for each message.

How to Teach This

TBD

SDK Reference Implementation

The following is a pseudo code example for creating a topic with a fixed fee, setting the fee, and sending a message.

// Create the Hedera client
const client = Client.forTestnet();

// Define the submit key
const submitKey = PrivateKey.generate();

// Define the fee collector account ID
const feeCollectorAccountId = AccountId.fromString("0.0.12345");

// Define the fixed fee
const topicCustomFee = new TopicCustomFee()
  .setAmount(100) // 100 tokens are transferred to the fee collecting account each time a message is submitted to the topic
  .setDenominatingTokenId(TokenId.fromString("0.0.56789")) // // The token to charge the fee in. HBAR if unset
  .setFeeCollectorAccountId(feeCollectorAccountId); // 100 tokens are sent to this account for each HCS message to the topic

// Create the topic with the custom fee
const transactionResponse = await new TopicCreateTransaction()
  .setTopicMemo("Example Topic with Fixed Fee")
  .setTopicCustomFees([topicCustomFee]) // List of custom fees. In this example, a single fixed fee in tokens
  .execute(client);

// Request the receipt of the transaction
const receipt = await transactionResponse.getReceipt(client);
console.log(`Created topic with ID: ${receipt.topicId}`);

[...]

// Define max custom fee
const maxCustomFee = new FixedFee()
  .setAmount(100) // a maximum of 100 tokens is paid for submitting the message
  .setDenominatingTokenId(TokenId.fromString("0.0.56789")); // The token to charge the fee in. HBAR if unset

// Send message to the topic
transactionResponse = await new TopicMessageSubmitTransaction({ topicId: topicId, message: "Hello, HCS!" })
  .setMaxCustomFees([maxCustomFee]) // Set the maximum fee for the message
  .execute(client);

This implementation shows the creation of a topic where each message submission requires a fixed fee of 100 tokens with ID 0.0.56789, collected by the specified account.

Rejected Ideas

  • Setting a mandatory network enforced allowCustomFeesPayment flag in HCS message transactions to allow payment of fees.

References

Copyright/license

This document is licensed under the Apache License, Version 2.0 – see LICENSE or (https://www.apache.org/licenses/LICENSE-2.0)

Citation

Please cite this document as: