Suppose the owner of account A wants to send a payment to account
TMPL_TO, but does not want to pay a transaction fee. If account A signs the following contract with the appropriate parameters (specifying all of the necessary details of the payment transaction), then anyone can cover a fee for that payment on account A's behalf.
The contract works by approving a group of two transactions (meaning the two transactions will occur together or not at all). The first transaction must spend the transaction fee into account A, and the second transaction must be the specified payment transaction from account A to account
TMPL_TO: the recipient of the payment from account A
TMPL_AMT: the amount to send from account A to
TMPL_CLS: the account to close out the remainder of account A's funds to after paying
TMPL_FV: the required first valid round of the payment from account A
TMPL_LV: the required last valid round of the payment from account A
TMPL_LEASE: the string to use for the transaction lease in the payment from account A (to avoid replay attacks)
First, check that the transaction group contains exactly two transactions. Push the result of this check to the stack.
global GroupSize int 2 ==
Next, check that the first transaction is a payment, which is required since the first transaction should be paying the fee for the second. The possible valid values of this enum may be found here.
Additionally, fold the result of this check into the previous one with a logical
gtxn 0 TypeEnum int 1 == &&
Next, specify that the receiver of funds from the first transaction is equal to the sender of the second transaction (since the first transaction is paying the second transaction's fee).
gtxn 0 Receiver txn Sender == &&
Next, check that the first transaction's amount is equal to the fee of the second transaction.
gtxn 0 Amount txn Fee == &&
Now check that the transaction associated with this contract (the payment whose fee is being paid for) is the second transaction in the group.
When writing contracts intended to be used in group transactions, it is a good idea to check that the group is laid out as expected. If you don't do this, a contract might be tricked into serving multiple, unexpected roles within the group.
txn GroupIndex int 1 == &&
Check that the second transaction is a payment.
txn TypeEnum int 1 == &&
Finally, check that all of the fields in the second transaction are equal to their corresponding contract parameters. Fold all of these checks into a single boolean.
txn Receiver addr TMPL_TO == && txn CloseRemainderTo addr TMPL_CLS == && txn Amount int TMPL_AMT == && txn FirstValid int TMPL_FV == && txn LastValid int TMPL_LV == && txn Lease byte base64 TMPL_LEASE == &&
At this point, the stack contains just one value: a boolean indicating whether or not the transaction has been approved by this contract.