# Fee Delegation Explained

**URL:** https://devforum.kaia.io/t/fee-delegation-explained/31
**Category:** Kaia
**Created:** [2월 7, 2020, 9:33오전 UTC](https://devforum.kaia.io/t/fee-delegation-explained/31 "2020-02-07T09:33:46Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Eric](https://yyz1.discourse-cdn.com/flex035/user_avatar/devforum.kaia.io/eric/32/7_2.png) [@Eric](https://devforum.kaia.io/u/Eric)
#### Post date: [2월 7, 2020, 9:33오전 UTC](https://devforum.kaia.io/t/fee-delegation-explained/31/1 "2020-02-07T09:33:46Z")

</div>

## Idea

Fee Delegation (FD) is a mechanism allowing a user to delegate his or her gas fee to a third party. Gas fee incurred from a transaction of type `TxTypeFeeDelegated*` will be charged to **fee payer** whose address and signature are present in the transaction. Refer the following list of transaction types for available FD features:

- `TxTypeFeeDelegatedValueTransfer`
- `TxTypeFeeDelegatedValueTransferWithMemo`
- `TxTypeFeeDelegatedSmartContractDeploy`
- `TxTypeFeeDelegatedSmartContractExecution`
- `TxTypeFeeDelegatedAccountUpdate`
- `TxTypeFeeDelegatedCancel`

> Note that partial fee delegation is also possible (with type suffix `WithRatio`).

* * *

## FD in Action

### Scenario

Suppose Alice (with address `0xALICE`) wants to send 1 KLAY to Bob (with address `0xBOB`). Because her balance is exactly 1 KLAY, Alice decides to ask Fred (with address `0xFRED`) to pay her fees.

### Transaction Flow

#### 1. Alice

Alice creates a transaction transferring 1 KLAY from her account to Bob’s, and signs it with her private key. **The transaction must have correct type**. In this case it has to be `TxTypeFeeDelegatedValueTrasfer`. Alice’s transaction would look like the following:

```json
{
   "from" : "0xALICE",
   "to": "0xBOB",
   "type": "TxTypeFeeDelegatedValueTransfer",
   "value": "0xde0b6b3a7640000", // 1 KLAY
   "signatures": [{ "R": "0x...", "S": "0x...", "V": "0x..." }],
   "gas" : "0x2dc6c0", // 3,000,000
   "gasPrice": "0x5d21dba00" // 25 Ston
   ...
}

```

When Alice is done signing, she does not send it to an EN she knows. Rather, she sends her **signed raw transaction** to Fred. How? I don’t know 🙄 Using whatever method she prefers, Alice must deliver her transaction to Fred.

```plaintext
Alice ---> Fred

```

#### 2. Fred

Once he receives Alice’s transaction, Fred adds his address, signs the transaction, and sends the outcome to an EN. Notice that because Alice’s transaction has already been signed, **Fred cannot alter the content of the transaction but to add more information**.

```plaintext
Alice ---> Fred ---> [[Klaytn]]

```

#### 3. Klaytn

The transaction Fred sends to Klaytn looks like this:

```json
{
   "from" : "0xALICE",
   "to": "0xBOB",
   "feePayer": "0xFRED",
   "feePayerSignatures": [{ "R": "0x...", "S": "0x...", "V": "0x..." }],
   "type": "TxTypeFeeDelegatedValueTransfer",
   "value": "0xde0b6b3a7640000", // 1 KLAY
   "signatures": [{ "R": "0x...", "S": "0x...", "V": "0x..." }],
   "gas" : "0x2dc6c0", // 3,000,000
   "gasPrice": "0x5d21dba00" // 25 Ston
   ...
}

```

Assuming the rest of the transaction is correct (e.g., nonce), Klaytn validates and executes this transaction as follows:

1. Check the type
2. If the type starts with `TxTypeFeeDelegated`, check the following fields: `from`, `signatures`, `feePayer`, and `feePayerSignatures`
3. If all four fields are correct, then deducts `gas * gasPrice` from the account pointed by `0xFRED` and executes the transaction
4. Once the transaction is executed, refunds the remaining fees (`(gas - gasUsed) * gasPrice`) to Fred’s account at `0xFRED`.

Finally, when the transaction gets included in a block, Bob will see the 1 KLAY Alice sent in his account.

* * *

## FD in Javascript

Okay, so how do we use FD with Klaytn SDK? Let’s take a look at the following code snippet:

```javascript
const Caver = require('caver-js');
const caver = new Caver('https://api.baobab.klaytn.net:8651/');

let sender = caver.klay.accounts.wallet.add("0xALICE_PRIV_KEY");
let payer = caver.klay.accounts.wallet.add("0xFRED_PRIV_KEY");

let { rawTransaction: senderRawTransaction } = await caver.klay.accounts.signTransaction({
        type: 'FEE_DELEGATED_VALUE_TRANSFER',
        from: sender.address,
        to: '0xBOB',
        gas: '3000000',
        value: caver.utils.toPeb('1', 'KLAY'),
    }, sender.privateKey);

// Alice ---> Fred
// : Alice somehow delivers raw tx to Fred

let { rawTransaction: finalTx } = await caver.klay.accounts.signTransaction({
        senderRawTransaction: senderRawTransaction,
        feePayer: payer.address
    }, payer.privateKey);

caver.klay.sendSignedTransaction(finalTx).then((err, receipt) => {
   console.log(receipt);
});

```

The above code is very unlikely (unless Fred totally trusts Alice), but I’m just trying to make a point here.

### Alice

Alice encodes her transactions. Notice that `FEE_DELEGATED_VALUE_TRANSFER` is used, not `TxTypeFeeDelegatedValueTransfer`. When using caver-js,

1. remove `TxType`
2. indicate letters in all caps, and
3. separate words with underscores

If this is too complicated, refer to this [page](https://docs.klaytn.com/bapp/sdk/caver-js/api-references/caver.klay/transaction/sendtx_value_transfer) and find the transaction type you want to use.

Once done signing her transaction, Alice sends the raw transaction to Fred.

### Fred

Fred signs Alice’s transaction with one additional field — `feePayer`. The final outcome `finalTx` is RLP encoded transaction containing Fred’s address and his signature (we signed with `payer.privateKey`).

Fred uses `sendSignedTransaction` to deliver `finalTx` to a Klaytn EN.

### Wrap up

That was easy, right? If you want to see a more realistic example, take a look at [this](https://docs.klaytn.com/bapp/tutorials/fee-delegation-example). This one at least has courtesy to separate client and server 😛

* * *

## FD in Java

Here’s a code snippet which does exactly the same thing as the one shown above in Javascript.

```auto
/* Omitted package statement and import statements for brevity */

public class FeeDelegatedValueTransfer {
    private static final BigInteger GAS_LIMIT = BigInteger.valueOf(3000000L);
    private static final BigInteger GAS_PRICE = BigInteger.valueOf(25000000000L);
    private static DefaultBlockParameter BLK_PARAM = DefaultBlockParameterName.LATEST;

    private static int CHAIN_ID;
    private static Caver caver;

    private static KlayCredentials senderCredential;
    private static KlayCredentials payerCredential;

    @BeforeClass
    public static void setup() {
        // Baobab setting
        CHAIN_ID = ChainId.BAOBAB_TESTNET;
        caver = Caver.build("https://api.baobab.klaytn.net:8651/");
        senderCredential = KlayCredentials.create("0xALICE_PRIV_KEY");
        payerCredential = KlayCredentials.create("0xFRED_PRIV_KEY");
    }

    @Test
    public void feeDelegatedValueTransferTest() throws IOException {
        BigInteger nonce = caver.klay().getTransactionCount(senderCredential.getAddress(), BLK_PARAM).send().getValue();
        TxTypeFeeDelegatedValueTransfer tx = TxTypeFeeDelegatedValueTransfer
                .createTransaction(
                        nonce,
                        GAS_PRICE,
                        GAS_LIMIT,
                        "0xBOB",
                        BigInteger.ONE,
                        senderCredential.getAddress()
                );
        String rawTx = tx.sign(senderCredential, CHAIN_ID).getValueAsString();

        FeePayerManager feePayerManager = new FeePayerManager.Builder(caver, payerCredential)
                .setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(caver, 1000, 10))
                .setChainId(CHAIN_ID)
                .build();

        KlayTransactionReceipt.TransactionReceipt transactionReceipt = feePayerManager.executeTransaction(rawTx);
    }
}

```
