def __init__(self, mode: OpUpMode, target_app_id: Expr = None): """Create a new OpUp object. Args: mode: OpUpMode that determines the style of budget increase to use. See the OpUpMode Enum for more information. target_app_id (optional): In Explicit mode, the OpUp utility requires the app_id to target for inner app calls. Defaults to None. """ # With only OnCall and Explicit modes supported, the mode argument # isn't strictly necessary but it will most likely be required if # we do decide to add more modes in the future. if mode == OpUpMode.Explicit: if target_app_id is None: raise TealInputError( "target_app_id must be specified in Explicit OpUp mode") require_type(target_app_id, TealType.uint64) self.target_app_id = target_app_id elif mode == OpUpMode.OnCall: if target_app_id is not None: raise TealInputError( "target_app_id is not used in OnCall OpUp mode") else: raise TealInputError("Invalid OpUp mode provided") self.mode = mode
def __init__( self, slot: Optional[ScratchSlot], value: Expr, index_expression: Expr = None ): """Create a new ScratchStore expression. Args: slot (optional): The slot to store the value in. value: The value to store. index_expression (optional): As an alternative to slot, an expression can be supplied for the slot index. """ super().__init__() if (slot is None) == (index_expression is None): raise TealInternalError( "Exactly one of slot or index_expressions must be provided" ) if index_expression: if not isinstance(index_expression, Expr): raise TealInputError( "index_expression must be an Expr but was of type {}".format( type(index_expression) ) ) require_type(index_expression, TealType.uint64) self.slot = slot self.value = value self.index_expression = index_expression
def validate_txn_index_or_throw(txnIndex: Union[int, Expr]): if not isinstance(txnIndex, (int, Expr)): raise TealInputError( f"Invalid txnIndex type: Expected int or Expr, but received {txnIndex}" ) if isinstance(txnIndex, Expr): require_type(txnIndex, TealType.uint64)
def store(self, value: Expr) -> Expr: """Store value in Scratch Space Args: value: The value to store. Must conform to this ScratchVar's type. """ require_type(value, self.type) return self.slot.store(value)
def __init__( self, op: Op, inputType: TealType, outputType: TealType, arg: Expr ) -> None: super().__init__() require_type(arg, inputType) self.op = op self.outputType = outputType self.arg = arg
def __getitem__(self, index: Union[int, Expr]) -> TxnaExpr: if type(index) is int: if index < 0: raise TealInputError("Invalid array index: {}".format(index)) else: require_type(cast(Expr, index), TealType.uint64) return self.txnObject.makeTxnaExpr(self.accessField, index)
def globalDel(cls, key: Expr) -> "App": """Delete a key from the global state of the current application. Args: key: The key to delete from the global application state. Must evaluate to bytes. """ require_type(key, TealType.bytes) return cls(AppField.globalDel, [key])
def __init__(self, type: JsonRefType, json_obj: Expr, key: Expr) -> None: super().__init__() self.type = type require_type(json_obj, TealType.bytes) self.json_obj = json_obj require_type(key, TealType.bytes) self.key = key
def __init__(self, asset: Expr) -> None: """Create a new AssetParamObject for the given asset. Args: asset: An identifier for the asset. It must be an index into Txn.ForeignAssets that corresponds to the asset to check, or since v4, an asset ID that appears in Txn.ForeignAssets. In either case, it must evaluate to uint64. """ require_type(asset, TealType.uint64) self._asset: Final = asset
def Do(self, doBlock: Expr, *do_block_multi: Expr): if self.doBlock is not None: raise TealCompileError("While expression already has a doBlock", self) doBlock = _use_seq_if_multiple(doBlock, *do_block_multi) require_type(doBlock, TealType.none) self.doBlock = doBlock return self
def globalPut(cls, key: Expr, value: Expr) -> "App": """Write to the global state of the current application. Args: key: The key to write in the global application state. Must evaluate to bytes. value: THe value to write in the global application state. Can evaluate to any type. """ require_type(key, TealType.bytes) require_type(value, TealType.anytype) return cls(AppField.globalPut, [key, value])
def type_of(self): if self.thenBranch is None: raise TealCompileError("If expression must have a thenBranch", self) if self.elseBranch is None: # if there is only a thenBranch, it must evaluate to TealType.none require_type(self.thenBranch, TealType.none) return self.thenBranch.type_of()
def __init__(self, app: Expr) -> None: """Create a new AppParamObject for the given application. Args: app: An identifier for the app. It must be an index into Txn.ForeignApps that corresponds to the app to check, or since v4, an application ID that appears in Txn.ForeignApps or is the CurrentApplicationID. In either case, it must evaluate to uint64. """ require_type(app, TealType.uint64) self._app: Final = app
def localDel(cls, account: Expr, key: Expr) -> "App": """Delete a key from an account's local state for the current application. Args: account: An index into Txn.Accounts that corresponds to the account to check, must be evaluated to uint64 (or, since v4, an account address that appears in Txn.Accounts or is Txn.Sender, must be evaluated to bytes). key: The key to delete from the account's local state. Must evaluate to bytes. """ require_type(account, TealType.anytype) require_type(key, TealType.bytes) return cls(AppField.localDel, [account, key])
def __getitem__(self, txnIndex: Union[int, Expr]) -> TxnObject: if type(txnIndex) is int: if txnIndex < 0 or txnIndex >= MAX_GROUP_SIZE: raise TealInputError( "Invalid Gtxn index {}, shoud be in [0, {})".format( txnIndex, MAX_GROUP_SIZE)) else: require_type(cast(Expr, txnIndex), TealType.uint64) return TxnObject( lambda field: GtxnExpr(txnIndex, field), lambda field, index: GtxnaExpr(txnIndex, field, index), )
def address(cls, app: Expr) -> MaybeValue: """Get the escrow address for the application. Args: app: An index into Txn.applications that correspond to the application to check. Must evaluate to uint64. """ require_type(app, TealType.uint64) return MaybeValue(Op.app_params_get, TealType.bytes, immediate_args=["AppAddress"], args=[app])
def __init__( self, stringArg: Expr, startArg: Expr, ) -> None: super().__init__() require_type(stringArg, TealType.bytes) require_type(startArg, TealType.uint64) self.stringArg = stringArg self.startArg = startArg
def __init__(self, op: Op, inputType: TealType, outputType: TealType, args: Sequence[Expr]): super().__init__() if len(args) == 0: raise TealInputError("NaryExpr requires at least one child") for arg in args: if not isinstance(arg, Expr): raise TealInputError( "Argument is not a PyTeal expression: {}".format(arg)) require_type(arg, inputType) self.op = op self.outputType = outputType self.args = args
def optedIn(cls, account: Expr, app: Expr) -> "App": """Check if an account has opted in for an application. Args: account: An index into Txn.Accounts that corresponds to the account to check, must be evaluated to uint64 (or, since v4, an account address that appears in Txn.Accounts or is Txn.Sender, must be evaluated to bytes). app: An index into Txn.applications that corresponds to the application to read from, must be evaluated to uint64 (or, since v4, an application id that appears in Txn.applications or is the CurrentApplicationID, must be evaluated to int). """ require_type(account, TealType.anytype) require_type(app, TealType.uint64) return cls(AppField.optedIn, [account, app])
def creator(cls, asset: Expr) -> MaybeValue: """Get the creator address for an asset. Args: asset: An index into Txn.assets that corresponds to the asset to check. Must evaluate to uint64. """ require_type(asset, TealType.uint64) return MaybeValue( Op.asset_params_get, TealType.bytes, immediate_args=["AssetCreator"], args=[asset], )
def extraProgramPages(cls, app: Expr) -> MaybeValue: """Get the number of Extra Program Pages of code space for the application. Args: app: An index into Txn.applications that correspond to the application to check. Must evaluate to uint64. """ require_type(app, TealType.uint64) return MaybeValue( Op.app_params_get, TealType.uint64, immediate_args=["AppExtraProgramPages"], args=[app], )
def localNumByteSlice(cls, app: Expr) -> MaybeValue: """Get the number of byte array values allowed in Local State for the application. Args: app: An index into Txn.applications that correspond to the application to check. Must evaluate to uint64. """ require_type(app, TealType.uint64) return MaybeValue( Op.app_params_get, TealType.uint64, immediate_args=["AppLocalNumByteSlice"], args=[app], )
def clearStateProgram(cls, app: Expr) -> MaybeValue: """Get the bytecode of Clear State Program for the application. Args: app: An index into Txn.applications that correspond to the application to check. Must evaluate to uint64. """ require_type(app, TealType.uint64) return MaybeValue( Op.app_params_get, TealType.bytes, immediate_args=["AppClearStateProgram"], args=[app], )
def authAddr(cls, acct: Expr) -> MaybeValue: """Get the authorizing address for an account. If the account is not rekeyed, the empty addresss is returned. Args: acct: An index into Txn.accounts that corresponds to the application to check or an address available at runtime. May evaluate to uint64 or an address. """ require_type(acct, TealType.anytype) return MaybeValue( Op.acct_params_get, TealType.bytes, immediate_args=["AcctAuthAddr"], args=[acct], )
def globalGetEx(cls, app: Expr, key: Expr) -> MaybeValue: """Read from the global state of an application. Args: app: An index into Txn.applications that corresponds to the application to read from, must be evaluated to uint64 (or, since v4, an application id that appears in Txn.applications or is the CurrentApplicationID, must be evaluated to uint64). key: The key to read from the global application state. Must evaluate to bytes. """ require_type(app, TealType.uint64) require_type(key, TealType.bytes) return MaybeValue(AppField.globalGetEx.get_op(), TealType.anytype, args=[app, key])
def EcdsaRecover(curve: EcdsaCurve, data: Expr, recovery_id: Expr, sigA: Expr, sigB: Expr) -> MultiValue: """Recover an ECDSA public key from a signature. All byte arguments must be big endian encoded. Args: curve: Enum representing the ECDSA curve used for the public key data: Hash value of the signed data. Must be 32 bytes long. recovery_id: value used to extract public key from signature. Must evaluate to uint. sigA: First component of the signature. Must evaluate to bytes. sigB: Second component of the signature. Must evaluate to bytes. Returns: A MultiValue expression representing the two components of the public key, big endian encoded. """ if not isinstance(curve, EcdsaCurve): raise TealTypeError(curve, EcdsaCurve) if curve != EcdsaCurve.Secp256k1: raise TealInputError("Recover only supports Secp256k1") require_type(data, TealType.bytes) require_type(recovery_id, TealType.uint64) require_type(sigA, TealType.bytes) require_type(sigB, TealType.bytes) return MultiValue( Op.ecdsa_pk_recover, EcdsaPubkey, immediate_args=[curve.arg_name], args=[data, recovery_id, sigA, sigB], compile_check=lambda options: verifyFieldVersion( curve.arg_name, curve.min_version, options.version), )
def minBalance(cls, acct: Expr) -> MaybeValue: """Get the minimum balance in microalgos for an account. Args: acct: An index into Txn.accounts that corresponds to the application to check or an address available at runtime. May evaluate to uint64 or an address. """ require_type(acct, TealType.anytype) return MaybeValue( Op.acct_params_get, TealType.uint64, immediate_args=["AcctMinBalance"], args=[acct], )
def defaultFrozen(cls, asset: Expr) -> MaybeValue: """Check if an asset is frozen by default. Args: asset: An index into Txn.assets that corresponds to the asset to check, must be evaluated to uint64 (or since v4, an asset ID that appears in Txn.assets). """ require_type(asset, TealType.uint64) return MaybeValue( Op.asset_params_get, TealType.uint64, immediate_args=["AssetDefaultFrozen"], args=[asset], )
def clawback(cls, asset: Expr) -> MaybeValue: """Get the clawback address for an asset. Args: asset: An index into Txn.assets that corresponds to the asset to check, must be evaluated to uint64 (or since v4, an asset ID that appears in Txn.assets). """ require_type(asset, TealType.uint64) return MaybeValue( Op.asset_params_get, TealType.bytes, immediate_args=["AssetClawback"], args=[asset], )
def total(cls, asset: Expr) -> MaybeValue: """Get the total number of units of an asset. Args: asset: An index into Txn.assets that corresponds to the asset to check, must be evaluated to uint64 (or since v4, an asset ID that appears in Txn.assets). """ require_type(asset, TealType.uint64) return MaybeValue( Op.asset_params_get, TealType.uint64, immediate_args=["AssetTotal"], args=[asset], )