Dealing with fees in smart contracts

What is the best practice for dealing with fees in smart contracts? I have seen examples where it is set to 1000 microalgos, but I have seen other examples where they use suggested fees. Which method should I use?

It depends what you mean by “in smart contracts”.

If you mean choosing the fee to send a transaction (whether an application call or not):

  • In general, using the suggested fee is the safest approach as it allows you to send transactions even in case of congestion and even in case the minimum fee changes. However, you may want to add in production a check that the fee is not too high before sending the transaction. Otherwise, you may end up paying way too much.
  • If your dApp’s transactions are not very time sensitive, you may also consider always using the minimum fee. Transactions may fail more often in case of congestion but you can just retry until congestion ends. Note that:
    1. To my knowledge, there has never been any period of congestion on Algorand up to now and there is a huge margin between the actual TPS and the max TPS supported.
    2. Although very unlikely in the near future, the value 1000 microAlgos may change.

If you are interested in the fees for inner transactions in smart contracts or for approving/rejecting transactions for smart signatures:

  • One option is to set it to 0 Algo and require the other transactions in the group to pay for it (remember that fees in groups of transactions are shared by all the transactions).
  • Another option is to use global MinTxnFee (which is currently 1000) which will always work except in case of congestion.
  • If the first two options are not possible, then you need to decide on an upper bound for the fee that is reasonable and hopefully will always work. This solution is less future-proof and a bit more dangerous. I would not recommend it in general.
1 Like

Thank you, Fabrice. This is really helpful!

I have been looking through on how to get one transaction to pay for all fees of all transactions and can’t seem to find an example online.

params = algod_client.suggested_params()
    # comment out the next two (2) lines to use suggested fees
    params.flat_fee = True
    params.fee = 1000

	# create transactions
    print("Creating transactions...")
	# from account 1 to account 3
    sender = account_1
    receiver = account_3
    amount = 1000000
    txn_1 = transaction.PaymentTxn(sender, params, receiver, amount)
    print("...txn_1: from {} to {} for {} microAlgos".format(sender, receiver, amount))
    print("...created txn_1: ", txn_1.get_txid())

	# from account 2 to account 1
    sender = account_2
    receiver = account_1
    amount = 2000000
    txn_2 = transaction.PaymentTxn(sender, params, receiver, amount)
    print("...txn_2: from {} to {} for {} microAlgos".format(sender, receiver, amount))
    print("...created txn_2: ", txn_2.get_txid())

	# combine transations
    print("Combining transactions...")
	# the SDK does this implicitly within grouping below
    print("Grouping transactions...")
	# compute group id and put it into each transaction
    group_id = transaction.calculate_group_id([txn_1, txn_2])
    print("...computed groupId: ", group_id) = group_id = group_id

	# split transaction group
    print("Splitting unsigned transaction group...")
    # this example does not use files on disk, so splitting is implicit above

	# sign transactions
    print("Signing transactions...")
    stxn_1 = txn_1.sign(sk_1)    
    print("...account1 signed txn_1: ", stxn_1.get_txid())
    stxn_2 = txn_2.sign(sk_2)
    print("...account2 signed txn_2: ", stxn_2.get_txid())

	# assemble transaction group
    print("Assembling transaction group...")
    signed_group =  [stxn_1, stxn_2]

	# send transactions
    print("Sending transaction group...")
    tx_id = algod_client.send_transactions(signed_group)

In the example code above, how would I get txn_1 to pay for all the fees?

Also, if the second transaction was an application inner transaction (hypothetically), would I need to write Teal code to have the fees payed by txn_1?

set params.fee = 2* algosdk.ALGORAND_MIN_TX_FEE at the beginning
and params.fee = 0 before second transaction

I recommend using algosdk.ALGORAND_MIN_TX_FEE instead of 1000 to have your application work even in the future if min fee changes.

1 Like