Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(HIP-991): Permissionless revenue - Generating Topic Ids for Topic Operators #895

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/zxc-build-library.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ jobs:
solo node keys -i node1 --gossip-keys --tls-keys
solo cluster setup
solo network deploy -i node1 -n solo-e2e
solo node setup -i node1 -n solo-e2e -t v0.57.0
solo node setup -i node1 -n solo-e2e -t v0.59.0
solo node start -i node1 -n solo-e2e
kubectl port-forward svc/haproxy-node1-svc -n "${SOLO_NAMESPACE}" 50211:50211 &
solo mirror-node deploy -n "${SOLO_NAMESPACE}" --pinger true
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,7 @@ src/proto/*.proto
/proto/mirror
/proto/state
/proto/auxiliary
/proto/event

### Ignore Generated Package Files
package
Expand Down
5 changes: 3 additions & 2 deletions HieroApi.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
set(HAPI_VERSION_TAG "v0.57.0" CACHE STRING "Use the configured version tag for the Hiero API protobufs")
set(HAPI_VERSION_TAG "v0.59.0" CACHE STRING "Use the configured version tag for the Hiero API protobufs")

if (HAPI_VERSION_TAG STREQUAL "")
set(HAPI_VERSION_TAG "v0.57.0")
set(HAPI_VERSION_TAG "v0.59.0")
endif ()

# Fetch the protobuf definitions
Expand Down Expand Up @@ -50,6 +50,7 @@ endif()

file(INSTALL ${PROJECT_SOURCE_DIR}/proto/service-external-proto/mirror/ DESTINATION ${PROTO_SRC}/mirror)
file(INSTALL ${hproto_SOURCE_DIR}/hapi/hedera-protobufs/services/ DESTINATION ${PROTO_SRC})
file(INSTALL ${hproto_SOURCE_DIR}/hapi/hedera-protobufs/platform/ DESTINATION ${PROTO_SRC})
file(INSTALL ${PROJECT_SOURCE_DIR}/proto/service-external-proto/sdk/ DESTINATION ${PROTO_SRC})

add_subdirectory(proto)
Expand Down
9 changes: 7 additions & 2 deletions proto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ set(PROTO_FILES
token_update_nfts.proto
token_wipe_account.proto
transaction.proto
transaction_body.proto
transaction_contents.proto
transaction_get_fast_record.proto
transaction_get_receipt.proto
Expand All @@ -111,10 +110,16 @@ set(PROTO_FILES
util_prng.proto
util_service.proto

auxiliary/history/history_proof_signature.proto
auxiliary/history/history_proof_key_publication.proto
auxiliary/history/history_proof_vote.proto
auxiliary/tss/tss_message.proto
auxiliary/tss/tss_share_signature.proto
auxiliary/tss/tss_vote.proto

event/state_signature_transaction.proto

state/history/history_types.proto

mirror/consensus_service.proto
mirror/mirror_network_service.proto)
# End Protobuf Definitions
Expand Down
4 changes: 4 additions & 0 deletions src/sdk/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ set(MULTI_APP_TRANSFER_EXAMPLE_NAME ${PROJECT_NAME}-multi-app-transfer-example)
set(MULTI_SIG_OFFLINE_EXAMPLE_NAME ${PROJECT_NAME}-multi-sig-offline-example)
set(NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME ${PROJECT_NAME}-nft-add-remove-allowances-example)
set(PRNG_EXAMPLE_NAME ${PROJECT_NAME}-prng-example)
set(REVENUE_GENERATING_TOPICS_EXAMPLE_NAME ${PROJECT_NAME}-revenue-generating-topics-example)
set(SCHEDULE_EXAMPLE_NAME ${PROJECT_NAME}-schedule-example)
set(SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME ${PROJECT_NAME}-schedule-identical-transaction-example)
set(SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME ${PROJECT_NAME}-schedule-multisig-transaction-example)
Expand Down Expand Up @@ -101,6 +102,7 @@ add_executable(${MULTI_APP_TRANSFER_EXAMPLE_NAME} MultiAppTransferExample.cc)
add_executable(${MULTI_SIG_OFFLINE_EXAMPLE_NAME} MultiSigOfflineExample.cc)
add_executable(${NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME} NftAddRemoveAllowancesExample.cc)
add_executable(${PRNG_EXAMPLE_NAME} PrngExample.cc)
add_executable(${REVENUE_GENERATING_TOPICS_EXAMPLE_NAME} RevenueGeneratingTopicsExample.cc)
add_executable(${SCHEDULE_EXAMPLE_NAME} ScheduleExample.cc)
add_executable(${SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME} ScheduleIdenticalTransactionExample.cc)
add_executable(${SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME} ScheduleMultiSigTransactionExample.cc)
Expand Down Expand Up @@ -180,6 +182,7 @@ target_link_libraries(${MULTI_APP_TRANSFER_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
target_link_libraries(${MULTI_SIG_OFFLINE_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
target_link_libraries(${NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
target_link_libraries(${PRNG_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
target_link_libraries(${REVENUE_GENERATING_TOPICS_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
target_link_libraries(${SCHEDULE_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
target_link_libraries(${SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
target_link_libraries(${SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME})
Expand Down Expand Up @@ -239,6 +242,7 @@ install(TARGETS
${MULTI_SIG_OFFLINE_EXAMPLE_NAME}
${NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME}
${PRNG_EXAMPLE_NAME}
${REVENUE_GENERATING_TOPICS_EXAMPLE_NAME}
${SCHEDULE_EXAMPLE_NAME}
${SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME}
${SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME}
Expand Down
224 changes: 224 additions & 0 deletions src/sdk/examples/RevenueGeneratingTopicsExample.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// SPDX-License-Identifier: Apache-2.0
#include "AccountBalance.h"
#include "AccountBalanceQuery.h"
#include "AccountCreateTransaction.h"
#include "AccountId.h"
#include "Client.h"
#include "CustomFixedFee.h"
#include "ED25519PrivateKey.h"
#include "TokenCreateTransaction.h"
#include "TopicCreateTransaction.h"
#include "TopicId.h"
#include "TopicMessageSubmitTransaction.h"
#include "TopicUpdateTransaction.h"
#include "TransactionReceipt.h"
#include "TransactionResponse.h"
#include "TransferTransaction.h"

#include <dotenv.h>
#include <iostream>

using namespace Hiero;

int main(int argc, char** argv)
{
dotenv::init();
const AccountId operatorAccountId = AccountId::fromString(std::getenv("OPERATOR_ID"));
const std::shared_ptr<PrivateKey> operatorPrivateKey = ED25519PrivateKey::fromString(std::getenv("OPERATOR_KEY"));

// Get a client for the Hiero testnet, and set the operator account ID and key such that all generated transactions
// will be paid for by this account and be signed by this key.
Client client = Client::forTestnet();
client.setOperator(operatorAccountId, operatorPrivateKey);

/*
* Step 1:
* Create account - alice
*/
std::cout << "Creating account - alice" << std::endl;

std::shared_ptr<PrivateKey> aliceKey = ED25519PrivateKey::generatePrivateKey();

AccountId alice = AccountCreateTransaction()
.setKeyWithoutAlias(aliceKey->getPublicKey())
.setInitialBalance(Hbar(10LL))
.execute(client)
.getReceipt(client)
.mAccountId.value();

std::cout << "Alice account id:" << alice.toString() << std::endl;

/*
* Step 2:
* Create a topic with hbar custom fee
*/
int64_t feeAmount = 100000000; // 1 HBAR equivalent

CustomFixedFee customFixedFee = CustomFixedFee().setAmount(feeAmount).setFeeCollectorAccountId(operatorAccountId);

TopicId topicId = TopicCreateTransaction()
.setAdminKey(operatorPrivateKey->getPublicKey())
.setFeeScheduleKey(operatorPrivateKey->getPublicKey())
.addCustomFixedFee({ customFixedFee })
.execute(client)
.getReceipt(client)
.mTopicId.value();

/*
* Step 3:
* Submit a message to that topic, paid for by alice, specifying max custom fee amount bigger than the topic’s amount.
*/
AccountBalance accountBalanceBefore = AccountBalanceQuery().setAccountId(alice).execute(client);
AccountBalance feeCollectorBalanceBefore = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client);

CustomFeeLimit limit = CustomFeeLimit().setPayerId(alice).addCustomFee(CustomFixedFee().setAmount(feeAmount * 2));

client.setOperator(alice, aliceKey);
TopicMessageSubmitTransaction()
.setTopicId(topicId)
.setMessage("message")
.addCustomFeeLimit(limit)
.execute(client)
.getReceipt(client);

std::cout << "Message submitted successfully" << std::endl;

/*
* Step 4:
* Verify alice was debited the fee amount and the fee collector account was credited the amount.
*/
client.setOperator(operatorAccountId, operatorPrivateKey);

AccountBalance accountBalanceAfter = AccountBalanceQuery().setAccountId(alice).execute(client);
AccountBalance feeCollectorBalanceAfter = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client);

std::cout << "Alice account balance before: " << accountBalanceBefore.toString() << std::endl;
std::cout << "Alice account balance after: " << accountBalanceAfter.toString() << std::endl;
std::cout << "Fee collector account balance before: " << feeCollectorBalanceBefore.toString() << std::endl;
std::cout << "Fee collector account balance after: " << feeCollectorBalanceAfter.toString() << std::endl;

/*
* Step 5:
* Create a fungible token and transfer some tokens to alice
*/
TokenId tokenId = TokenCreateTransaction()
.setTokenName("revenueGeneratingToken")
.setTokenSymbol("RGT")
.setInitialSupply(10)
.setTreasuryAccountId(operatorAccountId)
.execute(client)
.getReceipt(client)
.mTokenId.value();

std::cout << "Created token with Id: " << tokenId.toString() << std::endl;

TransferTransaction()
.addTokenTransfer(tokenId, operatorAccountId, -1ULL)
.addTokenTransfer(tokenId, alice, 1ULL)
.execute(client)
.getReceipt(client);

/*
* Step 6:
* Update the topic to have a fee of the token.
*/
std::cout << "Updating the topic to have a custom fee of the token" << std::endl;

CustomFixedFee customTokenFixedFee =
CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId).setFeeCollectorAccountId(operatorAccountId);

TopicUpdateTransaction()
.setTopicId(topicId)
.setCustomFixedFees({ customTokenFixedFee })
.execute(client)
.getReceipt(client);

/*
* Step 7:
* Submit another message to that topic, paid by alice, without specifying max custom fee amount.
*/
accountBalanceBefore = AccountBalanceQuery().setAccountId(alice).execute(client);
feeCollectorBalanceBefore = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client);

std::cout << "Submitting a message as alice to the topic" << std::endl;

client.setOperator(alice, aliceKey);
TopicMessageSubmitTransaction().setTopicId(topicId).setMessage("message").execute(client).getReceipt(client);

std::cout << "Message submitted successfully" << std::endl;

/*
* Step 8:
* Verify alice was debited the new fee amount and the fee collector account was credited the amount.
*/
client.setOperator(operatorAccountId, operatorPrivateKey);

accountBalanceAfter = AccountBalanceQuery().setAccountId(alice).execute(client);
feeCollectorBalanceAfter = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client);

std::cout << "Alice account balance before: " << accountBalanceBefore.toString() << std::endl;
std::cout << "Alice account balance after: " << accountBalanceAfter.toString() << std::endl;
std::cout << "Fee collector account balance before: " << feeCollectorBalanceBefore.toString() << std::endl;
std::cout << "Fee collector account balance after: " << feeCollectorBalanceAfter.toString() << std::endl;

/*
* Step 9:
* Create account - bob
*/
std::cout << "Creating account - bob" << std::endl;

std::shared_ptr<PrivateKey> bobKey = ED25519PrivateKey::generatePrivateKey();

AccountId bob = AccountCreateTransaction()
.setKeyWithoutAlias(bobKey->getPublicKey())
.setInitialBalance(Hbar(10LL))
.setMaxAutomaticTokenAssociations(-1)
.execute(client)
.getReceipt(client)
.mAccountId.value();

std::cout << "Bob account id:" << bob.toString() << std::endl;

/*
* Step 10:
* Update the topic’s fee exempt keys and add bob’s public key.
*/
std::cout << "Updating the topic fee exempt keys with bob's public key" << std::endl;

TopicUpdateTransaction()
.setTopicId(topicId)
.addFeeExemptKey(bobKey->getPublicKey())
.execute(client)
.getReceipt(client);

/*
* Step 11:
* Submit another message to that topic, paid with bob, without specifying max custom fee amount.
*/
accountBalanceBefore = AccountBalanceQuery().setAccountId(bob).execute(client);
feeCollectorBalanceBefore = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client);

std::cout << "Submitting a message as bob to the topic" << std::endl;

client.setOperator(bob, bobKey);
TopicMessageSubmitTransaction().setTopicId(topicId).setMessage("message").execute(client).getReceipt(client);

std::cout << "Message submitted successfully" << std::endl;

/*
* Step 12:
* Verify bob was not debited the fee amount.
*/
client.setOperator(operatorAccountId, operatorPrivateKey);

accountBalanceAfter = AccountBalanceQuery().setAccountId(bob).execute(client);
feeCollectorBalanceAfter = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client);

std::cout << "Bob account balance before: " << accountBalanceBefore.toString() << std::endl;
std::cout << "Bob account balance after: " << accountBalanceAfter.toString() << std::endl;

// Clean up:
client.close();

return 0;
}
2 changes: 1 addition & 1 deletion src/sdk/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ add_library(${PROJECT_NAME} STATIC
src/AccountInfoQuery.cc
src/AccountRecords.cc
src/AccountRecordsQuery.cc
src/AccountStakersQuery.cc
src/AccountUpdateTransaction.cc
src/AddressBookQuery.cc
src/AssessedCustomFee.cc
Expand All @@ -53,6 +52,7 @@ add_library(${PROJECT_NAME} STATIC
src/ContractUpdateTransaction.cc
src/CustomFee.cc
src/CustomFeeBase.cc
src/CustomFeeLimit.cc
src/CustomFixedFee.cc
src/CustomFractionalFee.cc
src/CustomRoyaltyFee.cc
Expand Down
Loading
Loading