Hi,
A recurring difficulty when building and reviewing algorand applications is the lack of clear information about transactions groups. Most of the user interactions with an application requires execution of multiple contracts. The current standards only give specifications to describe a single contract. Lack of this information about the transaction groups and the logic-sigs required for a transaction makes it difficult to use and reason about the application.
To ease this, we propose the creation of a lightweight group information specification.
Motivating example
For example, a function foo in contract A might require some validation to be performed in a function bar in contract B. To ensure the call of B.bar, A.foo might check B.bar is executed using the following patterns
B is a logic sig, A checks that B.bar is executed by using logic-sig address:
def assert_B_bar_is_called() -> Expr:
return Assert(Txn.sender() == B_BAR_LOGIC_SIG_ADDRESS)
B is an application:
@router.method(no_op=CallConfig.CALL)
def foo(b_bar: abi.ApplicationCallTransaction):
return Seq(
Assert(And(
b_bar.get().application_id() == B_APP_ID,
b_bar.get().application_args[0] == MethodSignature("bar()"),
))
# [...]
)
However it is difficult to reason for developer, security reviewers and tools to understand the relation between the function calls.
This pattern is frequently used, for example in:
Proposal summary
We propose the creation of a lightweight group information specification using the ARC-4 specification as:
- The group information specification contains a list of ARC-4 contract descriptions of every contract in the project/protocol.
- Each ARC-4 contract description is updated as following:
- Every transaction argument description will have two fields “has_logic_sig” and “logic_sig_name” that will be filled if that transaction is signed with a logic-sig.
- Every application call transaction type argument will have the “application_name” field.
This will help developers and reviewers to understand the interactions between the applications. In addition the information can be used by automated tools (ex tealer) to be more accurate.
In the long term, this format might even be implemented as code notation for high level language. For example, pyteal could use an annotation that allows developers to assign the reference to the “router” object of the target application for application call transaction type arguments.
The implications of the above approach need to be investigated. We are opening this issue to receive feedback from the community.
Proposal draft
The following describe an example of what the group information could look like, but is not final and might require iteration
In order to cover all general use cases, the following specification can be considered:
- The group specification will have a list of group-transactions. A group transaction is a list of transactions.
- Each transaction has following fields:
-
txn_idx
: used to reference the transaction within the group transaction. -
txn_type
: The transaction type. -
has_logic_sig
: True if the transaction will be signed using a logic-sig. -
logic_sig
: The name of the logic-sig contract and the function ifhas_logic_sig
is True. -
application
: The name of the application contract and the function iftxn_type
isappl
. -
absolute_index
: The index of this transaction in the on-chain group transaction(Txn.group_index()
) if it is fixed. -
relative_indexes
: Relative indexes of other transactions in the group from this transaction.
-
Example:
groups:
- - txn_idx: T0
txn_type: appl
has_logic_sig: true
logic_sig:
contract: B
function: bar
application:
contract: A
function: foo
absolute_index: 0
- - txn_idx: T0
txn_type: appl
application:
contract: B
function: bar
- txn_idx: T1
txn_type: appl
application:
contract: A
function: foo
absolute_index: 1
relative_indexes:
- target_txn_idx: T0
relative_index: -1 # B bar is previous transaction
We would love to receive community’s feedback on this idea proposal.
Authors: