Skip to content
This new developer portal is under construction. For complete documentation, please refer to the old developer portal.

Logic Signatures

Logic Signatures (LogicSig), are a feature in Algorand that allows transactions to be authorized using a TEAL program. These signatures are used to sign transactions from either a Contract Account or a Delegated Account.

Logic signatures contain logic used to sign transactions. When submitted with a transaction, the Algorand Virtual Machine (AVM) evaluates the logic to determine whether the transaction is authorized. If the logic fails, the transaction will not execute. Compiled logic signatures generate a corresponding Algorand account that can hold Algos or assets. Transactions from this account require successful logic execution. Alternatively, logic signatures can delegate signature authority, where another account signs the logic signature to authorize transactions from the original account.

Niche Use Cases for Logic Signatures

While smart contracts are the preferred solution in most cases, logic signatures can be useful for:

  1. Costly Operations: Logic signatures can be used for tasks that require expensive operations like ed25519verify but are not part of a composable smart contract.
  2. Free Transactions: Logic signatures can allow certain users to send specific transactions without paying fees, as long as the logic restricts the transaction rate.
  3. Delegated Authority: Used in cases where certain operations need to be delegated to another account or key, such as transferring assets in a custodial system.
  4. Escrow/Contract Accounts: In cases requiring conditional spending based on specific logic. However, smart contracts are generally preferred when dealing with escrow scenarios.

Logic Signature Structure

Logic Signatures are structures that contain four parts and are considered valid if one of the following scenarios is true:

Figure: Logic Signature Structure

  1. Signature (Sig): A valid signature of the program from the account sending the transaction.
  2. Multi-Signature (Msig): A valid multi-signature of the program from the multi-sig account sending the transaction.
  3. Program Hash: The hash of the program matches the sender’s address.

In the first two cases, delegation is possible, allowing account owners to sign the logic signature and authorize transactions on their behalf. The third case pertains to Contract Accounts, where the program fully governs the account, and Algos or assets can only leave the account when the logic approves a transaction.

Computational Cost

Smart contracts and logic signatures are also limited in opcode cost for optimal performance. This cost is evaluated when a smart contract runs and represents its computational expense. Every opcode executed by the AVM has a numeric value that represents its computational cost. Most opcodes have a computational cost of 1. Some, such as SHA256 (cost 35) or ed25519verify (cost 1900) have substantially larger computational costs. The TEAL Opcodes( FUTURELINK: description ) reference lists the opcode cost for every opcode. Logic signatures are limited to 20,000 for total computational cost. In comparison, traditional applications can handle up to 700 opcode cost per transaction, significantly increasing the computational flexibility, allowing for more complex operations per transaction than Algorand’s current limitations.

Modes of Use

Logic signatures have two basic usage scenarios: as a contract account or as a delegated signature. These modes approve transactions in different ways, which are described below. Both modes use Logic Signatures. While using logic signatures for contract accounts is possible, it is now possible to create a contract account using a smart contract.

  1. Contract Account Mode: When compiled, a logic signature generates an Algorand address. This address functions like a regular account but is governed by the logic in the logic signature. Funds in the account can only be spent when a transaction satisfies the logic of the signature.
  2. Delegated Signature Mode: An account can sign a TEAL program, delegating authority to use the signature for future transactions. For instance, a user can create a recurring payment logic signature and allow a vendor to use it to collect payments within predefined limits.

Contract Account

For each unique compiled logic signature program there exists a single corresponding Algorand address, output by goal clerk compile. For more details, refer here. To use a TEAL program as a contract account, send Algos to its address to turn it into an account on Algorand with a balance. Outwardly, this account looks no different from any other Algorand account and anyone can send it Algos or Algorand Standard Assets to increase its balance. The account differs in how it authenticates spends from it, in that the logic determines if the transaction is approved. To spend from a contract account, create a transaction that will evaluate True against the TEAL logic, then add the compiled TEAL code as its logic signature. It is worth noting that anyone can create and submit the transaction that spends from a contract account as long as they have the compiled TEAL contract to add as a logic signature.

Figure: TEAL Contract Account

Delegated Approval

Logic signatures can also be used to delegate signature authority, which means that a private key can sign a TEAL program and the resulting output can be used as a signature in transactions on behalf of the account associated with the private key. The owner of the delegated account can share this logic signature, allowing anyone to spend funds from his or her account according to the logic within the TEAL program. For example, if Alice wants to set up a recurring payment with her utility company for up to 200 Algos every 50000 rounds, she creates a TEAL contract that encodes this logic, signs it with her private key, and gives it to the utility company. The utility company uses that logic signature in the transaction they submit every 50000 rounds to collect payment from Alice. The logic signature can be produced from either a single or multi-signature account.

Figure: TEAL Delegated Signature

For more information on how to sign using logic signatures refer to signing using logic signatures

Code example:

Return Seq(
Assert(Txn.Amount() == Int(1)),
Assert(Txn.TypeEnum() == TxnType.Payment),
Assert(Txn.Receiver() == intended_receiver)
)

This contract can:

  1. CloseRemainderTo vulnerability: The code doesn’t check the CloseRemainderTo field. This allows a transaction to drain the account by closing it to another address.
  2. RekeyTo vulnerability: There’s no check for the RekeyTo field. This could lead to loss of authorization if a transaction rekeys the account to another address.
  3. Fee draining: The code doesn’t limit the transaction fee, potentially allowing the account to be drained via high fees.
  4. Lack of group transaction checks: If this LogicSig is used in a group transaction, it could be called multiple times, potentially leading to unexpected behavior.
  5. No expiration mechanism: The LogicSig doesn’t include any expiration mechanism, which is recommended for security.

Transition from Logic Signatures to Smart Contracts

Logic signatures were historically the only way to write smart contracts on Algorand before applications were introduced. They were used in specific scenarios, including asset transfers, multisignature transactions, and atomic swaps. Applications, which came later, offer enhanced functionality and flexibility, but logic signatures remain important for simpler operations.

  • Escrow accounts: Before inner transactions, contract accounts were used as escrow. Since AVM 1.0/TEAL v5, application accounts with inner transactions are preferred. However, rare cases (like TEAL v8 limits) still require contract accounts for specific methods, but this should be minimized.
  • Multiple escrow accounts: Rekeying accounts to the application account simplifies managing multiple escrows. With advancements in Algorand (such as inner transactions and storage boxes), many use cases previously handled by logic signatures can now be implemented more efficiently with smart contracts. It is generally recommended to migrate to smart contracts unless a specific use case requires logic signatures. While logic signatures offer certain niche benefits, their use should be limited to specific scenarios as discussed in niche use cases section. Refer to the code example section which explains using logic signature. For most applications, especially those involving complex dApp logic, inner transactions, or composability, smart contracts are the preferred solution. If using logic signatures, ensure strict validation of transaction fields and implement expiration mechanisms to mitigate risks.

Code Example

The following code checks if the transaction is a self-payment with zero amount and no rekey or close actions. It ensures the transaction happens within a specific round and prevents replay attacks by verifying the genesis hash and lease field.

1
@logicsig
2
def self_payment() -> bool:
3
"""
4
This Delegated Account will authorize a single empty self payment in a block known ahead of time.
5
"""
6
return (
7
Txn.type_enum == TransactionType.Payment
8
and Txn.receiver == Txn.sender
9
and Txn.amount == 0
10
and Txn.rekey_to == Global.zero_address
11
and Txn.close_remainder_to == Global.zero_address
12
and Txn.fee == Global.min_txn_fee
13
and Global.genesis_hash == TemplateVar[Bytes]("TARGET_NETWORK_GENESIS")
14
# Acquiring a lease with last_round and a non-empty lease field prevents replay attacks.
15
and Txn.last_valid == TemplateVar[UInt64]("LAST_ROUND")
16
and Txn.lease == op.sha256(b"self-payment")
17
)

The following logic signature ensures the contract will cover the fee for a prior transaction in a group, which must be an application call to a known app. It confirms the fee for this app call is zero and ensures the conditions are met for the payment to proceed.

1
@logicsig
2
def subsidize_app_call() -> bool:
3
"""
4
This Contract Account will subsidize the fees for any AppCall transaction directed to a known application.
5
"""
6
return (
7
# is it safe to pay for the fees of the previous transaction?
8
Txn.type_enum == TransactionType.Payment
9
and Txn.receiver == Txn.sender
10
and Txn.amount == 0
11
and Txn.rekey_to == Global.zero_address
12
and Txn.close_remainder_to == Global.zero_address
13
and Txn.fee == 2 * Global.min_txn_fee
14
and Txn.last_valid <= TemplateVar[UInt64]("EXPIRATION_ROUND")
15
and Global.genesis_hash == TemplateVar[Bytes]("TARGET_NETWORK_GENESIS")
16
# is the previous transaction in the group an application call to a known app?
17
and GTxn.type_enum(Txn.group_index - 1) == TransactionType.ApplicationCall
18
and GTxn.application_id(Txn.group_index - 1)
19
== TemplateVar[Application]("KNOWN_APP")
20
and GTxn.fee(Txn.group_index - 1) == 0
21
)

Limitations and Considerations

  • Security Considerations: Logic signatures do not inherently define how frontends, particularly wallets, should consider them safe. It is recommended that only the signing of audited or otherwise trusted logic signatures be supported. The decision is made solely by the frontends as to which logic signatures they allow to be signed.
  • Auditability and Flexibility on Upgrading: Logic Signatures are harder to audit than smart contracts in most settings and less flexible than smart contracts. While some simple dApps could be based on Logic Signatures, adding any feature would become problematic, and any upgrade would most likely be impossible.
  • Lack of Standardized ABI: Unlike smart contracts, Logic Signatures do not have a standardized ABI (Application Binary Interface). Smart contracts have ARC-4.
  • Potential for Malicious Use: Most wallets do not support signing delegated logic signatures, as this operation is potentially dangerous. A malicious delegated logic signature can remain dormant for years and can allow to siphon out funds from an account much later.
  • Non expiration: Also, logic signatures don’t expire by default. It’s always recommended to include an expiration block in the logic to prevent any lsig from being valid indefinitely. This helps mitigate long-term security risks.
  • Size and Cost Constraints: The maximum size of compiled TEAL code combined with arguments is 1000 bytes, and the maximum cost of TEAL code is 20000.
  • Public Nature of Code and Arguments: The logic signature code, the transaction fields, and the arguments of the logic signature are all public. An attacker can replay a transaction signed by a logic signature. Also, arguments of Logic Signatures are not signed by the sender account and are not part of the computation of the group ID.
  • Network Considerations: The same logic signature can be used in multiple networks. If a logic signature is signed with the intent of using it on TestNet, that same transaction can be sent to MainNet with that same logic signature. Its always recommended to check which network lsig is running on.