I've edited my answer to take into account the answer of Groxan.
- 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.