### boot_process.txt Startup Process *************** Standard library provides a built-in bootloader that bridges internal ABI to a more Pythonic interface. Bootloader is located in module "_genlayer_runner" and is executed on import. Bootloader Module ================= "_genlayer_runner" handles contract execution in three distinct modes: Entry Points ------------ The bootloader dispatches execution based on "entry_kind" from the VM message: MAIN ~~~~ Handles standard contract method calls and initialization. * Loads user "contract" module and resolves the target method of a declared "Contract" class * Validates method access permissions (public/private, payable) * Handles special methods: "__receive__", "__handle_undefined_method__", "__on_errored_message__" * Routes initialization calls to "__init__" method * Enforces security restrictions on dunder methods SANDBOX ~~~~~~~ Executes pickled function objects. CONSENSUS_STAGE ~~~~~~~~~~~~~~~ Runs consensus stage functions with additional stage data parameter (leader non-deterministic blocks outputs or "None"). Method Resolution ----------------- For MAIN entry kind, the bootloader implements comprehensive method resolution: * **Initialization**: Routes to private "__init__" method during contract deployment * **Named Methods**: Resolves public method calls by name with validation * **Special Handling**: Supports "__receive__" for direct calls and "__handle_undefined_method__" for undefined method calls * **Security**: Blocks calls to methods starting with "__" and unknown special methods starting with "#" Error Handling -------------- The bootloader provides centralized error management: * Catches "genlayer.gl.vm.UserError" exceptions and triggers rollback with error message * Validates contract structure and method accessibility * Returns appropriate error messages for invalid method calls Profiling Support ----------------- Optional performance profiling when "GENLAYER_ENABLE_PROFILER" environment variable is set to "true": * Uses "cProfile" with microsecond timing precision * Outputs compressed, base64-encoded statistics to stderr on exit * Integrates with *GenVM* debugging infrastructure Storage Integration ------------------- Manages contract storage lifecycle: * Locks default *Storage Slot*s during contract initialization * Provides contract instance from the root slot ### changelog.txt Change Log ********** v0.1.8 ====== Breaking Changes ---------------- 1. Calldata encoding behavior changed - dataclasses now encoded automatically without requiring custom "default" parameter 2. "genlayer.py.public_abi" file marked as auto-generated - manual edits will be overwritten New Features ------------ 1. **Enhanced calldata encoding**: Automatic dataclass encoding support without custom default functions 2. **Standardized error types**: New "VmError" enum for consistent error handling across the platform 3. **Extended public ABI**: Additional constants for internal VM operations ("CODE_SLOT_OFFSET") API Improvements ---------------- 1. Simplified dataclass serialization - no longer requires explicit "default" parameter in "calldata.encode()" 2. Better type safety with standardized error enums 3. Cleaner API for encoding complex data structures v0.1.3 ====== Migration Guide --------------- This section provides code examples for migrating from v0.1.0 to v0.1.3: Contract Interfaces ~~~~~~~~~~~~~~~~~~~ # v0.1.0 contract = gl.ContractAt(address) contract.view().some_method() contract.emit().some_method() # v0.1.3 contract = gl.get_contract_at(address) contract.view().some_method() contract.emit().some_method() Error handling ~~~~~~~~~~~~~~ # v0.1.0 from genlayer import Rollback gl.advanced.rollback_immediate("error message") # v0.1.3 from genlayer.gl.vm import UserError # or use gl.vm.UserError gl.advanced.user_error_immediate("error message") VM operations ~~~~~~~~~~~~~ # v0.1.0 gl.advanced.run_nondet(leader_fn, validator_fn) # v0.1.3 gl.vm.run_nondet(leader_fn, validator_fn) EVM contracts ~~~~~~~~~~~~~ # v0.1.0 @gl.eth_contract class MyEthContract: # contract definition # v0.1.3 @gl.evm.contract_interface class MyEthContract: # contract definition Non-deterministic functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # v0.1.0 result = gl.get_webpage(url, mode='text') response = gl.exec_prompt("prompt text") # v0.1.3 result = gl.nondet.web.render(url, mode='text') response = gl.nondet.exec_prompt("prompt text") Equivalence principles ~~~~~~~~~~~~~~~~~~~~~~ # v0.1.0 result = gl.eq_principle_strict_eq(fn) result = gl.eq_principle_prompt_comparative(fn, principle) # v0.1.3 result = gl.eq_principle.strict_eq(fn) result = gl.eq_principle.prompt_comparative(fn, principle) Breaking Changes ---------------- 1. Removed "Rollback" exception from top-level imports - use "genlayer.gl.vm.UserError" instead 2. Error handling methods now use "#error" and "#get-schema" special method names from "genlayer.py.public_abi.SpecialMethod" 3. Contract interface changes: "eth_contract" renamed to "evm_contract_interface" in EVM module New Features ------------ 1. **Module reorganization**: Core functionality moved to "genlayer.gl" namespace with lazy loading for better performance 2. **Contract interface system**: New "@contract_interface" decorator for type-safe contract interactions 3. **Enhanced contract deployment**: "deploy_contract" function with deterministic addressing via salt nonce 4. **Contract proxy system**: "get_contract_at" function returns proxy objects with "view()" and "emit()" methods 5. **Advanced event system**: "Event" class with proper topic generation and indexed field support 6. **VM operations**: New "genlayer.gl.vm" module with "run_nondet", "spawn_sandbox" functions 7. **EVM integration**: Enhanced "genlayer.py.evm" module with contract generation capabilities 8. **Equivalence principles**: New "genlayer.gl.eq_principle" module with "strict_eq", "prompt_comparative", "prompt_non_comparative" 9. **Advanced utilities**: "genlayer.gl.advanced" module with "user_error_immediate" and "emit_raw_event" API Improvements ---------------- 1. Storage system improvements with better slot management 2. Type annotations added for WASI bindings ("_genlayer_wasi.pyi") 3. Enhanced error handling with "UserError" replacing "Rollback" 4. Better lazy loading system for improved import performance 5. Documentation generation support with "GENERATING_DOCS" environment variable v0.1.0 ====== Initial release ### genlayer.txt Package genlayer **************** Top level ========= Common import for all contracts It exposes most of the types to the top scope and encapsulates other utility under "gl" namespace which is a proxy to "genlayer.gl" genlayer.gl Blockchain specific functionality, that won't work without GenVM and reexports form "genlayer.py" provided for convenience Proxy to "genlayer.gl" module. class genlayer.Address Bases: "object" Represents GenLayer Address SIZE: Final[int] = 20 Constant that represents size of a Genlayer address __eq__(r) Return self==value. __format__(fmt: Literal['x', 'b64', 'cd', '']) -> str Default object formatter. Return str(self) if format_spec is empty. Raise TypeError otherwise. Return type: str __ge__(r) Return self>=value. __gt__(r) Return self>value. __hash__() Return hash(self). __init__(val: str | Buffer) Parameters: **val** (*str** | **Buffer*) -- either a hex encoded address (that starts with '0x'), or base64 encoded address, or buffer of 20 bytes Warning: checksum validation is not performed __le__(r) Return self<=value. __lt__(r) Return self str Return repr(self). Return type: str __str__() -> str Return str(self). Return type: str property as_b64: str >>> Address('0x5b38da6a701c568545dcfcb03fcb875f56beddc4').as_b64 'WzjaanAcVoVF3PywP8uHX1a+3cQ=' Returns: base64 representation of an address (most compact string) property as_bytes: bytes >>> Address('0x5b38da6a701c568545dcfcb03fcb875f56beddc4').as_bytes b'[8\xdajp\x1cV\x85E\xdc\xfc\xb0?\xcb\x87_V\xbe\xdd\xc4' Returns: raw bytes of an address (most compact representation) property as_hex: str >>> Address('0x5b38da6a701c568545dcfcb03fcb875f56beddc4').as_hex '0x5B38Da6a701c568545dCfcB03FcB875f56beddC4' Returns: checksum string representation property as_int: u160 >>> Address('0x5b38da6a701c568545dcfcb03fcb875f56beddc4').as_int 1123907236495940146162314350759402901750813440091 >>> hex(Address('0x5b38da6a701c568545dcfcb03fcb875f56beddc4').as_int) '0xc4ddbe565f87cb3fb0fcdc4585561c706ada385b' Returns: int representation of an address (unsigned little endian) class genlayer.Array Bases: "Sequence", "SizedArray", "Generic" Constantly sized array that can be persisted on the blockchain __getitem__(idx: SupportsIndex) -> T __getitem__(idx: slice) -> Array __init__() This class can't be created with "Array()" Raises: **TypeError** -- always __iter__() __len__() -> int Return type: int __setitem__(idx: int, val: T) -> None class genlayer.DynArray Bases: "MutableSequence", "Generic" Represents exponentially growing array ("list" in python terms) that can be persisted on the blockchain __delitem__(idx: int) -> None __delitem__(idx: slice) -> None __getitem__(idx: int) -> T __getitem__(idx: slice) -> list[T] __init__() This class can't be created with "DynArray()" Raises: **TypeError** -- always __iter__() -> Any Return type: *Any* __len__() -> int Return type: int __repr__() -> str Return repr(self). Return type: str __setitem__(idx: SupportsIndex, val: T) -> None __setitem__(idx: slice, val: collections.abc.Sequence[T]) -> None append(value: T) -> None S.append(value) -- append value to the end of the sequence append_new_get() -> T Return type: T clear() -> None -- remove all items from S insert(index: int, value: T) -> None S.insert(index, value) -- insert value before index pop([index]) -> item -- remove and return item at index (default last). Raise IndexError if list is empty or index is out of range. genlayer.Keccak256(initial_input: Buffer | None = None) class genlayer.TreeMap Bases: "MutableMapping", "Generic" Represents a mapping from keys to values that can be persisted on the blockchain Tparam K: must implement "genlayer.py.storage.tree_map.Comparable" protocol ("<" is needed) and be storage-allowed Tparam V: must be storage-allowed __contains__(k: object) -> bool Return type: bool __delitem__(k: K) __getitem__(k: K) -> V Return type: V __gl_allow_storage__ = True __iter__() __len__() -> int Return type: int __repr__() -> str Return repr(self). Return type: str __setitem__(k: K, v: V) clear() -> None. Remove all items from D. compute_if_absent(k: K, supplier: Callable[[], V]) -> V Returns: Value associated with *k* if it is present, otherwise get's new value from the supplier, stores it at *k* and returns Return type: V get(k: K, /) -> V | None get(k: K, /, default: G) -> V | G Returns: Value associated with *k* or *default* if there is no such value get_or_insert_default(k: K) -> V Return type: V items() -> a set-like object providing a view on D's items Return type: *ItemsView* genlayer.allow_storage(cls: T) -> T Return type: T Integer aliases --------------- It also have aliases for signed and unsigned integer types (such as "u256") and "bigint" alias that can be used in storage unlike regular "int" gl == Blockchain specific functionality, that won't work without GenVM and reexports form "genlayer.py" provided for convenience class genlayer.gl.Contract Bases: "BaseContract" Class for declaring main GenVM contract. This class must be inherited by user contracts to be deployable on GenVM. It provides essential contract functionality including balance access, address information, and storage proxying. Only one "Contract" subclass is allowed per module. The class automatically generates storage management code and registers itself as the main contract. Example: >>> import genlayer.gl as gl >>> >>> class MyContract(gl.Contract): >>> def __init__(self, initial_value: int): >>> self.value = initial_value >>> >>> @gl.public.view >>> def get_value(self) -> int: >>> return self.value >>> >>> @gl.public.write >>> def set_value(self, new_value: int): >>> self.value = new_value Warning: Only one Contract subclass is allowed per Python module. Attempting to define multiple Contract subclasses will raise a TypeError. classmethod __get_schema__() -> str Generate and return the JSON schema for this contract. This method analyzes the contract class and generates a JSON schema describing its public interface, including all public methods and their type signatures. Returns: JSON string containing the contract schema Return type: str Note: This method is used internally by the GenVM runtime for contract introspection and interface generation abstract __handle_undefined_method__(method_name: str, args: list[Any], kwargs: dict[str, Any]) Handle calls to undefined methods. This method is called when a message is sent to the contract with a method name that doesn't exist. If it is overriden, it must be either a "gl.public.write" or "gl.public.write.payable" method. Parameters: * **method_name** (*str*) -- Name of the method that was called * **args** (*list**[**Any**]*) -- Positional arguments passed to the method * **kwargs** (*dict**[**str**, **Any**]*) -- Keyword arguments passed to the method Raises: **NotImplementedError** -- Must be implemented by subclasses if used Example: >>> class MyContract(gl.Contract): >>> @gl.public.write >>> def __handle_undefined_method__(self, method_name: str, args: list, kwargs: dict): >>> if method_name == "fallback_method": >>> self.handle_fallback(args, kwargs) >>> else: >>> raise ValueError(f"Unknown method: {method_name}") __on_errored_message__() Handle failed messages that included value transfers. This method is called when am emitted message with non-zero value fails during execution. By default, it simply accepts the refunded value. Override this method to implement custom error handling logic. The method must be decorated with "@gl.public.write.payable". Example: >>> class MyContract(gl.Contract): >>> @gl.public.write.payable >>> def __on_errored_message__(self): >>> # Log the failed transaction >>> failed_value = gl.message.value >>> self.failed_transfers.append((gl.message.sender, failed_value)) abstract __receive__() Handle plain value transfers to this contract. This method is called when native tokens are sent to the contract without calling any specific method. It must be implemented as a public payable write method. Raises: **NotImplementedError** -- Must be implemented by subclasses if used Example: >>> class MyContract(gl.Contract): >>> @gl.public.write.payable >>> def __receive__(self): >>> # Handle incoming transfers >>> sender = gl.message.sender >>> value = gl.message.value >>> self.total_received += value property address: Address The contract's address on the blockchain. property balance: u256 Current balance of the contract in native tokens. class genlayer.gl.Event Bases: "object" class TransferOccurredEvent(gl.Event): def __init__(self, from: Address, to: Address, /): ... class TransferOccurredEvent(gl.Event): def __init__(self, from: Address, to: Address, /, **blob): ... __init__() emit() -> None indexed: tuple[str, ...] tuple of indexed arguments name in **sorted** order name: str Event name. If not overridden it will be set to "__name__" signature: str Event signature (built-in/main topic). Consists of name and indexed fields in parenthesis, **sorted** Example: "TransferOccurredEvent(from,to)" class genlayer.gl.Lazy Bases: "Generic" Base class to support lazy evaluation __init__(_eval: Callable[[], T]) get() -> T Performs evaluation if necessary (only ones) and stores the result Returns: result of evaluating Raises: *iff* evaluation raised, this outcome is also cached, so subsequent calls will raise same exception Return type: T class genlayer.gl.MessageRawType Bases: "TypedDict" __optional_keys__ = frozenset({}) __required_keys__ = frozenset({'chain_id', 'contract_address', 'datetime', 'entry_data', 'entry_kind', 'entry_stage_data', 'is_init', 'origin_address', 'sender_address', 'stack', 'value'}) __total__ = True chain_id: u256 Current chain ID contract_address: Address Address of current Intelligent Contract datetime: str Transaction datetime. For "#get-schema" it can be some predefined datetime entry_data: bytes entry_kind: int One of: * "0" for "MAIN" * "1" for "SANDBOX" * "2" for "CONSENSUS_STAGE" See *startup-process-reference* for more details. entry_stage_data: Encodable is_init: bool "True" *iff* it is a deployment origin_address: Address Entire transaction initiator sender_address: Address Address of this call initiator stack: list[Address] Stack of view method calls, excluding last ("contract_address") value: u256 class genlayer.gl.MessageType Bases: "NamedTuple" MessageType(contract_address, sender_address, origin_address, value, chain_id) __getnewargs__() Return self as a plain tuple. Used by copy and pickle. static __new__(_cls, contract_address: Address, sender_address: Address, origin_address: Address, value: u256, chain_id: u256) Create new instance of MessageType(contract_address, sender_address, origin_address, value, chain_id) __repr__() Return a nicely formatted representation string chain_id: u256 Current chain ID contract_address: Address Address of current Intelligent Contract origin_address: Address Entire transaction initiator sender_address: Address Address of this call initiator value: u256 Alias for field number 3 genlayer.gl.contract_interface(_declaration: GenVMContractDeclaration) -> Callable[[Address], ContractProxy] Decorator for creating type-safe contract interfaces. This decorator creates a factory function that returns strongly- typed contract proxies, enabling IDE autocompletion and static type checking for contract interactions. Parameters: **_contr** -- Contract declaration class with View and Write nested classes Returns: Factory function that creates typed contract proxies Return type: *Callable*[[*Address*], *ContractProxy*] Example: >>> @gl.contract_interface >>> class ERC20Contract: >>> class View: >>> def balance_of(self, owner: Address) -> u256: ... >>> def total_supply(self) -> u256: ... >>> >>> class Write: >>> def transfer(self, to: Address, amount: u256) -> None: ... >>> def approve(self, spender: Address, amount: u256) -> None: ... >>> >>> # Usage: >>> token = ERC20Contract(token_address) >>> balance = token.view().balance_of(user_address) # Fully typed! >>> token.emit().transfer(recipient, amount) Note: This decorator provides no runtime functionality - it's purely for type safety and developer experience. The actual contract interaction uses the same runtime mechanisms as *get_contract_at*. genlayer.gl.deploy_contract(*, code: bytes, args: Sequence[Encodable] = [], kwargs: Mapping[str, Encodable] = {}, salt_nonce: u256 | Literal[0] = u256(0), value: u256 = u256(0), on: ON = 'finalized') -> Address | None Deploy a new GenVM contract to the blockchain. This function deploys a new contract using the provided "code" and constructor arguments. The deployment address can be deterministic (with a salt) or non-deterministic. Parameters: * **code** (*bytes*) -- Source code of the contract to deploy. It can be regular Python code. See *runners-reference* for more information * **args** (*Sequence**[**Encodable**]*) -- Positional arguments for the contract constructor * **kwargs** (*Mapping**[**str**, **Encodable**]*) -- Keyword arguments for the contract constructor * **salt_nonce** (*u256** | **Literal**[**0**]*) -- Salt for deterministic deployment. Use 0 for non-deterministic. * **value** (*u256*) -- Amount of native tokens to send to the contract during deployment * **on** (*ON*) -- When to execute the deployment ('accepted' or 'finalized') Returns: Contract address if salt_nonce != 0, None otherwise Return type: *Address* | None Example: >>> # Non-deterministic deployment >>> deploy_contract( >>> code=contract_source_str.encode('utf-8'), >>> args=[initial_supply], >>> kwargs={"name": "MyToken", "symbol": "MTK"} >>> ) >>> >>> # Deterministic deployment >>> address = deploy_contract( >>> code=contract_source_zip_as_bytes, >>> args=[initial_supply], >>> salt_nonce=u256(12345), >>> value=u256(1000) # Send 1000 native tokens >>> ) >>> print(f'Contract deployed at: {address}') Note: * For deterministic deployments (salt_nonce != 0), the contract address is computed using CREATE2 and is returned immediately * For non-deterministic deployments (salt_nonce == 0), the address is assigned by the consensus and not returned. Considering asynchronous nature of GenLayer consensus the address should not be predicted * The contract's constructor will be called with the provided "args" and "kwargs" * Refer to consensus documentation for CREATE2 address derivation process and details about transaction ordering genlayer.gl.get_contract_at(address: Address) -> ContractProxy Create a proxy object for interacting with a deployed GenVM contract. This function returns a contract proxy that provides runtime access to the methods of a deployed contract without requiring type annotations describing its interface. Parameters: **address** (*Address*) -- Address of the deployed contract Returns: ContractProxy object for interacting with the contract Return type: *ContractProxy* Example: >>> addr = Address('0x1234567890abcdef...') >>> contract = get_contract_at(addr) >>> result = contract.view().some_view_method(arg1, arg2) >>> contract.emit(value=u256(100)).some_write_method(arg1) genlayer.gl.message: MessageType = Ellipsis Represents fields from a transaction message that was sent genlayer.gl.message_raw: MessageRawType = Ellipsis Raw message, parsed genlayer.gl.private(f) Decorator that marks method as private. As all methods are private by default it does nothing. class genlayer.gl.public Bases: "object" static view(f) Decorator that marks a contract method as a public view write = Decorator that marks a contract method as a public write. Has *.payable* @gl.public.write def foo(self) -> None: ... @gl.public.write.payable def bar(self) -> None: ... @gl.public.write.min_gas(leader=100, validator=20).payable def bar(self) -> None: ... Return type: T gl.vm ===== class genlayer.gl.vm.Return Bases: "Generic" Represents a successful return value from a VM operation. __eq__(other) Return self==value. __hash__ = None __init__(calldata: T) -> None __repr__() Return repr(self). calldata: T Decoded return value from the VM execution exception genlayer.gl.vm.UserError Bases: "Exception" Represents an error that user contract rose during execution of their code in the VM. __eq__(other) Return self==value. __hash__ = None __init__(message: str) -> None __repr__() Return repr(self). __str__() -> str Return str(self). Return type: str message: str User-provided message. Be careful to use concise message, as by default they are checked for strict equality by the validator class genlayer.gl.vm.VMError Bases: "object" Represents an error that occurred within the VM during execution. It indicates user-caused error, such as OOM. __eq__(other) Return self==value. __hash__ = None __init__(message: str) -> None __repr__() Return repr(self). message: str Description of the VM error that occurred. It begins with code, such as "exit_code" genlayer.gl.vm.run_nondet(leader_fn: ~typing.Callable[[], T], validator_fn: ~typing.Callable[[Result], bool], /, *, compare_user_errors: ~typing.Callable[[~genlayer.gl.vm.UserError, ~genlayer.gl.vm.UserError], bool] = >, compare_vm_errors: ~typing.Callable[[~genlayer.gl.vm.VMError, ~genlayer.gl.vm.VMError], bool] = >) -> T Executes a non-deterministic block with comprehensive error handling. This is the recommended API for custom non-deterministic execution. It provides safer error handling compared to "run_nondet_unsafe()" by running the validator in a sandbox and handling validator errors with provided functions with sensible defaults. Parameters: * **leader_fn** (*Callable**[**[**]**, **T**]*) -- Function executed by the leader node * **validator_fn** (*Callable**[**[**Result**]**, **bool**]*) -- Function that validates the leader's result, is ran in a sandbox * **compare_user_errors** (*Callable**[**[**UserError**, **UserError**]**, **bool**]*) -- Function to compare UserError instances for equality * **compare_vm_errors** (*Callable**[**[**VMError**, **VMError**]**, **bool**]*) -- Function to compare VMError instances for equality Returns: The result from the leader if validation passes Return type: T Error handling: - If leader and validator both succeed: returns leader result - If leader fails and validator agrees: propagates leader error - If results don't match: consensus fails Example: >>> def leader() -> list[int]: ... return fetch_external_data() >>> def validator(result): ... if not isinstance(result, Return): ... return False ... my_data = leader() ... return numpy.linalg.norm(np.array(result.calldata) - np.array(my_data)) < 0.1 >>> value = run_nondet(leader, validator) Note: supports ".lazy()" version, which will return "Lazy" genlayer.gl.vm.run_nondet_unsafe(leader_fn: Callable[[], T], validator_fn: Callable[[Result], bool], /) -> T Executes a non-deterministic block with leader-validator consensus. This is the most generic API for non-deterministic execution. The leader function runs as is, validators one checks the result. Parameters: * **leader_fn** (*Callable**[**[**]**, **T**]*) -- Function executed by the leader node (must be serializable) * **validator_fn** (*Callable**[**[**Result**]**, **bool**]*) -- Function that validates the leader's result and returns bool Returns: The result from the leader (iff validation passes, otherwise VM will be terminated) Return type: T Warning: This function does not use extra sandbox for catching validator errors. Validator error will result in a "Disagree" error in executor (same as if this function returned "False"). Use "run_nondet()" instead if you want to catch and inspect "validator_fn" errors, or use sandbox inside of it. Note: All sub-vm returns go through "genlayer.py.calldata" encoding. Example: >>> def leader(): ... return os.urandom(1)[0] % 3 >>> def validator(result): ... return unpack_result(result) == 1 # agree in 33% of cases >>> value = gl.vm.run_nondet_unsafe(leader, validator) Note: supports ".lazy()" version, which will return "Lazy" genlayer.gl.vm.spawn_sandbox(fn: Callable[[], T], *, allow_write_ops: bool = False) -> Return | VMError | UserError Runs a function in an isolated sandbox environment. The function is executed in a separate VM instance with controlled permissions. This provides isolation and security for potentially unsafe operations. Determinism of spawned VM matches the determinism of the current VM. Parameters: * **fn** (*Callable**[**[**]**, **T**]*) -- Function to execute in the sandbox (must be serializable with cloudpickle) * **allow_write_ops** (*bool*) -- Whether to allow write operations in the sandbox. Only effective if current VM has corresponding permission Return type: *Return* | *VMError* | *UserError* Example: >>> result = spawn_sandbox(lambda: risky_computation()) >>> safe_value = unpack_result(result) Note: supports ".lazy()" version, which will return "Lazy" genlayer.gl.vm.unpack_result(res: Result, /) -> T Extracts the successful result from a VM operation result. Parameters: **res** (*Result*) -- The result from a VM operation Returns: The actual return value if successful Raises: * **UserError** -- If the result represents a user error * **UserError** -- If the result represents a "VMError" (rewrapped as user error) Return type: T Example: >>> result = gl.vm.spawn_sandbox(lambda: 42) >>> value = unpack_result(result) # Returns 42 or raises on error gl.advanced =========== This module provides some "advanced" features that can be used for optimizations Warning: If you are using something "advanced" you must know what you do genlayer.gl.advanced.emit_raw_event(topics: list[bytes], blob: Encodable) -> None Emits a raw event with the given name, indexed fields and blob of data. genlayer.gl.advanced.user_error_immediate(reason: str) -> NoReturn Performs an immediate error, current VM won't be able to handle it, stack unwind will not happen Return type: *NoReturn* gl.calldata =========== This module is responsible for working with genvm calldata Calldata natively supports following types: 1. Primitive types: 1. python built-in: "bool", "None", "int", "str", "bytes" 2. "Address()" type 2. Composite types: 1. "list" (and any other "collections.abc.Sequence") 2. "dict" with "str" keys (and any other "collections.abc.Mapping" with "str" keys) For full calldata specification see genvm repo class genlayer.gl.calldata.CalldataEncodable Bases: "object" Abstract class to support calldata encoding for custom types Can be used to simplify code abstract __to_calldata__() -> Encodable Override this method to return calldata-compatible type Warning: returning "self" may lead to an infinite loop or an exception Return type: Encodable exception genlayer.gl.calldata.DecodingError Bases: "ValueError" genlayer.gl.calldata.decode(mem0: Buffer, *, memview2bytes: Callable[[memoryview], Any] = bytes) -> Decoded Decodes calldata encoded bytes into python DSL Out of composite types it will contain only "dict" and "list" Return type: Decoded genlayer.gl.calldata.encode(x: EncodableWithDefault, *, default: Callable[[EncodableWithDefault], Encodable] = encode_default_parameter) -> bytes Encodes python object into calldata bytes Parameters: **default** (*Callable**[**[**EncodableWithDefault**]**, **Encodable**]*) -- function to be applied to each object recursively, it must return object encodable to calldata Return type: bytes Warning: All composite types in the end are coerced to "dict" and "list", so custom type information is *not* be preserved. Such types include: 1. "CalldataEncodable" 2. "dataclasses" genlayer.gl.calldata.to_str(d: Encodable) -> str Transforms calldata DSL into human readable json-like format, should be used for debug purposes only Return type: str gl.storage ========== class genlayer.gl.storage.Array Bases: "Sequence", "SizedArray", "Generic" Constantly sized array that can be persisted on the blockchain __getitem__(idx: SupportsIndex) -> T __getitem__(idx: slice) -> Array __init__() This class can't be created with "Array()" Raises: **TypeError** -- always __iter__() __len__() -> int Return type: int __setitem__(idx: int, val: T) -> None class genlayer.gl.storage.DynArray Bases: "MutableSequence", "Generic" Represents exponentially growing array ("list" in python terms) that can be persisted on the blockchain __delitem__(idx: int) -> None __delitem__(idx: slice) -> None __getitem__(idx: int) -> T __getitem__(idx: slice) -> list[T] __init__() This class can't be created with "DynArray()" Raises: **TypeError** -- always __iter__() -> Any Return type: *Any* __len__() -> int Return type: int __repr__() -> str Return repr(self). Return type: str __setitem__(idx: SupportsIndex, val: T) -> None __setitem__(idx: slice, val: collections.abc.Sequence[T]) -> None append(value: T) -> None S.append(value) -- append value to the end of the sequence append_new_get() -> T Return type: T clear() -> None -- remove all items from S insert(index: int, value: T) -> None S.insert(index, value) -- insert value before index pop([index]) -> item -- remove and return item at index (default last). Raise IndexError if list is empty or index is out of range. class genlayer.gl.storage.Indirection Bases: "Generic" This class provides ability to save data at its own slot. Occupies 1 byte to prevent collision. __init__() get() -> T Return type: T set(val: T) -> None slot() -> Slot Returns: "Slot" at which data resides Return type: *Slot* class genlayer.gl.storage.Manager Bases: "object" do_read(id: bytes, off: int, len: int, /) -> bytes Return type: bytes do_write(id: bytes, off: int, what: Buffer, /) get_store_slot(addr: bytes, /) -> Slot Return type: *Slot* class genlayer.gl.storage.Root Bases: "object" This ABI is known and used by: 1. genvm 2. node MANAGER: ClassVar[Manager] = __gl_allow_storage__ = True __init__(*args, **kwargs) property code contract code property contract_instance static get() -> Root Return type: *Root* get_contract_instance(typ: Type) -> T Return type: T lock_default() property locked_slots Slot ids that can not be modified after deployment. Use "Slot.as_int()" for conversion of Slot to "int" By default it will be populated by "code", "frozen_slots" slot() -> Slot Return type: *Slot* property upgraders final class genlayer.gl.storage.Slot Bases: "object" __eq__(r: object) -> bool Return self==value. Return type: bool __final__ = True __getstate__() Helper for pickle. __hash__() -> int Return hash(self). Return type: int __init__(addr: bytes, manager: Manager) __repr__() Return repr(self). __setstate__(state) __str__() Return str(self). as_int() -> u256 Return type: *u256* id indirect(off: int, /) -> Slot Return type: *Slot* manager: Manager read(off: int, len: int, /) -> bytes Return type: bytes write(off: int, what: Buffer, /) -> None class genlayer.gl.storage.TreeMap Bases: "MutableMapping", "Generic" Represents a mapping from keys to values that can be persisted on the blockchain Tparam K: must implement "genlayer.py.storage.tree_map.Comparable" protocol ("<" is needed) and be storage-allowed Tparam V: must be storage-allowed __contains__(k: object) -> bool Return type: bool __delitem__(k: K) __getitem__(k: K) -> V Return type: V __gl_allow_storage__ = True __iter__() __len__() -> int Return type: int __repr__() -> str Return repr(self). Return type: str __setitem__(k: K, v: V) clear() -> None. Remove all items from D. compute_if_absent(k: K, supplier: Callable[[], V]) -> V Returns: Value associated with *k* if it is present, otherwise get's new value from the supplier, stores it at *k* and returns Return type: V get(k: K, /) -> V | None get(k: K, /, default: G) -> V | G Returns: Value associated with *k* or *default* if there is no such value get_or_insert_default(k: K) -> V Return type: V items() -> a set-like object providing a view on D's items Return type: *ItemsView* class genlayer.gl.storage.VLA Bases: "PseudoSequence", "Generic" Variable Length Array. Can be used in pair with "Indirection" to save length at the same place as data. Can also be used in C language way. Occupies at least 4 bytes (for length) __getitem__(idx: int) -> T Return type: T __iter__() __len__() -> int Return type: int __setitem__(idx: int, val: T) append(val: T) extend(val: PseudoSequence) slot() -> Slot Return type: *Slot* truncate(to: int = 0) genlayer.gl.storage.allow_storage(cls: T) -> T Return type: T genlayer.gl.storage.inmem_allocate(t: Type, *init_args, **init_kwargs) -> T Return type: T gl.evm ====== This module is responsible for interactions with ghost/external contracts class genlayer.gl.evm.ContractDeclaration Bases: "Protocol", "Generic" Interface for declaring interfaces of external contracts View: type[TView] Write: type[TWrite] __init__(*args, **kwargs) class genlayer.gl.evm.ContractProxy Bases: "Generic" __init__(address: Address, view_impl: Callable[[ContractProxy], TView], balance_impl: Callable[[ContractProxy], u256], send_impl: Callable[[ContractProxy, TransactionDataKwArgs], TWrite], transfer_impl: Callable[[ContractProxy, TransactionDataKwArgs], None]) address: Address property balance: u256 emit(**data: Unpack[TransactionDataKwArgs]) -> TWrite Return type: TWrite emit_transfer(**data: Unpack[TransactionDataKwArgs]) -> None view() -> TView Return type: TView class genlayer.gl.evm.InplaceTuple Bases: "object" This class indicates that tuple should be encoded/decoded in-place. Which means that even if it is dynamically sized, it is ignored. It is useful for encoding/decoding arguments and returns tuple[InplaceTuple, str, u256] class genlayer.gl.evm.MethodEncoder Bases: "object" __init__(name: str, params: tuple[Any, ...], ret: type) decode_ret(data: Buffer) -> Any Return type: *Any* encode_call(args: tuple[Any, ...]) -> bytes Return type: bytes genlayer.gl.evm.contract_interface(contr: ContractDeclaration) -> Callable[[Address], ContractProxy] Return type: *Callable*[[*Address*], *ContractProxy*] genlayer.gl.evm.decode(expected: Type, encoded: Buffer) -> T Return type: T genlayer.gl.evm.encode(params: Type, args: T) -> bytes Return type: bytes genlayer.gl.evm.selector_of(name: str, params: Type[tuple[Unpack[T]]]) -> bytes Return type: bytes genlayer.gl.evm.signature_of(name: str, params: Type[tuple[Unpack[T]]]) -> str calculates signature that is used for making method selector Return type: str genlayer.gl.evm.type_name_of(t: type) -> str Return type: str gl.eq_principle =============== genlayer.gl.eq_principle.prompt_comparative(fn: Callable[[], T], principle: str) -> T Comparative equivalence principle that utilizes NLP for verifying that results are equivalent For validator: in case of non-"Return" result in "fn", agreement will be decided by "genlayer.gl.vm.run_nondet()", which executed validator wrapper function in a sandbox VM. If on the other hand leader reported an error, while our function execution is successful, the validator votes "False". Parameters: * **fn** (*Callable**[**[**]**, **T**]*) -- function that does all the job * **principle** (*str*) -- principle with which equivalence will be evaluated in the validator (via performing NLP) Return type: T See "genlayer.gl.vm.run_nondet()" for description of data transformations Note: As leader results are encoded as calldata, "format()" is used for string representation. However, operating on strings by yourself is more safe in general Warning: See "genlayer.gl.vm.run_nondet()" for description of data transformations Note: supports ".lazy()" version, which will return "Lazy" genlayer.gl.eq_principle.prompt_non_comparative(fn: Callable[[], str], *, task: str, criteria: str) -> str Non-comparative equivalence principle that must cover most common use cases Both leader and validator finish their execution via NLP, that is used to perform "task" on "input". Leader just executes this task, but the validator checks if task was performed with integrity. This principle is useful when task is subjective. For instance, when you want to check if some text is a good summary of the input text. For validator: in case of non-"Return" result in "fn", agreement will be decided by "genlayer.gl.vm.run_nondet()", which executed validator wrapper function in a sandbox VM. If on the other hand leader reported an error, while our function execution is successful, the validator votes "False". Note: supports ".lazy()" version, which will return "Lazy" Return type: str genlayer.gl.eq_principle.strict_eq(fn: Callable[[], T]) -> T Comparative equivalence principle that checks for strict equality This function checks that VM result is of the same type and has the same value inside. It is the most performant equivalence principle, but it is also the most strict one. Parameters: **fn** (*Callable**[**[**]**, **T**]*) -- function that provides result that will be validated Return type: T Warning: See "genlayer.gl.vm.run_nondet()" for description of data transformations Note: supports ".lazy()" version, which will return "Lazy" gl.nondet ========= class genlayer.gl.nondet.Image Bases: "object" Image(raw: bytes, pil: 'PIL.Image.Image') __eq__(other) Return self==value. __hash__ = None __init__(raw: bytes, pil: PIL.Image.Image) -> None __repr__() Return repr(self). pil: PIL.Image.Image raw: bytes genlayer.gl.nondet.exec_prompt(prompt: str, *, images: collections.abc.Sequence[bytes | Image] | None = None) -> str genlayer.gl.nondet.exec_prompt(prompt: str, *, response_format: Literal['text'], images: collections.abc.Sequence[bytes | Image] | None = None) -> str genlayer.gl.nondet.exec_prompt(prompt: str, *, response_format: Literal['json'], image: bytes | Image | None = None) -> dict[str, Any] API to execute a prompt (perform NLP) Parameters: * **prompt** ("str") -- prompt itself * ****config** ("ExecPromptKwArgs") -- configuration Return type: "str" Note: supports ".lazy()" version, which will return "Lazy" gl.nondet.web ============= class genlayer.gl.nondet.web.Response Bases: "object" Response(status: int, headers: dict[str, bytes], body: bytes | None) __eq__(other) Return self==value. __hash__ = None __init__(status: int, headers: dict[str, bytes], body: bytes | None) -> None __repr__() Return repr(self). body: bytes | None headers: dict[str, bytes] status: int genlayer.gl.nondet.web.delete(url: str, *, body: str | bytes | None = None, headers: dict[str, str | bytes] = {}) -> Response Note: supports ".lazy()" version, which will return "Lazy" Return type: *Response* genlayer.gl.nondet.web.get(url: str, *, headers: dict[str, str | bytes] = {}) -> Response Note: supports ".lazy()" version, which will return "Lazy" Return type: *Response* genlayer.gl.nondet.web.head(url: str, *, body: str | bytes | None = None, headers: dict[str, str | bytes] = {}) -> Response Note: supports ".lazy()" version, which will return "Lazy" Return type: *Response* genlayer.gl.nondet.web.patch(url: str, *, body: str | bytes | None = None, headers: dict[str, str | bytes] = {}) -> Response Note: supports ".lazy()" version, which will return "Lazy" Return type: *Response* genlayer.gl.nondet.web.post(url: str, *, body: str | bytes | None = None, headers: dict[str, str | bytes] = {}) -> Response Note: supports ".lazy()" version, which will return "Lazy" Return type: *Response* genlayer.gl.nondet.web.render(url: str, *, wait_after_loaded: str | None = None, mode: Literal['text', 'html']) -> str genlayer.gl.nondet.web.render(url: str, *, wait_after_loaded: str | None = None, mode: Literal['screenshot']) -> Image API to get a webpage after rendering it in a browser-like environment Parameters: * **url** -- url of website * **mode** -- Mode in which to return the result * **wait_after_loaded** -- How long to wait after dom loaded (for js to emit dynamic content). Should be in format such as "1000ms" or "1s" Note: supports ".lazy()" version, which will return "Lazy" genlayer.gl.nondet.web.request(url: str, *, method: Literal['GET', 'POST', 'DELETE', 'HEAD', 'OPTIONS', 'PATCH'], body: str | bytes | None = None, headers: dict[str, str | bytes] = {}) -> Response Note: supports ".lazy()" version, which will return "Lazy" Return type: *Response* ### genlayer_embeddings.txt Package genlayer_embeddings *************************** class genlayer_embeddings.Distance Bases: "Protocol" __call__(l, r) -> Any Call self as a function. Return type: *Any* __init__(*args, **kwargs) class genlayer_embeddings.EuclideanDistanceSquared Bases: "Distance" __call__(l, r) Call self as a function. __gl_allow_storage__ = True batch(l, r) genlayer_embeddings.SentenceTransformer(model: str) -> Callable[[str], ndarray] Return type: *Callable*[[str], *ndarray*] genlayer_embeddings.SentenceTransformerFromPath(path: str) -> Callable[[str], ndarray] Return type: *Callable*[[str], *ndarray*] class genlayer_embeddings.VecDB Bases: "Generic" Data structure that supports storing and querying vector data using Cover Trees Cover trees provide logarithmic time nearest neighbor search with theoretical guarantees. There are two entities that can act as a key: 1. vector (can have duplicates) 2. id (int alias, can't have duplicates) Warning: import "numpy" before "from genlayer import *" if you wish to use "VecDB"! Element = Element Id = Id __gl_allow_storage__ = True __init__() __iter__() __len__() -> int Return type: int get_by_id(id: Id) -> VecDBElement[T, S, V, None] Return type: VecDBElement[T, S, V, None] get_by_id_or_none(id: Id) -> VecDBElement[T, S, V, None] | None Return type: VecDBElement[T, S, V, None] | None insert(key: np.ndarray[tuple[S], np.dtype[T]], val: V) -> Id Return type: Id knn(v: np.ndarray[tuple[S], np.dtype[T]], k: int) -> Iterator[VecDBElement[T, S, V, T]] Find k nearest neighbors using cover tree Return type: *Iterator*[VecDBElement[T, S, V, T]] genlayer_embeddings.get_model(model: str, inputs: dict[str, dtype[Any] | None | type[Any] | _SupportsDType[dtype[Any]] | str | tuple[Any, int] | tuple[Any, SupportsIndex | Sequence[SupportsIndex]] | list[Any] | _DTypeDict | tuple[Any, Any]], *, models_db=_ALL_MODELS) ### index.txt Public API ********** Note: Single text file docs for AI Packages: ^^^^^^^^^ * Package genlayer * Top level * "gl" * "Address" * "Array" * "DynArray" * "Keccak256()" * "TreeMap" * "allow_storage()" * Integer aliases * gl * "Contract" * "Event" * "Lazy" * "MessageRawType" * "MessageType" * "contract_interface()" * "deploy_contract()" * "get_contract_at()" * "message" * "message_raw" * "private()" * "public" * gl.vm * "Return" * "UserError" * "VMError" * "run_nondet()" * "run_nondet_unsafe()" * "spawn_sandbox()" * "unpack_result()" * gl.advanced * "emit_raw_event()" * "user_error_immediate()" * gl.calldata * "CalldataEncodable" * "DecodingError" * "decode()" * "encode()" * "to_str()" * gl.storage * "Array" * "DynArray" * "Indirection" * "Manager" * "Root" * "Slot" * "TreeMap" * "VLA" * "allow_storage()" * "inmem_allocate()" * gl.evm * "ContractDeclaration" * "ContractProxy" * "InplaceTuple" * "MethodEncoder" * "contract_interface()" * "decode()" * "encode()" * "selector_of()" * "signature_of()" * "type_name_of()" * gl.eq_principle * "prompt_comparative()" * "prompt_non_comparative()" * "strict_eq()" * gl.nondet * "Image" * "exec_prompt()" * gl.nondet.web * "Response" * "delete()" * "get()" * "head()" * "patch()" * "post()" * "render()" * "request()" * Package genlayer_embeddings * "Distance" * "Distance.__call__()" * "Distance.__init__()" * "EuclideanDistanceSquared" * "EuclideanDistanceSquared.__call__()" * "EuclideanDistanceSquared.__gl_allow_storage__" * "EuclideanDistanceSquared.batch()" * "SentenceTransformer()" * "SentenceTransformerFromPath()" * "VecDB" * "VecDB.Element" * "VecDB.Id" * "VecDB.__gl_allow_storage__" * "VecDB.__init__()" * "VecDB.__iter__()" * "VecDB.__len__()" * "VecDB.get_by_id()" * "VecDB.get_by_id_or_none()" * "VecDB.insert()" * "VecDB.knn()" * "get_model()" * Change Log * v0.1.8 * Breaking Changes * New Features * API Improvements * v0.1.3 * Migration Guide * Breaking Changes * New Features * API Improvements * v0.1.0