1

Need so help to understand the below transaction :

[
    {
        "type": "transaction",
        "id": 279,
        "level": 26,
        "timestamp": "2018-06-30T18:07:27Z",
        "hash": "opDckVrXacor6B25F3SD2epxC13iCoN6xjwsvvJDYo5aa9AMbqz",
        "counter": 5,
        "originalSender": {
            "address": "tz1NKVAxzJusWgKewn4LEViPSQVRE5Kg6XFV"
        },
        "sender": {
            "alias": "Vested funds 5",
            "address": "KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio"
        },
        "nonce": 0,
        "gasLimit": 0,
        "gasUsed": 107,
        "storageLimit": 0,
        "storageUsed": 0,
        "bakerFee": 0,
        "storageFee": 0,
        "allocationFee": 0,
        "target": {
            "alias": "Foundation baker 8",
            "address": "tz3NExpXn9aPNZPorRE4SdjJ2RGrfbJgMAaV"
        },
        "amount": 199041301565,
        "parameters": "{\"prim\":\"Unit\"}",
        "status": "applied",
        "hasInternals": false
    }

Please help me validate my understanding

Address - KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio has "X" tez.

with the above transaction KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio has transferred 199041301565 tezos to target tz3NExpXn9aPNZPorRE4SdjJ2RGrfbJgMAaV.

  1. Amount left with KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio = ("X" - ( 199041301565 + bakerFee)) - Is my assumption correct in this case?

  2. Why is the baker fee zero in this case ?

1

2 Answers 2

5

1. No, it's not correct.

There are two types of operations in Tezos: ordinary and internal (aka a result of smart contracts execution). If there is a nonce field or originalSender field, then it's an internal operation.

In case of internal operation, original sender pays for all the fees, so here is the correct code:

if (tx.originalSender != null)
{
    tx.sender.Balance -= tx.amount;
    tx.originalSender.Balance -= tx.storageFee + tx.allocationFee;
    //bakerFee in internal operations is always 0
}
else
{
    tx.sender.Balance -= tx.amount + tx.bakerFee + tx.storageFee + tx.allocationFee;
}

2. In this particular case bakerFee is 0, because it's an internal operation.

But it may be 0 even if it's not an internal operation (sender can set any fee value). Also, on the early blocks many operations have zero fee...

4
  • the above transaction sample has an original sender field that means the transaction is initiated by original sender but what the role of sender field in this case
    – Debasish22
    Feb 18, 2020 at 7:14
  • 1
    Sender transfers its funds
    – Groxan
    Feb 18, 2020 at 7:59
  • if i understand it correct sender is a originated account (KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio) which is derived from implicit account(tz1NKVAxzJusWgKewn4LEViPSQVRE5Kg6XFV) referred as original sender. 2. So if my understanding is true then the funds which the originated account aka sender is sending to target is the amount which have been transferred from impilicit account aka original sender to sender some time during a delegation operation.
    – Debasish22
    Feb 22, 2020 at 12:23
  • KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio is a smart contract (originated account), but it wasn't derived from tz1NKVAxzJusWgKewn4LEViPSQVRE5Kg6XFV, but was bootstrapped during blockchain initialization. Look at detailed account history on TzKT: tzkt.io/KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio/operations. And tz1NKVAxzJusWgKewn4LEViPSQVRE5Kg6XFV is just the one who invoked the smart contract, that's it.
    – Groxan
    Feb 22, 2020 at 21:41
1

I've edited my answer to take into account the answer of Groxan.

  1. Yes, the contract KT1... that is the emitter of the internal transaction only pays the amount of the transaction. However, as detailed below in the answer of Groxan, fees are payed by the original sender.

Now follows a discussion on other cases where the fees of the outer transaction may have zero fees:

There is no fixed baker fee. Instead, when someone injects a transaction onto the network, they propose a fee. A baker is free to accept, or not, to bake that transactions for the given fee:

Another interesting thing we learn from the receipt is that there are more costs being added on top of the transfer and the burn: fees. In order to encourage a baker to include our operation, and in general to pay for the cost of running the blockchain, each operation usually includes a fee that goes to the baker. Fees are variable over time and depend on many factors but the tezos client selects a default for us.

Lets try this out in a sandbox. When submitting a transaction using tezos-client, we can set the fee using the --fee flag (search "--fee" in the CLI reference):

$ tezos-client transfer 100 from bootstrap1 to bootstrap2 --fee 0
Node is bootstrapped, ready for injecting operations.
Estimated gas: 10207 units (will add 100 for safety)
Estimated storage: no bytes added
Fatal error:
  The proposed fee (ꜩ0) are lower than the fee that baker expect by default (ꜩ0.001281).
   Use `--force-low-fee` to emit this operation anyway.

The client complains about the low fee, but we can force it with --force-low-fee:

tezos-client transfer 100 from bootstrap1 to bootstrap2 --fee 0 --force-low-fee

The transactions is now injected, but the command will wait until it has been validated by a baker. In a separate terminal, let's bake it:

$ tezos-client bake for bootstrap3
Feb 17 14:34:27 - alpha.baking.forge: found 0 valid operations (1 refused) for timestamp 2020-02-17T13:34:27-00:00 (fitness 01::0000000000000001)

The baker refuses transactions because of the low fee. But we can force it by setting minimum fees requires:

$ tezos-client bake for bootstrap3 --minimal-fees 0 --minimal-nanotez-per-gas-unit 0 --minimal-nanotez-per-byte 0
Feb 17 14:37:41 - alpha.baking.forge: found 1 valid operations (0 refused) for timestamp 2020-02-17T13:37:41-00:00 (fitness 01::0000000000000004)

We get the following receipt:

Operation found in block: BMRSeaNGPB5AfqzqEVkdnEBzJfNCoP9WyXK2zZTY18H9hvrcx1H (pass: 3, offset: 0)
This sequence of operations was run:
  Manager signed operations:
    From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx
    Fee to the baker: ꜩ0
    Expected counter: 1
    Gas limit: 10307
    Storage limit: 0 bytes
    Transaction:
      Amount: ꜩ100
      From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx
      To: tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN
      This transaction was successfully applied
      Consumed gas: 10207
      Balance updates:
        tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ... -ꜩ100
        tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN ... +ꜩ100

We can find the transaction in the RPC and compare it to what you've got:

$ tezos-client rpc get /chains/main/blocks/head/operations/3
[ { "protocol": "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK",
    "chain_id": "NetXdQprcVkpaWU",
    "hash": "opYqCQPfhDEMGeCrTa55XrHTFrQweThEFNSTQuWpUVVgKzGDHt3",
    "branch": "BLfZzHax3gG7GyQzee6AqS6UremB9hJpidqRpmo56FoLRiRaj6Z",
    "contents":
      [ { "kind": "transaction",
          "source": "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx", "fee": "0",
          "counter": "1", "gas_limit": "10307", "storage_limit": "0",
          "amount": "100000000",
          "destination": "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN",
          "metadata":
            { "balance_updates": [],
              "operation_result":
                { "status": "applied",
                  "balance_updates":
                    [ { "kind": "contract",
                        "contract": "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx",
                        "change": "-100000000" },
                      { "kind": "contract",
                        "contract": "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN",
                        "change": "100000000" } ], "consumed_gas": "10207" } } } ],
    "signature":
      "sigvyNn4gV5N4hC9VyGMq5rCZ62mNp1pn6GYPH57WM2PLh8UV6WNJDQ7sNKzD8dsc1ndfTodqYpCtMSrH7ptsP8cgL4jWo1m" } ]

As you can see, the fee is 0.

However in the case of your question, the reason is that the transaction is internal, as detailed below in the answer of Groxan.

4
  • Thanks . Your explanation makes complete sense to me but i have one quick question as per the above analogy if the sender, target and baker are the same entity then they can approve any of the transactions(malicious/bad) into the block. And if this happens then blockchain data is compromised in this case. How does it actually work in case of tezos .Kindly help
    – Debasish22
    Feb 18, 2020 at 6:44
  • 2
    Hi, turns out my explanation was wrong, the one of Groxan is the correct one for your case. However, 0-fee transactions can still be validated as my examples demonstrate. There are several mechanisms put in place to ensure that bakers do not cheat: notably, they pay a deposit that is retained if cheating is detected. Also, a system of endorsements and accusations are used. You can read more here: tezos.gitlab.io/whitedoc/proof_of_stake.html#baking if you have a more specific scenario of cheating in mind, I can give more specifics.
    – arvidj
    Feb 18, 2020 at 8:07
  • i understood your example but in balance_updates section why the kind is mentioned as contract . tz1 accounts are not contracts .caould you please help me understnd
    – Debasish22
    Feb 22, 2020 at 12:33
  • In tezos, both tz1 and KT1's are referred to as contracts. Tz1 are called "implicit accounts" and kt1 are called originated accounts. But in general, a contract can be either a kt1 or a tz1.
    – arvidj
    Feb 22, 2020 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.