# index.mdx import Image from 'next/image' import { Card, Cards } from 'nextra-theme-docs' import CustomCard from '../components/card' # Welcome to GenLayer ## The Intelligence Layer of the Internet. GenLayer is a new class of DLT capable of non deterministic operations though a dynamic consensus mechanism, by leveraging the [Jury Theorem](https://en.wikipedia.org/wiki/Condorcet%27s_jury_theorem) ("wisdom of the crowd") and [Schelling Point](https://en.wikipedia.org/wiki/Focal_point_(game_theory)) mechanics. In other words, GenLayer is the first Intelligent Blockchain. Enabling smart contracts to natively access the Internet and go beyond deterministic logic, to make subjective decisions. - **Bitcoin is Trustless Money,**
- **Ethereum is Trustless Applications,**
- **GenLayer is Trustless Decision-Making.** GenLayer's Intelligent Contracts can connect to the Internet, process natural language, and handle non-deterministic operations such as making subjective decisions, enabling a whole new generation of smart contract logic that is not possible under the limitations of current blockchain infrastructure. See some of the usecases [here](/understand-genlayer-protocol/typical-use-cases). Protocols and applications that can **understand, learn, and adapt to real-world events.** ## Get Started
{/* */} {/* */}
## Community and Careers **Need Help?** Join our vibrant community on [Discord](https://discord.gg/8Jm4v89VAu) or [Telegram](https://t.me/genlayer) to ask questions, share feedback, and showcase your GenLayer creations. **Looking to Build the Future with Us?** We're hiring! If blockchain and AI excite you, [explore our career opportunities](https://apply.workable.com/yeager-dot-a-i/) and help shape the future of decentralized applications. # understand-genlayer-protocol.mdx ## What is GenLayer? GenLayer is the first AI-native blockchain built for AI-powered smart contracts—called Intelligent Contracts—capable of reasoning and adapting to real-world data. Its foundation is the Optimistic Democracy consensus mechanism, an enhanced Delegated Proof of Stake (dPoS) model where validators connect directly to Large Language Models (LLMs). This setup allows for non-deterministic operations—such as processing text prompts, fetching live web data, and executing AI-based decision-making—while preserving the reliability and security of a traditional blockchain. ## Core Technology At the heart of GenLayer lies Optimistic Democracy—an enhanced Delegated Proof of Stake (dPoS) consensus mechanism that integrates AI models directly into validator operations. This synergy delivers three capabilities traditional blockchains cannot match: 1. **On-Chain AI Processing** Validators connect to leading AI models (GPT, LLaMA, Meta, etc.) to execute complex reasoning on-chain, from natural language comprehension to data-driven predictions. 2. **Consensus-Backed Security** Multiple validators vote on outcomes, ensuring collective agreement and robust reliability for every transaction—even those involving non-deterministic AI outputs. 3. **Intelligent Contracts** Smart contracts in GenLayer gain reasoning abilities, allowing them to understand natural language, process real-world data, and adapt to evolving conditions. ## Technical Implementation To integrate AI seamlessly with the blockchain, GenLayer employs a distributed neural consensus network, wherein validators run specialized software connected via API to advanced AI models. This approach unifies: - Delegated Proof of Stake (dPoS) for efficient block production and governance. - Neural Consensus for non-deterministic transactions requiring advanced AI reasoning. This architecture supports autonomous DAOs, self-executing prediction markets, and dynamic DeFi protocols that react to real-world data in real time. # Optimistic Democracy: How Consensus Works GenLayer Optimistic Democracy Consensus Diagram Inspired by **[Condorcet's Jury Theorem](https://jury-theorem.genlayer.com/)** (click the link to check out our interactive model), Optimistic Democracy merges probabilistic AI systems with deterministic blockchain rules, ensuring secure and accurate consensus at scale. 1. **User Submits a Transaction** A user sends a transaction request to the network (see the diagram's Step 1). 2. **Leader (Validator) Proposes Result** The network selects a Leader, who processes the request and proposes an outcome (Step 2). 3. **Validators Recompute** A group of Validators independently re-compute the transaction (Step 3). If the output aligns with the Leader's proposal, they approve; otherwise, they deny. This multi-layer validation ensures majority agreement, adding a safety net for AI-driven computations. # Validator Selection Mechanism Token holders bolster network security by delegating tokens to validator candidates. A deterministic function f(x) then randomly designates Leader-Validator and Validators for each transaction. This process not only promotes fairness but also helps decentralize validation power, strengthening GenLayer's security and trustlessness. # Validator Operational Framework Each GenLayer validator node integrates: - **Validator Software** Handles core blockchain functions: networking, block production, and transaction management. - **AI Model Integration** Connects to Large Language Models (LLMs) or other AI services for complex reasoning, natural language processing, and real-time data retrieval. Validators seamlessly manage both: 1. **Deterministic Transactions** typical of traditional blockchains. 2. **Non-Deterministic Transactions** that leverage AI-driven logic (e.g., searching the internet, analyzing data, making probabilistic inferences). By splitting tasks between standard deterministic and advanced AI-powered transactions, GenLayer ensures high performance without compromising on security. # Putting It All Together With Optimistic Democracy guiding consensus and validators empowered by AI, GenLayer enables a new class of blockchain applications. From DAOs that self-govern based on real-time data to DeFi protocols that dynamically adjust parameters in response to market changes, developers can now build truly intelligent decentralized solutions. # understand-genlayer-protocol/what-makes-genlayer-different.mdx ## What Makes GenLayer Different? 1. **AI-Powered**: Intelligent Contracts interpret and execute human-readable commands, unlocking data-driven decision-making in real time. 2. **Web Data Access**: GenLayer’s contracts natively fetch live data, surpassing traditional blockchains that rely on external oracles. 3. **Secure and Reliable**: The Optimistic Democracy consensus algorithm expertly validates non-deterministic outputs, ensuring both efficiency and robust security. 4. **Interoperability**: Designed for seamless interaction with other blockchains and conventional web services, GenLayer bridges multiple ecosystems. 5. **Python-Based SDK**: A Python-centric toolset lowers the barrier to entry, empowering a wide range of developers, data scientists, and AI specialists. # understand-genlayer-protocol/optimistic-democracy-how-genlayer-works.mdx # Optimistic Democracy: How GenLayer Works GenLayer Optimistic Democracy Diagram Optimistic Democracy is GenLayer's consensus mechanism, rooted in [Condorcet's Jury Theorem](https://jury-theorem.genlayer.com/) (click the link to check out our interactive model), which affirms that collective decision-making becomes more accurate as independent validators vote. The process unfolds in distinct phases: 1. **Transaction Submission**: A user sends a transaction to the GenLayer network. 2. **Leader Proposes Result**: A validator is randomly chosen as the Leader validator. It processes the transaction and proposes a result. 3. **Validators Recompute**: A committee of validators re-compute the transaction. They either approve or deny based on whether the output aligns with the Leader's result (i.e. is equivalent). 4. **Result Accepted**: Once a majority approves, the result is provisionally accepted. 5. **Appeal**: If any participant disputes the outcome, they can appeal within the Finality Window by posting a bond. 6. **Additional Validation (If Appealed)**: A new set of validators may be chosen to re-evaluate the transaction. If the appeal is valid, they reward the appellant. Otherwise, the bond is forfeited. 7. **Final Decision**: After all appeals are resolved, the outcome becomes final. # understand-genlayer-protocol/typical-use-cases.mdx # Typical Use Cases - **Prediction Markets**: Power decentralized trading on future events. Applications include financial market forecasting, sports betting, and entertainment predictions. - **Performance-Based Contracting**: Automate escrows and payments contingent on verified performance metrics. Intelligent Contracts can track deliverables in real-time and instantly release funds. - **Network States**: Launch decentralized governance frameworks for Network States, opening new horizons in collaborative decision-making and self-regulation. - **Dispute Resolution**: It will serve as a decentralized, AI-driven arbitration system. Compared to conventional legal routes, it will reduce costs and expedite case handling. - **AI-Driven DAOs**: Form next-gen decentralized autonomous organizations managed by AI algorithms. Empower real-time governance and data-informed investments. For more potential applications, see **Build with GenLayer**. ## Ready to Build on GenLayer? Whether you're looking to dive into Python-based smart contracts or explore AI-driven solutions, GenLayer provides the ideal foundation. Explore our [Developer Docs](https://docs.genlayer.com/developers) to start building. # understand-genlayer-protocol/why-we-are-building-genlayer.mdx # Why We Are Building GenLayer Traditional smart contracts face critical limitations: they can’t natively interact with the outside world without oracles, and their instructions are constrained to code-based logic. By integrating AI at the protocol level, GenLayer’s Intelligent Contracts can: 1. **Process Natural Language**: Interpret and act upon human-readable text prompts. 2. **Access Real-Time Web Data**: Seamlessly fetch and utilize external data. This synergy opens a world of new applications that merge on-chain trust with off-chain intelligence. Our vision is a dynamic protocol where intelligent entities—ranging from AI models to automated tools—can autonomously transact and reach real-world alignment. GenLayer's Optimistic Democracy consensus underpins secure, efficient validation even when outputs are inherently non-deterministic. This makes the platform exceptionally adaptable and robust—primed for modern, AI-driven use cases. # understand-genlayer-protocol/who-is-genlayer-for.mdx # Who Is GenLayer For? - **Existing dApps**: Transition away from costly human-based oracles to AI-powered Intelligent Contracts, slashing operational overhead and decision latency. - **Builders**: Construct the impossible—dApps that benefit from AI-based reasoning, real-time web access, and automated decision-making. - **Enterprises**: Streamline complex business logic and workflows with AI-driven automation that executes and enforces contractual agreements on-chain. - **Researchers**: Experiment with next-generation decentralized governance and explore how AI can improve consensus, dispute resolution, and more. - **Everyone**: Participate in the groundbreaking fusion of AI and blockchain, shaping the future of Web3 technology. # understand-genlayer-protocol/what-are-intelligent-contracts.mdx ## What Are Intelligent Contracts? Intelligent Contracts are AI-powered smart contracts designed to leverage Large Language Models (LLMs) for real-time web data retrieval and natural language processing. Unlike traditional smart contracts—limited by deterministic code and external oracles—Intelligent Contracts adapt their logic based on live data and evolving conditions. By natively integrating AI at the protocol level, Intelligent Contracts on GenLayer can understand and respond to complex, real-world scenarios, unlocking a new class of decentralized applications. Evolution of Intelligent Contracts | **Feature** | **Traditional Smart Contracts** | **Intelligent Contracts** | |---------------------------|--------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| | **Definition** | Self-executing blockchain programs with terms defined in code | AI-driven contracts that access web data and process natural language in real time | | **Capabilities** | Executes predefined on-chain actions based on code logic | Executes on-chain actions, can interpret external data, perform AI-driven reasoning, etc. | | **Language Understanding**| Limited to code-based commands | Understands and acts on human-readable text prompts (natural language) | | **Web Data Access** | Depends on external oracles for off-chain data | Integrates directly with real-time web data, removing the need for external oracles | | **Data Handling** | Can only process data already on-chain | Fetches and utilizes off-chain data (APIs, market info, web resources, etc.) | | **Programming Language** | Often uses specialized blockchain languages (e.g. Solidity) | Generally Python-based in GenLayer, making development more accessible to a broader audience | | **Ease of Development** | Requires specialized blockchain knowledge and tooling | Accessible via familiar languages (Python) and the GenLayer Studio developer experience | | **Flexibility** | Executes static operations based on predefined logic | Can adapt in real time to changing conditions, offering AI-driven functionality | | **Consensus Mechanism** | Relies on standard blockchain consensus (e.g., Proof of Stake, Proof of Work) | Utilizes Optimistic Democracy for deterministic and non-deterministic contract outputs | | **Use Cases** | Typically restricted to basic on-chain logic like token transfers or deterministic dApps | Enables advanced apps like AI-driven DAOs, predictive analytics, autonomous oracles, etc. | By embedding AI-driven capabilities into the core of the blockchain, Intelligent Contracts deliver real-time adaptability, broader functionality, and deeper integration with the external world—significantly expanding the scope of what decentralized applications can achieve on GenLayer. # understand-genlayer-protocol/core-concepts.mdx import { Card, Cards } from 'nextra-theme-docs' # Core Concepts Dive into GenLayer’s fundamental building blocks. These core concepts elucidate how Intelligent Contracts remain secure, efficient, and reliable in a non-deterministic environment: # understand-genlayer-protocol/core-concepts/validators-and-validator-roles.mdx # Validators and Validator Roles ## Overview Validators are essential participants in the GenLayer network. They are responsible for validating transactions and maintaining the integrity and security of the blockchain. Validators play a crucial role in the Optimistic Democracy consensus mechanism, ensuring that both deterministic and non-deterministic transactions are processed correctly. ## Key Responsibilities - **Transaction Validation**: Validators verify the correctness of transactions proposed by the leader, using mechanisms like the Equivalence Principle for non-deterministic operations. - **Leader Selection**: Validators participate in the process of randomly selecting a leader for each transaction, ensuring fairness and decentralization. - **Consensus Participation**: Validators cast votes on proposed transaction outcomes, contributing to the consensus process. - **Staking and Incentives**: Validators stake tokens to earn the right to validate transactions and receive rewards based on their participation and correctness. ## Validator Selection and Roles - **Leader Validator**: For each transaction, a leader is randomly selected among the validators. The leader is responsible for executing the transaction and proposing the result to other validators. - **Consensus Validators**: Other validators assess the leader's proposed result and vote to accept or reject it based on predefined criteria. ## Becoming a Validator - **Staking Requirement**: Participants must stake a certain amount of tokens to become validators. - **Validator Configuration**: Validators must configure their nodes with the appropriate LLM providers and models, depending on the network's requirements. - **Reputation and Slashing**: Validators must act honestly to avoid penalties such as slashing of their staked tokens. # understand-genlayer-protocol/core-concepts/genvm.mdx # GenVM (GenLayer Virtual Machine) The GenVM is the execution environment for Intelligent Contracts in the GenLayer protocol. It serves as the backbone for processing and managing contract operations within the GenLayer ecosystem. ## Purpose of GenVM The only purpose of the GenVM is to execute Intelligent Contracts, which can have non-deterministic code while maintaining blockchain security and consistency. In summary, the GenVM plays a crucial role in enabling GenLayer's unique features, bridging the gap between traditional smart contracts and AI-powered, web-connected Intelligent Contracts. ## Key Features That Make the GenVM Different Unlike traditional blockchain virtual machines such as Ethereum Virtual Machine (EVM), the GenVM has some advanced features. - **Integration with LLMs**: the GenVM facilitates seamless interaction between Intelligent Contracts and Large Language Models - **Web access**: the GenVM provides access to the Internet - **User friendliness**: Intelligent Contracts can be written in Python, which makes the learning curve much more shallow ## How the GenVM Works 1. **Contract Deployment**: When an Intelligent Contract is deployed, the GenVM compiles and executes the contract code. 2. **Transaction Processing**: As transactions are submitted to the network, the GenVM executes the relevant contract functions and produces the contract's next state. ## Developer Considerations When developing Intelligent Contracts for the GenVM: - Utilize Python's robust libraries and features - Consider potential non-deterministic outcomes when integrating LLMs - Implement proper error handling for web data access - Optimize code for efficient execution within the rollup environment # understand-genlayer-protocol/core-concepts/optimistic-democracy.mdx import { Callout } from 'nextra-theme-docs' # Optimistic Democracy Optimistic Democracy is the consensus method used by GenLayer to validate transactions and operations of Intelligent Contracts. This approach is especially good at handling unpredictable outcomes from transactions involving web data or AI models, which is important for keeping the network reliable and secure. ## Key Components - **Validators:** Participants who stake tokens to earn the right to validate transactions. They play a crucial role in both the initial validation and any appeals process if needed. - **Leader Selection:** A process that randomly picks one validator to propose the outcome for each transaction, ensuring fairness and reducing potential biases. ## How It Works Optimistic Democracy relies on a mix of trust and verification to ensure transaction integrity: ![](/optimistic-democracy-concept.png) 1. **Initial Validation:** When a transaction is submitted, a small group of randomly selected validators checks its validity. One is chosen as the leader. The leader executes the transaction, and the other validators assess the leader's proposal using the Equivalence Principle. 2. **Majority Consensus:** If most validators accept the leader's proposal, the transaction is provisionally accepted. However, this decision is not final yet, allowing for possible appeals during a limited window of time, known as the **Finality Window**. If any validator fails to vote within the specified timeframe, they are replaced, and a new validator is selected to cast a vote. 3. **Initiating an Appeal:** If a participant disagrees with the initial validation (if it's incorrect or fraudulent), they can appeal during the Finality Window. They must submit a request and provide a bond. After the appeal starts, a new group of validators joins the original ones. This group first votes on whether the transaction should be re-evaluated. If they agree, a new leader is chosen to reassess the transaction, and all validators then review this new evaluation. 4. **Appeal Evaluation:** The new leader re-evaluates the transaction, while the other validators assess the leader's proposal using the Equivalence Principle. This step involves more validators, increasing the chances of an accurate decision. 5. **Escalating Appeals:** If the appealing party is still not satisfied, the process can escalate, with each round involving more validators. Each round doubles the number of validators. A new leader is only chosen if the transaction is overturned. 6. **Final Decision:** The appeals process continues until a majority consensus is reached or until all validators have participated. The final decision is recorded, and the transaction's state is updated accordingly. If the appealing party is correct, they receive a reward for their efforts, while incorrect appellants lose their bond. # understand-genlayer-protocol/core-concepts/optimistic-democracy/equivalence-principle.mdx # Equivalence Principle Mechanism The Equivalence Principle mechanism is a cornerstone in ensuring that Intelligent Contracts function consistently across various validators when handling non-deterministic outputs like responses from Large Language Models (LLMs) or data retrieved through web browsing. It plays a crucial role in how validators assess and agree on the outcomes proposed by the Leader. The Equivalence Principle protects the network from manipulations or errors by ensuring that only suitable, equivalent outcomes influence the blockchain state. ## Key Features of the Equivalence Principle The Equivalence Principle is fundamental to how Intelligent Contracts operate, ensuring they work reliably across different network validators. - **Consistency in Decentralized Outputs:** The Equivalence Principle allows outputs from various sources, such as LLMs or web data, to be different yet still considered valid as long as they meet predefined standards. This is essential to maintain fairness and uniform decision-making across the blockchain, despite the natural differences in AI-generated responses or web-sourced information. - **Security Enhancement:** To protect the integrity of transactions, the Equivalence Principle requires that all validators check each other’s work. This mutual verification helps prevent errors and manipulation, ensuring that only accurate and agreed-upon data affects the blockchain. - **Output Validation Flexibility:** Intelligent Contracts often need to handle complex and varied data. This part of the principle allows developers to set specific rules for what counts as "equivalent" or acceptable outputs. This flexibility helps developers tailor the validation process to suit different needs, optimizing either for accuracy or efficiency depending on the contract's requirements. ## Types of Equivalence Principles Validators work to reach a consensus on whether the result set by the Leader is acceptable, which might involve direct comparison or qualitative evaluation, depending on the contract’s design. If the validators do not reach a consensus due to differing data interpretations or an error in data processing, the result might be challenged or an appeal process might be initiated. ### Comparative Equivalence Principle In the Comparative Equivalence Principle, both the Leader and the validators perform identical tasks and then directly compare their respective results with the predefined criteria in the Equivalence Principle to ensure consistency and accuracy. This method uses an acceptable margin of error to handle slight variations in results between validators and is suitable for quantifiable outputs. However, since multiple validators perform the same tasks as the Leader, it increases computational demands and associated costs. For example, if an Intelligent Contract is tasked with calculating the average rating of a product based on user reviews, the Equivalence Principle specifies that the average ratings should not differ by more than 0.1 points. Here's how it works: 1. **Leader Calculation**: The Leader validator calculates the average rating from the user reviews and arrives at a rating of 4.5. 2. **Validators' Calculations**: Each validator independently calculates the average rating using the same set of user reviews. Suppose one validator calculates an average rating of 4.6. 3. **Comparison**: The validators compare their calculated average (4.6) with the Leader's average (4.5). According to the Equivalence Principle, the ratings should not differ by more than 0.1 points. 4. **Decision**: Since the difference (0.1) is within the acceptable margin of error, the validators accept the Leader's result as valid. ### Non-Comparative Equivalence Principle In contrast, the Non-Comparative Equivalence Principle does not require validators to replicate the Leader's output, which makes the validation process faster and less costly. Instead, validators assess the accuracy of the Leader’s result against the criteria defined in the Equivalence Principle. This method is particularly useful for qualitative outputs like text summaries. For example, in an Intelligent Contract designed to summarize news articles, the process works as follows: 1. **Leader Summary**: The Leader validator generates a summary of a news article. 2. **Evaluation Criteria**: The Equivalence Principle defines criteria for an acceptable summary, such as accuracy, relevance, and length. 3. **Validators' Assessment**: Instead of generating their own summaries, validators review the Leader’s summary and check if it meets the predefined criteria. - **Accuracy**: Does the summary accurately reflect the main points of the article? - **Relevance**: Is the summary relevant to the content of the article? - **Length**: Is the summary within the acceptable length? 4. **Decision**: If the Leader’s summary meets all the criteria, it is accepted by the validators. ## Key Points for Developers - **Setting Equivalence Criteria:** Developers must define what 'equivalent' means for each non-deterministic operation in their Intelligent Contract. This guideline helps validators judge if different outcomes are close enough to be treated as the same. - **Ensuring Contract Reliability:** By clearly defining equivalence, developers help maintain the reliability and predictability of their contracts, even when those contracts interact with the unpredictable web or complex AI models. # understand-genlayer-protocol/core-concepts/optimistic-democracy/appeal-process.mdx # Appeals Process The appeals process in GenLayer is a critical component of the Optimistic Democracy consensus mechanism. It provides a means for correcting errors or disagreements in the validation of Intelligent Contracts. This process ensures that non-deterministic transactions are accurately evaluated, contributing to the robustness and fairness of the platform. ## How It Works - **Initiating an Appeal**: Participants can appeal the initial decision by submitting a request and a required bond during the Finality Window. A new set of validators is then added to the original group to reassess the transaction. - **Appeal Evaluation**: The new validators first review the existing transaction to decide if it needs to be overturned. If they agree it should be re-evaluated, a new leader re-evaluates the transaction. The combined group of original and new validators then review this new evaluation to ensure accuracy. - **Escalating Appeals**: If unresolved, the appeal can escalate, doubling the number of validators each round until a majority consensus is reached or all validators have participated. Once a consensus is reached, the final decision is recorded, and the transaction's state is updated. Correct appellants receive a reward, while those who are incorrect may lose their bond. ## Gas Costs for Appeals The gas costs for an appeal can be covered by the original user, the appellant, or any third party. When submitting a transaction, users can include an optional tip to cover potential appeal costs. If insufficient gas is provided, the appeal may fail to be processed, but any party can supply additional gas to ensure the appeal proceeds. # understand-genlayer-protocol/core-concepts/optimistic-democracy/finality.mdx # Finality Finality refers to the state in which a transaction is considered settled and unchangeable. In GenLayer, once a transaction achieves finality, it cannot be appealed or altered, providing certainty to all participants in the system. This is particularly important for applications that rely on accurate and definitive outcomes, such as financial contracts or decentralized autonomous organizations (DAOs). ## Finality Window The Finality Window is a time frame during which a transaction can be challenged or appealed before it becomes final. This window serves several purposes: 1. **Appeals**: During the Finality Window, any participant can appeal a transaction if they believe the validation was incorrect. This allows for a process of checks and balances, ensuring that non-deterministic transactions are evaluated properly. 2. **Re-computation**: If a transaction is appealed, the system can re-evaluate the transaction with a new set of validators. The Finality Window provides the time necessary for this process to occur. 3. **Security**: The window also acts as a security feature, allowing the network to correct potential errors or malicious activity before finalizing a transaction. import Image from 'next/image' ## Deterministic vs. Non-Deterministic Transactions In GenLayer, Intelligent Contracts are classified as either deterministic or non-deterministic. ### Deterministic Contracts These contracts have a shorter Finality Window because their validation process is straightforward and not subject to appeals. However, it is essential that all interactions with the contract remain deterministic to maintain this efficiency. ### Non-Deterministic Contracts Non-deterministic contracts involve Large Language Model (LLM) calls or web data retrieval, which introduce variability in their outcomes. These contracts require a longer Finality Window to account for potential appeals and re-computation. import { Callout } from 'nextra-theme-docs' If a specific transaction within the contract is deterministic but interacts with a non-deterministic part of the contract, it will be treated as non-deterministic. This ensures that any appeals or re-computations of previous transactions are handled consistently, maintaining the integrity of the contract's overall state. ## Fast Finality For scenarios requiring immediate finality, such as emergency decisions in a DAO, it is possible to pay for all validators to validate the transaction immediately. This approach, though more costly, allows for fast finality, bypassing the typical Finality Window. Fast finality only works if there are no previous non-deterministic transactions still within their Finality Window. Even if your transaction is considered final, if a previous transaction is reverted, your transaction will have to be recomputed as it might depend on the same state. ## Appealability and Gas When submitting a transaction, users can include additional gas to cover potential appeals. If a transaction lacks sufficient gas for appeals, third parties can supply additional gas during the Finality Window. Developers of Intelligent Contracts can also set minimum gas requirements for appealability, ensuring that critical transactions have adequate coverage. # understand-genlayer-protocol/core-concepts/optimistic-democracy/staking.mdx # Staking in GenLayer Participants, known as validators, commit a specified amount of tokens to the network by locking them up on the rollup layer. This commitment supports the network's consensus mechanism and enables validators to actively participate in processing transactions and managing the network. ## How Staking Works - **Stake Deposit**: To become a validator on GenLayer, participants must deposit GEN tokens on the rollup layer. This deposit acts as a security bond and qualifies them to join the pool of active validators. - **Validator Participation**: Only a certain number of validators, typically between 100 and 1000, with the highest stakes can be part of the active validator set. Once staked, validators take on the responsibility of validating transactions and executing Intelligent Contracts. Their role is crucial for ensuring the network’s reliability and achieving consensus on transaction outcomes. - **Delegated Proof of Stake (DPoS)**: GenLayer enhances accessibility and network security through a Delegated Proof of Stake system. This allows token holders who are not active validators themselves to delegate their tokens to trusted validators. By delegating their tokens, users increase the total stake of the validator and share in the rewards. Typically, the validator takes a configurable fee (around 10%), with the remaining rewards (90%) going to the delegating user. - **Earning Rewards**: Validators, and those who delegate their tokens to them, earn rewards for their contributions to validating transactions, paid in GEN tokens. These rewards are proportional to the amount of tokens staked and the transaction volume processed. - **Risk of Slashing**: Validators, and by extension their delegators, face the risk of having a portion of their staked tokens [slashed](/core-concepts/optimistic-democracy/slashing) if they fail to comply with network rules or if the validator supports fraudulent transactions. ## Unstaking and Withdrawing To stop validating or to retrieve staked tokens, validators must initiate an [unstaking](/core-concepts/optimistic-democracy/unstaking) process, which includes a cooldown period to finalize all pending transactions. This ensures the network remains secure and all obligations are fulfilled before the withdrawal. # understand-genlayer-protocol/core-concepts/optimistic-democracy/slashing.mdx # Slashing in GenLayer Slashing is a mechanism used in GenLayer to penalize validators who engage in behavior detrimental to the network. This ensures that validators act honestly and effectively, maintaining the integrity of the platform and the Intelligent Contracts executed within it. By penalizing undesirable behavior, slashing helps align validators' incentives with those of the network and its users. ## Slashing Process 1. **Violation Detection**: The network identifies a violation, such as missing an execution window. 2. **Slash Calculation**: The amount to be slashed is calculated based on the specific violation and platform rules. 3. **Stake Reduction**: The slashed amount is deducted from the validator's stake. 4. **Finality**: The slashing becomes final after the Finality Window closes, ensuring that the validator's balance is finalized and accounts for any potential appeals. ## When Slashing Occurs Validators in GenLayer can be slashed for several reasons: 1. **Missing Transaction Execution Window**: Validators are expected to execute transactions within a specified time frame. If a validator misses this window, they are penalized, ensuring that validators remain active and responsive. 2. **Missing Appeal Execution Window**: During the appeals process, validators must respond within a set time frame. If they fail to do so, they are slashed, which motivates validators to participate in the appeals process. ### Amount Slashed The amount slashed varies based on the severity of the violation and the specific rules set by the GenLayer platform. The slashing amount is designed to be substantial enough to deter malicious or negligent behavior while not being excessively punitive for honest mistakes. # understand-genlayer-protocol/core-concepts/optimistic-democracy/unstaking.mdx # Unstaking in GenLayer Unstaking in GenLayer is the process by which validators disengage their staked tokens from the network, ending their active participation as validators. They must initiate an unstaking process, which includes a cooldown period to finalize all pending transactions. This procedure ensures that all obligations are fulfilled and pending issues resolved, maintaining the network's integrity and securing the platform’s operations. ## How Unstaking Works The unstaking process includes several key steps: 1. **Initiating Unstaking**: Validators initiate their exit from active duties by submitting an unstaking transaction, signaling their intention to cease participation in validating transactions. 2. **Validator Removal**: Once the unstaking request is made, the validator is promptly removed from the pool of active validators, meaning they will no longer receive new transactions or be called upon for appeal validations. 3. **Finality Period**: During this period, validators must wait for all transactions they have participated in to reach full finality. This is crucial to ensure that validators do not exit while still having potential influence over unresolved transactions. This cooldown period helps prevent the situation where new transactions with new finality windows could prevent them from ever achieving full finality on all transactions they were involved in. 4. **Withdrawing Stake**: After all transactions have achieved finality and no outstanding issues remain, validators and their delegators can safely withdraw their staked tokens and any accrued rewards. ## Purpose of Unstaking The unstaking process is designed to: - **Ensure Accountability**: By enforcing a Finality Window, validators are held accountable for their actions until all transactions they influenced are fully resolved. This prevents premature exit from the network and ensures that all potential disputes are settled. - **Align Incentives**: The requirement for validators to wait through the Finality Window aligns their incentives with the long-term security and reliability of the network, promoting responsible participation. - **Maintain Network Security**: The unstaking process discourages abrupt departures and ensures that validators address any possible security concerns related to their past validations before leaving. ## Implications for Validators and Delegators For validators, this process mandates careful planning regarding their exit strategy from the network, considering the need to wait out the Finality Window. Delegators must also be patient, understanding that their assets will remain locked until their validator has cleared all responsibilities, safeguarding their investments from potential liabilities caused by unresolved validations. # understand-genlayer-protocol/core-concepts/rollup-integration.mdx # Rollup Integration GenLayer leverages Ethereum rollups, such as ZKSync or Polygon CDK, to ensure scalability and compatibility with existing Ethereum infrastructure. This integration is crucial for optimizing transaction throughput and reducing fees while maintaining the security guarantees of the Ethereum mainnet. ## Key Aspects of Rollup Integration ### Scalability - **High Transaction Throughput**: Rollups allow GenLayer to process a much higher number of transactions per second compared to Layer 1 solutions. - **Reduced Congestion**: By moving computation off-chain, GenLayer helps alleviate congestion on the Ethereum mainnet. ### Cost Efficiency - **Lower Transaction Fees**: Users benefit from significantly reduced gas fees compared to direct Layer 1 transactions. - **Batched Submissions**: Transactions are batched and submitted to the Ethereum mainnet, distributing costs across multiple operations. ### Security - **Ethereum Security Inheritance**: While execution happens off-chain, the security of assets and final state is guaranteed by Ethereum's robust consensus mechanism. - **Fraud Proofs/Validity Proofs**: Depending on the specific rollup solution (Optimistic or ZK), security is ensured through either fraud proofs or validity proofs. ## How Rollup Integration Works with GenLayer 1. **Transaction Submission**: Users submit transactions to the rollup. 2. **Transaction Execution**: Transactions are executed within the GenVM environment. 3. **Consensus**: The rollup layer implements the Optimistic Democracy mechanism to reach consensus on the state updates. 4. **State Updates**: The rollup layer maintains an up-to-date state of all accounts and contracts. 5. **Batch Submission**: Periodically, batches of transactions and state updates are submitted to the Ethereum mainnet. 6. **Verification**: The Ethereum network verifies the integrity of the submitted data, ensuring its validity. ## Benefits for Developers and Users - **Ethereum Compatibility**: Developers can leverage existing Ethereum tools and infrastructure. - **Improved User Experience**: Lower fees and faster transactions lead to a better overall user experience. ## Considerations - **Withdrawal Periods**: Depending on the rollup solution, there might be waiting periods for withdrawing assets back to the Ethereum mainnet. - **Rollup-Specific Features**: Different rollup solutions may offer unique features or limitations that developers should be aware of. By integrating with Ethereum rollups, GenLayer combines the innovative capabilities of Intelligent Contracts with the scalability and efficiency of Layer 2 solutions, creating a powerful platform for next-generation decentralized applications. # understand-genlayer-protocol/core-concepts/non-deterministic-operations-handling.mdx # Non-Deterministic Operations Handling ## Overview GenLayer extends traditional smart contracts by allowing Intelligent Contracts to perform non-deterministic operations, such as interacting with Large Language Models (LLMs) and accessing web data. Handling the variability inherent in these operations is crucial for maintaining consensus across the network. ## Challenges - **Variability of Outputs**: Non-deterministic operations can produce different outputs when executed by different validators. - **Consensus Difficulty**: Achieving consensus on varying outputs requires specialized mechanisms. ## Solutions in GenLayer - **Equivalence Principle**: Validators assess whether different outputs are equivalent based on predefined criteria, allowing for consensus despite variability. - **Optimistic Democracy**: The consensus mechanism accommodates non-deterministic operations by allowing provisional acceptance of transactions and providing an appeals process. ## Developer Considerations - **Defining Equivalence Criteria**: Developers must specify what constitutes equivalent outputs in their Intelligent Contracts. - **Testing and Validation**: Thorough testing is essential to ensure that non-deterministic operations behave as expected in the consensus process. # understand-genlayer-protocol/core-concepts/large-language-model-llm-integration.mdx # Large Language Model (LLM) Integration ## Overview Intelligent Contracts in GenLayer can interact directly with Large Language Models (LLMs), enabling natural language processing and more complex decision-making capabilities within blockchain applications. ## Key Features - **Natural Language Understanding**: Contracts can process and interpret instructions written in natural language. - **Dynamic Decision Making**: Utilizing LLMs allows contracts to make context-aware decisions based on complex inputs. ## Implementation 1. **LLM Providers**: Validators are configured with LLM providers (e.g., OpenAI, Ollama) to process LLM requests. 2. **Equivalence Principle**: LLM outputs are validated using the Equivalence Principle to ensure consensus among validators. 3. **Prompt Design**: Developers craft prompts to interact effectively with LLMs, specifying expected formats and constraints. ## Considerations - **Cost and Performance**: LLM interactions may incur additional computational costs and latency. - **Security**: Care must be taken to prevent prompt injections and ensure the reliability of LLM responses. # understand-genlayer-protocol/core-concepts/web-data-access.mdx # Web Data Access in Intelligent Contracts ## Overview GenLayer enables Intelligent Contracts to directly access and interact with web data, removing the need for oracles and allowing for real-time data integration into blockchain applications. ## Key Features - **Direct Web Access**: Contracts can retrieve data from web sources. - **Dynamic Applications**: Access to web data allows for applications that respond to external events and real-world data. - **Equivalence Validation**: Retrieved data is validated across validators to ensure consistency. ## Implementation 1. **Data Retrieval Functions**: GenLayer provides mechanisms for fetching web data within contracts. 2. **Data Parsing and Validation**: Contracts must parse web data and validate it according to defined equivalence criteria. 3. **Security Measures**: Contracts should handle potential security risks such as untrusted data sources and ensure data integrity. ## Considerations - **Network Dependencies**: Reliance on external web sources introduces dependencies that may affect contract execution. - **Performance Impact**: Web data retrieval may introduce latency and affect transaction processing times. # understand-genlayer-protocol/core-concepts/transactions.mdx # Transactions Transactions are the fundamental operations that drive the GenLayer protocol. Whether it's deploying a new contract, sending value between accounts, or invoking a function within an existing contract, transactions are the means by which state changes occur on the network. Here is the general structure of a transaction: ```json { "consensus_data": { "leader_receipt": { "args": [ [ 2, "0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2" ] ], "class_name": "LlmErc20", "contract_state": "gASVnAAAAAAAAACMF2JhY2tlbmQubm9kZS5nZW52bS5iYXNllIwITGxtRXJjMjCUk5QpgZR9lIwIYmFsYW5jZXOUfZQojCoweEQyNzFjNzRBNzgwODNGMzU3YTlmOGQzMWQ1YWRDNTlCMzk1Y2YxNmKUS2KMKjB4NzkzQWUyQ2ZGMTc0NjJjYzlmOUQ2OGUxOTRiN2I5NDlkMjA4MEVhMpRLAnVzYi4=", "eq_outputs": { "leader": { "0": "{\"transaction_success\": true, \"transaction_error\": \"\", \"updated_balances\": {\"0xD271c74A78083F357a9f8d31d5adC59B395cf16b\": 98, \"0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2\": 2}}" } }, "error": null, "execution_result": "SUCCESS", "gas_used": 0, "method": "transfer", "mode": "leader", "node_config": { "address": "0x185D2108D9dE15ccf6beEb31774CA96a4f19E62B", "config": {}, "model": "gpt-4o", "plugin": "openai", "plugin_config": { "api_key_env_var": "OPENAIKEY", "api_url": null }, "provider": "openai", "stake": 1 }, "vote": "agree" }, "validators": [ { "args": [ [ 2, "0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2" ] ], "class_name": "LlmErc20", "contract_state": "gASVnAAAAAAAAACMF2JhY2tlbmQubm9kZS5nZW52bS5iYXNllIwITGxtRXJjMjCUk5QpgZR9lIwIYmFsYW5jZXOUfZQojCoweEQyNzFjNzRBNzgwODNGMzU3YTlmOGQzMWQ1YWRDNTlCMzk1Y2YxNmKUS2KMKjB4NzkzQWUyQ2ZGMTc0NjJjYzlmOUQ2OGUxOTRiN2I5NDlkMjA4MEVhMpRLAnVzYi4=", "eq_outputs": { "leader": { "0": "{\"transaction_success\": true, \"transaction_error\": \"\", \"updated_balances\": {\"0xD271c74A78083F357a9f8d31d5adC59B395cf16b\": 98, \"0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2\": 2}}" } }, "error": null, "execution_result": "SUCCESS", "gas_used": 0, "method": "transfer", "mode": "validator", "node_config": { "address": "0x31bc9380eCbF487EF5919eBa7457F457B5196FCD", "config": {}, "model": "gpt-4o", "plugin": "openai", "plugin_config": { "api_key_env_var": "OPENAIKEY", "api_url": null }, "provider": "openai", "stake": 1 }, "pending_transactions": [], "vote": "agree" }, ... ], "votes": { "0x185D2108D9dE15ccf6beEb31774CA96a4f19E62B": "agree", "0x2F04Fb1e5daf7DCbf170E4CB0e427d9b11aB96cA": "agree", "0x31bc9380eCbF487EF5919eBa7457F457B5196FCD": "agree" } }, "created_at": "2024-10-02T20:32:50.469443+00:00", "data": { "function_args": "[2,\"0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2\"]", "function_name": "transfer" }, "from_address": "0xD271c74A78083F357a9f8d31d5adC59B395cf16b", "gaslimit": 66, "hash": "0xb7486f70a3fec00af5f929fc1cf1078af9ff3a063afe8b6f370a44a96635505d", "leader_only": false, "nonce": 66, "r": null, "s": null, "status": "FINALIZED", "to_address": "0x5929bB548a2Fd7E9Ea2577DaC9c67A08BbC2F356", "type": 2, "v": null, "value": 0 } ``` ## Explanation of fields: - consensus_data: Object containing information about the consensus process - leader_receipt: Object containing details about the leader's execution of the transaction - args: Arguments passed to the contract function - class_name: Name of the contract class - contract_state: Encoded state of the contract - eq_outputs: Outputs from every equivalence principle in the execution of the contract method - error: Any error that occurred during execution (null if no error) - execution_result: Result of the execution (e.g., "SUCCESS" or "ERROR") - gas_used: Amount of gas used in the transaction - method: Name of the method called on the contract - mode: Execution mode (e.g., "leader" or "validator") - node_config: Configuration of the node executing the transaction - address: Address of the node - config: Configuration of the node - model: Model of the node - plugin: Plugin used for the LLM provider connection - plugin_config: Configuration of the plugin - api_key_env_var: Environment variable containing the API key for the given provider - api_url: API URL for the given provider - provider: Provider of the node - stake: Stake of the validator - vote: The leader's vote on the transaction (e.g., "agree") - validators: Array of objects containing similar information for each validator - votes: Object mapping validator addresses to their votes - created_at: Timestamp of when the transaction was created - data: Object containing details about the function call in the transaction - from_address: Address of the account initiating the transaction - gaslimit: Maximum amount of gas the transaction is allowed to consume - hash: Unique identifier (hash) of the transaction - leader_only: Boolean indicating whether the transaction is to be executed by the leader node only - nonce: Number of transactions sent from the from_address (used to prevent double-spending) - r: Part of the transaction signature (null if not yet signed) - s: Part of the transaction signature (null if not yet signed) - status: Current status of the transaction (e.g., "FINALIZED") - to_address: Address of the contract or account receiving the transaction - type: Internal type of the transaction (2 indicates a contract write call) - v: Part of the transaction signature (null if not yet signed) - value: Amount of native currency (GEN) being transferred in the transaction # understand-genlayer-protocol/core-concepts/transactions/types-of-transactions.mdx # Types of Transactions There are three different types of transactions that users can send in GenLayer. All three types are sent through the same RPC method, but they differ in the data they contain and the actions they perform. ## 1. Deploy a Contract Deploying a contract involves creating a new Intelligent Contract on the GenLayer network. This transaction initializes the contract's state and assigns it a unique address on the blockchain. The deployment process ensures that the contract code is properly validated and stored, making it ready to be called. ### Example ```json { "consensus_data": { "leader_receipt": { "args": [ { "total_supply": 100 } ], "class_name": "LlmErc20", "contract_state": "gASVnAAAAAAAAACMF2JhY2tlbmQubm9kZS5nZW52bS5iYXNllIwITGxtRXJjMjCUk5QpgZR9lIwIYmFsYW5jZXOUfZQojCoweEQyNzFjNzRBNzgwODNGMzU3YTlmOGQzMWQ1YWRDNTlCMzk1Y2YxNmKUS2KMKjB4NzkzQWUyQ2ZGMTc0NjJjYzlmOUQ2OGUxOTRiN2I5NDlkMjA4MEVhMpRLAnVzYi4=", ... }, "validators": [ ... ], ... }, "data": { "constructor_args": "{\"total_supply\":100}", "contract_address": "0x5929bB548a2Fd7E9Ea2577DaC9c67A08BbC2F356", "contract_code": "import json\nfrom backend.node.genvm.icontract import IContract\nfrom backend.node.genvm.equivalence_principle import EquivalencePrinciple\n\n\nclass LlmErc20(IContract):\n def __init__(self, total_supply: int) -> None:\n self.balances = {}\n self.balances[contract_runner.from_address] = total_supply\n...", }, ... } ``` ## 2. Send Value Sending value refers to transferring the native GEN token from one account to another. This is one of the most common types of transactions. Each transfer updates the balance of the involved accounts, and the transaction is recorded on the blockchain to ensure transparency and security. ### Example ```json { "consensus_data": null, "created_at": "2024-10-02T21:21:04.192995+00:00", "data": {}, "from_address": "0x0Bd6441CB92a64fA667254BCa1e102468fffB3f3", "gaslimit": 0, "hash": "0x6357ec1e86f003b20964ef3b2e9e072c7c9521f92989b08e04459b871b69de89", "leader_only": false, "nonce": 2, "r": null, "s": null, "status": "FINALIZED", "to_address": "0xf739FDe22E0C0CB6DFD8f3F8D170bFC07329489E", "type": 0, "v": null, "value": 200 } ``` ## 3. Call Contract Function Calling a contract function is the process of invoking a specific method within an existing Intelligent Contract. This could involve anything from querying data stored within the contract to executing more complex operations like transferring tokens or interacting with other contracts. Each function call is a transaction that modifies the contract’s state based on the inputs provided. ### Example ```json { "consensus_data": { "leader_receipt": { "args": [ [ 2, "0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2" ] ], "class_name": "LlmErc20", "contract_state": "gASVnAAAAAAAAACMF2JhY2tlbmQubm9kZS5nZW52bS5iYXNllIwITGxtRXJjMjCUk5QpgZR9lIwIYmFsYW5jZXOUfZQojCoweEQyNzFjNzRBNzgwODNGMzU3YTlmOGQzMWQ1YWRDNTlCMzk1Y2YxNmKUS2KMKjB4NzkzQWUyQ2ZGMTc0NjJjYzlmOUQ2OGUxOTRiN2I5NDlkMjA4MEVhMpRLAnVzYi4=", "eq_outputs": { "leader": { "0": "{\"transaction_success\": true, \"transaction_error\": \"\", \"updated_balances\": {\"0xD271c74A78083F357a9f8d31d5adC59B395cf16b\": 98, \"0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2\": 2}}" } }, ... }, "validators": [ ... ], ... }, "data": { "function_args": "[2,\"0x793Ae2CfF17462cc9f9D68e194b7b949d2080Ea2\"]", "function_name": "transfer" }, ... } ``` * For a list of all the fields in a transaction, see [here](/core-concepts/transactions) # understand-genlayer-protocol/core-concepts/transactions/transaction-statuses.mdx # Transaction Processing In GenLayer, transactions are processed through an account-based queue system that ensures orderliness. Here’s how transactions transition through different statuses: ## 1. Pending When a transaction is first submitted, it enters the pending state. This means it has been received by the network but is waiting to be processed. Transactions are queued per account, ensuring that each account's transactions are processed in the order they were submitted. ## 2. Proposing In this stage, the transaction is moved from the pending queue to the proposing stage. A leader and a set of voters are selected from the validator set via a weighted random selection based on total stake. The leader proposes a receipt for the transaction, which is then committed to by the validators. ## 3. Committing The transaction enters the committing stage, where validators commit their votes and cost estimates for processing the transaction. This stage is crucial for reaching consensus on the transaction's execution. ## 4. Revealing After the committing stage, validators reveal their votes and cost estimates, allowing the network to finalize the transaction's execution cost and validate the consensus. ## 5. Accepted Once the majority of validators agree on the transaction's validity and cost, the transaction is marked as accepted. This status indicates that the transaction has passed through the initial validation process successfully. ## 6. Finalized After all validations are completed and any potential appeals have been resolved, the transaction is finalized. In this state, the transaction is considered irreversible and is permanently recorded in the blockchain. ## 7. Undetermined If the transaction fails to reach consensus after all voting rounds, it enters the undetermined state. This status indicates that the transaction's outcome is unresolved, and it may require further validation or be subject to an appeal process. ## 8. Canceled A transaction can be canceled by the user or by the system if it fails to meet certain criteria (e.g., insufficient funds). Once canceled, the transaction is removed from the processing queue and will not be executed. # understand-genlayer-protocol/core-concepts/transactions/transaction-execution.mdx ## Transaction execution Once a transaction is received and properly verified by the `eth_sendRawTransaction` method on the RPC server, it is stored with a PENDING status and its hash is returned as the RPC method response. This means that the transaction has been validated for authenticity and format, but it has not yet been executed. From this point, the transaction enters the GenLayer consensus mechanism, where it is picked up for execution by the network's validators according to the consensus rules. As the transaction progresses through various stages—such as proposing, committing, and revealing—its status is updated accordingly. Throughout this process, the current status and output of the transaction can be queried by the user. This is done by calling the `eth_getTransactionByHash` method on the RPC server, which retrieves the transaction's details based on its unique hash. This method allows users to track the transaction's journey from submission to finalization, providing transparency and ensuring that they can monitor the outcome of their transactions in real-time. ### Transaction Status Transitions In the journey of a transaction within the GenLayer protocol, it begins its life when an Externally Owned Account (EOA) submits it, entering the `Pending` state. Here, it awaits further processing unless it encounters an `OutOfFee` state due to insufficient fees. If the fees are topped up, it returns to `Pending`. Alternatively, the user can cancel the transaction, moving it to the `Canceled` state. From `Pending`, the transaction progresses to the `Proposing` stage, where a leader is selected to propose a receipt. Upon successful proposal, it advances to the `Committing` stage, where all validators must commit to the transaction. If all validators commit, the transaction moves to the `Revealing` stage. In the `Revealing` stage, the transaction's fate is determined. If a majority agrees, it is `Accepted`. However, if there is no majority agreement, it returns to `Proposing`. If all leaders are rotated without agreement, it becomes `Undetermined`. In cases of disagreement, a successful appeal can revert it to `Pending`, while a failed appeal results in `Accepted`. Once `Accepted`, the transaction awaits the passing of the appeal window to become `Finalized`. An `Undetermined` transaction also becomes `Finalized` after the appeal window passes. However, an appeal can initiate a return to `Committing` from `Accepted`, or automatically revert an `Undetermined` transaction to `Pending`. ```mermaid graph TD; Start(( )) -->|EOA submits| Pending(Pending) Start -->|Insufficient fee| OutOfFee(OutOfFee) OutOfFee -->|Fee topped up| Pending Pending -->|User cancels| Canceled(Canceled) Pending -->|Select leader| Proposing(Proposing) Proposing -->|Leader proposes receipt| Committing(Committing) Committing -->|All validators commit| Revealing(Revealing) Revealing -->|Majority agrees| Accepted(Accepted) Revealing -->|No majority agreement| Proposing Revealing -->|All leaders rotated| Undetermined(Undetermined) Revealing -.->|Disagreement, appeal successful| Pending Revealing -.->|Agreement, appeal failed| Accepted Accepted -->|Appeal window passes| Finalized(Finalized) Undetermined -->|Appeal window passes| Finalized Accepted -.->|Appeal initiated| Committing Undetermined -->|Appeal automatically| Pending ``` # understand-genlayer-protocol/core-concepts/transactions/transaction-encoding-serialization-and-signing.mdx ## Transaction encoding, serialization, and signing In GenLayer, all three types of transactions needs to be properly encoded, serialized, and signed on the client-side. This process ensures that the transaction data is packaged into a relieable cross-platform efficient format, and securely signed using the sender's private key to verify the sender's identity. Once prepared, the transaction is sent to the network via the `eth_sendRawTransaction` method on the RPC Server. This method performs the inverse process: it decodes and deserializes the transaction data, and then verifies the signature to ensure its authenticity. By handling all transaction types through `eth_sendRawTransaction`, GenLayer ensures that transactions are processed securely and efficiently while maintaining compatibility with Ethereum’s specification. # understand-genlayer-protocol/core-concepts/economic-model.mdx # Economic Model ## Overview GenLayer's economic model is designed to incentivize participants to maintain the network's security and functionality. It involves staking, rewards, transaction fees, and penalties. ## Key Components - **Staking**: Validators must stake tokens to participate in the validation process, aligning their interests with the network's health. - **Rewards**: Validators receive rewards for correctly validating transactions. - **Transaction Fees**: Users pay fees for transaction processing, which are partly used to reward validators. - **Slashing**: Validators acting maliciously or incompetently can have their staked tokens slashed as a penalty. ## Incentive Mechanisms - **Positive Incentives**: Rewards and fees motivate validators to act in the network's best interest. - **Negative Incentives**: Slashing and penalties deter malicious behavior. ## Economic Security - **Stake-Based Security**: The amount staked by validators serves as a deterrent against attacks, as they risk losing their stake. - **Balancing Supply and Demand**: The economic model aims to balance the supply of validation services with demand from users. # understand-genlayer-protocol/core-concepts/accounts-and-addresses.mdx # Accounts and Addressing ## Overview Accounts are fundamental to interacting with the GenLayer network. They represent users or entities that can hold tokens, deploy Intelligent Contracts, and initiate transactions. ## Types of Accounts 1. **Externally Owned Accounts (EOAs)**: - Controlled by private keys - Can initiate transactions and hold tokens 2. **Contract Accounts**: - Associated with deployed Intelligent Contracts - Have their own addresses and code ## Account Addresses - **Address Format**: GenLayer uses a specific address format, typically represented as a hexadecimal string prefixed with `0x`. - **Public and Private Keys**: Addresses are derived from public keys, which in turn are generated from private keys kept securely by the account owner. ## Interacting with Intelligent Contracts - **Transaction Sending**: Accounts initiate transactions to call functions on Intelligent Contracts or transfer tokens. - **Gas Fees**: Transactions require gas fees to be processed. ## Account Management - **Creating Accounts**: Users can create new accounts using wallets or development tools provided by GenLayer. - **Security Practices**: Users must securely manage their private keys, as losing them can result in loss of access to their funds. # developers.mdx import { Card, Cards } from 'nextra-theme-docs' # Getting Started with GenLayer Welcome to the GenLayer getting started guide. This guide helps developers exploit the full potential of the GenLayer environment. This documentation will provide you with the tools and knowledge needed to build, deploy, and manage Intelligent Contracts on GenLayer. The next topics focus on key areas of the development process. From setting up your development environment and writing your first Intelligent Contract to exploring advanced features and best practices, these resources are designed to support your journey in creating cutting-edge decentralized applications on GenLayer. Click on any link to delve into detailed guides and enhance your development skills with GenLayer. import { Tabs } from 'nextra/components' # developers/intelligent-contracts/introduction.mdx # Introduction to Intelligent Contracts ## What are Intelligent Contracts? Intelligent Contracts are an advanced evolution of smart contracts that combine traditional blockchain capabilities with natural language processing and web connectivity. Built in Python, they enable developers to create contracts that can understand human language, process external data, and make complex decisions based on real-world information. ## Key Features of Intelligent Contracts ### Natural Language Processing (NLP) Intelligent Contracts leverage Large Language Models (LLMs) to process and understand human language inputs. This integration enables the contracts to interpret complex text-based instructions and requirements, moving beyond simple conditional logic. Through NLP capabilities, these contracts can analyze qualitative criteria and make nuanced decisions based on contextual understanding, bringing a new level of intelligence to contract execution. ### Web Connectivity These contracts can actively interact with web APIs to fetch real-time information, enabling dynamic decision-making based on current data. By incorporating external services for data verification, they maintain a reliable connection to real-world events and conditions, bridging the gap between on-chain and off-chain environments. ### Non-Deterministic Operations Intelligent Contracts introduce a sophisticated approach to handling operations with unpredictable outputs, a significant advancement over traditional deterministic smart contracts. Through the implementation of a built-in equivalence principle, multiple validators can reach consensus even when processing non-deterministic results. This system supports both comparative validation, where outputs are directly matched, and non-comparative validation, where validators assess the reasonableness of results within defined parameters. ## How Do Intelligent Contracts Work? ### Contract Structure Intelligent Contracts are written in Python using the GenVM SDK library. The basic structure consists of: 1. Dependencies Declaration: Specify required GenVM SDK modules 2. Contract Decorator: Use `@gl.contract` to define a contract class 3. State Variables: Declare with type annotations for strong typing 4. Methods: - `@gl.public.view`: Read-only methods that don't modify state - `@gl.public.write`: Methods that can modify contract state Here's an example: ```py # { "Depends": "py-genlayer:test" } from genlayer import * @gl.contract class MyContract: # State variables with type annotations variable: str def __init__(self): self.variable = "initial value" @gl.public.view def read_method(self) -> str: return self.variable @gl.public.write def write_method(self, new_value: str): self.variable = new_value ``` ### Validation Process - When transactions are submitted to Intelligent Contracts, they are automatically queued in a contract-specific order and marked with a "pending" status - A randomly selected group of validators is assigned to process the transaction, with one designated as the leader to propose the outcome - Once all validators evaluate the proposal and reach consensus using the equivalence principle, the transaction is accepted and enters the Finality Window [Learn more about the validation process](/about-genlayer/core-concepts/optimistic-democracy) ## Advantages over Traditional Smart Contracts ### Enhanced Decision Making Intelligent Contracts can process complex and qualitative criteria that traditional smart contracts cannot handle. Through their natural language understanding capabilities, they can interpret and act on human-readable inputs without requiring strict formatting or coding syntax. This flexibility allows the contracts to dynamically adapt to changing conditions, making them more responsive and intelligent in their decision-making processes. ### External Data Integration Intelligent Contracts can seamlessly integrate with external data sources, providing direct access to real-world information without intermediate layers. Their real-time data processing capabilities ensure that contract decisions are based on current and accurate information. This direct connectivity significantly reduces the traditional reliance on oracle services, making the contracts more efficient and cost-effective. ### Flexible Programming Development of Intelligent Contracts leverages Python's robust ecosystem, providing developers with a familiar and powerful programming environment. The platform supports the data structures needed to handle complex business logic and requirements. ## Challenges and Mitigations ### Non-Deterministic Operations **Challenge** The primary challenge in handling non-deterministic operations is maintaining consistency across multiple validators when operations may naturally produce varying results. This is particularly evident when dealing with LLM outputs or real-time data processing. **Mitigation** To address this, GenLayer provides the Equivalence Principle as a flexible framework for developers to decide how the validators will try to reach consensus. This system allows for both strict output matching and more nuanced validation approaches where validators can assess results within acceptable parameters, ensuring reliable contract execution even with non-deterministic elements. ### External Data Reliability **Challenge** Integrating external data sources introduces potential points of failure and data inconsistency risks that must be carefully managed. External APIs may experience downtime, return inconsistent results, or become deprecated over time. **Mitigation** To combat these challenges, Intelligent Contracts employ a robust multi-validator verification system where multiple independent validators must confirm external data integrity. ### Performance Considerations **Challenge** The integration of LLM operations and complex data processing can introduce significant computational overhead, potentially impacting contract execution speed and cost efficiency. **Mitigation** To tackle these performance challenges, GenLayer implements optimized validation processes that balance thoroughness with efficiency. The platform provides configurable consensus mechanisms that allow developers to fine-tune the validation process based on their specific needs, whether prioritizing speed or verification thoroughness. # developers/intelligent-contracts/tooling-setup.mdx import CustomCard from '../../../components/card' # Tooling Setup This guide will help you set up the GenLayer environment by installing the GenLayer CLI and launching the GenLayer Studio, write your first Intelligent Contract, deploy it, and interact with it using the GenLayer Studio. You'll also learn how to use the Genlayer Project Boilerplate to write end-to-end tests and build a frontend dApp with GenLayerJS. ## Table of Contents 1. [Using the GenLayer Studio](#using-the-genlayer-studio) 2. [Local Installation of the GenLayer CLI](#local-installation-of-the-genlayer-cli) 3. [Launching the GenLayer Studio](#launching-the-genlayer-studio) 4. [Writing Intelligent Contracts](#writing-intelligent-contracts) 5. [Deploying and Interacting with Intelligent Contracts](#deploying-and-interacting-with-intelligent-contracts) 6. [Writing End-to-End Tests with genlayer-project-boilerplate](#writing-end-to-end-tests-with-genlayer-project-boilerplate) 7. [Building a Frontend dApp with GenLayerJS](#building-a-frontend-dapp-with-genlayerjs) ## Using the GenLayer Studio The GenLayer Studio is a web-based interface for developing, testing, and deploying Intelligent Contracts. It provides a user-friendly environment for interacting with the GenLayer ecosystem. You can find it at [studio.genlayer.com](https://studio.genlayer.com). ## Local Installation of the GenLayer CLI The GenLayer CLI is used to set up the GenLayer Studio and, in the future, mainnet and testnet environments. ### Prerequisites Ensure you have the following installed and updated:
### Installation Steps 1. **Install GenLayer CLI** Open your terminal and run: ```bash npm install -g genlayer ``` 2. **Initialize GenLayer Environment** Run the following command to set up your development environment: ```bash genlayer init ``` During initialization, you'll be prompted to select your preferred LLM provider(s) and enter any required API keys. **Optional Initialization Parameters** You can customize the initialization with the following options: - `--numValidators `: Specify the number of validators (default is 5) - `--headless`: Run in headless mode without UI (default is false) - `--reset-db`: Reset the database to a clean state (default is false) - `--localnet-version `: Specify the localnet version to use (default is latest stable version) Example: ```bash genlayer init --numValidators 3 --headless --reset-db --localnet-version v0.32.1 ``` ## Launching the GenLayer Studio After initializing the environment, you can start the Studio by running: ```bash genlayer up ``` This command launches the GenLayer Studio using your existing configuration. **Optional Parameters:** - `--reset-validators`: Removes all current validators and creates new ones. - `--numValidators `: Specify the number of validators to start. - `--headless`: Run in headless mode without UI (default is false) - `--reset-db`: Reset the database to a clean state (default is false) Example: ```bash genlayer up --reset-validators --numValidators 3 --headless --reset-db ``` Once the Studio is running, access it at http://localhost:8080/. ## Writing Intelligent Contracts Refer to the [Your First Contract](./your-first-contract) page for more information on how to write Intelligent Contracts. ## Deploying and Interacting with Intelligent Contracts ### Deploying the Contract 1. **Load Your Contract**
In the GenLayer Studio, navigate to the Contracts section and upload your contract file. 3. **Deploy the Contract**
Navigate to the Run and Deploy section and click the "Deploy" button.
The Studio will automatically detect constructor parameters. Provide the required values.
Upon successful deployment, the contract address will be displayed. ### Interacting with the Contract 1. **Read Methods**
View the current state of the contract using Read Methods. These are methods that return data without modifying the state. 2. **Write Methods**
Execute Write Methods to interact with your contract. Provide any required input parameters. 3. **Execution Logs**
Monitor transactions and validator consensus via the Node Logs at the bottom of the Studio. 4. **Transaction Details**
View detailed information about a transaction by clicking on it in the bottom left list of transactions. ## Writing End-to-End Tests with genlayer-project-boilerplate The [genlayer-project-boilerplate](https://github.com/yeagerai/genlayer-project-boilerplate/) provides a starting point for writing end-to-end (e2e) tests for your Intelligent Contracts. ### Setting Up the Boilerplate 1. **Clone the Repository** On a location different from the GenLayer Studio, clone the repository: ```bash git clone https://github.com/yeagerai/genlayer-project-boilerplate.git ``` 2. **Install Dependencies**
Navigate to the project directory and install the required packages: ```bash cd genlayer-project-boilerplate npm install ``` 3. **Configure Environment**
Ensure the GenLayer Studio is running. Update the configuration files if necessary. ### Writing E2E Tests 1. **Create Test Files**
In the `test` directory, create test files using your pytest as a testing framework. 2. **Example Test** ```python import pytest from genlayer import GenLayer, Account def test_simple_contract(): # Account account_1 = create_new_account() # Deploy contract contract_code = open("contracts/my_contract.py", "r").read() contract_address, transaction_response_deploy = deploy_intelligent_contract( account_1, contract_code, "{value = 10}", ) # Test initial state initial_value = call_contract_method( contract_address, account_1, "get_value", [] ) assert initial_value == 10 # Test state change send_transaction_response = send_transaction( account_1, contract_address, "set_value", ["20"], ) # Test updated state updated_value = call_contract_method( contract_address, account_1, "get_value", [] ) assert updated_value == 20 ``` **Note on Deployment**: For deployment, developers should currently use the GenLayer Studio UI. Deploying through the CLI is not yet supported. ## Building a Frontend dApp with GenLayerJS You can build a frontend decentralized application (dApp) that interacts with your Intelligent Contract using GenLayerJS, a JavaScript SDK for GenLayer. You can start by cloning the [genlayer-dapp-boilerplate](https://github.com/yeagerai/genlayer-project-boilerplate/) repository or start from scratch with a new frontend project. After you have your project ready, continue with the following steps: ### Installing GenLayerJS ```bash npm install genlayer-js ``` ### Connecting to GenLayer ```javascript import { createClient } from 'genlayer-js'; const client = createClient(config); ``` ### Interacting with Contracts 1. **Read from a Contract** ```javascript const value = await client.readContract({ address: contractAddress, functionName: "get_value", args: [], }); ``` 2. **Update Contract State** ```javascript const txHash = await client.writeContract({ address: contractAddress, functionName: "set_value", args: [newValue], }); const receipt = await client.waitForTransactionReceipt({ hash: txHash, status: "FINALIZED", }); ``` ### Running the Frontend Ensure your frontend application is configured to connect to the GenLayer Studio's RPC endpoint (http://localhost:4000/api). Start your frontend application: ```bash npm run dev ``` # developers/intelligent-contracts/first-contract.mdx import { Callout } from 'nextra-theme-docs' # Your First Contract While a GenLayer Intelligent Contract is a pure Python program, there are few things that must be present in your file. ### Version Comment First of all, you need to place a magic comment with the version of GenVM you wish to use on the **first** line of your file ```py # { "Depends": "py-genlayer:test" } ``` It is similar to Solidity's `pragma solidity`, and `test` after a colon is a version. When GenLayer releases, it will be changed to some exact hash of a version, which will be frozen forever. ### Importing the Standard Library After the version comment, you can import the GenLayer standard library: ```py from genlayer import * ``` This will import all necessary types into the global scope, and everything else under `gl` namespace. ### The Contract Class An Intelligent Contract is a regular Python class, with a regular constructor and methods, which allows you to use your favorite IDE for type checking and auto completion. However, there are some additional requirements to make a class an Intelligent Contract. #### Decorators The GenVM makes use of decorators to identify the contract class and its methods. The contract class must be decorated with `@gl.contract` so that GenVM knows that it's an Intelligent Contract. There can be only one contract class in a file. Furthermore, public methods must be decorated with either `@gl.public.view` for read-only methods or `@gl.public.write` for methods that modify storage. Constructor (`__init__`) must be private (not decorated) #### Persistent data The GenVM enables Intelligent Contracts to maintain persistent data. This data is stored on the blockchain and can be accessed and modified via transactions. This is done by declaring fields in the contract class. All persistent fields must be declared in the class body and annotated with types.
Fields declared outside the class body by creating new instance variables (`self.field = value`) are not persistent and will be discarded after the contract execution.
#### Types In your contracts, you can use any Python types, but for persisted fields, there are some restrictions: - `list[T]` needs to be replaced with `DynArray[T]` - `dict[K, V]` needs to be replaced with `TreeMap[K, V]` - `int` type isn't supported on purpose. You most likely wish to use some fixed-size integer type, such as `i32` or `u256`. If this is not the case and you are sure that you need big integers, you can annotate your field with `bigint`, which is just an alias for python `int` Only fully instantiated generic types can be used, so `TreeMap` is forbidden, while `TreeMap[str, u256]` is not #### Example Here is a simple example of an Intelligent Contract that stores a name and allows changing it: ```py # { "Depends": "py-genlayer:test" } from genlayer import * @gl.contract class Hello: name: str def __init__(self, name: str): self.name = name @gl.public.view def run(self) -> str: return f'Hello, {self.name}' @gl.public.write def set_name(self, name: str): print(f'debug old name: {self.name}') # <- you can use prints for debugging # they will be included in the GenVM execution log self.name = name ``` The GenLayer Studio automatically detects the constructor parameters from your code. When you run your contract in the Studio, it provides the UI for all parameters for both constructor and methods, making it easy to manage and modify these inputs. # developers/intelligent-contracts/types.mdx # Types in Intelligent Contracts The GenVM provides type support for both contract development (storage/state variables) and contract interaction (calldata). Understanding these types is crucial for developing robust Intelligent Contracts. ## Contract Development Types When writing Intelligent Contracts, you can use the following types for state variables and method parameters: ### Primitive Types - **Integers** - `u8`, `u16`, `u32`, `u64`, `u128`, `u256` - Unsigned integers of various sizes - `i8`, `i16`, `i32`, `i64`, `i128`, `i256` - Signed integers of various sizes - `bigint` - Arbitrary precision integer (use with caution, prefer sized integers) - **Other Primitives** - `bool` - Boolean values (True/False) - `str` - UTF-8 encoded string - `bytes` - Raw byte sequences - `Address` - Blockchain address (20 bytes) ### Collection Types - **Arrays** - `DynArray[T]` - Dynamic array of type T (replaces Python's `list[T]`) - **Maps** - `TreeMap[K, V]` - Ordered map from key type K to value type V (replaces Python's `dict[K, V]`) ### Custom Types You can use custom Python classes in storage, for example: ```python @dataclass class User: name: str balance: u256 @gl.contract class Contract: users: DynArray[User] ``` ## Calldata Types When interacting with contract methods, the following types are supported: - **Basic Types** - Integers (converted to appropriate sized type) - Strings - Bytes - Booleans - `None` - Address (as hex string with '0x' prefix) - **Collections** - Lists (converted to `DynArray`) - Dictionaries (must have string keys, converted to `TreeMap`) ## Type Restrictions and Best Practices ### Storage Type Restrictions 1. **No Raw Python Collections** - Use `DynArray[T]` instead of `list[T]` - Use `TreeMap[K, V]` instead of `dict[K, V]` 2. **No Raw Integers** - Use sized integers (`u256`, `i64`, etc.) instead of `int` - Use `bigint` only when absolutely necessary 3. **Generic Types Must Be Fully Specified** ```python # ❌ Wrong storage: TreeMap # Not fully specified # ✅ Correct storage: TreeMap[str, u256] # Fully specified ``` ### Type Conversion in Calldata When calling contract methods: - String keys are required for dictionary parameters - Numbers are automatically converted to appropriate sized integers - Addresses should be provided as hex strings with '0x' prefix # developers/intelligent-contracts/storage.mdx import { Callout } from 'nextra-theme-docs' # Persisting data on the blockchain Usual data structures aren't suitable for representing blockchain persistent storage: 1. Allocated addresses (`id` in python terms) are not persistent 2. Allocation requires knowledge about all allocated addresses, which takes a lot of space and would cost a lot of reads at start time 3. Serialization works poorly as it will rewrite entire storage (consider rehash) Intelligent Contracts store data publicly on chain, attached to their account's address. The storage starts zero-initialized until a contract is deployed and initializes a state. For storage declaration GenLayer uses contract class fields. All persistent fields must be declared in the class body and annotated with types.
Fields declared outside the class body by creating new instance variables (`self.field = value`) are not persistent and will be discarded after the contract execution.
Example: ```py @gl.contract class PersistentContract: minter: Address def __init__(self): self.minter = gl.message.sender_account ``` In your contracts, you can use any Python types, but for persisted fields, there are some restrictions: - `list[T]` needs to be replaced with `DynArray[T]` - `dict[K, V]` needs to be replaced with `TreeMap[K, V]` - `int` type isn't supported on purpose. You most likely wish to use some fixed-size integer type, such as `i32` or `u256`. If this is not the case and you are sure that you need big integers, you can annotate your field with `bigint`, which is just an alias for python `int` Only fully instantiated generic types can be used, so `TreeMap` is forbidden, while `TreeMap[str, u256]` is not Simple examples: ```py @gl.contract class PersistentContract: a: str b: bytes # c: list[str] # ❌ `list` is forbidden! c: DynArray[str] # b: dict[Address, u256] # ❌ `dict` is forbidden! # b: TreeMap # ❌ only fully specialized generic types are allowed! b: TreeMap[Address, u256] # d: int # ❌ `int` is forbidden d: bigint # ⚠️ most likely you don't need an arbitrary big integer d_sized: i256 ``` ## Few words about `DynArray` and `TreeMap` These types implement python `collections.abc.MutableSequence` and `collections.abc.MutableMapping` which makes them compatible with most of the python code They can be encoded into calldata as-is as well, which means that following code is correct: ```py @gl.contract class PersistentContract: storage: DynArray[str] @gl.public.view def get_complete_storage(self) -> collections.abc.Sequence[str]: return self.storage ``` Calldata format supports mappings only with `str` keys, like JSON does. ## Using custom data types In the future it may be required to decorate classes that are used in the storage You can use other python classes in storage, for example: ```py @dataclass class User: name: str birthday: datetime.datetime @gl.contract class Contract: users: DynArray[User] ``` ## Differences from regular python types Even though storage classes mimic python types, remember that they provide you only with a view on memory, not actual data that is "here". For example, consider the above example ```py self.users.append(User("Ada")) user = self.users[-1] self.users[-1] = User("Definitely not Ada", datetime.datetime.now()) assert user.name == "Definitely not Ada" # this is true! ``` # developers/intelligent-contracts/first-intelligent-contract.mdx # Your First **Intelligent** Contract Now is the time to utilize all the power of GenLayer! For blockchain integrity reasons, non-determinism must be contained within special non-deterministic blocks. Such blocks are regular Python functions with no arguments, which can return arbitrary values. However, there are some limitations: - Storage is inaccessible from non-deterministic blocks - State of the Python interpreter is not passed back to the deterministic code (for instance, you won't see changes in global variables) ### Simple Case To illustrate how it works, let's get a webpage as plain HTML, and verify that it has a link to the owner: ```py example_web_address = 'https://example.org' def my_non_deterministic_block(): web_data = gl.get_webpage(example_web_address, mode='html') return 'iana' in web_data print(gl.eq_principle_strict_eq(my_non_deterministic_block)) ``` Here are a few important parts: 1. It is **mandatory** to call `gl.get_webpage` from a function invoked via `gl.eq_principle_*`, otherwise it will give an error 2. Type annotations are not required 3. `example_web_address` gets captured without the need to specify it explicitly 4. We are getting the page in plain HTML, because we want text from a link (`` HTML tag), which is not visible in the text representation 5. We are using `eq_principle_strict_eq` because we return a `bool` (`True` or `False`), so there is no need to run LLMs or other complex computations: validators will agree _if_ they both get the exactly the same result, which makes sense for our case. However, if you wish to return more complex data (such as a text summary), you should use other `eq_principle`. More on this topic on the next page ### As a Full Contract ```py # { "Depends": "py-genlayer:test" } from genlayer import * @gl.contract class Contract: had_iana: bool def __init__(self): example_web_address = 'https://example.org' def my_non_deterministic_block(): web_data = gl.get_webpage(example_web_address, mode='html') return 'iana' in web_data self.had_iana = gl.eq_principle_strict_eq(my_non_deterministic_block) ``` # developers/intelligent-contracts/equivalence-principle.mdx import { Callout } from 'nextra-theme-docs' import { Fragment } from 'react'; # Managing Intelligent Contract Operations with the Equivalence Principle The Equivalence Principle is a core concept in GenLayer's Intelligent Contract framework. It ensures consistency and reliability when handling non-deterministic operation results, such as responses from Large Language Models or web data retrieval, by establishing a standard for validators to agree on the correctness of these outputs. These functions give users detailed control over how the outputs are validated. Depending on how you want the validators to work, you can choose from a few options, such as a principle that uses LLMs or one that just uses a strict comparison. Advanced users may also choose to write their own equivalence principle The Equivalence Principle involves multiple validators randomly selected to determine whether different outputs from non-deterministic operations can be considered equivalent. One validator acts as the leader, proposing the output, while others validate it and then return it instead of their computation. ## Equivalence Principles Options Validators work to reach a consensus on whether the result set by the leader is acceptable, which might involve direct comparison or qualitative evaluation, depending on the contract's design. If the validators do not reach a consensus due to differing data interpretations or an error in data processing, the transaction will become undetermined. ### Comparative Equivalence Principle In the Comparative Equivalence Principle, the leader and the validators perform identical tasks and then directly compare their respective results with the predefined criteria to ensure consistency and accuracy. This method uses an acceptable margin of error to handle slight variations in results between validators and is suitable for quantifiable outputs. However, computational demands and associated costs increase since multiple validators perform the same tasks as the leader. ```python gl.eq_principle_prompt_comparative( your_non_deterministic_function, "The result must not differ by more than 5%" ) ``` For example, if an intelligent contract is tasked with fetching the follower count of a Twitter account and the Equivalence Principle specifies that _follower counts should not differ by more than 5%_, validators will compare their results to the leader's result utilizing their own LLMs to ensure they fall within this margin. ### Non-Comparative Equivalence Principle GenLayer SDK provides function `gl.eq_principle_prompt_non_comparative` for handling most scenarios that require performing subjective NLP tasks #### Non-Comparative Equivalence Principle Parameters The `eq_principle_prompt_non_comparative` function takes three key parameters that define how validators should evaluate non-deterministic operations: 1. **input** (function) The input parameter represents the original data or function that needs to be processed by the task. For instance, when building a sentiment analysis contract, the input might be a text description that needs to be classified. The function processes this input before passing it to the validators for evaluation. 2. **task** (str) The task parameter provides a clear and concise instruction that defines exactly what operation needs to be performed on the input. This string should be specific enough to guide the validators in their evaluation process while remaining concise enough to be easily understood. For example, in a sentiment analysis context, the task might be "Classify the sentiment of this text as positive, negative, or neutral". This instruction serves as a guide for both the leader and validators in processing the input. 3. **criteria** (str) The criteria parameter defines the specific rules and requirements that validators use to determine if an output is acceptable. This string should contain a comprehensive set of validation parameters that ensure consistency across different validators. While the criteria can be structured in various ways, it typically outlines the expected format of the output and any specific considerations that should be taken into account during validation. For example: ```python criteria = """ Output must be one of: positive, negative, neutral Consider context and tone Account for sarcasm and idioms """ ``` This criteria helps validators make consistent decisions about whether to accept or reject the leader's proposed output, even when dealing with subjective or non-deterministic results. #### Example Usage ```python @gl.contract class SentimentAnalyzer: @gl.public.write def analyze_sentiment(self, text: str) -> str: self.sentiment = gl.eq_principle_prompt_non_comparative( input=text, task="Classify the sentiment of this text as positive, negative, or neutral", criteria=""" Output must be one of: positive, negative, neutral Consider context and tone Account for sarcasm and idioms """ ) ``` In this example: - `input` is the text to analyze - `task` defines what operation to perform - `criteria` ensures consistent validation across validators without requiring exact output matching ### Data flow
```mermaid --- title: Comparative Equivalence Principle --- graph TD input[Input function] criteria[Criteria] final_result[Final result] output_leader[Output leader] output_validator[Output validator] subgraph Leader input_leader[Executing input function] leader["Performing task (LLM)"] input_leader --> leader end subgraph Validator input_validator[Executing input function] validator["Performing task (LLM)"] input_validator --> validator end input --> Leader input --> Validator leader --> output_leader validator --> output_validator output_leader --> final_result criteria --> final_result output_validator --> final_result ```
```mermaid --- title: Non-Comparative Equivalence Principle --- graph TD task[Task & criteria] input[Input function] subgraph Leader input_leader[Executing input function] leader["Performing task (LLM)"] input_leader --> leader end task --> leader leader --> Output subgraph Validator input_validator[Executing input function] validator["Validating (LLM)"] input_validator --> validator end task --> validator Output --> validator input --> Leader input --> Validator final_result[Final result] Output --> final_result validator -..- final_result ```
# developers/intelligent-contracts/debugging.mdx import { Callout } from 'nextra-theme-docs' # Debugging Intelligent Contracts on GenLayer Debugging Intelligent Contracts on GenLayer involves deploying contracts, sending transactions, validating their behavior, and identifying issues using logs. Here is some guidance on how to debug using the GenLayer Studio. ## 2. Debugging in GenLayer Studio When testing in GenLayer Studio, you can debug issues by examining the logs and outputs. The Studio provides detailed logs for every transaction and contract execution. ### Getting Static Code Syntax Errors If you get a syntax error in your contract, you can see the error on a red panel in the Studio in the **Run and Debug** tab. Here is an example of a syntax error in line 42 of the Wizard of Coin contract: ![Syntax Error](/studio/syntax-error.png) ### Viewing Logs #### Access Logs The logs are located in the bottom section of the Studio in the **Run and Debug** tab. #### Filter Relevant Logs Use filters to isolate logs related to specific transactions or contracts. You can select the debug level (info, success, error), the execution layer (RPC Server, GenVM, and Consensus), and the transaction hash. Also, you can select a transaction from the left list and see the logs for that specific transaction. ### Identifying Common Issues #### Input Validation Errors - Look for incorrect or missing parameters in the transaction payload #### Contract Logic Errors - Debug issues in contract logic by examining state changes and variable values in logs #### Non-deterministic Output Issues - Analyze LLM or web data interactions for discrepancies or timeouts #### Consensus Errors - Investigate validator disagreements or timeout errors to identify potential misconfigurations # developers/intelligent-contracts/error-handling.mdx import { Callout } from 'nextra-theme-docs' # Error handling Sometimes contracts can produce errors. There are two kinds of GenVM errors: - unrecoverable errors - rollbacks If a non-deterministic block or contract call produces an unrecoverable error, it will terminate your contract execution. Unrecoverable errors include: - `exit(x)` where $x \neq 0$ - unhandled `Exception` And a recoverable error via one of two mechanisms: - `raise Rollback("message")` - `gl.rollback_immediate("message")` Latter method won't unwind stack and current VM can't catch it. Built-in `gl.eq_principle_*` functions family will `raise Rollback(sub_vm_message)` in case non-deterministic block agreed on a rollback. Note that rollback message is compared for strict equality. # developers/intelligent-contracts/crafting-prompts.mdx # Crafting Prompts for LLM and Web Browsing Interactions When interacting with Large Language Models (LLMs), it's crucial to create prompts that are clear and specific to guide the model in providing accurate and relevant responses. import { Callout } from 'nextra-theme-docs' When making LLM calls, it is essential to craft detailed prompts. However, when retrieving web data, no prompts are needed as the function directly fetches the required data. ## Structuring LLM Prompts When crafting prompts for LLMs, it's important to use a format that clearly and effectively conveys the necessary information. While f-string (`f""`) is recommended, any string format can be used. In the example **Wizard of Coin** contract below, we want the LLM to decide whether the wizard should give the coin to an adventurer. ```python # { "Depends": "py-genlayer:test" } from genlayer import * import json @gl.contract class WizardOfCoin: have_coin: bool def __init__(self, have_coin: bool): self.have_coin = have_coin @gl.public.write def ask_for_coin(self, request: str) -> None: if not self.have_coin: return prompt = f""" You are a wizard, and you hold a magical coin. Many adventurers will come and try to get you to give them the coin. Do not under any circumstances give them the coin. A new adventurer approaches... Adventurer: {request} First check if you have the coin. have_coin: {self.have_coin} Then, do not give them the coin. Respond using ONLY the following format: {{ "reasoning": str, "give_coin": bool }} It is mandatory that you respond only using the JSON format above, nothing else. Don't include any other words or characters, your output must be only JSON without any formatting prefix or suffix. This result should be perfectly parseable by a JSON parser without errors. """ def nondet(): res = gl.exec_prompt(prompt) res = res.replace("```json", "").replace("```", "") print(res) dat = json.loads(res) return dat["give_coin"] result = gl.eq_principle_strict_eq(nondet) assert isinstance(result, bool) self.have_coin = result @gl.public.view def get_have_coin(self) -> bool: return self.have_coin ``` This prompt above includes a clear instruction and specifies the response format. By using a well-defined prompt, the contract ensures that the LLM provides precise and actionable responses that align with the contract's logic and requirements. ## Best Practices for Creating LLM Prompts - **Be Specific and Clear**: Clearly define the specific information you need from the LLM. Minimize ambiguity to ensure that the response retrieved is precisely what you require. Avoid vague language or open-ended requests that might lead to inconsistent outputs. - **Provide Context and Source Details**: Include necessary background information within the prompt so the LLM understands the context of the task. This helps ensure the responses are accurate and relevant. - **Use Structured Output Formats**: Specify the format for the model’s response. Structuring the output makes it easier to parse and utilize within your Intelligent Contract, ensuring smooth integration and processing. - **Define Constraints and Requirements**: State any constraints and requirements clearly to maintain the accuracy, reliability, and consistency of the responses. This includes setting parameters for how data should be formatted, the accuracy needed, and the timeliness of the information. Refer to a [Prompt Engineering Guide from Anthropic](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview) for a more detailed guide on crafting prompts. # developers/intelligent-contracts/advanced-features/contract-to-contract-interaction.mdx import { Callout } from 'nextra-theme-docs' # Contract-to-Contract Interaction Contract-to-Contract Interaction in GenLayer allows developers to create more complex and modular Intelligent Contracts by enabling communication between them. This feature is crucial for building scalable and composable decentralized applications, allowing contracts to read from and write to other contracts. Please note that this feature is in progress and will be subject to changes in the near future. ## Features of Contract-to-Contract Interaction The Contract-to-Contract Interaction provides several powerful capabilities: #### 1. Cross-Contract Reads Contracts can read data from other contracts, allowing for the sharing of state and information across different parts of your application. #### 2. Cross-Contract Writes Contracts can initiate state changes in other contracts, enabling complex multi-step operations that span multiple contracts. #### 3. Modular Design By separating concerns into different contracts, developers can create more maintainable and upgradable systems. #### 4. Composability Contracts can be designed to work together, creating more powerful and flexible applications by combining different functionalities. ## Methods for Contract-to-Contract Interaction #### 1. Reading from Another Contract To read data from another contract, create an instance of the `Contract` class and call its methods: ```python filename="token_interaction" copy token_contract = gl.ContractAt(self.token_contract_address) balance = token_contract.view().get_balance_of(account_address) ``` #### 2. Writing to Another Contract To initiate a state change in another contract, call a method that modifies its state: ```python filename="token_interaction" copy token_contract = gl.ContractAt(self.token_contract_address) success = token_contract.emit().transfer(to_address, amount) ``` #### 3. Handling Multiple Contract Interactions For more complex scenarios involving multiple contracts: ```python filename="multi_contract_interaction" copy @gl.contract class MultiContractInteraction: token_contract: Address storage_contract: Address def __init__(self, token_contract: str, storage_contract: str): self.token_contract = Address(token_contract) self.storage_contract = Address(storage_contract) @gl.public.write def complex_operation(self, account: str, amount: int, data: str) -> bool: token = gl.ContractAt(self.token_contract) storage = gl.ContractAt(self.storage_contract) # Read from token contract balance = token.view().get_balance_of(account) if balance >= amount: # Write to token contract token.emit().transfer(self.address, amount) # Write to storage contract storage.emit().store_data(account, data) return True return False ``` ## How to Use Contract-to-Contract Interaction in Your Contracts As GenLayer calldata is dynamically typed users can send whatever they want to a contract, or use statically typed interface to facilitate type checking and autocompletion Exact parameters of `.view()` and `.emit()` are subject to change ### Dynamically typed approach ```py address = Address("0x03FB09251eC05ee9Ca36c98644070B89111D4b3F") result = gl.ContractAt(address).view().method_name(1, '234') gl.ContractAt(address).emit().method_name(1, '234') # ^ write methods do not return anything! ``` ### Statically typed approach ```py @gl.contract_interface class GenLayerContractIface: class View: def method_name(self, a: int, b: str): ... class Write: pass ### in your contract method ### address = Address("0x03FB09251eC05ee9Ca36c98644070B89111D4b3F") result = GenLayerContractIface(address).view().method_name(1, '234') ``` ## Interacting with Ghost Contracts Eth contracts have statically typed calldata format, which means that only statically typed approach with interfaces is applicable This is not supported in the Studio right now ```py @gl.ghost_contract class GhostContractIface: class View: def method_name(self, param: str, /) -> tuple[u32, str]: ... class Write: def bar(self, param: str, /): ... ### in your contract method ### address = Address("0x03FB09251eC05ee9Ca36c98644070B89111D4b3F") i, s = GhostContractIface(address).view().method_name('234') ``` ## Best Practices for Contract-to-Contract Interaction 1. **Security**: Always validate inputs and check permissions before allowing cross-contract interactions. 2. **Error Handling**: Implement proper error handling for cases where called contracts might revert or throw exceptions. 3. **Upgradability**: Consider using upgradable patterns if you need to change contract interactions in the future. 4. **Testing**: Thoroughly test all contract interactions, including edge cases and potential vulnerabilities. # developers/intelligent-contracts/advanced-features/vector-store.mdx # Vector Store The Vector Store feature in GenLayer allows developers to enhance their Intelligent Contracts by efficiently storing, retrieving, and calculating similarities between texts using vector embeddings. This feature is particularly useful for tasks that require natural language processing (NLP), such as creating context-aware applications or indexing text data for semantic search. ## Key Features of Vector Store The Vector Store provides several powerful features for managing text data: #### 1. Text Embedding Storage You can store text data as vector embeddings, which are mathematical representations of the text, allowing for efficient similarity comparisons. Each stored text is associated with a vector and metadata. #### 2. Similarity Calculation The Vector Store allows you to calculate the similarity between a given text and stored vectors using cosine similarity. This is useful for finding the most semantically similar texts, enabling applications like recommendation systems or text-based search. #### 3. Metadata Management Along with the text and vectors, you can store additional metadata (any data type) associated with each text entry. This allows developers to link additional information (e.g., IDs or tags) to the text for retrieval. #### 4. CRUD Operations The Vector Store provides standard CRUD (Create, Read, Update, Delete) operations, allowing developers to add, update, retrieve, and delete text and vector entries efficiently. ## How to Use Vector Store in Your Contracts To use the Vector Store in your Intelligent Contracts, you will interact with its methods to add and retrieve text data, calculate similarities, and manage vector storage. Below are the details of how to use this feature. #### Importing Vector Store First, import the VectorStore class from the standard library in your contract: ```python from backend.node.genvm.std.vector_store import VectorStore ``` #### Creating a Contract with Vector Store Here’s an example of a contract using the Vector Store for indexing and searching text logs: ```python # { # "Seq": [ # { "Depends": "py-lib-genlayermodelwrappers:test" }, # { "Depends": "py-genlayer:test" } # ] # } from genlayer import * import genlayermodelwrappers import numpy as np from dataclasses import dataclass @dataclass class StoreValue: log_id: u256 text: str # contract class @gl.contract class LogIndexer: vector_store: VecDB[np.float32, typing.Literal[384], StoreValue] def __init__(self): pass def get_embedding_generator(self): return genlayermodelwrappers.SentenceTransformer("all-MiniLM-L6-v2") def get_embedding( self, txt: str ) -> np.ndarray[tuple[typing.Literal[384]], np.dtypes.Float32DType]: return self.get_embedding_generator()(txt) @gl.public.view def get_closest_vector(self, text: str) -> dict | None: emb = self.get_embedding(text) result = list(self.vector_store.knn(emb, 1)) if len(result) == 0: return None result = result[0] return { "vector": list(str(x) for x in result.key), "similarity": str(1 - result.distance), "id": result.value.log_id, "text": result.value.text, } @gl.public.write def add_log(self, log: str, log_id: int) -> None: emb = self.get_embedding(log) self.vector_store.insert(emb, StoreValue(text=log, log_id=u256(log_id))) @gl.public.write def update_log(self, log_id: int, log: str) -> None: emb = self.get_embedding(log) for elem in self.vector_store.knn(emb, 2): if elem.value.text == log: elem.value.log_id = u256(log_id) @gl.public.write def remove_log(self, id: int) -> None: for el in self.vector_store: if el.value.log_id == id: el.remove() ``` # developers/intelligent-contracts/security-and-best-practices/prompt-injection.mdx # Prompt Injection Intelligent Contracts exclusively interact with public data, reducing certain types of risks such as data leakage. However, ensuring the integrity of these contracts still requires careful management of inputs and outputs. ## Understanding Prompt Injection Prompt injection involves manipulating the prompts fed to AI models to produce unintended outcomes. In GenLayer, this risk is primarily associated with how inputs are structured and how outputs are managed within Intelligent Contracts. ## Strategies for Mitigating Prompt Injection To safeguard against prompt injection in GenLayer, you need to implement these key strategies: - **Restrict Inputs**: Limit user inputs to the minimum necessary information. This reduces the chances of malicious data entering the system. Construct prompts within the contract code as much as possible, rather than allowing free-form user inputs which could be manipulated. - **Restrict Outputs**: Define and enforce strict parameters on what outputs are permissible from the AI models. This helps prevent the model from generating outputs that could trigger unintended actions within the contract. - **Simplify and Secure Contract Logic**: Ensure that the logic within Intelligent Contracts is clear and robust against manipulation. Errors in contract logic can be exploited just as easily as manipulated inputs. - **Human-in-the-Loop**: For critical operations or decisions, consider implementing a human review step before actions are finalized. This adds an additional layer of scrutiny and can catch issues that automated systems might miss. These measures are essential for maintaining the security and reduce the risk of prompt injections # developers/intelligent-contracts/examples/storage.mdx # Storage Contract The Storage contract sets up a simple scenario to store and retrieve a string value. This contract demonstrates basic data storage and retrieval functionality within a blockchain environment. ```python # { "Depends": "py-genlayer:test" } from genlayer import * # contract class @gl.contract class Storage: storage: str # constructor def __init__(self, initial_storage: str): self.storage = initial_storage # read methods must be annotated with view @gl.public.view def get_storage(self) -> str: return self.storage # write method @gl.public.write def update_storage(self, new_storage: str) -> None: self.storage = new_storage ``` ## Code Explanation - **Initialization**: The `Storage` class initializes the contract with an `initial_storage` value. This value is stored in the `self.storage` attribute. - **Read Method**: The `get_storage()` method is a read-only function that returns the current value stored in `self.storage`. - **Write Method**: The `update_storage(new_storage)` method allows updating the stored value with a new string. ## Deploying the Contract To deploy the Storage contract, you need to initialize the contract state correctly. This setup will determine the initial value stored in the contract. 1. **Set Initial Storage**: Provide the initial storage value. The `initial_storage` constructor parameter is detected from the code. For example, you might set `initial_storage` to "Hello, World!". 2. **Deploy the Contract**: Once the initial storage is set, deploy the contract to make it ready for interaction. ## Checking the Contract State After deploying the contract, its address is displayed and you can check its state in the **Read Methods** section. Use the `get_storage()` function to see the current value stored in the contract. ## Executing Transactions To interact with the deployed contract, go to the **Write Methods** section. Here, you can call the `update_storage` method to change the stored value. This triggers the contract's logic to update the storage with the new value. ## Analyzing the Contract's Behavior When the `update_storage` method is executed: - The contract updates the `self.storage` attribute with the new value provided. - You can then use the `get_storage()` method to verify that the value has been updated. ## Handling Different Scenarios - **Initial State**: When the contract is first deployed, the `get_storage()` method will return the initial value set during deployment. - **After Update**: After calling `update_storage`, the `get_storage()` method will return the newly set value. - **Multiple Updates**: You can update the storage multiple times, and each time the most recent value will be stored and returned by `get_storage()`. You can view the logs to see detailed information about the contract interaction, including the values being stored and retrieved. This Storage contract provides a simple example of how data can be stored and retrieved on a blockchain, demonstrating basic state management within a smart contract. # developers/intelligent-contracts/examples/user-storage.mdx # UserStorage Contract The UserStorage contract sets up a scenario to store and retrieve string values associated with different user accounts. This contract demonstrates basic per-user data storage and retrieval functionality within a blockchain environment. ```python # { "Depends": "py-genlayer:test" } from genlayer import * @gl.contract class UserStorage: storage: TreeMap[Address, str] # constructor def __init__(self): pass # read methods must be annotated @gl.public.view def get_complete_storage(self) -> dict[str, str]: return {k.as_hex: v for k, v in self.storage.items()} @gl.public.view def get_account_storage(self, account_address: str) -> str: return self.storage[Address(account_address)] @gl.public.write def update_storage(self, new_storage: str) -> None: self.storage[gl.message.sender_account] = new_storage ``` ## Code Explanation - **Initialization**: The `UserStorage` class initializes the contract with an empty dictionary `self.storage` to store user-specific data. - **Read Methods**: - `get_complete_storage()` returns the entire storage dictionary, containing all user data. - `get_account_storage(account_address)` returns the stored value for a specific user account. - **Write Method**: `update_storage(new_storage)` allows updating the stored value for the user who called the contract (identified by `contract_runner.from_address`). ## Deploying the Contract To deploy the UserStorage contract, you don't need to provide any initial parameters: 1. **Deploy the Contract**: Simply deploy the contract to make it ready for interaction. ## Checking the Contract State After deploying the contract, its address is displayed and you can check its state in the **Read Methods** section. - Use `get_complete_storage()` to see all stored user data. - Use `get_account_storage(account_address)` to see the data for a specific user account. ## Executing Transactions To interact with the deployed contract, go to the **Write Methods** section. Here, you can call the `update_storage` method to change the stored value for the calling user. This triggers the contract's logic to update the storage with the new value. ## Analyzing the Contract's Behavior When the `update_storage` method is executed: - The contract updates the `self.storage` dictionary, associating the new value with the address of the user who called the function (`contract_runner.from_address`). - You can then use the `get_account_storage()` or `get_complete_storage()` methods to verify that the value has been updated for the specific user. ## Handling Different Scenarios - **Initial State**: When the contract is first deployed, the storage is empty. `get_complete_storage()` will return an empty dictionary. - **First Update for a User**: When a user first calls `update_storage`, a new entry is created in the storage dictionary for that user's address. - **Subsequent Updates**: If a user calls `update_storage` again, their existing entry in the storage is updated with the new value. - **Multiple Users**: Different users can store and retrieve their own values independently. - **Accessing Non-existent Data**: If `get_account_storage()` is called with an address that hasn't stored any data yet, it will raise a `KeyError`. You can view the logs to see detailed information about the contract interaction, including the values being stored and retrieved for different user accounts. This UserStorage contract provides a simple example of how user-specific data can be stored and retrieved on a blockchain, demonstrating basic multi-user state management within a smart contract. # developers/intelligent-contracts/examples/llm-hello-world.mdx # LlmHelloWorld Contract The LlmHelloWorld contract demonstrates a simple example of integrating AI capabilities within an intelligent contract. This contract shows how to use the [comparative equivalence principle](/developers/intelligent-contracts/equivalence-principle#comparative-equivalence-principle) to call an LLM and store the response in the contract state. ```python # { "Depends": "py-genlayer:test" } from genlayer import * import typing @gl.contract class LlmHelloWorld: message: str def __init__(self): self.message = "" @gl.public.write def set_message(self) -> typing.Any: def get_message() -> str: task = "There is no context, I just want you to answer with a string equal to 'yes'" result = gl.exec_prompt(task) print(result) return result self.message = gl.eq_principle_strict_eq(get_message) @gl.public.view def get_message(self) -> str: return self.message ``` ## Code Explanation - **Initialization**: The `LlmHelloWorld` class initializes with an empty string in the `message` variable. - **Write Method**: - `set_message()` uses AI functionality to generate and store a message. - It contains an inner function `get_message()` that prompts an AI model with a simple task. - Uses `gl.eq_principle_strict_eq()` to ensure deterministic AI responses across the network. - **Read Method**: - `get_message()` returns the stored message. ## Key Components 1. **AI Integration**: The contract uses `gl.exec_prompt()` to interact with an AI model. 2. **Deterministic Execution**: `gl.eq_principle_strict_eq()` ensures that all nodes in the network arrive at the same exact result. 3. **State Management**: The contract maintains a single string state variable that stores the AI response. ## Deploying the Contract To deploy the LlmHelloWorld contract: 1. **Deploy the Contract**: No initial parameters are needed for deployment. 2. The contract will initialize with an empty message. ## Checking the Contract State After deployment, you can: - Use `get_message()` to view the currently stored message. - Initially, this will return an empty string. ## Executing Transactions To interact with the deployed contract: 1. Call `set_message()` to trigger the AI interaction. 2. The function will: - Execute the AI prompt requesting a "yes" response - Store the result using the equivalence principle - Print the result to the logs ## Understanding AI Integration This contract demonstrates several important concepts: - **AI Prompting**: Shows how to formulate simple prompts for AI models within smart contracts. - **Deterministic AI**: Uses the equivalence principle to ensure all nodes reach consensus on AI outputs. - **State Updates**: Demonstrates how AI-generated content can be stored in blockchain state. ## Handling Different Scenarios - **Initial State**: The message starts empty. - **After set_message()**: The message will contain "yes" (the AI's response). - **Multiple Calls**: Each call to `set_message()` will update the stored message. - **Network Consensus**: All nodes will agree on the same message due to the equivalence principle. ## Important Notes 1. This is a minimal example to demonstrate AI-blockchain integration. 2. The AI prompt is intentionally simple for demonstration purposes. 3. The equivalence principle ensures that the AI response is consistent across all network nodes. You can monitor the contract's behavior through transaction logs, which will show the AI responses and state updates as they occur. # developers/intelligent-contracts/examples/llm-hello-world-non-comparative.mdx # LlmHelloWorldNonComparative Contract The LlmHelloWorldNonComparative contract demonstrates a simple example of integrating AI capabilities within an intelligent contract without requiring that all the validators execute the full task. They just need to evaluate the leader's response against the specified criteria. This is done by using the [non-comparative equivalence principle](/developers/intelligent-contracts/equivalence-principle#non-comparative-equivalence-principle). ```python # { "Depends": "py-genlayer:test" } from genlayer import * import typing @gl.contract class LlmHelloWorldNonComparative: message: str def __init__(self): self.message = "" @gl.public.write def set_message(self) -> typing.Any: self.message = gl.eq_principle_prompt_non_comparative( lambda: "There is no context, I just want you to answer with truthy value in python (for example: 'yes', 'True', 1)", task="Answer with truthy value in python (for example: 'yes', 'True', 1)", criteria="Answer should be a truthy value in python" ) @gl.public.view def get_message(self) -> str: return self.message ``` ## Code Explanation - **Initialization**: The `LlmHelloWorldNonComparative` class initializes with an empty string in the `message` variable. - **Write Method**: - `set_message()` uses AI functionality to generate and store a message. - Uses `gl.eq_principle_prompt_non_comparative()` with three parameters: - A lambda function providing the prompt - A task description - Validation criteria for the response - **Read Method**: - `get_message()` returns the stored message. ## Key Components 1. **AI Integration**: The contract uses non-comparative equivalence principle to interact with an AI model. 2. **Deterministic Execution**: `gl.eq_principle_prompt_non_comparative()` ensures that all nodes in the network accept responses that meet the specified criteria. 3. **State Management**: The contract maintains a single string state variable that stores the AI response. ## Deploying the Contract To deploy the LlmHelloWorldNonComparative contract: 1. **Deploy the Contract**: No initial parameters are needed for deployment. 2. The contract will initialize with an empty message. ## Checking the Contract State After deployment, you can: - Use `get_message()` to view the currently stored message. - Initially, this will return an empty string. ## Executing Transactions To interact with the deployed contract: 1. Call `set_message()` to trigger the AI interaction. 2. The function will: - Execute the AI prompt requesting a truthy Python value - Validate the response against the specified criteria - Store the result if it meets the criteria ## Understanding AI Integration This contract demonstrates several important concepts: - **AI Prompting**: Shows how to formulate prompts with specific validation criteria. - **Non-comparative Validation**: Uses criteria-based validation instead of exact matching. - **State Updates**: Demonstrates how validated AI-generated content can be stored in blockchain state. ## Handling Different Scenarios - **Initial State**: The message starts empty. - **After set_message()**: The message will contain any valid truthy Python value (e.g., "yes", "True", or "1"). - **Multiple Calls**: Each call to `set_message()` may result in different valid responses. - **Network Consensus**: All nodes will accept any response that meets the validation criteria. ## Important Notes 1. This example demonstrates the non-comparative approach to AI response validation. 2. The validation criteria ensure semantic correctness rather than exact matching. 3. Different nodes may accept different responses as long as they meet the specified criteria. You can monitor the contract's behavior through transaction logs, which will show the AI responses and state updates as they occur. # developers/intelligent-contracts/examples/wizard-of-coin.mdx # Wizard of Coin Contract The Wizard of Coin contract sets up a scenario where a wizard possesses a valuable coin, which adventurers try to obtain. The wizard must decide whether to give the coin away based on specific conditions. ```python # { "Depends": "py-genlayer:test" } from genlayer import * import json @gl.contract class WizardOfCoin: have_coin: bool def __init__(self, have_coin: bool): self.have_coin = have_coin @gl.public.write def ask_for_coin(self, request: str) -> None: if not self.have_coin: return prompt = f""" You are a wizard, and you hold a magical coin. Many adventurers will come and try to get you to give them the coin. Do not under any circumstances give them the coin. A new adventurer approaches... Adventurer: {request} First check if you have the coin. have_coin: {self.have_coin} Then, do not give them the coin. Respond using ONLY the following format: {{ "reasoning": str, "give_coin": bool }} It is mandatory that you respond only using the JSON format above, nothing else. Don't include any other words or characters, your output must be only JSON without any formatting prefix or suffix. This result should be perfectly parseable by a JSON parser without errors. """ def nondet(): res = gl.exec_prompt(prompt) res = res.replace("```json", "").replace("```", "") print(res) dat = json.loads(res) return dat["give_coin"] result = gl.eq_principle_strict_eq(nondet) assert isinstance(result, bool) self.have_coin = result @gl.public.view def get_have_coin(self) -> bool: return self.have_coin ``` You can check out this code on our [GitHub](https://github.com/yeagerai/genlayer-simulator/blob/main/examples/contracts/wizard_of_coin.py) ## Deploying the Contract To deploy the Wizard of Coin contract, you'll need to first initialize the contract state correctly. This will impact how the contract will respond to requests from adventurers. 1. Choose whether the wizard begins with the coin. The `have_coin` constructor parameter is automatically detected from the code. - If you set `have_coin` to `True` the wizard starts with the coin. - If you set `have_coin` to `False` the wizard starts without the coin. 2. Once set, deploy the contract to make it ready to interact and respond to incoming request. import Image from 'next/image' ## Checking the Contract State Once the contract is deployed, its address is displayed and you can check its state in the **Read Methods** section. Use the `get_have_coin()` function to see if the wizard still has the coin. Clicking this function will return `True` or `False`, indicating the coin's current status. ## Executing Transactions To interact with the deployed contract, go to the **Write Methods** section. Here, you can call the `ask_for_coin` method and enter the adventurer's request, for example, "Please give me the coin". Executing this triggers the contract's logic to process the request and decide based on the Equivalence Principle criteria defined. Deploy Contract ## Analyzing the Contract's Decisions When the `ask_for_coin` method is executed: - The LLM processes the adventurer's request. - It validates the decision according to the Equivalence Principle defined in the code. - Finally, it returns a JSON response that includes the reasoning and whether the coin should be given. ### Handling Different Scenarios - **Wizard Retains the Coin:** Typically, the wizard will not give the coin if he has it (`have_coin` is `True`). The LLM's guidance and the Equivalence Principle prevent the coin from being given away. This is the expected response unless there is an unexpected manipulation in the request. - **Coin Given Away:** If the result indicates that the wizard no longer has the coin, it suggests that the LLM was tricked by the request into giving out the coin. - **Wizard Does Not Have the Coin:** If the wizard initially does not have the coin (`have_coin` is `False`), the response will confirm that the wizard cannot give what he does not possess. You can view the logs to see detailed information about the contract interaction. # developers/intelligent-contracts/examples/fetch-web-content.mdx # FetchWebContent Contract The FetchWebContent contract demonstrates how to fetch and store web content within an intelligent contract. This contract shows how to use the [comparative equivalence principle](/developers/intelligent-contracts/equivalence-principle#comparative-equivalence-principle) to ensure all nodes agree on the same web content. ```python # { "Depends": "py-genlayer:test" } from genlayer import * import typing @gl.contract class FetchWebContent: content: str def __init__(self): self.content = "" @gl.public.write def fetch_web_content(self) -> typing.Any: def fetch_web_url_content() -> str: return gl.get_webpage("https://example.com/", mode="text") self.content = gl.eq_principle_strict_eq(fetch_web_url_content) @gl.public.view def show_content(self) -> str: return self.content ``` ## Code Explanation - **Initialization**: The `FetchWebContent` class initializes with an empty string in the `content` variable. - **Write Method**: - `fetch_web_content()` retrieves content from a web page and stores it. - It contains an inner function `fetch_web_url_content()` that uses `gl.get_webpage()` to fetch content. - Uses `gl.eq_principle_strict_eq()` to ensure all nodes agree on the same content. - **Read Method**: - `show_content()` returns the stored web content. ## Key Components 1. **Web Integration**: The contract uses `gl.get_webpage()` to fetch content from web URLs. 2. **Deterministic Execution**: `gl.eq_principle_strict_eq()` ensures that all nodes in the network arrive at the same exact content. 3. **State Management**: The contract maintains a single string state variable that stores the web content. ## Deploying the Contract To deploy the FetchWebContent contract: 1. **Deploy the Contract**: No initial parameters are needed for deployment. 2. The contract will initialize with an empty content string. ## Checking the Contract State After deployment, you can: - Use `show_content()` to view the currently stored web content. - Initially, this will return an empty string. ## Executing Transactions To interact with the deployed contract: 1. Call `fetch_web_content()` to trigger the web content fetch. 2. The function will: - Fetch the content from example.com - Store the result using the equivalence principle - Make the content available through `show_content()` ## Understanding Web Content Integration This contract demonstrates several important concepts: - **Web Fetching**: Shows how to safely retrieve content from web sources. - **Deterministic Results**: Uses the equivalence principle to ensure all nodes reach consensus on web content. - **State Updates**: Demonstrates how web content can be stored in blockchain state. ## Handling Different Scenarios - **Initial State**: The content starts empty. - **After fetch_web_content()**: The content will contain the text from example.com. - **Multiple Calls**: Each call to `fetch_web_content()` will update the stored content. - **Network Consensus**: All nodes will agree on the same content due to the equivalence principle. ## Important Notes 1. This example uses example.com as a stable demonstration URL. 2. Web content should be relatively stable to ensure consensus. 3. The equivalence principle ensures that all nodes store identical content. 4. The `mode="text"` parameter ensures only text content is retrieved. ## Security Considerations 1. Only fetch content from trusted and stable sources. 2. Be aware that web content can change over time. 3. Consider implementing content validation before storage. 4. Use appropriate error handling for network issues. You can monitor the contract's behavior through transaction logs, which will show the fetched content and state updates as they occur. ## HTML Mode for Web Content The `gl.get_webpage()` function supports different modes for retrieving web content. While `mode="text"` returns the plain text content, `mode="html"` allows you to retrieve the complete HTML `` of the webpage. Here's an example of using HTML mode: ```python @gl.contract class FetchHTMLContent: html_content: str def __init__(self): self.html_content = "" @gl.public.write def fetch_html_content(self) -> typing.Any: def fetch_web_url_html() -> str: return gl.get_webpage("https://example.com/", mode="html") self.html_content = gl.eq_principle_strict_eq(fetch_web_url_html) @gl.public.view def show_html_content(self) -> str: return self.html_content ``` ### Key Differences with HTML Mode: - **Complete Structure**: Returns the full HTML document including tags, attributes, and DOM structure - **Use Cases**: - Parsing specific HTML elements or attributes - Extracting links, images, or other structured content - Analyzing webpage structure and metadata - **Data Size**: HTML content is typically larger than text mode as it includes markup - **Processing**: May require additional HTML parsing to extract specific elements ### When to Use HTML Mode: 1. When you need to extract information from specific HTML elements 3. When analyzing page structure or links 4. If you need to process structured data like tables or forms This addition provides users with a clear understanding of the HTML mode option and its specific use cases, complementing the existing text mode example. # developers/intelligent-contracts/examples/fetch-github-profile.mdx # FetchGitHubProfile Contract The FetchGitHubProfile contract demonstrates how to fetch and store GitHub profile content within an intelligent contract. This contract shows how to use the [comparative equivalence principle](/developers/intelligent-contracts/equivalence-principle#comparative-equivalence-principle) to ensure all nodes agree on the same profile content. ```python # { "Depends": "py-genlayer:test" } from genlayer import * import typing @gl.contract class FetchGitHubProfile: github_profile: str def __init__(self): self.github_profile = "" @gl.public.write def fetch_github_profile(self, github_handle: str) -> typing.Any: github_profile_url = "https://github.com/"+github_handle def fetch_github_profile_page_content() -> str: return gl.get_webpage(github_profile_url, mode="text") self.github_profile = gl.eq_principle_strict_eq(fetch_github_profile_page_content) @gl.public.view def show_github_profile(self) -> str: return self.github_profile ``` ## Code Explanation - **Initialization**: The `FetchGitHubProfile` class initializes with an empty string in the `github_profile` variable. - **Write Method**: - `fetch_github_profile(github_handle)` takes a GitHub username and retrieves their profile content. - Constructs the profile URL using the provided handle. - Uses `gl.eq_principle_strict_eq()` to ensure all nodes agree on the same profile content. - **Read Method**: - `show_github_profile()` returns the stored profile content. ## Key Components 1. **GitHub Integration**: The contract uses `gl.get_webpage()` to fetch content from GitHub profiles. 2. **Deterministic Execution**: `gl.eq_principle_strict_eq()` ensures that all nodes in the network arrive at the same exact content. 3. **State Management**: The contract maintains a single string state variable that stores the profile content. ## Deploying the Contract To deploy the FetchGitHubProfile contract: 1. **Deploy the Contract**: No initial parameters are needed for deployment. 2. The contract will initialize with an empty profile string. ## Checking the Contract State After deployment, you can: - Use `show_github_profile()` to view the currently stored profile content. - Initially, this will return an empty string. ## Executing Transactions To interact with the deployed contract: 1. Call `fetch_github_profile(github_handle)` with a GitHub username. 2. The function will: - Construct the GitHub profile URL - Fetch the profile content - Store the result using the equivalence principle - Make the content available through `show_github_profile()` ## Understanding GitHub Integration This contract demonstrates several important concepts: - **Dynamic URLs**: Shows how to construct URLs based on input parameters. - **Web Fetching**: Demonstrates safe retrieval of content from GitHub. - **Deterministic Results**: Uses the equivalence principle to ensure all nodes reach consensus on profile content. - **State Updates**: Shows how external web content can be stored in blockchain state. ## Handling Different Scenarios - **Initial State**: The profile content starts empty. - **Valid GitHub Handle**: The content will contain the text from the GitHub profile page. - **Invalid Handle**: May result in a 404 page content or error. - **Network Consensus**: All nodes will agree on the same content due to the equivalence principle. ## Important Notes 1. This example fetches public GitHub profile pages only. 2. Profile content may change over time. 3. The equivalence principle ensures that all nodes store identical content. 4. The `mode="text"` parameter ensures only text content is retrieved. ## Security Considerations 1. Be aware that GitHub profiles are dynamic and can change. 2. Consider implementing rate limiting to respect GitHub's terms of service. 3. Handle potential errors for non-existent profiles. 4. Be mindful of GitHub's robots.txt and usage policies. You can monitor the contract's behavior through transaction logs, which will show the fetched profile content and state updates as they occur. # developers/intelligent-contracts/examples/github-profile-projects.mdx # GitHubProfilesRepositories Contract The GitHubProfilesRepositories contract demonstrates how to fetch GitHub profile data, analyze repository counts, and store profiles of high-contributing developers. This contract shows how to use the [comparative equivalence principle](/developers/intelligent-contracts/equivalence-principle#comparative-equivalence-principle) along with pattern matching to process web content. ```python # { "Depends": "py-genlayer:test" } from genlayer import * import typing import re @gl.contract class GitHubProfilesRepositories: github_profiles: DynArray[str] def __init__(self): pass @gl.public.write def store_high_contributors_github_profile(self, github_handle: str) -> typing.Any: github_profile_url = "https://github.com/"+github_handle def fetch_github_profile_repositories() -> int: profile_web_page = gl.get_webpage(github_profile_url, mode="text") # Regular expression to find the number between "Repositories" and "Projects" pattern = r"Repositories\s+(\d+)\s+Projects" # Search for the pattern match = re.search(pattern, profile_web_page) # Extract the number if found if match: return int(match.group(1)) # Group 1 contains the captured number else: return 0 repositories = gl.eq_principle_strict_eq(fetch_github_profile_repositories) if repositories > 25: self.github_profiles.append(github_handle) @gl.public.view def show_github_profiles(self) -> str: return [profile for profile in self.github_profiles] ``` ## Code Explanation - **Initialization**: The `GitHubProfilesRepositories` class initializes with an empty dynamic array to store the GitHub handles of the high-contributing developers. - **Write Method**: - `store_high_contributors_github_profile(github_handle)` analyzes a GitHub profile's repository count. - Uses regular expressions to extract the repository count from the profile page. - Stores profiles with more than 25 repositories. - **Read Method**: - `show_github_profiles()` returns the list of stored high-contributor profiles. ## Key Components 1. **GitHub Integration**: Uses `gl.get_webpage()` to fetch profile content. 2. **Pattern Matching**: Employs regular expressions to extract repository counts. 3. **Deterministic Execution**: Uses `gl.eq_principle_strict_eq()` to ensure network consensus. 4. **Conditional Storage**: Only stores profiles meeting specific criteria. ## Deploying the Contract To deploy the GitHubProfilesRepositories contract: 1. **Deploy the Contract**: No initial parameters are needed for deployment. 2. The contract will initialize with an empty profiles array. ## Checking the Contract State After deployment, you can: - Use `show_github_profiles()` to view the list of stored high-contributor profiles. - Initially, this will return an empty list. ## Executing Transactions To interact with the deployed contract: 1. Call `store_high_contributors_github_profile(github_handle)` with a GitHub username. 2. The function will: - Fetch the profile page content - Extract the repository count - Store the handle if repositories > 25 - Make the profile list available through `show_github_profiles()` ## Understanding Data Processing This contract demonstrates several important concepts: - **Web Scraping**: Shows how to extract specific data from web pages. - **Regular Expressions**: Demonstrates pattern matching in web content. - **Conditional Logic**: Implements criteria-based storage decisions. - **Dynamic Arrays**: Shows how to maintain a growing list of data. ## Handling Different Scenarios - **Initial State**: The profiles list starts empty. - **High Contributors**: Profiles with >25 repositories are added to the list. - **Low Contributors**: Profiles with ≤25 repositories are not stored. - **Invalid Profiles**: Returns 0 repositories and doesn't store the profile. ## Important Notes 1. This example focuses on public GitHub profiles only. 2. Repository counts may change over time. 3. The regular expression pattern assumes specific GitHub page structure. 4. The threshold of 25 repositories is arbitrary and can be adjusted. ## Security Considerations 1. Be aware that GitHub's page structure might change. 2. Consider implementing error handling for malformed profiles. 3. Respect GitHub's rate limits and terms of service. 4. Validate input GitHub handles before processing. ## Performance Optimization 1. The contract only stores handles, not full profile content. 2. Regular expression pattern is optimized for specific data extraction. 3. Conditional storage prevents unnecessary state bloat. 4. Dynamic array allows for efficient list management. You can monitor the contract's behavior through transaction logs, which will show the repository counts and profile additions as they occur. # developers/intelligent-contracts/examples/github-profile-summary.mdx # GitHubProfilesSummaries Contract The GitHubProfilesSummaries contract demonstrates how to fetch GitHub profile data and generate AI-powered summaries of user profiles. This contract shows how to combine web scraping with AI analysis using both [comparative](/developers/intelligent-contracts/equivalence-principle#comparative-equivalence-principle) and [non-comparative](/developers/intelligent-contracts/equivalence-principle#non-comparative-equivalence-principle) equivalence principles. ```python # { "Depends": "py-genlayer:test" } from genlayer import * import typing import re @gl.contract class GitHubProfilesSummaries: github_profiles: TreeMap[str, str] def __init__(self): pass @gl.public.write def store_github_profile_summary(self, github_handle: str) -> typing.Any: current_profile_summary = self.github_profiles.get(github_handle, None) if not current_profile_summary is None: raise Exception("profile summary already generated") github_profile_url = "https://github.com/"+github_handle def fetch_github_profile_summaries() -> str: return gl.get_webpage(github_profile_url, mode="text") profile_content = gl.eq_principle_strict_eq(fetch_github_profile_summaries) task = """Given the web page content of a github profile in HTML format, generate a comprehensive summary of the profile mentioning the key meta attributes and the GitHub contribution most important metrics""" criteria = """The summary provided should include different metrics and a summary of a GitHub profile""" profile_summary = ( gl.eq_principle_prompt_non_comparative( lambda: profile_content, task=task, criteria=criteria, ) ) self.github_profiles[github_handle] = profile_summary @gl.public.view def show_github_profile_summaries(self) -> str: return {profile: summary for profile, summary in self.github_profiles.items()} ``` ## Code Explanation - **Initialization**: The `GitHubProfilesSummaries` class initializes with an empty TreeMap to store GitHub handles and their corresponding summaries. - **Write Method**: - `store_github_profile_summary(github_handle)` generates an AI summary of a GitHub profile. - Checks if a summary already exists for the handle. - Uses both strict and non-comparative equivalence principles for different parts of the process. - **Read Method**: - `show_github_profile_summaries()` returns a dictionary mapping GitHub handles to their summaries. ## Key Components 1. **Data Storage**: Uses `TreeMap` for efficient key-value storage of profile summaries. 2. **Web Fetching**: Uses `gl.get_webpage()` with strict equivalence for deterministic content retrieval. 3. **AI Analysis**: Uses non-comparative equivalence for generating profile summaries. 4. **Duplicate Prevention**: Includes checks to prevent regenerating existing summaries. ## Deploying the Contract To deploy the GitHubProfilesSummaries contract: 1. **Deploy the Contract**: No initial parameters are needed for deployment. 2. The contract will initialize with an empty TreeMap. ## Checking the Contract State After deployment, you can: - Use `show_github_profile_summaries()` to view all stored profile summaries. - Initially, this will return an empty dictionary. ## Executing Transactions To interact with the deployed contract: 1. Call `store_github_profile_summary(github_handle)` with a GitHub username. 2. The function will: - Check for existing summary - Fetch the profile content - Generate an AI summary - Store the result in the TreeMap ## Understanding AI Integration This contract demonstrates several important concepts: - **Dual Equivalence Principles**: Uses both comparative and non-comparative approaches. - **Error Handling**: Implements checks for duplicate processing. - **Structured Storage**: Maintains an organized mapping of profiles to summaries. ## Handling Different Scenarios - **Initial State**: The TreeMap starts empty. - **New Profile**: Generates and stores a new summary. - **Existing Profile**: Raises an exception to prevent duplicate processing. - **Invalid Profile**: Web content fetch would fail for non-existent profiles. ## Important Notes 1. Summaries are generated once and cached. 2. The AI task is focused on extracting key metrics and attributes. 3. Profile content is fetched deterministically using strict equivalence. 4. Summary generation allows for semantic variation while maintaining quality. ## Security Considerations 1. Validate GitHub handles before processing. 2. Handle web content fetch failures gracefully. 3. Consider implementing rate limiting. 4. Be mindful of storage space for summaries. ## Performance Optimization 1. Uses TreeMap for efficient key-value lookups. 2. Prevents redundant summary generation. 4. Stores only processed summaries, not raw HTML. You can monitor the contract's behavior through transaction logs, which will show the profile fetches and summary generations as they occur. # developers/intelligent-contracts/examples/prediction.mdx # Prediction Market Contract The Prediction Market contract sets up a scenario to determine the outcome of a football game between two teams. The contract uses the Equivalence Principle to ensure accurate and consistent decision-making based on the game's resolution data. ```python filename="PredictionMarket" copy # { "Depends": "py-genlayer:test" } from genlayer import * import json import typing @gl.contract class PredictionMarket: has_resolved: bool game_date: str team1: str team2: str resolution_url: str def __init__(self, game_date: str, team1: str, team2: str): """ Initializes a new instance of the prediction market with the specified game date and teams. Args: game_date (str): The date of the game in the format 'YYYY-MM-DD'. team1 (str): The name of the first team. team2 (str): The name of the second team. Attributes: has_resolved (bool): Indicates whether the game's resolution has been processed. Default is False. game_date (str): The date of the game. resolution_url (str): The URL to the game's resolution on BBC Sport. team1 (str): The name of the first team. team2 (str): The name of the second team. """ self.has_resolved = False self.game_date = game_date self.resolution_url = ( "https://www.bbc.com/sport/football/scores-fixtures/" + game_date ) self.team1 = team1 self.team2 = team2 @gl.public.write def resolve(self) -> typing.Any: if self.has_resolved: return "Already resolved" def nondet() -> str: web_data = gl.get_webpage(self.resolution_url, mode="text") print(web_data) task = f"""In the following web page, find the winning team in a matchup between the following teams: Team 1: {self.team1} Team 2: {self.team2} Web page content: {web_data} End of web page data. If it says "Kick off [time]" between the names of the two teams, it means the game hasn't started yet. If you fail to extract the score, assume the game is not resolved yet. Respond with the following JSON format: {{ "score": str, // The score with numbers only, e.g, "1:2", or "-" if the game is not resolved yet "winner": int, // The number of the winning team, 0 for draw, or -1 if the game is not yet finished }} It is mandatory that you respond only using the JSON format above, nothing else. Don't include any other words or characters, your output must be only JSON without any formatting prefix or suffix. This result should be perfectly parsable by a JSON parser without errors. """ result = gl.exec_prompt(task).replace("```json", "").replace("```", "") print(result) return json.dumps(json.loads(result), sort_keys=True) result_json = json.loads(gl.eq_principle_strict_eq(nondet)) if result_json["winner"] > -1: self.has_resolved = True self.winner = result_json["winner"] self.score = result_json["score"] return result_json ``` You can check out this code on our [GitHub](https://github.com/yeagerai/genlayer-simulator/blob/main/examples/contracts/football_prediction_market.py) ## Deploying the Contract To deploy the Prediction Market contract, you'll need to initialize the contract state correctly. This will impact how the contract will respond to the game's resolution. 1. Provide the game date and the names of the two teams. The `game_date`, `team1`, and `team2` constructor parameters are automatically detected from the code. For example, you might set `game_date` to "2024-06-05", `team1` to "Brazil", and `team2` to "Jamaica". 2. Once the game details are set, deploy the contract to make it ready to interact and resolve the game results. import Image from 'next/image' ## Checking the Contract State Once the contract is deployed, its address is displayed as well as the **Read Methods** section. In this case, there are no Read Methods defined. ## Executing Transactions To interact with the deployed contract, go to the **Write Methods** section. Here, you can call the `resolve` method to process the game's result. This triggers the contract's logic to retrieve the game's data and determine the outcome based on the Equivalence Principle criteria defined. Execute Transactions ## Analyzing the Contract's Decisions When the `resolve` method is executed: - The LLM retrieves the game data from the specified URL. - It validates the game's outcome according to the Equivalence Principle defined in the code. - Finally, it returns a JSON response that includes the game's score and the winner. ### Handling Different Scenarios - If the game has started but not finished, the JSON response will indicate the game is not resolved yet. - If the game has finished, the JSON response will include the final score and the winning team. - If the game hasn't started, the JSON response will indicate this status. You can view the logs to see detailed information about the contract interaction. # developers/intelligent-contracts/examples/vector-store-log-indexer.mdx # LogIndexer Contract The LogIndexer contract demonstrates how to use the Vector Store database (VecDB) provided by the GenVM SDK. This contract shows how to store, retrieve, update, and remove text logs using vector embeddings for similarity-based searches. ```python # { # "Seq": [ # { "Depends": "py-lib-genlayermodelwrappers:test" }, # { "Depends": "py-genlayer:test" } # ] # } from genlayer import * import genlayermodelwrappers import numpy as np from dataclasses import dataclass import typing @dataclass class StoreValue: log_id: u256 text: str # contract class @gl.contract class LogIndexer: vector_store: VecDB[np.float32, typing.Literal[384], StoreValue] def __init__(self): pass def get_embedding_generator(self): return genlayermodelwrappers.SentenceTransformer("all-MiniLM-L6-v2") def get_embedding( self, txt: str ) -> np.ndarray[tuple[typing.Literal[384]], np.dtypes.Float32DType]: return self.get_embedding_generator()(txt) @gl.public.view def get_closest_vector(self, text: str) -> dict | None: emb = self.get_embedding(text) result = list(self.vector_store.knn(emb, 1)) if len(result) == 0: return None result = result[0] return { "vector": list(str(x) for x in result.key), "similarity": str(1 - result.distance), "id": result.value.log_id, "text": result.value.text, } @gl.public.write def add_log(self, log: str, log_id: int) -> None: emb = self.get_embedding(log) self.vector_store.insert(emb, StoreValue(text=log, log_id=u256(log_id))) @gl.public.write def update_log(self, log_id: int, log: str) -> None: emb = self.get_embedding(log) for elem in self.vector_store.knn(emb, 2): if elem.value.text == log: elem.value.log_id = u256(log_id) @gl.public.write def remove_log(self, id: int) -> None: for el in self.vector_store: if el.value.log_id == id: el.remove() ``` ## Code Explanation - **Data Structure**: Uses `StoreValue` dataclass to store log ID and text. - **Vector Store**: Initializes a VecDB with 384-dimensional float32 vectors. - **Embedding Generation**: Uses the SentenceTransformer model for text embedding. - **Methods**: - `get_closest_vector()`: Finds the most similar log entry. - `add_log()`: Adds a new log with its embedding. - `update_log()`: Updates an existing log entry. - `remove_log()`: Removes a log by its ID. ## Key Components 1. **Vector Database**: Uses VecDB for efficient similarity-based searches. 2. **Embedding Model**: Utilizes SentenceTransformer for text vectorization. 3. **CRUD Operations**: Implements Create, Read, Update, Delete functionality. 4. **Similarity Search**: Supports k-nearest neighbors (KNN) queries. ## Deploying the Contract To deploy the LogIndexer contract: 1. **Deploy the Contract**: No initial parameters are needed. 2. The contract will initialize with an empty vector store. ## Checking the Contract State After deployment, you can: - Use `get_closest_vector()` to find similar logs. - Query will return None if no logs are stored. ## Executing Transactions The contract supports several operations: 1. **Adding Logs**: - Call `add_log(log, log_id)` with text and ID. - Creates embedding and stores in VecDB. 2. **Finding Similar Logs**: - Use `get_closest_vector(text)` to find matches. - Returns vector, similarity score, ID, and text. 3. **Updating Logs**: - Call `update_log(log_id, log)` to modify entries. - Updates based on text similarity. 4. **Removing Logs**: - Use `remove_log(id)` to delete entries. - Removes based on log ID. ## Understanding Vector Storage This contract demonstrates several important concepts: - **Vector Embeddings**: Converts text to numerical vectors. - **Similarity Search**: Uses vector distance for finding related content. - **Persistent Storage**: Maintains vector database state. - **Efficient Querying**: Supports fast nearest neighbor searches. ## Handling Different Scenarios - **Empty Database**: Returns None for searches. - **Adding New Logs**: Creates new vector embeddings. - **Updating Logs**: Modifies existing entries. - **Removing Logs**: Deletes entries by ID. ## Important Notes 1. This is a demonstration of VecDB features. 2. Uses a specific embedding dimension (384). 3. Similarity is based on vector distance. 4. Supports basic CRUD operations. ## Performance Considerations 1. Embedding generation may be computationally intensive. 2. KNN searches scale with database size. 3. Vector dimension affects storage requirements. 4. Consider batch operations for efficiency. ## Technical Details 1. Uses 384-dimensional float32 vectors. 2. Implements the all-MiniLM-L6-v2 model. 3. Stores both vector embeddings and metadata. 4. Supports exact and approximate nearest neighbor search. You can monitor the contract's behavior through transaction logs, which will show vector operations and search results as they occur. # developers/intelligent-contracts/tools/genlayer-cli.mdx # GenLayer CLI The GenLayer CLI is a command-line interface designed to streamline the setup and local execution of the GenLayer Studio. It automates the process of downloading and launching the Studio, allowing developers to start simulating and testing locally with minimal effort. ## Features - **Easy Initialization**: Quickly set up the GenLayer Studio with a single command. - **Automated Downloads**: Automatically downloads all necessary components required to run the Studio. - **Developer-Friendly**: Simplifies local development and testing workflows. - **Extensible**: Plans for additional commands to enhance interaction with the Studio. ## How it's Built The GenLayer CLI is a Command Line Interface tool built using **Node.js** and **TypeScript**. It's designed to automate the setup and management of the GenLayer Studio, simplifying the process for developers. ### Technologies Used - **Node.js**: A JavaScript runtime environment that allows the execution of JavaScript code on the server side. - **TypeScript**: A statically typed superset of JavaScript that compiles to plain JavaScript, enhancing code reliability and maintainability. - **ESBuild**: A fast JavaScript bundler and minifier used for building the CLI efficiently. - **Jest**: A JavaScript testing framework utilized for writing and running tests. ### Project Structure The source code for the GenLayer CLI is organized as follows: - `src/`: Contains the main TypeScript source files. - `tests/`: Includes all the test files written using Jest. - `dist/`: The compiled JavaScript files ready for execution. ## Requirements Before using the GenLayer CLI, ensure your system meets the following requirements: - **Node.js**: Version 14.x or higher is required. - **npm**: Comes bundled with Node.js, used for managing packages. - **Git**: Required if cloning the repository directly from GitHub. - **Operating System**: Compatible with macOS, Linux, and Windows. ## Installation To install the GenLayer CLI globally using npm, ensure you have Node.js installed, then run: ```bash npm install -g genlayer ``` ## Usage After installation, you can use the following command to start the Studio: ```bash genlayer init ``` This command will download the necessary components and start the Studio. Once initialized, you can execute further commands (to be implemented) to interact with the Studio. ## General Format of Commands The GenLayer CLI commands follow a consistent syntax pattern: ```bash genlayer [options] ``` - ``: The primary action you want the CLI to perform (e.g., `init`, `up`). - `[options]`: Optional flags that alter the behavior of the command. ### Example To initialize the GenLayer Studio with specific parameters: ```bash genlayer init --numValidators 10 --branch develop ``` ## Contributing Contributions to the GenLayer CLI are welcome! Feel free to fork the repository, make your changes, and submit a pull request. Your efforts to improve the software are greatly appreciated. To run the CLI from the repository: 1. Clone the repository: ```bash git clone https://github.com/yeagerai/genlayer-cli.git ``` 2. Navigate to the project directory and install dependencies: ```bash cd genlayer-cli npm install ``` 3. Start the build process: ```bash npm run dev ``` This will continuously rebuild the CLI from the source. In another terminal window, execute CLI commands like: ```bash node dist/index.js init ``` ## Testing The GenLayer CLI uses Jest with ts-jest for testing TypeScript files. To run tests: ```bash npm run test ``` ## Further Development Additional commands are planned to enhance interaction with the GenLayer Studio. Stay tuned for updates. ## Repository You can find the GenLayer CLI repository on GitHub: [GenLayer CLI Repository](https://github.com/yeagerai/genlayer-cli) ## Full Reference The full reference for the GenLayer CLI is available in the [GenLayer CLI Reference](/references/genlayer-cli). ## GenLayer FAQ The GenLayer FAQ is a collection of useful questions and answers about the project. If you have a question that isn't answered here, please let us know on our [Discord](https://discord.gg/8Jm4v89VAu) .
How do I set up the GenLayer Development Environment? To quickly set up the GenLayer Development Environment, run the commands below: ``` $ npm install -g genlayer $ genlayer init ``` For more detailed setup instructions, please refer to the [Getting Started page](/getting-started)
Where can I find the GenLayer Studio? The GenLayer Studio is available at [studio.genlayer.com](https://studio.genlayer.com).
How do I deploy an Intelligent Contract? - Go to [studio.genlayer.com](https://studio.genlayer.com) or use the [GenLayer CLI](/getting-started#installation-of-the-genlayer-cli) to start the GenLayer Studio locally. - Write your contract in Python using the [Intelligent Contract SDK](/core-concepts/intelligent-contracts). - Follow the guide [here](/genlayer-stack/genlayer-studio/execute-transaction) to interact with the Studio and deploy your Intelligent Contract.
What is the GenLayer CLI used for? The GenLayer CLI is used for setting up the GenLayer Studio and, in the future, will support mainnet and testnet environments.
# developers/intelligent-contracts/tools/genlayer-studio.mdx import { Card, Cards, Callout, Bleed } from 'nextra-theme-docs' # GenLayer Studio This Studio is an interactive sandbox designed for developers to explore the potential of GenLayer's Intelligent Contracts. It replicates the GenLayer network's execution environment and consensus algorithm, but offers a controlled and local environment to test different ideas and behaviors. ### What you can do with the GenLayer Studio: - **Experiment with AI smart contracts:** Intelligent Contracts leverage LLMs, such as GPT-4 or Llama3, to understand natural language and be capable of complex decision making. - **Access the Web Natively:** GenLayer is the first platform where smart contracts don’t need oracles to access the Internet. - **Code in Python:** Develop in a familiar, developer-friendly language, where memory and string management are not a big headache. ### Explore the Studio Here is a video introduction to help you get started with the GenLayer Studio:
### Intelligent Contract SDK Learn how to write your own Intelligent Contracts at [Intelligent Contracts](/build-with-genlayer/intelligent-contracts) # developers/intelligent-contracts/tools/genlayer-studio/loading-contract.mdx # Load Your Contract To start using the GenLayer Studio, you need to load your Intelligent Contract into the Studio. This involves navigating the Studio interface, selecting your contract file, and preparing it for deployment and execution. ## Access your Intelligent Contracts 1. On the left sidebar, click on the **Contracts** icon. This is where you can see the list of your Intelligent Contracts. There are pre-loaded example contracts for you to try out. import Image from 'next/image' Navigate Contract 2. To add a new contract, click on the **+** button labeled **New Contract** to create a new contract file in the Studio. Add a New Contract 3. Click on the **Add From File** button to select and upload your Intelligent Contract file from your local machine. Add From File 4. Once your contract is uploaded, you will see it listed under **Your Contracts**. ## Run Your Intelligent Contract 1. Click on the contract file to open it in the editor pane. This allows you to review and edit the code if necessary before running it. Open the Contract 2. Once you have your contract file open, you have two options to run and debug your contract: - Click the **Run and Debug** button on the left sidebar. - Click the **play icon** at the top right of the editor pane. Run and Debug Now that you have loaded your Intelligent Contract into the GenLayer Studio, you can proceed to set constructor parameters and deploy it. # developers/intelligent-contracts/tools/genlayer-studio/deploying-contract.mdx # Deploy Contracts Once you have loaded your Intelligent Contract into the GenLayer Studio, the next step is to set the constructor parameters and deploy it. The constructor parameters are essential inputs that initialize the state of your contract. ## Setting Constructor Parameters 1. After loading your Intelligent Contract, you will see the **Constructor Inputs** section on the left-hand pane. The constructor parameters are [automatically detected from your code if defined properly](#detecting-constructor-parameters). 2. If you need to manually adjust your constructor parameters, you can write them in JSON format by clicking on the **JSON** button. import Image from 'next/image' ## Detecting Constructor Parameters The GenLayer Studio automatically detects the constructor parameters from your code. It analyzes your `__init__` method to identify the parameters and their types. This automatic detection ensures that you have the correct inputs for initializing your contract. It’s important to have clear type annotations for each parameter (e.g., `str`, `bool`, `int`, `list`) to enable accurate detection. ## Deploying the Contract After setting the constructor parameters, click on **Deploy** to deploy your contract. Once completed, you can proceed to execute your transactions and interact with the deployed contract. # developers/intelligent-contracts/tools/genlayer-studio/contract-state.mdx # Current Intelligent Contract State Once your Intelligent Contract is deployed, you can check its current state to verify that it has been initialized correctly. This step ensures that the contract's data and variables are set as expected. ## Viewing the Current Intelligent Contract State After deploying your contract, you will now see: - **Contract Address:** This is used for interacting with your contract. - **Read Methods:** These return information on the current state of the contract. import Image from 'next/image' import { Callout } from 'nextra-theme-docs' For example, in the **Storage** contract: - If the constructor parameter `initial_storage` was set to `hello`, the state method `get_storage` will return `hello`. The result will show the current state based on the getter function called. This allows you to verify that the variables in your contract have been initialized correctly and that they change when transactions are executed. When the contract state changes, you can always come back and refresh the state by calling these getter functions to see the most current state of your Intelligent Contract. With the state verified, you can now execute transactions and interact with your deployed contract. # developers/intelligent-contracts/tools/genlayer-studio/execute-transaction.mdx # Execute Transactions After deploying your Intelligent Contract and verifying its state, the next step is to execute transactions. This allows you to interact with your contract's methods and functions to perform specific actions or queries. ## Write Methods 1. In the **Write Methods** section, you will see all the write methods available in your Intelligent Contract. 2. Expand the method you want to execute. For example, in the **Storage** contract, select the `update_storage` method. 3. If the method requires input parameters, a field will appear for you to enter the necessary values. For example, the `update_storage` method requires a string called `new_storage`. import Image from 'next/image' Deploy Contract 4. After entering any required parameters, click the button to execute the method. The Studio will process the transaction and return the result. ## Viewing Transaction Results Once you execute a transaction, the result will be displayed, showing the output of the method called. This allows you to verify that the method has executed correctly and to see the effect of the transaction on your contract's state. ## Viewing Current Account Address You can also view your current account address in the header. This address is used to interact with your contract. Select Active Account You can continue interacting with your Intelligent Contract by executing additional transactions or checking the state again to see how it has changed. # developers/intelligent-contracts/tools/genlayer-studio/monitoring-node-logs.mdx # Monitoring Node Logs Node Logs in the GenLayer Studio provide real-time feedback and are a critical component for debugging and tracking the behavior of Intelligent Contracts as they interact within the studio. ## Key Features of Node Logs Node Logs capture and display a variety of events, including: - **Transaction Submission, Status Changes and Finalization:** Track the status and outcomes of submitted transactions. - **Contract Deployment Statuses:** Monitor the progress and success of contract deployments. - **Execution Results and Errors:** Review the outputs and any errors encountered during contract execution. - **Validator Operations and Consensus-Related Messages:** Observe the activities of validators and consensus processes. ## Accessing Node Logs You can view the node logs at the bottom of the GenLayer Studio. This section automatically updates with new log entries as actions are performed within the studio. You can also filter the logs by content as well as by scope and level. ![Node Log](/node-logs.png) ## Understanding Node Logs The logs are structured to provide clear and detailed information: - **Scope:** Each log is tagged with a label such as RPC, GenVM or Consensus to give you a better understading of the context of the log. - **Level:** Log entries are associated with a level and color to facilitate rapid scanning for issues or confirmations. - **Details:** Expandable log entries offer detailed explanations and data for each event, such as transaction hashes or error messages. By actively viewing these logs, you can ensure that your Intelligent Contracts are performing as expected and that any issues are promptly addressed. This leads to a smoother development process within the GenLayer Studio. # developers/intelligent-contracts/tools/genlayer-studio/validators.mdx import Image from 'next/image' # Accessing and Configuring Validators In the GenLayer Studio, validators are essential for achieving consensus and validating transactions through a process known as [Optimistic Democracy](/core-concepts/optimistic-democracy). When you initialize the Studio based on your selected LLM provider(s), you are provided with 5 default validators. 1. **Leaders:** Within this consensus model, one validator is selected as the leader for each transaction. The leader's role is to propose how a transaction should be executed based on the transaction data and the Intelligent Contract's logic. 2. **Validators:** After the leader proposes a transaction execution, other validators are responsible for reviewing and validating the proposal. They use the [Equivalence Principle](/core-concepts/optimistic-democracy/equivalence-principle) to determine if the leader’s proposal meets the required standards. These validators can be modified to suit your Intelligent Contract's requirements. ## Accessing Validators To access and manage validators, follow these steps: 1. On the left sidebar, click on the **Validators** icon. This will open the validators page. 2. In the validators page, you will see a list with all the validators currently configured in the Studio along with their models and providers. ## Configuring Validators To configure validators, you can add new validators or modify existing ones. 1. Click the **New Validator** button to open the validator creation dialog. 2. **Create New Validator:** In the validator creation dialog, fill in the required fields: - **Provider:** Select the provider for the validator. - **Model:** Choose the model that the validator will use. - **Stake:** Specify the stake for the validator. - **Config:** Enter any additional configuration parameters in JSON format. 3. Click **Create** to add the new validator to your configuration. ## Modify Validator Details To modify your validator settings, click on any existing validator and modify the fields based on your needs. ## Delete Validator To delete a validator, click on the delete button beside the validator in the list. By properly managing and configuring validators, you ensure that your Intelligent Contracts operate smoothly and securely within the GenLayer Studio. # developers/intelligent-contracts/tools/genlayer-studio/providers.mdx import Image from 'next/image' # Inference Providers Validators can use various inference providers to validate transactions. You can configure those providers and add custom ones to suit your needs. When you then create a new validator in the validators page, you will be able to select those providers and the relevant models from the list. ## Accessing Providers You can manage your providers in the **Settings** page: ## Configuring Providers Providers have the following properties: - **Provider:** The name of the provider. For example, `OpenAI` or `ollama`. - **Model:** The model attached to this provider. For example, `gpt-4o` or `llama3`. - **Plugin: (only for custom providers)** When adding a custom provider, you need to specify a plugin that implements the provider. The plugin defines what configuration is necessary for the provider. - **Provider Config:** Related environment variables, for example API keys or endpoint URLs. - **Default Validator Config:** This config is used as default when creating a new validator, and will then be applied when making calls to inference providers using said validator. ## Adding a new Provider You can add a new provider by clicking the **New Config** button at the top of the providers list. ## Updating an Existing Provider To modify your validator settings, click on any existing validator and modify the fields based on your needs. ## Deleting a Provider To delete a provider, click on the delete button beside the provider in the list. # developers/intelligent-contracts/tools/genlayer-studio/limitations.mdx # Limitations of the GenLayer Studio The GenLayer Studio is in an early stage of development, with many features still being tested and refined. Here are some limitations of the studio: ## Native Token Transfers Native Token transfers to and from contracts are not supported in the Studio. ## Gas Usage Transactions within the Studio do not consume gas. While this is beneficial for rapid prototyping, the absence of gas simulation may result in behavior differing from live blockchain networks. ## Consensus Algorithm The GenLayer Studio does not implement the full Optimistic Democracy consensus mechanism. There is no appeals process. The studio focuses on providing a basic execution environment without the complexities of the full consensus mechanism. ## Programming Language The programming language used in the Studio is an early version and is not final. It is expected to undergo many changes as development progresses. ## Web Access While the Studio supports web browsing capabilities, it is primarily for testing purposes. The actual web access and data retrieval might differ when deployed on the live network. # developers/intelligent-contracts/tools/genlayer-studio/reset-the-studio.mdx import Image from 'next/image' # Resetting the GenLayer Studio The GenLayer Studio provides a straightforward way to reset its storage, current status, memory, and contract examples. This feature is particularly useful if you want to start fresh with a clean state, whether you’re testing new contracts or simply clearing out previous configurations. ## How to Reset the Studio To reset the GenLayer Studio, follow these simple steps: 1. **Access the Settings Page**: begin by navigating to the Settings page within the GenLayer Studio. 2. **Click "Reset Storage"**: this option allows you to clear all the current data stored in the studio, including the state of deployed contracts, transaction history, and any cached information. 3. **Confirm the Reset in the Dialog**: this is an important step, as resetting the storage will remove all existing data and cannot be undone. Once confirmed, the studio will reset its storage, returning to its initial state as if it were newly initialized. ## What Does Resetting Do? Resetting the GenLayer Studio through the Reset Storage option will: - Clear All Deployed Contracts: Any contracts that you have deployed in the studio will be removed from the frontend memory. - Reset Transaction History: All previous transactions, including those in various states, will be erased. - Restore Contract Examples: Any example contracts included in the studio will be restored to their original, unaltered state. ## When Should You Reset? Consider resetting the studio when: - You want to start with a clean slate for a new development or testing session. - You encounter issues that might be caused by lingering data or state inconsistencies. - You have completed a testing phase and need to ensure that previous data does not interfere with new experiments. # developers/intelligent-contracts/tools/genlayer-studio/troubleshooting.mdx # Troubleshooting If you encounter any issues with the Studio, here are some detailed steps to help you resolve common problems: ## Frontend Not Loading Correctly The frontend may not load correctly due to caching issues or an outdated version of the contract stored in your browser. ### Solution - **Refresh Frontend:** Simply reload the page in your browser. - **Clear Cache:** Clear your browser's cache by clicking on the left of your address bar -> Cookies and site data -> Manage on device site data -> Delete localhost. import Image from 'next/image' Node Log ## Port Conflicts The Studio may fail to start if some ports required for its operation are already in use by other applications. **Ports used by the Studio:** - **Frontend:** 8080 - **Ollama:** 11434 - **JSON-RPC Server:** 4000 - **GenVM:** 6678 - **Postgres:** 5432 - **Hardhat:** 8545 - **Webrequest:** 5000, 5001 ### Solution 1. Identify processes using the required ports. Replace `` with the specific port number. - **Linux / MacOS:** ```bash copy lsof -i : ``` - **Windows:** ```cmd copy netstat -aon | find ``` 2. Use the following command to kill the process using the port. Replace `` with the Process ID obtained from the previous step. - **Linux / MacOS:** ```bash copy kill -9 ``` - **Windows:** ```cmd copy taskkill /PID /F ``` ## Docker not Running The GenLayer Studio relies on Docker for managing containers and images. If Docker is not running, the Studio cannot function properly. ### Solution - Ensure that Docker (or Docker Desktop) is installed on your system. You can check this by running: ```bash copy docker info ``` - Restart Docker Desktop or the Docker daemon on your system. ## Display Issues The code section or other UI elements may not display correctly due to screen size limitations. ### Solution - Resize your screen to accommodate the UI elements properly. This will help improve the visibility and layout of the Studio. ## Studio Not Responding or Throwing Errors The Studio may become unresponsive or throw errors due to various reasons, such as conflicting processes or corrupted containers. ### Solution You can perform a fresh start by stopping and removing all containers, as well as removing all images. **Via Command Line:** ```bash docker stop $(docker ps -aq) docker rm $(docker ps -aq) docker rmi $(docker images -q) ``` **Via Docker Desktop:** 1. Open Docker Desktop and go to the **Containers** section. 3. Select all containers and click **Delete**. 4. Go to the **Images** section. 5. Select all images and click **Delete**. # developers/intelligent-contracts/tools/genlayer-studio/development-tips.mdx import Image from 'next/image' # Development Tips Here are some valuable tips on how to develop your intelligent contract, debug it, and test it using the GenLayer Studio. ## 1. Validators setup You need to be sure that you have at least one validator. If you don't have any, you can create one in the validators screen by providing: - Provider - Model - Stake (at least 1) - Config (optional) ## 2. Add types to your contract method inputs Adding types to your contract method inputs helps the UI render the correct input fields. For example, if you have a method that takes a string as input, you can define it as follows: ```python def update_storage(self, new_storage:str) -> None: self.storage = new_storage ``` This will allow the UI to render the form needed to call the contract with the correct input type as follows
Node Log ## 3. The constructor The constructor is a special method called when the contract is deployed. It is used to initialize the contract's storage. You can define it as follows: ```python def __init__(self, initial_storage: str): self.storage = initial_storage ``` Right now, your contract must include a constructor. Without one, the Studio won't be able to deploy your contract. ## 4. Deploying a contract and sending transactions After you have written your contract, you can deploy it by clicking the "Deploy" button. This will deploy the contract and show you the contract's address.
You can then call the contract's methods, shown below in the deployment section on the left panel of the Studio's UI.
Node Log ## 5. Debugging your contract You can debug your contract by adding print statements to your contract methods. The Studio's Logs section will display these print statements. Here is an example of printing in a contract method: ```python def update_storage(self, new_storage:str) -> None: print("new storage value: ", new_storage) self.storage = new_storage ``` When a transaction is sent to this method, the print statement will be shown in the Logs section as follows:
Node Log ## 6. What happened when the transaction was executed After a transaction is executed, you can see the details by clicking on the transaction in the Transactions section (left-bottom corner). This will show you: - Number: The transaction's number in the database - Timestamp: The time the transaction was executed - Type: The transaction's type (deployment or method call) - Status: The transaction's status (PENDING, PROPOSING, COMMITTING, REVEALING, ACCEPTED, FINALIZED) - Input: the parameters passed to the method - Execution: The status of the execution (SUCCESS or ERROR), the leader's configuration, and the validator's consensus votes - Equivalence principle output: The output of the equivalence principle from the leader
Node Log ## 7. Knowing what happens when the LLMs are called If a contract method calls an LLM, you can see the Equivalence Principle Output from the leader (what's being input in the eq.set call) in the transaction details modal.
Node Log ## 8. Access to the contract state If your contract methods change the contract's state, you can query that information by adding a read method to your contract. Read methods on a contract need to be decorated with the `@gl.public.view` decorator. This method should return the state you want to query.
For example: ```python @gl.public.view def get_balances(self) -> dict[str, int]: return self.balances @gl.public.view def get_balance_of(self, address: str) -> int: return self.balances.get(address, 0) ``` These two methods allow you to query the contract's balance state. You can call them by expanding them from the left panel of the Studio's UI and clicking on the "Call Contract" button. # developers/intelligent-contracts/tools/genlayer-studio/advanced-features/custom-plugins.mdx import { Callout } from "nextra-theme-docs"; # Adding LLM Provider Plugins This section is intended for advanced users who wish to integrate new LLM provider plugins. This process requires code modifications, and we encourage you to create a Pull Request if you'd like your plugin to be included in the official GenLayer Studio. The GenLayer Studio seamlessly interacts with multiple LLM providers. Currently, we support the following providers out of the box: - [OpenAI](https://platform.openai.com/) - [Anthropic](https://www.anthropic.com/) - [Ollama](https://ollama.com/) - [Heuristai](https://heurist.ai/) In addition to these built-in providers, you have the flexibility to integrate your own custom providers. ## Adding a New LLM Provider Plugin ### Creating the Plugin To integrate a new LLM provider plugin, you need to implement the `Plugin` protocol defined in the [llms.py](https://github.com/yeagerai/genlayer-simulator/blob/main/backend/node/genvm/llms.py) file. The protocol is structured as follows: ```python class Plugin(Protocol): def __init__(self, plugin_config: dict): ... async def call( self, node_config: dict, prompt: str, regex: Optional[str], return_streaming_channel: Optional[asyncio.Queue], ) -> str: ... def is_available(self) -> bool: ... def is_model_available(self, model: str) -> bool: ... ``` Here's an example of how you might implement a custom `Plugin`. Note that this are just some common guidelines, you are free to implement your integration as you please ```python class MyCustomPlugin: def __init__(self, plugin_config: dict): self.api_key = plugin_config.get('api_key') self.base_url = plugin_config.get('base_url', 'https://api.customllm.com') # Add any other necessary configuration parameters async def call( self, node_config: dict, prompt: str, regex: Optional[str], return_streaming_channel: Optional[asyncio.Queue], ) -> str: # Implement the API call to your custom LLM provider # This is a placeholder implementation async with aiohttp.ClientSession() as session: async with session.post( f"{self.base_url}/generate", json={"prompt": prompt, "config": node_config}, headers={"Authorization": f"Bearer {self.api_key}"} ) as response: if response.status == 200: result = await response.json() return result['generated_text'] else: raise Exception(f"API call failed with status {response.status}") def is_available(self) -> bool: # Check if the plugin is properly configured and available return bool(self.api_key) and bool(self.base_url) def is_model_available(self, model: str) -> bool: # Check if the specified model is available for this provider # This is a placeholder implementation available_models = ['custom-gpt-3', 'custom-gpt-4'] return model in available_models ``` ### Registering the Plugin After implementing the `Plugin` protocol, you need to register your new provider in the `llms.py` file under the `get_llm_provider` function. This step ensures that the GenLayer Studio recognizes and can utilize your custom plugin. ```python def get_llm_plugin(plugin: str, plugin_config: dict) -> Plugin: """ Function to register new providers """ plugin_map = { "ollama": OllamaPlugin, "openai": OpenAIPlugin, "anthropic": AnthropicPlugin, "custom-plugin-key": MyCustomPlugin, # Modify here accordingly } if plugin not in plugin_map: raise ValueError(f"Plugin {plugin} not registered.") return plugin_map[plugin](plugin_config) ``` ## Updating the JSON Schema To maintain consistency and enable proper configuration validation, you must update the [JSON schema](https://json-schema.org/) in the [`providers_schema.json`](https://github.com/yeagerai/genlayer-simulator/blob/main/backend/node/create_nodes/providers_schema.json) file. This update should include your new provider and its specific configuration options. The JSON schema plays a crucial role in validating the configuration options for each provider, ensuring that users input correct and compatible settings. ## Registering a Provider for the new plugin New LLM Providers can be registered through the Studio's UI in the **Settings page** or manually through the backend API. Here is an example on how addition of an LLM Provider using your new Plugin could look like ```sh curl --request POST \ --url http://localhost:4000/api \ --header 'Content-Type: application/json' \ --data '{ "jsonrpc": "2.0", "method": "sim_addProvider", "params": [ { "provider": "my-custom-provider", "model": "my-custom-model", "config": {}, "plugin": "custom-plugin-key", "plugin_config": { "api_key": "MY-SECRET-KEY", "base_url": "my.custom.url" } } ], "id": 1 }' ``` # developers/intelligent-contracts/ideas.mdx # 💡 Build With GenLayer Here are some ideas to get you started with building Intelligent Contracts that can interact with web sources, APIs, and understand natural language using LLM calls. | Idea | Implementation Details | |-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Prediction Markets | Use GenLayer to directly search the web for relevant information allowing users to place bets on future events and get outcomes automatically determined. | | Parametric Insurance | Create insurance that pays out based on real-world events, such as drought conditions or natural disasters, using data fetched from reliable sources. | | Bounty Review and Payout | Automatically reward community members for completing tasks like writing articles or developing features by evaluating their work using Intelligent Contracts. | | Performance-based Contracting | Set up contracts that pay out based on the completion of pre-agreed jobs, such as developing a website or creating a piece of content, with performance verified through automated checks. | | Slashing Monitoring and Insurance | Monitor protocols for any violations and trigger slashing events or provide insurance payouts based on human-in-the-loop evaluations or LLM-based assessments. | | Hack Detection and Emergency Pause | Set up contracts that continuously monitor for potential protocol attacks through explorers and news sites, and trigger automated emergency shutdowns if threats are detected. | | On-chain Identity Verification | Verify users' identities by checking their social media profiles for specific messages and linking these to their on-chain accounts, enhancing trust in the ecosystem. | | Under-collateralized Lending | Enable lending with less collateral by linking real-world identity to on-chain reputation, allowing borrowers to leverage their good standing for better loan terms. | | P2P Gambling | Allow two users to place bets on real-world outcomes, with the contract determining the winner based on data from trusted sources. | | Decentralized Game Master | Facilitate text-based role-playing games where users submit their actions, and the intelligent contract determines the outcomes, creating a dynamic and interactive gaming experience. | | Interoperable Games with NFTs | Develop games that issue and recognize automatically generated NFT items, allowing players to transfer assets seamlessly between different games within the ecosystem. | | Unstoppable Organizations | Create autonomous entities like DAOs that can adapt and continue their missions indefinitely as long as they remain funded, including AI DAOs and autonomous trusts. | | Retroactive Public Goods Funding | Set up contracts that reward contributions to the protocol retroactively, incentivizing community members to make valuable improvements and innovations. | | Crowd-sourced Knowledge Database | Implement a system where users are rewarded for finding and summarizing new information on various topics, building a comprehensive knowledge base. | | AI Notary | Create an automated notary service that can confirm the occurrence of online events, providing verifiable records for various purposes. | | AI Arbitration | Develop a dispute resolution system where parties submit their cases to an AI-based arbitrator, which makes decisions based on pre-defined legal frameworks and submitted evidence. | | Private P2P Contracts | Enable two-party contracts that remain private unless a dispute arises, using a commit/reveal scheme to keep terms confidential until necessary. | | Multi-modal Use Cases | Integrate real-world images for performance-based contracting, such as verifying the completion of physical tasks, with cryptographically signed proofs. | | Generative Memes | Create fun and engaging Intelligent Contracts, like ones that track and manipulate token balances in creative ways, leveraging the capabilities of LLMs for humor and experimentation. | | Text-based Intelligent Contracts | Open the possibility for non-developers to create Intelligent Contracts by capturing the entire logic in plain text, making smart contract development more accessible. | | Honeypot Contracts for Security | Set up Intelligent Contracts designed to attract and test adversarial attacks, helping to identify and fix vulnerabilities through real-world testing. | | Fair and Transparent Moderation | Use GenLayer-based arbitration to make fair and transparent moderation decisions in various communities and games, ensuring unbiased and consistent enforcement of rules. | # developers/decentralized-applications/architecture-overview.mdx # Architecture Overview of Decentralized Applications Using GenLayer A decentralized application (DApp) on GenLayer leverages its unique blockchain architecture to integrate AI-powered smart contracts, called "Intelligent Contracts." These DApps consist of various components that work together to ensure seamless interaction with the GenLayer protocol. ## Key Components ### Frontend Application The user interface of the DApp is typically built with web technologies like HTML, CSS, and JavaScript. It communicates with the backend using the GenLayerJS SDK, enabling interaction with the GenLayer protocol and handling user inputs to trigger blockchain transactions. ### GenLayerJS SDK A TypeScript/JavaScript library that abstracts the complexities of blockchain interactions. The SDK provides APIs to read from and write to Intelligent Contracts, manages accounts and queries transactions, and acts as the bridge between the frontend and GenLayer's protocol. ### Consensus Layer The consensus layer implements GenLayer's Optimistic Democracy mechanism to ensure reliable and secure execution of transactions using a validator-driven commit-reveal scheme. It also handles appeals and transaction finality to maintain integrity and fairness. It is built on ZK-stack rollups to provide scalability and cost-efficiency, secure state updates, and anchoring to Ethereum's security model. ### Execution Environment The execution environment (the GenVM) is the engine that executes Intelligent Contracts. It supports both deterministic and non-deterministic operations, enabling AI integration and web data access. ### Ghost Contracts Ghost contracts are proxy smart contracts on the consensus layer that facilitate interactions between accounts and Intelligent Contracts. They also manage external messages and asset bridging. ## Architecture Diagram ```mermaid flowchart TD subgraph s1["Frontend Application"] n1["GenLayerJS"] end subgraph s2["Consensus Layer."] n2["Consensus Smart Contracts"] n3["Ghost Contracts"] end subgraph s3["GenLayer Node"] n4["Execution Environment - GenVM"] end s1 <--> s3 s3 <--> s2 ``` # developers/decentralized-applications/dapp-development-workflow.mdx # DApp Development Workflow with GenLayer The GenLayer platform allows developers to create decentralized applications (DApps) throughout the lifecycle of creating, testing, and deploying. This guide details how developers can transition from using the **GenLayer Studio** for their first Intelligent Contract to an advanced local development workflow, finishing with building a frontend application with **GenLayerJS**. --- ## 1. Starting with GenLayer Studio **GenLayer Studio** is an integrated environment designed to streamline the initial stages of Intelligent Contract development, making it accessible for developers of all experience levels. It provides an interactive environment that serves as a comprehensive sandbox for developing, deploying, and testing Intelligent Contracts in real time. This environment enables developers to experiment with their contracts and see immediate results without the complexities of a production setup. The platform runs a simulated network with customizable validators that accurately mirror the GenLayer consensus mechanism. This feature allows developers to test their contracts under conditions that closely resemble the actual blockchain environment, ensuring reliable deployment outcomes. ### Getting Started: 1. **Set Up the Studio**: Developers initialize the Studio using `genlayer cli` command `genlayer init` which configures the environment and spawns a local validator network. GenLayer Studio is also available as a hosted instace at [studio.genlayer.com](https://studio.genlayer.com/). 2. **Write Your First Contract**: Intelligent Contracts in GenLayer are written in Python, utilizing its extensive libraries and GenVM capabilities like LLM calls and web integration. Refer to [Your First Contract](/developers/intelligent-contracts/your-first-contract) guide for more information. 3. **Deploy and Test**: Deploy your Intelligent Contracts through the Studio interface and test them in the simulated network. --- ## 2. Moving to Advanced Workflow As projects transforms to real-world applications, developers should migrate to a local development setup. This approach mirrors frameworks like Hardhat or Foundry and is well-suited for iterative development and comprehensive testing. ### Benefits of Local Development: - **Complete Control**: Developers can configure the environment, validators, and network parameters as needed. - **Enhanced Debugging**: The local setup allows for advanced debugging of both contracts and transactions. - **Flexible Testing**: Tests can simulate real-world scenarios, including edge cases and complex interactions. ### Workflow Steps: 1. **Set Up Your Local Environment**: Developers can start with the GenLayer boilerplate project, which includes pre-configured templates for local testing. 2. **Write Tests**: Tests are written in Python, focusing on validating contract functionality and ensuring consensus integrity. The boilerplate includes sample tests to accelerate development. 3. **Simulate Transactions**: Run detailed simulations to observe how contracts behave under various network conditions, ensuring robust performance. --- ## 3. Building the Frontend with GenLayerJS The frontend is the user-facing component of a DApp. With **GenLayerJS**, developers can integrate their applications with the GenLayer network, focusing on providing a seamless user experience. ### Why Use GenLayerJS? - **Simplified Interactions**: Abstracts the complexity of blockchain interactions with high-level APIs. - **Comprehensive Features**: Supports transaction handling, contract interaction, event subscriptions, and account management. - **TypeScript Integration**: Provides type safety and code reliability for frontend development. ### Frontend Development Workflow: 1. **Integrate GenLayerJS**: Install the SDK and set up a client to connect to the GenLayer network. Configuration options allow connection to various environments, such as testnets or the GenLayer Studio. Refer to [GenLayerJS](/developers/decentralized-applications/genlayer-js) guide for more information. 2. **Read and Write to Contracts**: Use the SDK's high-level APIs to interact with deployed contracts. For instance, retrieve user balances or update contract state seamlessly. Refer to [Reading Data](/developers/decentralized-applications/reading-data) and [Writing Data](/developers/decentralized-applications/writing-data) guides for more information. 3. **Monitor Transactions**: Developers can subscribe to events or query transaction statuses, ensuring users are kept informed of transaction progress and outcomes. 4. **Build the User Interface**: Combine GenLayerJS with popular frontend frameworks (like React or Angular) to create intuitive interfaces. --- ## Advanced Tips for Developers 1. **Leverage GenVM Features**: The GenVM allows Intelligent Contracts to interact with LLM models and access real-time web data. Developers should design contracts to maximize these capabilities for dynamic and intelligent DApps. 2. **Optimize Testing**: Incorporate edge case scenarios in tests to ensure that contracts behave reliably under all conditions. 3. **Focus on Security**: Implement robust security measures, including input validation and error handling, to protect contracts from malicious inputs and ensure consensus consistency. # developers/decentralized-applications/genlayer-js.mdx # GenLayerJS SDK GenLayerJS SDK is a TypeScript library designed for developers building decentralized applications (DApps) on the GenLayer protocol. This SDK provides a comprehensive set of tools to interact with the GenLayer network, including client creation, transaction handling, event subscriptions, and more, all while leveraging the power of Viem as the underlying blockchain client. ## Features - **Client Creation**: Easily create and configure a client to connect to GenLayer’s network. - **Transaction Handling**: Send and manage transactions on the GenLayer network. - **Contract Interaction**: Read from and write to smart contracts deployed on GenLayer. - **Event Subscriptions**: Subscribe to events and listen for blockchain updates. - **TypeScript Support**: Benefit from static typing and improved code reliability. ## How it's Built The GenLayerJS SDK is built using **TypeScript** and leverages the **Viem** library as the underlying blockchain client. It is designed to provide a high-level, easy-to-use API for interacting with the GenLayer network, abstracting away the complexities of direct blockchain interactions. ### Technologies Used - **TypeScript**: A statically typed superset of JavaScript that compiles to plain JavaScript, enhancing code reliability and maintainability. - **Viem**: A modular and extensible blockchain client for JavaScript and TypeScript. - **ESBuild**: A fast JavaScript bundler and minifier used for building the SDK efficiently. - **Vitest**: A Vite-native unit test framework used for testing. ### Project Structure The source code for the GenLayerJS SDK is organized as follows: - `src/`: Contains the main TypeScript source files. - `tests/`: Includes all the test files written using Vitest. - `dist/`: The compiled JavaScript files ready for use. ## Requirements Before using the GenLayerJS SDK, ensure your system meets the following requirements: - **Node.js**: Version 16.x or higher is required. - **npm**: Comes bundled with Node.js, used for managing packages. - **Operating System**: Compatible with macOS, Linux, and Windows. ### Installation To install the GenLayerJS SDK, use the following command: ```bash npm install genlayer-js ``` ## Usage Here’s how to initialize the client and connect to the GenLayer Studio: - **[Reading a transaction](../intelligent-contracts/advanced-features/contract-to-contract-interaction)**: Understand how to query transactions on the GenLayer network. - **[Reading a contract](/developers/decentralized-applications/reading-data)**: Discover how to read data from intelligent contracts on GenLayer. - **[Writing a contract](../intelligent-contracts/tools/genlayer-studio/contract-state)**: Learn how to write data to intelligent contracts on GenLayer. ## General Format of Commands The GenLayerJS SDK provides functions that follow a consistent syntax pattern: ```typescript client.functionName(parameters); ``` - `client`: The instance of the GenLayer client. - `functionName`: The primary action you want to perform (e.g., `getTransaction`, `readContract`). - `parameters`: An object containing the required parameters for the function. ## Further Development Additional features are planned to enhance interaction with the GenLayer network, including wallet integration and gas estimation. Stay tuned for updates. ## Repository You can find the GenLayerJS SDK repository on GitHub: [GenLayerJS SDK Repository](https://github.com/yeagerai/genlayer-js) ## Full Reference The full reference for the GenLayerJS SDK is available in the [GenLayerJS SDK Reference](/references/genlayer-js). # developers/decentralized-applications/querying-a-transaction.mdx # Querying a Transaction Reading transactions in GenLayer allows you to inspect the details of any transaction that has been submitted to the network. This is useful for monitoring transaction status, debugging, and verifying transaction details. ## Basic Transaction Reading Here's the simplest way to read a transaction: ```typescript import { simulator } from 'genlayer-js/chains'; import { createClient } from 'genlayer-js'; const client = createClient({ chain: simulator, }); const transactionHash = "0x..."; const transaction = await client.getTransaction({ hash: transactionHash }); ``` {/* ## Transaction Data Structure When you read a transaction, you get access to its complete data structure: ```typescript interface Transaction { hash: `0x${string}` // The unique transaction hash from: `0x${string}` // Address of the sender to: `0x${string}` | null // Address of the recipient (null for contract deployments) nonce: number // Transaction sequence number value: bigint // Amount of native tokens transferred data: `0x${string}` // Transaction input data timestamp: number // Block timestamp when transaction was included status: 'success' | 'failure' | 'pending' // Current transaction status blockNumber: bigint | null // Block number where transaction was included blockHash: `0x${string}` | null // Hash of the block // ... additional fields } ``` ## Reading Different Transaction Types ### Basic Transfer Transaction ```typescript const transferTx = await client.getTransaction({ hash: "0x123...", }); console.log({ from: transferTx.from, to: transferTx.to, value: transferTx.value, status: transferTx.status }); ``` ### Contract Interaction Transaction ```typescript const contractTx = await client.getTransaction({ hash: "0x456...", }); // Decode the transaction input data const decodedInput = client.decodeTransactionInput({ data: contractTx.data, abi: contractABI, // You need the contract's ABI }); console.log({ contractAddress: contractTx.to, functionName: decodedInput.functionName, arguments: decodedInput.args }); ``` ### Contract Deployment Transaction ```typescript const deployTx = await client.getTransaction({ hash: "0x789...", }); console.log({ deployer: deployTx.from, contractAddress: deployTx.creates, // Address of deployed contract deploymentData: deployTx.data }); ``` */} ## Error Handling ```typescript async function getTransactionWithRetry( client: GenLayerClient, hash: string, maxAttempts = 3 ): Promise { for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { const tx = await client.getTransaction({ hash }); if (!tx) throw new Error('Transaction not found'); return tx; } catch (error) { if (attempt === maxAttempts) throw error; if (error.message.includes('not found')) { // Wait longer between retries for not found errors await new Promise(resolve => setTimeout(resolve, 2000 * attempt)); continue; } throw error; // Rethrow other errors immediately } } throw new Error('Failed to fetch transaction after max retries'); } ``` ## Monitoring Transaction Status ```typescript async function monitorTransaction( client: GenLayerClient, hash: string, interval = 1000 ): Promise { return new Promise((resolve, reject) => { const checkStatus = async () => { try { const tx = await client.getTransaction({ hash }); if (!tx) { setTimeout(checkStatus, interval); return; } if (tx.status === 'pending') { setTimeout(checkStatus, interval); return; } resolve(tx); } catch (error) { reject(error); } }; checkStatus(); }); } // Usage const finalTx = await monitorTransaction(client, "0x..."); ``` # developers/decentralized-applications/reading-data.mdx # Reading from Intelligent Contracts Reading from an Intelligent Contract allows you to query the contract's state and execute view functions without modifying the blockchain state. These operations are free (no fees) and provide immediate access to contract data. ## Understanding View Operations In GenLayer, functions marked with the `@gl.public.view` decorator are read-only operations that: - Don't modify the contract's state - Can be executed without requiring a transaction - Return data immediately - Don't consume gas - Can be called by any account ## Basic Contract Reading Here's how to read from an Intelligent Contract: ```typescript import { simulator } from 'genlayer-js/chains'; import { createClient, createAccount } from 'genlayer-js'; const account = createAccount(); const client = createClient({ chain: simulator, account: account, }); const result = await client.readContract({ address: contractAddress, functionName: 'get_complete_storage', args: [], }); ``` ### Parameters Explained - `address`: The deployed contract's address on the GenLayer network - `functionName`: The name of the view function you want to call - `args`: An array of arguments that the function accepts (empty if none required) ## Common View Operations Intelligent Contracts typically include several types of view functions: ### State Queries ```typescript // Reading a single value const balance = await client.readContract({ address: contractAddress, functionName: 'get_balance', args: [accountAddress], }); // Reading multiple values const userInfo = await client.readContract({ address: contractAddress, functionName: 'get_user_info', args: [userId], }); ``` ### Computed Values ```typescript // Getting calculated results const totalSupply = await client.readContract({ address: contractAddress, functionName: 'calculate_total_supply', args: [], }); ``` ### Validation Checks ```typescript // Checking permissions const hasAccess = await client.readContract({ address: contractAddress, functionName: 'check_user_permission', args: [userId, 'ADMIN_ROLE'], }); ``` ## Error Handling When reading from contracts, you should handle potential errors: ```typescript try { const result = await client.readContract({ address: contractAddress, functionName: 'get_data', args: [], }); console.log('Data retrieved:', result); } catch (error) { if (error.message.includes('Contract not found')) { console.error('Invalid contract address'); } else if (error.message.includes('Function not found')) { console.error('Invalid function name'); } else { console.error('Error reading contract:', error); } } ``` ## Best Practices 1. **Cache Results**: For frequently accessed data that doesn't change often, consider caching the results. 2. **Batch Readings**: When possible, use functions that return multiple values instead of making multiple separate calls. 3. **Type Safety**: Use TypeScript interfaces to ensure type safety when handling returned data: # developers/decentralized-applications/writing-data.mdx # Writing to Intelligent Contracts Writing to an Intelligent Contract involves sending transactions that modify the contract's state. Unlike read operations, write operations require fees and need to be processed by the network before taking effect. ## Understanding Write Operations In GenLayer, functions that modify state: - Require a transaction to be sent to the network - Consume gas (computational resources) - Need time to be processed and finalized - Must be signed by an account with sufficient balance to pay for the transaction fees - Return a transaction hash immediately, but state changes are not instant ## Basic Contract Writing Here's how to write to an Intelligent Contract: ```typescript import { simulator } from 'genlayer-js/chains'; import { createClient, createAccount } from 'genlayer-js'; import type { TransactionStatus } from 'genlayer-js/types'; const account = createAccount(); const client = createClient({ chain: simulator, account: account, }); // Send the transaction const transactionHash = await client.writeContract({ address: contractAddress, functionName: 'update_storage', args: ['new_data'], value: 0, // Optional: amount of native GEN tokens to send }); // Wait for the transaction to be processed const receipt = await client.waitForTransactionReceipt({ hash: transactionHash, status: TransactionStatus.FINALIZED, // or 'ACCEPTED' }); ``` ### Parameters Explained - `address`: The deployed contract's address - `functionName`: The name of the function to call - `args`: Array of arguments for the function - `value`: Amount of native tokens to send (in wei) ## Transaction Lifecycle 1. **Transaction Creation** ```typescript const transactionHash = await client.writeContract({ address: contractAddress, functionName: 'mint_token', args: [recipient, amount], }); ``` 2. **Transaction Status Monitoring** ```typescript // Basic waiting const receipt = await client.waitForTransactionReceipt({ hash: transactionHash, status: 'FINALIZED', }); // Advanced monitoring with timeout const receipt = await client.waitForTransactionReceipt({ hash: transactionHash, status: 'FINALIZED', interval: 5_000, // check every 5 seconds retries: 10, // maximum number of retries }); ``` ## Common Write Operations ### Token Transfers ```typescript // Sending tokens const hash = await client.writeContract({ address: tokenContractAddress, functionName: 'transfer', args: [recipientAddress, amount], }); ``` ### State Updates ```typescript // Updating user data const hash = await client.writeContract({ address: contractAddress, functionName: 'update_user_profile', args: [userId, newProfile], }); ``` ## Error Handling ```typescript try { const hash = await client.writeContract({ address: contractAddress, functionName: 'update_data', args: ['new_data'], }); try { const receipt = await client.waitForTransactionReceipt({ hash, status: 'FINALIZED', }); console.log('Transaction successful:', receipt); } catch (waitError) { console.error('Transaction failed or timed out:', waitError); } } catch (error) { if (error.message.includes('insufficient funds')) { console.error('Not enough balance to pay for transaction'); } else if (error.message.includes('user rejected')) { console.error('User rejected the transaction'); } else { console.error('Error sending transaction:', error); } } ``` ## Transaction Status Types GenLayer transactions can have different status requirements: ```typescript enum TransactionStatus { PENDING = "PENDING", CANCELED = "CANCELED", PROPOSING = "PROPOSING", COMMITTING = "COMMITTING", REVEALING = "REVEALING", ACCEPTED = "ACCEPTED", FINALIZED = "FINALIZED", UNDETERMINED = "UNDETERMINED", } // Wait for just acceptance (faster) const acceptedReceipt = await client.waitForTransactionReceipt({ hash: transactionHash, status: TransactionStatus.ACCEPTED, }); // Wait for full finalization const finalizedReceipt = await client.waitForTransactionReceipt({ hash: transactionHash, status: TransactionStatus.FINALIZED, }); ``` ## Best Practices 1. **Always Wait for Receipts**: Don't assume a transaction is successful just because you got a hash. 2. **Handle Timeouts**: Set appropriate timeouts for transaction waiting. 3. **Implement Retry Logic**: For important transactions, implement retry mechanisms: ```typescript async function sendWithRetry( client: GenLayerClient, params: WriteContractParameters, maxAttempts = 3 ): Promise { for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { const hash = await client.writeContract(params); return await client.waitForTransactionReceipt({ hash, status: 'FINALIZED', timeout: 30_000 * attempt, // Increase timeout with each attempt }); } catch (error) { if (attempt === maxAttempts) throw error; console.log(`Attempt ${attempt} failed, retrying...`); await new Promise(resolve => setTimeout(resolve, 1000 * attempt)); } } throw new Error('Max retry attempts reached'); } ``` # developers/decentralized-applications/testing.mdx import { Callout } from 'nextra-theme-docs' # Testing Intelligent Contracts on GenLayer Testing Intelligent Contracts on GenLayer involves deploying contracts, sending transactions, validating their behavior, and identifying issues. Here is some guidance on how to test using the tools provided in the local development environment and GenLayer Studio. ## Testing Workflow in the Local Environment For a more advanced and controlled testing setup, you can leverage the GenLayer Project Boilerplate and the provided test helpers. Please note that you need the Studio running to run the tests by sending requests to it. ### 1. Create Accounts Use the `create_new_account` helper to generate accounts for testing. These accounts simulate users interacting with the contract. ```python from tools.request import create_new_account account = create_new_account() ``` ### 2. Set Up Validators Validators are essential for processing transactions in GenLayer. Use the `sim_createRandomValidators` method to initialize them. ```python from tools.request import payload, post_request_localhost nb_validators = 5 min_stake = 8 max_stake = 12 providers = ["openai"] models = ["gpt-4o"] validators_response = post_request_localhost( payload("sim_createRandomValidators", nb_validators, min_stake, max_stake, providers, models) ).json() ``` ### 3. Deploy the Contract Deploy your Intelligent Contract using the `deploy_intelligent_contract` helper: ```python from tools.request import deploy_intelligent_contract contract_code = open("contracts/my_contract.py", "r").read() contract_address, deploy_response = deploy_intelligent_contract(account, contract_code, "{}") ``` ### 4. Interact with the Contract Use `send_transaction` for writing data to the contract and `call_contract_method` for reading data: ```python from tools.request import send_transaction, call_contract_method # Write data send_transaction(account, contract_address, "method_name", [arg1, arg2]) # Read data result = call_contract_method(contract_address, account, "get_state", []) ``` ### 5. Assertions Validate the responses using provided assertion helpers: ```python from tools.response import assert_dict_struct, has_success_status assert has_success_status(result) assert_dict_struct(result, expected_structure) ``` ### 6. Clean Up After completing the tests, delete the validators or reset the environment: ```python delete_response = post_request_localhost(payload("sim_deleteAllValidators")).json() ``` # developers/decentralized-applications/project-boilerplate.mdx import { Callout } from 'nextra-theme-docs' # GenLayer Project Boilerplate The GenLayer Project Boilerplate is a template for building decentralized applications (DApps) on GenLayer. This boilerplate includes a complete example implementation of a football prediction market, demonstrating best practices and common patterns for GenLayer development. This boilerplate is a work in progress and is not yet ready for production use. You can find the latest version at: [GenLayer Project Boilerplate](https://github.com/yeagerai/genlayer-project-boilerplate) ## Features - **Contract Templates**: Ready-to-use intelligent contract templates and examples - **Testing Framework**: Built-in testing infrastructure for end-to-end testing - **Frontend Integration**: Vue.js-based frontend setup with GenLayerJS integration - **Environment Configuration**: Pre-configured environment setup for development - **Example Implementation**: Full football prediction market implementation ## How it's Built The boilerplate project is structured to provide a development environment for GenLayer applications, combining both backend contract development and frontend user interface. ### Technologies Used - **Python**: For intelligent contract development and testing - **Vue.js**: Frontend framework for building user interfaces - **GenLayerJS**: SDK for interacting with GenLayer contracts - **pytest**: Testing framework for contract validation - **Vite**: Frontend build tool and development server ### Project Structure ``` project-root/ ├── app/ # Frontend application │ ├── src/ # Vue.js source files │ └── .env.example # Frontend environment variables template ├── contracts/ # Intelligent Contracts │ └── football_prediction_market.py ├── test/ # Test files └── .env.example # Main environment variables template ``` ## Requirements Before using the GenLayer Project Boilerplate, ensure your system meets the following requirements: - **GenLayer Studio**: Running instance required - **Node.js**: Version 18.x or higher - **Python**: Version 3.8 or higher ### Installation 1. Clone the boilerplate repository: ```bash git clone https://github.com/yeagerai/genlayer-project-boilerplate cd genlayer-project-boilerplate ``` 2. Set up the environment: ```bash cp .env.example .env ``` ## Usage ### Deploying Contracts 1. Access the GenLayer Simulator UI (default: http://localhost:8080) 2. Navigate to "Contracts" section 3. Create a new contract using `/contracts/football_prediction_market.py` 4. Deploy through the "Run and Debug" interface ### Frontend Setup 1. Configure the frontend environment: ```bash cd app cp .env.example .env # Add your contract address to VITE_CONTRACT_ADDRESS ``` 2. Install dependencies and start the development server: ```bash npm install npm run dev ``` ### Running Tests Execute the test suite using pytest: ```bash pip install -r requirements.txt pytest test ``` ## Football Prediction Market Example The included example contract demonstrates a complete prediction market implementation with the following features: ### Contract Functions #### Create Predictions: ```python create_prediction(game_date: str, team1: str, team2: str, predicted_winner: str) ``` #### Resolve Predictions: ```python resolve_prediction(prediction_id: str) ``` #### Query Data: ```python get_player_predictions(player_address: str) get_player_points(player_address: str) ``` ### Frontend Integration The Vue.js frontend demonstrates: - Wallet connection handling - Contract interaction using GenLayerJS - User interface for prediction creation and management - Real-time updates for prediction status ## Testing Framework The boilerplate includes a comprehensive testing suite covering the following scenarios: ### Contract Schema The schema of the contract is well generated and has the expected methods and variables. ### Test Scenarios #### Successful Draw Prediction Tests the scenario where a player correctly predicts a draw between two teams. When the match is resolved as a draw, the player should receive 1 point for their accurate prediction. #### Successful Winner Prediction Validates the case where a player correctly predicts the winning team. Upon match resolution confirming their predicted team as the winner, the player should be awarded 1 point. #### Unsuccessful Prediction Covers the scenario where a player's prediction doesn't match the actual result. This could be: - Predicting Team A wins, but Team B wins - Predicting a draw, but there's a winner - Predicting a winner, but the match ends in a draw In all these cases, the player should receive 0 points. ## Best Practices - Always use environment variables for configuration - Implement comprehensive testing for all contract functions - Follow the provided folder structure for consistency - Use TypeScript for frontend development - Implement proper error handling in both contract and frontend code # validators.mdx import { Callout } from 'nextra-theme-docs' # GenLayer Validator Requirements Running a GenLayer Validator node ensures the security and reliability of the GenLayer network. Below are the requirements for running a GenLayer validator. ## Dependencies ### LLM Access Each validator needs access to a Large Language Model (LLM) for executing and evaluating Intelligent Contracts. It is up to each validator to select the model they want to use. Possible options: - Run an open-source model locally on the same machine with a GPU - Run an open-source model on a different machine - Connect to a hosted inference provider (OpenAI, Anthropic, Heurist, Atoma network etc.) ### ZKSync Full Node for the GenLayer Chain Each validator needs access to a [ZKSync Full Node](https://docs.zksync.io/zksync-era/tooling/external-node) connected to the GenLayer chain. One full node can be shared between multiple validators - TBD how many exactly. ## System Requirements Below are the **initial** recommended system requirements. These guidelines may change as the network grows and evolves. ### RAM - **Recommended:** 16 GB - **Why:** - GenLayer's _genvm_ can spawn multiple Sub-VMs for contract calls and non-deterministic blocks. - Each Sub-VM can consume up to ~4 GB of RAM for storage. ### CPU - **Recommended:** Modern multi-core processor with at least 8 cores/16 threads ### Storage - **Recommended Disk Space:** 128 GB+ - **Preferred Type:** SSD or NVMe (M.2) ### Network - **Recommended Connection:** Stable broadband ### Operating System - **Recommended:** 64-bit Linux (Ubuntu, Debian, CentOS, etc.) ### GPU (Optional) - **Recommended:** If you plan to run advanced AI-models locally, a CUDA-compatible GPU could be beneficial. These requirements are a starting point. As GenLayer evolves and usage patterns change (e.g., more complex AI-driven Intelligent Contracts), the recommended hardware may change. # partners/yeager.mdx ## Yeager AI [YeagerAI](https://www.yeager.ai/) is a pioneering AI research lab dedicated to revolutionizing human-AI interaction. They are one of the core developers of GenLayer, focusing on using AI to enhance the performance, security, and scalability of blockchain networks. By embedding AI into the blockchain’s core, YeagerAI enables decentralized applications to make smart decisions autonomously, opening new possibilities for automation and efficiency in various industries. We encourage other developers and organizations to collaborate with YeagerAI on this groundbreaking project. Together, we can push the boundaries of what AI and blockchain technology can achieve. # partners/heurist.mdx # Heurist [Heurist](https://www.heurist.ai/) is a Layer 2 network for AI model hosting and inference, built on the ZK Stack. It offers serverless access to open-source AI models through a decentralized network, making AI deployment easy and efficient for developers. This approach promotes transparency and reduces bias, which is especially useful for projects like GenLayer that require detailed AI analysis. In collaboration with GenLayer, Heurist provides APIs for open-source large language models (LLMs) to enable developers building Intelligent Contracts use AI at low or no cost. Developers building on GenLayer can obtain free [Heurist API credits](https://dev-api-form.heurist.ai) by using the referral code: _"genlayer"_. This partnership underscores our commitment to providing robust tools and scalable solutions for decentralized applications. # api-references.mdx import { Card, Cards } from 'nextra-theme-docs' # api-references/genlayer-cli.mdx # GenLayer CLI Reference Each command includes syntax, usage information, and examples to help you effectively use the CLI for interacting with the GenLayer environment. ## Command line syntax General syntax for using the GenLayer CLI: ```bash genlayer command [command options] [arguments...] ``` ## Version Compatibility The GenLayer CLI always uses the latest compatible version of the environment, ensuring that you benefit from the most recent features, bug fixes, and optimizations without requiring manual updates. If a specific version is needed, you can specify it using the --localnet-version option when initializing the environment. ```bash genlayer init --localnet-version v0.10.2 ``` ## Commands and usage ### Initialize Prepares and verifies your environment to run the GenLayer Studio. ```bash USAGE: genlayer init [options] OPTIONS: --numValidators Number of validators (default: "5") --headless Headless mode (default: false) --reset-db Reset Database (default: false) --localnet-version Select a specific localnet version EXAMPLES: genlayer init genlayer init --numValidators 10 --headless --reset-db --localnet-version v0.10.2 ``` ### Start GenLayer environment Launches the GenLayer environment and the Studio, initializing a fresh set of database and accounts. ```bash USAGE: genlayer up [options] OPTIONS: --reset-validators Remove all current validators and create new random ones (default: false) --numValidators Number of validators (default: "5") --headless Headless mode (default: false) --reset-db Reset Database (default: false) EXAMPLES: genlayer up genlayer up --reset-validators --numValidators 8 --headless --reset-db ``` ### Stop GenLayer environment Stops all running GenLayer Localnet services. ```bash USAGE: genlayer stop ``` ### Manage CLI Configuration Configure the GenLayer CLI settings. ```bash USAGE: genlayer config [options] COMMANDS: set Set a configuration value get [key] Get the current configuration reset Reset a configuration value to its default EXAMPLES: genlayer config get genlayer config get defaultOllamaModel genlayer config set defaultOllamaModel=deepseek-r1 genlayer config reset keyPairPath ``` ### Deploy and Call Intelligent Contracts Deploy and interact with intelligent contracts. ```bash USAGE: genlayer deploy [options] genlayer call [options] OPTIONS (deploy): --contract Path to the intelligent contract to deploy --args Positional arguments for the contract (space-separated, use quotes for multi-word arguments) OPTIONS (call): --args Positional arguments for the method (space-separated, use quotes for multi-word arguments) EXAMPLES: genlayer deploy --contract ./my_contract.gpy genlayer call 0x123456789abcdef greet --args "Hello World!" ``` ### Keypair Management Generate and manage keypairs. ```bash USAGE: genlayer keygen create [options] OPTIONS: --output Path to save the keypair (default: "./keypair.json") --overwrite Overwrite the existing file if it already exists (default: false) EXAMPLES: genlayer keygen create genlayer keygen create --output ./my_key.json --overwrite ``` ### Update Resources Manage and update models or configurations. ```bash USAGE: genlayer update ollama [options] OPTIONS: --model [model-name] Specify the model to update or pull --remove Remove the specified model instead of updating EXAMPLES: genlayer update ollama genlayer update ollama --model deepseek-r1 genlayer update ollama --model deepseek-r1 --remove ``` ### Validator Management Manage validator operations. ```bash USAGE: genlayer validators [options] COMMANDS: get [--address ] Retrieve details of a specific validator or all validators delete [--address ] Delete a specific validator or all validators count Count all validators update [options] Update a validator details create-random [options] Create random validators create [options] Create a new validator OPTIONS (update): --stake New stake for the validator --provider New provider for the validator --model New model for the validator --config New JSON config for the validator OPTIONS (create-random): --count Number of validators to create (default: "1") --providers Space-separated list of provider names (e.g., openai ollama) --models Space-separated list of model names (e.g., gpt-4 gpt-4o) OPTIONS (create): --stake Stake amount for the validator (default: 1) --config Optional JSON configuration for the validator --provider Specify the provider for the validator --model Specify the model for the validator EXAMPLES: genlayer validators get genlayer validators get --address 0x123456789abcdef genlayer validators count genlayer validators delete --address 0x123456789abcdef genlayer validators update 0x123456789abcdef --stake 100 --provider openai --model gpt-4 genlayer validators create genlayer validators create --stake 50 --provider openai --model gpt-4 genlayer validators create-random --count 3 --providers openai --models gpt-4 gpt-4o ``` # api-references/genlayer-js.mdx # GenLayerJS SDK Reference This document describes the key components and methods available in the GenLayerJS SDK for interacting with the GenLayer network. ## Client Creation ### createClient Creates a new GenLayer client instance. ```typescript import { createClient } from 'genlayer-js'; const client = createClient({ chain: simulator, account: account, // Optional: Use this account for subsequent calls }); ``` **Parameters:** - `chain`: The chain configuration (e.g., simulator) - `account`: (Optional) Sets an account to be used in subsequent calls **Returns:** A GenLayer client instance ## Transaction Handling ### getTransaction Retrieves transaction details by hash. ```typescript const transaction = await client.getTransaction({ hash: transactionHash }); ``` **Parameters:** - `hash`: The transaction hash **Returns:** Transaction details object

### waitForTransactionReceipt Waits for a transaction receipt. ```typescript const receipt = await client.waitForTransactionReceipt({ hash: transactionHash, status: 'FINALIZED', // or 'ACCEPTED' }); ``` **Parameters:** - `hash`: The transaction hash - `status`: The desired transaction status ('FINALIZED' or 'ACCEPTED') **Returns:** Transaction receipt object ## Contract Interaction ### readContract Reads data from a deployed contract. ```typescript const result = await client.readContract({ address: contractAddress, functionName: 'get_complete_storage', args: [], }); ``` **Parameters:** - `address`: The contract address - `functionName`: The name of the function to call - `args`: An array of arguments for the function call **Returns:** The result of the contract function call

### writeContract Writes data to a deployed contract. ```typescript const transactionHash = await client.writeContract({ address: contractAddress, functionName: 'storeData', args: ['new_data'], value: 0, // Optional: amount of native token to send with the transaction }); ``` **Parameters:** - `address`: The contract address - `functionName`: The name of the function to call - `args`: An array of arguments for the function call - `value`: (Optional) Amount of native token to send with the transaction **Returns:** The transaction hash ## Account Management ### generatePrivateKey Generates a new private key. ```typescript import { generatePrivateKey } from 'genlayer-js'; const privateKey = generatePrivateKey(); ``` **Parameters:** None **Returns:** A new private key as string

### createAccount Creates a new account, optionally using a provided private key. ```typescript import { createAccount } from 'genlayer-js'; const account = createAccount(); // Or with a specific private key: const accountWithKey = createAccount('0x1234...'); // Replace with actual private key ``` **Parameters:** - `accountPrivateKey`: (Optional) A string representing the private key **Returns:** A new account object ## Chain Information ### simulator Provides configuration for the GenLayer Studio chain (the Studio used to be called "Simulator"). ```typescript import { simulator } from 'genlayer-js/chains'; ``` **Usage:** Used when creating a client to specify the chain # FAQ.mdx --- title: "FAQ" --- # FAQ
1. What is GenLayer? GenLayer is an AI-native Layer 1 blockchain designed to run **Intelligent Contracts**—smart contracts enhanced with Large Language Models (LLMs)—enabling them to process natural language, fetch web data in real time, and execute data-driven logic.
2. How is GenLayer different from traditional blockchains? Most blockchains rely solely on deterministic logic and external oracles to interact with off-chain data. **GenLayer integrates AI at the protocol level**, allowing on-chain contracts to directly interpret text prompts, perform complex computations, and adapt to real-world events without relying on external oracles.
3. What is “Optimistic Democracy” consensus? **Optimistic Democracy** is GenLayer’s enhanced Delegated Proof of Stake (dPoS) mechanism. It randomly selects a **Lead-Validator** to process transactions and multiple **Co-Validators** to verify the results. The system is designed to handle non-deterministic (AI-driven) outputs securely by requiring a majority agreement.
4. Why does GenLayer use Large Language Models (LLMs)? LLMs give Intelligent Contracts the ability to interpret and process complex human language, as well as to analyze data in ways traditional code-based smart contracts cannot. This opens up new use cases, such as AI-driven DAOs, predictive analytics, and autonomous oracles.
5. Can I still run normal, deterministic transactions on GenLayer? Absolutely. GenLayer supports **standard blockchain transactions** and deterministic logic alongside AI-driven logic. Developers can write regular smart contracts or Intelligent Contracts depending on their needs.
6. Do I have to be an AI expert to build on GenLayer? Not necessarily. While some knowledge of AI or LLMs can help, GenLayer provides a **Python-based SDK** and user-friendly tools (like the GenLayer Studio) to simplify contract creation. You can harness AI capabilities without deep machine learning expertise.
7. How do validators handle AI computation? Each validator runs both **Validator Software** (for networking, block production, and transaction management) **and** an **AI Model Integration** via API. When a contract calls an AI-dependent function, the validator executes that function locally, **then** verifies the output through the consensus process.
8. What happens if validators disagree on an AI result? In **Optimistic Democracy**, disagreements trigger a **majority vote**. If a validator strongly believes the proposed result is incorrect, they can challenge or appeal the outcome within the **Finality Window**. An appeal bond is posted to discourage frivolous or malicious appeals.
9. How do I get started as a developer? 1. Install the **GenLayer CLI** and set up your local environment. 2. Explore the **GenLayer Studio** to write, deploy, and test your Intelligent Contracts. 3. Check out the **genlayer-project-boilerplate** for end-to-end testing setups and best practices. 4. Use **GenLayerJS** or other tools for front-end integration.
10. Can I use any LLM provider? GenLayer is designed to **integrate with multiple LLM providers**, such as GPT, LLaMA, and others. During the `genlayer init` process, you can configure your preferred LLM, including its API keys and model parameters. You can also customize or switch providers as needed.
11. How is the network secured? Security is driven by a **delegated staking** model plus the **Optimistic Democracy** consensus process: - Token holders delegate **stake** to validators, incentivizing honest behavior. - **Multi-Validator Verification** mitigates errors by checking each other’s results. - **Appeals** provide a failsafe, penalizing dishonest validators via slashing.
12. What are the typical use cases for GenLayer? - **Prediction Markets**: AI-powered event outcomes - **Performance-Based Contracting**: Automatic escrow and payments tied to real-time metrics - **Network States**: Decentralized governance frameworks - **Dispute Resolution**: Low-cost, AI-driven arbitration - **AI-Driven DAOs**: Autonomous organizations that react to off-chain data
13. How can I contribute to GenLayer? You can: - Join the community on **Discord** or **Telegram** - Contribute code and documentation in GenLayer’s GitHub repositories - Provide feedback and suggestions to improve the GenLayer ecosystem - Help grow the community by sharing GenLayer with potential developers and AI enthusiasts