GitHub Logo HIP-213: Application Signs for End User

Author Justin Atwell, Greg Scullard
Discussions-To https://github.com/hashgraph/hedera-improvement-proposal/discussions/304
Status Active
Needs Council Approval No
Review period ends Tue, 21 Dec 2021 07:00:00 +0000
Type Informational
Created 2021-11-13
Updated 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: