I’m writing a stateful contract that should approve a transaction group if its first element is an “asset transfer transaction” and the asset to be transferred has the url “test”. (The contract has some additional logic, but this is the part I don’t understand.)
I know that Gtxn[0].xfer_asset() contains the ID of the asset to be transferred. But how to get the url from this?
I know that Gtxn[0] has the attribute assets, but I don’t know what it represents. Gtxn[2].assets[0].url() == Bytes("test") gives me the error AttributeError: 'GtxnaExpr' object has no attribute 'url', which is fair enough because instances of the class GtxnaExprdon’t seem to have any attributes at all.
I think only transactions of type TxnType.AssetConfig have the attribute config_asset_url(). My transaction is of type TxnType.AssetTransfer and doesn’t have that attribute.
You need to have the asset ID transferred in the first transaction to also be indicated as a “foreign asset” for the application call transaction. See Overview - Algorand Developer Portal
You can check it’s the correct asset using something like
Txn.assets[0] == Gtxn[0].xfer_asset()
(First [0] is because it’s the first foreign asset; second [0] is because you want to look at the asset of the first transaction.)
The line Assert(AssetParam.url(Int(0)).value() == Bytes('test')) gives me the error pyteal.TealCompileError: Scratch slot load occurs before store. Any idea what that means and how it can be fixed?
# get the total number of units for Txn.assets[0]
# if the asset is invalid, exit with an error
assetURL = AssetParam.url(Int(0))
program = Seq([
assetURL,
Assert(assetURL.hasValue()),
assetURL.value()
])
Thanks, that works. Tragically, this does not seem to be supported in Signature mode. When I try to compile this code in signature mode I get the error pyteal.TealInputError: Op not supported in Signature mode: asset_params_get. Is there a way to get this functionality in Signature mode? I am aware of the possible workaround of creating a Stateful contract that makes these checks, but I was hoping to get away with only Signature mode.
No there is no way you can do that in Signature mode.
The reason is that TEAL scripts in Signature mode are evaluated when the transactions is received by the node and are not re-evaluated when a block is proposed.
This is to allow for higher performance.
But this means that in Signature mode, TEAL cannot access any data that may change between the time the transaction is submitted and the time the transaction is added to a block.
I see, that makes sense. Can the creator address be used in Signature mode? There is no risk of this changing. But I didn’t find any way to access that at all (in Signature or Application mode).
There is a risk changing: the asset may not exist when you submit the transaction, but then it exists when it’s in a block.
But actually, the current constraint is a bit stronger: in Signature mode, the only things that can be accessed are fields of the transactions in the group, and nothing from the ledger.