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 |
Table of Contents
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 fieldmax_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
, andcustom_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" }
- Changes to the body of the response. The response should include three new fields:
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: