Source code for beaker.lib.storage.box_list

from pyteal import (
    BoxCreate,
    BoxExtract,
    BoxReplace,
    Bytes,
    CompileOptions,
    Expr,
    Int,
    TealBlock,
    TealSimpleBlock,
    TealType,
    abi,
)
from pyteal.types import require_type


[docs]class BoxList: """List stores a list of static types in a box, named as the class attribute unless an overriding name is provided"""
[docs] def __init__( self, value_type: type[abi.BaseType], elements: int, name: str | None = None ): ts = abi.type_spec_from_annotation(value_type) assert not ts.is_dynamic(), "Expected static type for value" assert ( ts.byte_length_static() * elements < 32e3 ), "Cannot be larger than MAX_BOX_SIZE" # Will be set later if its part of an Application self.name: Expr | None = None if name is not None: self.name = Bytes(name) self.value_type = ts self._element_size = ts.byte_length_static() self.element_size = Int(self._element_size) self._elements = elements self.elements = Int(self._elements) self._box_size = self._element_size * self._elements self.box_size = Int(self._box_size)
def __set_name__(self, owner: type, name: str) -> None: if self.name is None: self.name = Bytes(name)
[docs] def create(self) -> Expr: """creates a box with the given name and with a size that will allow storage of the number of the element specified.""" assert self.name is not None return BoxCreate(self.name, self.box_size)
[docs] class Element(Expr):
[docs] def __init__(self, name: Expr, element_size: Expr, idx: Expr): super().__init__() require_type(name, TealType.bytes) require_type(element_size, TealType.uint64) require_type(idx, TealType.uint64) self.name = name self.element_size = element_size self.idx = idx
[docs] def store_into(self, val: abi.BaseType) -> Expr: """decode the bytes from this list element into the instance of the type provided Args: val: An instance of the type to decode into """ return val.decode(self.get())
[docs] def get(self) -> Expr: """get the bytes for this element in the list""" return BoxExtract( self.name, self.element_size * self.idx, self.element_size )
[docs] def set(self, val: abi.BaseType) -> Expr: """set the bytes for this element in the list Args: The value to write into the list at the given index """ return BoxReplace(self.name, self.element_size * self.idx, val.encode())
def __str__(self) -> str: return f"List Element: {self.name}[{self.idx}]" def __teal__( self, compile_options: CompileOptions ) -> tuple[TealBlock, TealSimpleBlock]: return self.get().__teal__(compile_options)
[docs] def has_return(self) -> bool: return False
[docs] def type_of(self) -> TealType: return TealType.bytes
def __getitem__(self, idx: Expr) -> Element: assert self.name is not None return self.Element(self.name, self.element_size, idx)