HIP-213: Application Signs for End User Source

AuthorJustin Atwell, Greg Scullard
Discussions-Tohttps://github.com/hashgraph/hedera-improvement-proposal/discussions/304
StatusActive
Needs Council ApprovalNo
Review period endsTue, 21 Dec 2021 07:00:00 +0000
TypeInformational
Created2021-11-13
Updated2021-11-13, 2021-12-07

Abstract

Describes the concept of how transactions can be issued by one account, but paid for by another account.

Motivation

Oftentimes it is appropriate for the application to pay fees associated with a transation rather than the end user.

Rationale

N/A

User stories

As an end user that does not want to incur transaction fees on the network, I still want the ability to hold tokens on the Hedera network

Specification

//Java

private AccountId getAccountId() throws TimeoutException, PrecheckStatusException, ReceiptStatusException {
// Retrieve the Operator Id
AccountId OPERATOR_ID = AccountId.fromString(Objects.requireNonNull(Dotenv.load().get("OPERATOR_ID")));

// need a placeholder key to satisfy the client.setOperator;
PrivateKey dummyKey = PrivateKey.generate();

//Create a testnet Client
Client client = Client.forTestnet();

// Set the operator (and default signer) to the new private key
client.setOperator(OPERATOR_ID, dummyKey);

// We need the public key of the operator id for the signWith operation below
PublicKey OPERATOR_PUBLIC_KEY = PrivateKey.fromString(Dotenv.load().get("OPERATOR_KEY")).getPublicKey();

// Creates a function that is invoked during the signWith method
Function<byte[], byte[]> transactionSigner = generateSignatureFunction();

// Create a TransferTransaction that transfers 1 tinyBar from the operator to account 0.0.3
TransactionResponse response = new TransferTransaction()
        .addHbarTransfer(OPERATOR_ID, Hbar.fromTinybars(1).negated())
        .addHbarTransfer(AccountId.fromString("0.0.3"), Hbar.fromTinybars(1))
        .freezeWith(client)
        .signWith(OPERATOR_PUBLIC_KEY, transactionSigner)
        .execute(client);
TransactionReceipt receipt = response.getReceipt(client);

return receipt.accountId;
}

private Function<byte[],byte[]> generateSignatureFunction() {
// Retrieve the Private Key from the .env file
PrivateKey OPERATOR_KEY = PrivateKey.fromString(Objects.requireNonNull(Dotenv.load().get("OPERATOR_KEY")));

// return a function that will sign the byte array transaction during the signWith method
return (
        t -> OPERATOR_KEY.sign(t)
);
}

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: