algorand / go-algorand

Algorand's official implementation in Go.
https://developer.algorand.org/
Other
1.35k stars 471 forks source link

TEAL - Document arguments and add another variant #1051

Open jeapostrophe opened 4 years ago

jeapostrophe commented 4 years ago

Nearly all of the TEAL examples provided by Algorand use "template variables" in their source to allow specific values to be substituted prior to the program being compiled. These then become constants embedded in the program, which can then be signed by another account to delegate access to it, thereby fixing those values before the delegation happens.

On the other hand, TEAL also has the concepts of arguments. The Specification says, "Some 'Args' may be attached to a transaction being validated by a TEAL program. Args are an array of byte strings.", which implies these are like runtime arguments and are attached when a transaction is used.

However, the SDKs (I'm looking at the JS SDK for this example) offer the following two functions:

makeLogicSig : program x arguments -> signature
signLogicSigTransaction : unsigned-txn x signature -> signed-txn

I think these SDK functions and the specification are inconsistent. If the arguments are "attached to a transaction being validated", then they should be arguments to signLogicSigTransaction. Similarly, if makeLogicSig really will take arguments, then it should be necessary to have "template variables" in TEAL programs, because they could just as well be compile time arguments. By my reading of the SDKs, that's what is actually implemented now.

In other words, I think that the SDKs should offer these functions:

makeLogicSig : program x arguments -> signature
signLogicSigTransaction : unsigned-txn x signature x arguments -> signed-txn

where the arguments provided at signLogicSigTransaction time are accessible via the arg opcode while the arguments provided by makeLogicSig time are accessible via a new compile_arg virtual opcode. This "virtual opcode" would register a spot in the constant block for the argument and compile into a constant access. Then the SDKs implement makeLogicSig to take the provided arguments and insert them into the corresponding constant block locations.

This pattern would allow Algorand programs to not ship the source code for their TEAL contracts for instantiation of template variables at runtime by clients, but could instead pre-compile them with goal clerk and then instantiate the arguments as above. This would also simplify the various SDKs because they would not have to implement the TEAL compiler or otherwise provide access to it.

jeapostrophe commented 4 years ago

It may be nice/possible to have a single opcode, arg, but allow there to be multiple places to add arguments, so I can add arguments at make time and then add more at sign time. I suspect that this would require too much out of the SDK though.

pzbitskiy commented 4 years ago

It may be nice/possible to have a single opcode, arg

In theory LogicSig program might look into ApplicationArgs and take their value into account. Additionally ApplicationArgs is part of a transaction and txn/txna are made for accessing regular transaction fields.

JasonWeathersby commented 4 years ago

Arguments are not under the signature and can be set before or after the logic sig is signed. IE you can change them before you submit a transaction.

jeapostrophe commented 4 years ago

Thanks @JasonWeathersby

That is true and good to know, but I am making a different point and asking a different question.

My point is that the existing API, makeLogicSig, implies that the arguments are “secure and signed” because you give them before the signature and, in fact, all existing uses of TEAL actually use a feature like that by baking arguments into the text of the program. So this is a feature that people (a) actually want, (b) think they have because of the way API the looks, but (c) don’t actually have because of you can actually modify the arguments at transaction dispatch time.

I believe that my issue is very detailed on this point. I am not asking a question about how an existing feature works; I am pointing out a missing feature and what appears to be an inconsistency between the API and the docs.

I think that the recent change to have algod run the TEAL compiler is a short-cut to the real feature, which is that TEAL contract authors want to be able to write code that is parameterized at two separate points: once when it gets signed (so-called "template" variables) and once when it gets (arguments), but TEAL only supports the second and the API implies it supports the first.

JasonWeathersby commented 4 years ago

I agree. Ideally, both cases should be supported. They are today but the first use should be covered under the signature.