diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/delegate-call-vouchers.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/delegate-call-vouchers.md deleted file mode 100644 index 3edea9ce..00000000 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/delegate-call-vouchers.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: delegate-call-vouchers -title: DELEGATECALL Vouchers ---- - -:::danger Security Considerations -DELEGATECALL Vouchers are a powerful feature that should be used with extreme caution. Incorrect implementation can lead to serious security vulnerabilities as the target contract's code has full access to the Application contract's storage and funds. -::: - -DELEGATECALL Vouchers are an extension of vouchers that enables advanced smart contract interactions through the [`DELEGATECALL`](https://www.evm.codes/?fork=cancun#f4) opcode. - -Unlike regular vouchers, DELEGATECALL vouchers allow dApps to separate their execution logic from their storage context. When using DELEGATECALL voucher, the Application contract always maintains the storage, context, and funds (both ETH and tokens), while the target contract provides only the execution logic. This separation enables more flexible and reusable smart contract patterns while keeping all state changes and assets within the Application contract. - -When a DELEGATECALL voucher is executed through the Application contract, the code at the target address is executed with the following characteristics: - -- All storage operations occur in the Application contract's storage space -- All funds (ETH and tokens) remain in and are managed by the Application contract -- The msg.sender and msg.value from the original transaction are preserved -- The execution logic comes from the target contract, but operates on the Application contract's state and funds - -This mechanism, where the Application contract maintains the state and funds while borrowing logic from other contracts, enables powerful patterns such as: - -- **Paid Vouchers**: Vouchers that provide payment to the user who executes them. - -- **Future Vouchers**: Vouchers that are time-locked and can only be executed after a specific timestamp. - -- **Expirable Vouchers**: Vouchers that have an expiration timestamp, after which they can no longer be executed. - -- **Targeted Vouchers**: Vouchers that are restricted to execution by specific addresses or a list of authorized addresses. - -- **Atomic Vouchers**: A sequence of message calls that must be executed in order, ensuring atomicity of the operations. - -- **Re-executable Vouchers**: Vouchers that can be executed multiple times, unlike standard vouchers which can only be executed once. - -- **Ordered Vouchers**: Vouchers that must be executed in a specific sequence. For example, voucher A can only be executed after voucher B has been executed. - -The [`Application`](../contracts/application.md) contract handles the execution of DELEGATECALL vouchers through its [`executeOutput()`](../../contracts/application/#executeoutput) function, which validates and processes the DELEGATECALL operation on the blockchain. - -## Implementation Considerations - -When implementing DELEGATECALL vouchers, consider the following: - -1. **Storage Layout**: Since all storage operations happen in the Application contract, the storage layout of the target contract must be compatible with the Application contract's layout to prevent unintended storage collisions. - -2. **Security**: Since DELEGATECALL operations execute code in the context of the Application contract, careful validation of the target contract and its code is essential to prevent malicious modifications to the Application's state. - -3. **State Management**: All state changes occur in the Application contract's storage, making it the single source of truth for the application's state. - -:::note create a DELEGATECALL voucher -[Refer to the documentation here](../../development/asset-handling.md) for implementing DELEGATECALL vouchers in your dApp. -::: - -## Execution Context - -In a DELEGATECALL voucher execution: - -- The Application contract provides the execution context and storage -- The target contract provides only the logic to be executed -- All storage operations affect the Application contract's state -- msg.sender and msg.value from the original transaction are preserved - -This architecture, where the Application contract maintains all state while being able to execute logic from other contracts, makes DELEGATECALL vouchers particularly useful for customizable logics while keeping all application state centralized in the Application contract. - -## Epoch Configuration - -An epoch refers to a specific period during which a batch of updates is processed off-chain, and upon agreement by validators, the finalized state is recorded on-chain. - -Epoch Length is the number of blocks that make up an epoch. It determines how long each epoch lasts in terms of block counts. For instance, if an epoch length is set to 7200 blocks, the epoch will end once 7200 blocks have been processed. This length directly influences how frequently updates are finalized and recorded on the blockchain. - -Delegate call vouchers, like regular vouchers, are executed on the blockchain upon the closure of the corresponding epoch. This ensures that all state changes and logic executions are properly validated and recorded in the blockchain. - -You can manually set the epoch length to facilitate quicker execution of DELEGATECALL vouchers during development. - -:::note epoch duration -[Refer to the documentation here](../../development/cli-commands.md/#run) to manually configure epoch length during development. -::: \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/exception.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/exception.md index 4b505136..90ec4ae1 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/exception.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/exception.md @@ -11,7 +11,7 @@ When an exception occurs during request processing, the dApp backend should: 3. Exit the processing loop The Rollup HTTP Server will: -- Skip the input with the reason [`EXCEPTION`](../graphql/enums/completion-status.md) +- Skip the input with the reason [`EXCEPTION`](../jsonrpc/types.md#inputcompletionstatus) - Forward the exception message - Return status code 200 diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/introduction.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/introduction.md index 223ab73e..ddb215a0 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/introduction.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/introduction.md @@ -3,16 +3,18 @@ id: introduction title: Introduction --- -The backend of a Cartesi dApp processes requests in the following manner: +The backend of a Cartesi dApp retrieves a new request as follows: - - **Finish** — Called via [`/finish`](./finish.md), indicates that any previous processing has been completed and the backend is ready to handle the next request. The subsequent request is returned as the call's response and can be of the following types: +- Finish — Communicates that any previous processing has been completed and that the backend is ready to handle the subsequent request. This following request is returned as the call's response and can be of the following types: - - **Advance** — Provides input to be processed by the backend to advance the Cartesi Machine state. When processing an Advance request, the backend can call the [`/voucher`](./vouchers.md), [`/delegate-call-voucher`](./delegate-call-vouchers.md), [`/notice`](./notices.md), and [`/report`](./reports.md) endpoints. For such requests, the input data contains both the payload and metadata, including the account address that submitted the input. + - **Advance** — Provides input to be processed by the backend to advance the Cartesi Machine state. When processing an `Advance` request, the backend can call the methods `/voucher`, `/notice`, and `/report`. For such requests, the input data contains the payload and metadata, such as the account address that submitted the input. - - **Inspect** — Submits a query about the application's current state. When running inside a Cartesi Machine, this operation is guaranteed to leave the state unchanged, as the machine reverts to its exact previous condition after processing. For Inspect requests, the input data contains only a payload, and the backend can only call the [`/report`](./reports.md) endpoint. + - **Inspect** — This function submits a query about the application's current state. When running inside a Cartesi Machine, this operation is guaranteed to leave the state unchanged since the machine is reverted to its exact previous condition after processing. For Inspect requests, the input data has only a payload. + + :::caution Inspect requests + Inspect requests are best suited for non-production use, such as debugging and testing. They may not function reliably in production environments, potentially leading to errors or disruptions. + ::: - - **Exception** — Called by the backend when it encounters an unrecoverable error during request processing. This signals to the Rollup HTTP Server that the current request processing failed and should be terminated. See [`/exception`](./exception.md) for more details. - ## Advance and Inspect Here is a simple boilerplate application that handles Advance and Inspect requests: @@ -120,34 +122,31 @@ while True: -An **Advance** request involves sending input data to the base layer via JSON-RPC, allowing it to reach the dApp backend to change the application's state. +An **Advance** request involves sending input data to the base layer via JSON-RPC so they can reach the dApp backend to change the application's state. ![img](../../../../static/img/v1.3/advance.jpg) -Here is how an advance request works in the dApp architecture: +In the dApp architecture, here is how an advance request plays out. - Step 1: Send an input to the [`addInput(address, bytes)`](../contracts/input-box.md#addinput) function of the InputBox smart contract. -- Step 2: The HTTP Rollups Server reads the data and sends it to the Cartesi Machine for processing. +- Step 2: The HTTP Rollups Server reads the data and gives it to the Cartesi machine for processing. -- Step 3: After computation, the machine state is updated, and the results are returned to the rollup server. +- Step 3: After the computation, the machine state is updated, and the results are returned to the rollup server. -An **Inspect** request involves making an external HTTP API call to the rollups server to read the dApp state without modifying it. +An **Inspect** request involves making an external HTTP API call to the rollups server to read the dApp state without changing it. ![img](../../../../static/img/v1.3/inspect.jpg) You can make a simple inspect call from your frontend client to retrieve reports. -To perform an Inspect call, send an HTTP POST request to `
/inspect/` with a payload in the request body. For example: +To perform an Inspect call, use an HTTP GET request to `
/inspect/`. For example: ```shell -curl -X POST http://localhost:8080/inspect/ \ - -H "Content-Type: application/json" \ - -d '{"payload": "0xdeadbeef"}' +curl http://localhost:8080/inspect/mypath ``` -The payload should be a hex-encoded string starting with '0x' followed by pairs of hexadecimal numbers. +Once the call's response is received, the payload is extracted from the response data, allowing the backend code to examine it and produce outputs as **reports**. -After receiving the call's response, the payload is extracted from the response data, allowing the backend code to examine it and produce outputs as **reports**. -The direct output types for **Advance** requests are [vouchers](./vouchers.md), [DELEGATECALL vouchers](./delegate-call-vouchers.md), [notices](./notices.md), and [reports](./reports.md), while **Inspect** requests generate only [reports](./reports.md). +The direct output types for **Advance** requests are [vouchers](./vouchers.md), [notices](./notices.md), and [reports](./reports.md), while **Inspect** requests generate only [reports](./reports.md). diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/notices.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/notices.md index 0bddfc35..3ff59a4c 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/notices.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/notices.md @@ -13,7 +13,7 @@ Crucially, the base layer conducts on-chain validation of these notices through This validation process ensures the integrity and authenticity of the submitted notices, enabling the blockchain to verify and authenticate the declared off-chain events or conditions. -Let's see how a Cartesi dApp's **Advance** request sends an output to the rollup server as a notice: +Here are sample functions you can add to your application, then call to send a notice to the rollup server: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -23,25 +23,30 @@ import TabItem from '@theme/TabItem';

 
 ```javascript
-async function handle_advance(data) {
-  console.log("Received advance request data " + JSON.stringify(data));
-
-  const inputPayload = data["payload"];
+import { stringToHex, hexToString } from "viem";
 
+const emitNotice = async (inputPayload) => {
+  let hexPayload = stringToHex(inputPayload); // convert payload from string to hex 
   try {
     await fetch(rollup_server + "/notice", {
       method: "POST",
       headers: {
         "Content-Type": "application/json",
       },
-      body: JSON.stringify({ payload: inputPayload }),
+      body: JSON.stringify({ payload: hexPayload }),
     });
   } catch (error) {
     // Handle error here
   }
+}
 
+async function handle_advance(data) {
+  console.log("Received advance request data " + JSON.stringify(data));
+  const payload = hexToString(data.payload); // convert input from hex to string for processing
+  await emitNotice(payload);
   return "accept";
 }
+
 ```
 
 
@@ -51,22 +56,16 @@ async function handle_advance(data) {

 
 ```python
-def handle_advance(data):
-   logger.info(f"Received advance request data {data}")
-
-   status = "accept"
-   try:
-       inputPayload = data["payload"]
-       # Send the input payload as a notice
-       response = requests.post(
-           rollup_server + "/notice", json={"payload": inputPayload}
-       )
-       logger.info(
-           f"Received notice status {response.status_code} body {response.content}"
-       )
-   except Exception as e:
-       # Emit report with error message here
-   return status
+# Notice creation Process from a message string
+def emit_notice(message):
+    notice_payload = {"payload": "0x" + message.encode("utf-8").hex()}
+    response = requests.post(rollup_server + "/notice", json=notice_payload)
+    if response.status_code == 200 or response.status_code == 201:
+        logger.info(f"Notice emitted successfully with data: {notice_payload}")
+    else:
+        logger.error(f"Failed to emit Notice with data: {notice_payload}. Status code: {response.status_code}")
+
+emit_notice("hello world")
 ```
 
 
@@ -75,5 +74,5 @@ def handle_advance(data): :::note querying notices -Frontend clients can query notices using a GraphQL API exposed by Cartesi Nodes. [Refer to the documentation here](../../development/query-outputs.md/#query-all-reports) to query notices from the rollup server. +Frontend clients can query notices using a GraphQL API exposed by the Cartesi Nodes. [Refer to the documentation here](../../development/query-outputs.md/#query-all-reports) to query notices from the rollup server. ::: diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/vouchers.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/vouchers.md index 1c0e9938..43b72538 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/vouchers.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/vouchers.md @@ -6,13 +6,13 @@ title: Vouchers Vouchers serve as a mechanism for facilitating on-chain actions initiated in the execution layer. -Imagine vouchers as digital authorization tickets that grant dApps the authority to execute specific actions directly on the base layer. These vouchers encapsulate the details of the desired on-chain action, such as a token swap request or asset transfer. +Imagine vouchers as digital authorization tickets, granting dApps the authority to execute specific actions directly on the base layer. This voucher encapsulates the details of the desired on-chain action, such as a token swap request or asset transfer. -A voucher explicitly specifies the action that the dApp intends to execute on the base layer. +The voucher explicitly specifies the action that the dApp intends to execute on the base layer. For instance, in a DeFi application built on Cartesi, users may want to swap one token for another. The dApp generates a voucher that authorizes the on-chain smart contract to execute the swap on the user's behalf. -The [`Application`](../contracts/application.md) contract is crucial in validating and executing the received voucher on the blockchain. This execution process occurs through the [`executeOutput()`](../../contracts/application/#executeoutput) function, which handles different types of outputs including vouchers and DELEGATECALL vouchers. +The [`CartesiDApp`](../contracts/application.md) contract is crucial in validating and executing the received voucher on the blockchain. This execution process occurs through the [`executeVoucher()`](../contracts/application.md/#executevoucher) function, ensuring that the action specified in the voucher is legitimate and authorized. The result of the voucher execution is recorded on the base layer. This recording typically involves submitting claims by a consensus contract, ensuring the integrity and transparency of the executed on-chain action. @@ -20,17 +20,13 @@ The result of the voucher execution is recorded on the base layer. This recordin [Refer to the documentation here](../../development/asset-handling.md) for asset handling and creating vouchers in your dApp. ::: -## DELEGATECALL Vouchers - -Delegate call vouchers enable advanced smart contract interactions through the [DELEGATECALL](https://www.evm.codes/?fork=cancun#f4) opcode, allowing dApps to separate their execution logic from their storage context. For more details, see [DELEGATECALL Vouchers](./delegate-call-vouchers.md). - -## Epoch Configuration +## Epoch configuration An epoch refers to a specific period during which a batch of updates is processed off-chain, and upon agreement by validators, the finalized state is recorded on-chain. Epoch Length is the number of blocks that make up an epoch. It determines how long each epoch lasts in terms of block counts. For instance, if an epoch length is set to 7200 blocks, the epoch will end once 7200 blocks have been processed. This length directly influences how frequently updates are finalized and recorded on the blockchain. -One common use of vouchers in Cartesi dApps is to withdraw assets. Users initiate asset withdrawals by generating vouchers, which are then executed on the blockchain upon the closure of the corresponding epoch. +One everyday use of vouchers in Cartesi dApps is to withdraw assets. Users initiate asset withdrawals by generating vouchers, which are then executed on the blockchain upon the closure of the corresponding epoch. You can manually set the epoch length to facilitate quicker asset deposits and withdrawals. diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application-factory.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application-factory.md index a1456c36..0818208c 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application-factory.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application-factory.md @@ -2,104 +2,72 @@ id: application-factory title: ApplicationFactory resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/dapp/ApplicationFactory.sol + - url: https://github.com/cartesi/rollups-contracts/blob/prerelease/2.0.0/contracts/dapp/ApplicationFactory.sol title: Application Factory contract --- -The **ApplicationFactory** contract allows anyone to reliably deploy a new `IApplication` contract. +The **ApplicationFactory** contract is a tool for reliably deploying new instances of the [`Application`](../contracts/application.md) contract with or without a specified salt value for address derivation. -This contract inherits from `IApplicationFactory`. +Additionally, it provides a function to calculate the address of a potential new `CartesiDApp` contract based on input parameters. -## Functions +This contract ensures efficient and secure deployment of `Application` contracts within the Cartesi Rollups framework. -### `newApplication()` +## `newApplication()` ```solidity -function newApplication( - IOutputsMerkleRootValidator outputsMerkleRootValidator, - address appOwner, - bytes32 templateHash, - bytes calldata dataAvailability -) external override returns (IApplication) +function newApplication( IConsensus consensus, address appOwner, bytes32 templateHash) external override returns (IApplication) ``` -Deploys a new Application contract without a salt value for address derivation. +Deploys a new Application contract without specifying a salt value for address derivation. Emits an `ApplicationCreated` event upon successful deployment. -**Parameters** +#### Parameters -| Name | Type | Description | -|------|------|-------------| -| `outputsMerkleRootValidator` | `IOutputsMerkleRootValidator` | The initial outputs Merkle root validator contract | -| `appOwner` | `address` | Address of the owner of the application | -| `templateHash` | `bytes32` | Hash of the template for the application | -| `dataAvailability` | `bytes` | The data availability solution | +| Name | Type | Description | +| ------------ | ---------- | ---------------------------------------- | +| consensus | IConsensus | Instance of the consensus interface | +| appOwner | address | Address of the owner of the application | +| templateHash | bytes32 | Hash of the template for the application | -**Return Values** - -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `IApplication` | The deployed Application contract | - -### `newApplication()` (with salt) +## `newApplication()`(with salt) ```solidity -function newApplication( - IOutputsMerkleRootValidator outputsMerkleRootValidator, - address appOwner, - bytes32 templateHash, - bytes calldata dataAvailability, - bytes32 salt -) external override returns (IApplication) +function newApplication( IConsensus consensus, address appOwner, bytes32 templateHash, bytes32 salt ) external override returns (IApplication) ``` Deploys a new `Application` contract with a specified salt value for address derivation. Emits an `ApplicationCreated` event upon successful deployment. -**Parameters** - -| Name | Type | Description | -|------|------|-------------| -| `outputsMerkleRootValidator` | `IOutputsMerkleRootValidator` | The initial outputs Merkle root validator contract | -| `appOwner` | `address` | Address of the owner of the application | -| `templateHash` | `bytes32` | Hash of the template for the application | -| `dataAvailability` | `bytes` | The data availability solution | -| `salt` | `bytes32` | Salt value for address derivation | - -**Return Values** +#### Parameters -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `IApplication` | The deployed Application contract | +| Name | Type | Description | +| ------------ | ---------- | ---------------------------------------- | +| consensus | IConsensus | Instance of the consensus interface | +| appOwner | address | Address of the owner of the application | +| templateHash | bytes32 | Hash of the template for the application | +| salt | bytes32 | Salt value for address derivation | ### `calculateApplicationAddress()` ```solidity -function calculateApplicationAddress( - IOutputsMerkleRootValidator outputsMerkleRootValidator, - address appOwner, - bytes32 templateHash, - bytes calldata dataAvailability, - bytes32 salt -) external view override returns (address) +function calculateApplicationAddress( IConsensus consensus, address appOwner, bytes32 templateHash, bytes32 salt ) external view override returns (address) ``` Calculates the address of a potential new Application contract based on input parameters. -**Parameters** +#### Parameters -| Name | Type | Description | -|------|------|-------------| -| `outputsMerkleRootValidator` | `IOutputsMerkleRootValidator` | The initial outputs Merkle root validator contract | -| `appOwner` | `address` | Address of the owner of the application | -| `templateHash` | `bytes32` | Hash of the template for the application | -| `dataAvailability` | `bytes` | The data availability solution | -| `salt` | `bytes32` | Salt value for address derivation | +| Name | Type | Description | +| ------------ | ---------- | ---------------------------------------- | +| consensus | IConsensus | Instance of the consensus interface | +| appOwner | address | Address of the owner of the application | +| templateHash | bytes32 | Hash of the template for the application | +| salt | bytes32 | Salt value for address derivation | -**Return Values** +#### Returns -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `address` | Address of the potential new Application contract | +| Type | Description | +| ------- | ------------------------------------------------- | +| address | Address of the potential new Application contract | diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application.md index 50ead232..a8af6c7b 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/application.md @@ -2,337 +2,167 @@ id: application title: Application resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/dapp/Application.sol + - url: https://github.com/cartesi/rollups-contracts/tree/prerelease/2.0.0/contracts/dapp/Application.sol title: Application contract - url: https://docs.openzeppelin.com/contracts/5.x/ title: OpenZeppelin Contracts --- -The **Application** contract serves as the base layer representation of the application running on the execution layer. The application can interact with other smart contracts through the execution and validation of outputs. These outputs, generated by the application backend on the execution layer, can be proven in the base layer through claims submitted by a consensus contract. +The **Application** contract acts as the base layer incarnation of the application running on the execution layer. The application can interact with other smart contracts through the execution and validation of outputs. The application backend on the execution layer generates these outputs, which can be proven in the base layer thanks to claims submitted by a consensus contract. -Every Application is subscribed to a consensus contract and governed by a single address—the owner. The consensus has the authority to submit claims, which are then used to validate outputs. The owner has complete control over the Application and can replace the consensus at any time. Consequently, users of an Application must trust both the consensus and the application owner. Depending on centralization or ownership concerns, the ownership model can be modified. This process is managed by the consensus contract. For more information about different ownership and consensus models, refer to the [IConsensus](https://github.com/cartesi/rollups-contracts/blob/prerelease/2.0.0/contracts/consensus/IConsensus.sol). +Every Application is subscribed to a consensus contract and governed by a single address, the owner. The consensus has the power to submit claims, which, in turn, are used to validate outputs. The owner has complete power over the Application, as it can replace the consensus at any time. Therefore, the users of an Application must trust both the consensus and the application owner. It is important to note that, depending on centralization or ownership concerns, it is possible to change the ownership model. This process is managed under the consensus contract. For more information about different ownership and consensus models, refer to the [IConsensus](https://github.com/cartesi/rollups-contracts/blob/prerelease/2.0.0/contracts/consensus/IConsensus.sol). -This contract inherits from the following contracts: +This contract inherits the following OpenZeppelin contracts. -- `IApplication` - `Ownable` - `ERC721Holder` - `ERC1155Holder` - `ReentrancyGuard` +- `IERC721Receiver` +- `BitMaps` For more information, please consult [OpenZeppelin's official documentation](https://docs.openzeppelin.com/contracts/5.x/). -## State Variables - -### `_deploymentBlockNumber` -Deployment block number - -```solidity -uint256 immutable _deploymentBlockNumber = block.number; -``` - -### `_templateHash` -The initial machine state hash. - -*See the `getTemplateHash` function.* - -```solidity -bytes32 internal immutable _templateHash; -``` - -### `_executed` -Keeps track of which outputs have been executed. - -*See the `wasOutputExecuted` function.* - -```solidity -BitMaps.BitMap internal _executed; -``` - -### `_outputsMerkleRootValidator` -The current outputs Merkle root validator contract. - -*See the `getOutputsMerkleRootValidator` and `migrateToOutputsMerkleRootValidator` functions.* - -```solidity -IOutputsMerkleRootValidator internal _outputsMerkleRootValidator; -``` - -### `_dataAvailability` -The data availability solution. - -*See the `getDataAvailability` function.* - -```solidity -bytes internal _dataAvailability; -``` - -## Functions - -### `constructor` - -Creates an `Application` contract. - -*Reverts if the initial application owner address is zero.* +## `executeOutput()` ```solidity -constructor( - IOutputsMerkleRootValidator outputsMerkleRootValidator, - address initialOwner, - bytes32 templateHash, - bytes memory dataAvailability -) Ownable(initialOwner); +function executeOutput(bytes calldata output, OutputValidityProof calldata proof) external override nonReentrant (bool) ``` -**Parameters** - -| Name | Type | Description | -|------|------|-------------| -| `outputsMerkleRootValidator` | `IOutputsMerkleRootValidator` | The initial outputs Merkle root validator contract | -| `initialOwner` | `address` | The initial application owner | -| `templateHash` | `bytes32` | The initial machine state hash | -| `dataAvailability` | `bytes` | The data availability solution | - -### `receive()` - -```solidity -receive() external payable -``` - -Accept Ether transfers. - -*If you wish to transfer Ether to an application while informing the backend of it, then please do so through the Ether portal contract.* - -### `executeOutput()` - -```solidity -function executeOutput(bytes calldata output, OutputValidityProof calldata proof) external override nonReentrant -``` - -Execute an output. - -*On a successful execution, emits a OutputExecuted event.* - -**Parameters** - -| Name | Type | Description | -|------|------|-------------| -| `output` | `bytes` | The output | -| `proof` | `OutputValidityProof` | The proof used to validate the output against a claim accepted to the current outputs Merkle root validator contract | +Try to execute an output. -### `migrateToOutputsMerkleRootValidator()` +Reverts if output was already successfully executed or if the caller is attempting to execute a non-executable output. -```solidity -function migrateToOutputsMerkleRootValidator(IOutputsMerkleRootValidator newOutputsMerkleRootValidator) external override onlyOwner -``` - -Migrate the application to a new outputs Merkle root validator. +_On a successful execution, emits an `OutputExecuted` event._ -*Can only be called by the application owner.* +### Parameters -**Parameters** +| Name | Type | Description | +| ------------- | ------------ | -------------------------------------------------------------------------------------------------- | +| output | bytes | The output contains, encapsulated in the form of bytes to be decoded within the function logic, the destination contract (address), the output value (uint256), and the payload (bytes) which encodes a function call. | +| proof | struct OutputValidityProof | The proof used to validate the output against a claim submitted by the current consensus contract | -| Name | Type | Description | -|------|------|-------------| -| `newOutputsMerkleRootValidator` | `IOutputsMerkleRootValidator` | The new outputs Merkle root validator | - -### `wasOutputExecuted()` +## `wasOutputExecuted()` ```solidity function wasOutputExecuted(uint256 outputIndex) external view override returns (bool) ``` -Check whether an output has been executed. +Check whether a voucher has been executed. -**Parameters** +### Parameters -| Name | Type | Description | -|------|------|-------------| -| `outputIndex` | `uint256` | The index of output | +| Name | Type | Description | +| ----------------- | ------- | ---------------------------------------- | +| outputIndex | uint256 | The index of output emitted by the input | -**Return Values** +### Return Values -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `bool` | Whether the output has been executed before | +| Name | Type | Description | +| ---- | ---- | -------------------------------------------- | +| [0] | bool | Whether the output has been executed before | -### `validateOutput()` +## `migrateToConsensus()` ```solidity -function validateOutput(bytes calldata output, OutputValidityProof calldata proof) public view override +function migrateToConsensus(IConsensus newConsensus) external override onlyOwner; ``` -Validate an output. - -*May raise any of the errors raised by validateOutputHash.* - -**Parameters** - -| Name | Type | Description | -|------|------|-------------| -| `output` | `bytes` | The output | -| `proof` | `OutputValidityProof` | The proof used to validate the output against a claim accepted to the current outputs Merkle root validator contract | - -### `validateOutputHash()` - -```solidity -function validateOutputHash(bytes32 outputHash, OutputValidityProof calldata proof) public view override -``` - -Validate an output hash. - -*May raise InvalidOutputHashesSiblingsArrayLength or InvalidOutputsMerkleRoot.* - -**Parameters** - -| Name | Type | Description | -|------|------|-------------| -| `outputHash` | `bytes32` | The output hash | -| `proof` | `OutputValidityProof` | The proof used to validate the output against a claim accepted to the current outputs Merkle root validator contract | - -### `getTemplateHash()` - -```solidity -function getTemplateHash() external view override returns (bytes32) -``` - -Get the application's template hash. - -**Return Values** - -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `bytes32` | The application's template hash | +Migrate the Application to a new consensus. -### `getOutputsMerkleRootValidator()` +_Can only be called by the Application owner._ -```solidity -function getOutputsMerkleRootValidator() external view override returns (IOutputsMerkleRootValidator) -``` - -Get the current outputs Merkle root validator. +### Parameters -**Return Values** +| Name | Type | Description | +| -------------- | ------------------- | ----------------- | +| \_newConsensus | contract IConsensus | The new consensus address | -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `IOutputsMerkleRootValidator` | The current outputs Merkle root validator | - -### `getDataAvailability()` +## `validateOutput()` ```solidity -function getDataAvailability() external view override returns (bytes memory) +function validateOutput(bytes calldata output, OutputValidityProof calldata proof) public view override; ``` -Get the data availability solution used by application. - -**Return Values** - -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `bytes` | Solidity ABI-encoded function call that describes the source of inputs that should be fed to the application. | - -### `getDeploymentBlockNumber()` - -```solidity -function getDeploymentBlockNumber() external view override returns (uint256) -``` +Validate an output. -Get number of block in which contract was deployed. +### Parameters -**Return Values** +| Name | Type | Description | +| -------- | ---------------------- | --------------------------- | +| output | bytes | The output | +| proof | struct OutputValidityProof | Data for validating outputs | -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `uint256` | The deployment block number | +Reverts if the output or its corresponding proof is invalid. -### `owner()` +## `validateOutputHash()` ```solidity -function owner() public view override(IOwnable, Ownable) returns (address) +function validateOutputHash(bytes32 outputHash, OutputValidityProof calldata proof) public view override; ``` -Returns the address of the current owner. +Verifies the hash of an output against its proof. -**Return Values** +| Name | Type | Description | +|--------------|-------------------------------|-----------------------------------| +| outputHash | bytes32 | The hash of the output | +| proof | struct OutputValidityProof | The proof used to validate the output against a claim submitted by the current consensus contract | -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `address` | The address of the current owner | +Reverts if the proof's integrity check fails or if the output Merkle root hash was ever accepted by the consensus for a particular application. -### `renounceOwnership()` +## `getTemplateHash()` ```solidity -function renounceOwnership() public override(IOwnable, Ownable) +function getTemplateHash() external view returns (bytes32) ``` -Leaves the contract without owner. It will not be possible to call onlyOwner functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner. +Get the application template hash. -### `transferOwnership()` +### Return Values -```solidity -function transferOwnership(address newOwner) public override(IOwnable, Ownable) -``` - -Transfers ownership of the contract to a new account (newOwner). Can only be called by the current owner. - -**Parameters** +| Name | Type | Description | +| ---- | ------- | ------------------------ | +| [0] | bytes32 | The application template hash | -| Name | Type | Description | -|------|------|-------------| -| `newOwner` | `address` | The new owner address | - -### `_isOutputsMerkleRootValid()` +## `getConsensus()` ```solidity -function _isOutputsMerkleRootValid(bytes32 outputsMerkleRoot) internal view returns (bool) +function getConsensus() external view override returns (IConsensus); ``` -Check if an outputs Merkle root is valid, according to the current outputs Merkle root validator. - -**Parameters** - -| Name | Type | Description | -|------|------|-------------| -| `outputsMerkleRoot` | `bytes32` | The output Merkle root | +Get the current consensus. -**Return Values** +### Return Values -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `bool` | Whether the outputs Merkle root is valid | +| Name | Type | Description | +| ---- | ------------------- | --------------------- | +| [0] | contract IConsensus | The current consensus | -### `_executeVoucher()` +### `receive()` ```solidity -function _executeVoucher(bytes calldata arguments) internal +receive() external payable ``` -Executes a voucher. - -**Parameters** +Accept Ether transfers. -| Name | Type | Description | -|------|------|-------------| -| `arguments` | `bytes` | ABI-encoded arguments | +_If the caller wants to transfer Ether to an application while informing the backend of it, then please do so through the Ether portal contract._ -### `_executeDelegateCallVoucher()` +### `NewConsensus()` ```solidity -function _executeDelegateCallVoucher(bytes calldata arguments) internal +event NewConsensus(IConsensus newConsensus); ``` -Executes a delegatecall voucher. - -**Parameters** +A new consensus is used, this event is emitted when a new consensus is set. This event must be triggered on a successful call to [migrateToConsensus](#migratetoconsensus). -| Name | Type | Description | -|------|------|-------------| -| `arguments` | `bytes` | ABI-encoded arguments | +### Parameters -## Events +| Name | Type | Description | +| ------------ | ---------- | -------------------------- | +| newConsensus | IConsensus | The new consensus contract | -### `OutputExecuted()` +## `OutputExecuted()` ```solidity event OutputExecuted(uint64 outputIndex, bytes output); @@ -340,9 +170,9 @@ event OutputExecuted(uint64 outputIndex, bytes output); An output was executed from the Application, this event is emitted when a output is executed so it must be triggered on a successful call to [executeOutput](#executeOutput). -**Parameters** +### Parameters -| Name | Type | Description | -|------|------|-------------| -| `outputIndex` | `uint64` | The index of the output | -| `output` | `bytes` | The output | +| Name | Type | Description | +|--------------|---------|-----------------------| +| outputIndex | uint64 | The index of the output | +| output | bytes | The output | diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/abstract-consensus.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/abstract-consensus.md new file mode 100644 index 00000000..89a4624f --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/abstract-consensus.md @@ -0,0 +1,66 @@ +--- +id: abstract-consensus +title: AbstractConsensus +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/AbstractConsensus.sol + title: AbstractConsensus Contract +--- + +The **AbstractConsensus** contract provides an abstract implementation of `IConsensus` with common consensus functionality. + +## Functions + +### `isOutputsMerkleRootValid()` + +```solidity +function isOutputsMerkleRootValid(address appContract, bytes32 outputsMerkleRoot) public view override returns (bool) +``` + +Check whether an outputs Merkle root is valid. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `bool` | True if the outputs Merkle root is valid | + +### `getEpochLength()` + +```solidity +function getEpochLength() public view override returns (uint256) +``` + +Get the epoch length. + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `uint256` | The epoch length | + +### `supportsInterface()` + +```solidity +function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) +``` + +Check if the contract supports a specific interface. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `interfaceId` | `bytes4` | The interface identifier | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `bool` | True if the interface is supported | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/authority-factory.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/authority-factory.md new file mode 100644 index 00000000..d09cfece --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/authority-factory.md @@ -0,0 +1,80 @@ +--- +id: authority-factory +title: AuthorityFactory +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/authority/AuthorityFactory.sol + title: AuthorityFactory Contract +--- + +The **AuthorityFactory** contract allows anyone to reliably deploy new `IAuthority` contracts. + +## Functions + +### `newAuthority()` + +```solidity +function newAuthority(address authorityOwner, uint256 epochLength) external override returns (IAuthority) +``` + +Deploy a new authority contract. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `authorityOwner` | `address` | The initial authority owner | +| `epochLength` | `uint256` | The epoch length | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IAuthority` | The deployed authority contract | + +### `newAuthority()` (with salt) + +```solidity +function newAuthority(address authorityOwner, uint256 epochLength, bytes32 salt) external override returns (IAuthority) +``` + +Deploy a new authority contract deterministically using CREATE2. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `authorityOwner` | `address` | The initial authority owner | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the authority address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IAuthority` | The deployed authority contract | + +### `calculateAuthorityAddress()` + +```solidity +function calculateAuthorityAddress( + address authorityOwner, + uint256 epochLength, + bytes32 salt +) external view override returns (address) +``` + +Calculate the address of an authority to be deployed deterministically. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `authorityOwner` | `address` | The initial authority owner | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the authority address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `address` | The deterministic authority address | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/authority.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/authority.md new file mode 100644 index 00000000..a2f8cf25 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/authority.md @@ -0,0 +1,87 @@ +--- +id: authority +title: Authority +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/authority/Authority.sol + title: Authority Contract +--- + +The **Authority** contract implements a single-owner consensus mechanism where only the contract owner can submit and accept claims. + +## Functions + +### `submitClaim()` + +```solidity +function submitClaim( + address appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot +) external onlyOwner +``` + +Submit a claim to the consensus. Only the contract owner can call this function. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | + +### `owner()` + +```solidity +function owner() public view override(IOwnable, Ownable) returns (address) +``` + +Returns the address of the current owner. + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `address` | The current owner address | + +### `renounceOwnership()` + +```solidity +function renounceOwnership() public override(IOwnable, Ownable) +``` + +Leaves the contract without owner. It will not be possible to call onlyOwner functions. + +### `transferOwnership()` + +```solidity +function transferOwnership(address newOwner) public override(IOwnable, Ownable) +``` + +Transfers ownership of the contract to a new account. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `newOwner` | `address` | The new owner address | + +### `supportsInterface()` + +```solidity +function supportsInterface(bytes4 interfaceId) public view override(IERC165, AbstractConsensus) returns (bool) +``` + +Check if the contract supports a specific interface. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `interfaceId` | `bytes4` | The interface identifier | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `bool` | True if the interface is supported | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/iauthority-factory.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/iauthority-factory.md new file mode 100644 index 00000000..11423631 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/iauthority-factory.md @@ -0,0 +1,96 @@ +--- +id: iauthority-factory +title: IAuthorityFactory +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/authority/IAuthorityFactory.sol + title: IAuthorityFactory Interface +--- + +The **IAuthorityFactory** interface defines the contract for deploying new `IAuthority` contracts. + +## Events + +### `AuthorityCreated` + +```solidity +event AuthorityCreated(IAuthority authority) +``` + +A new authority was deployed. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `authority` | `IAuthority` | The authority | + +## Functions + +### `newAuthority()` + +```solidity +function newAuthority(address authorityOwner, uint256 epochLength) external returns (IAuthority) +``` + +Deploy a new authority. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `authorityOwner` | `address` | The initial authority owner | +| `epochLength` | `uint256` | The epoch length | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IAuthority` | The authority | + +### `newAuthority()` (with salt) + +```solidity +function newAuthority(address authorityOwner, uint256 epochLength, bytes32 salt) external returns (IAuthority) +``` + +Deploy a new authority deterministically. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `authorityOwner` | `address` | The initial authority owner | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the authority address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IAuthority` | The authority | + +### `calculateAuthorityAddress()` + +```solidity +function calculateAuthorityAddress( + address authorityOwner, + uint256 epochLength, + bytes32 salt +) external view returns (address) +``` + +Calculate the address of an authority to be deployed deterministically. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `authorityOwner` | `address` | The initial authority owner | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the authority address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `address` | The deterministic authority address | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/iauthority.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/iauthority.md new file mode 100644 index 00000000..c9a2aad5 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/authority/iauthority.md @@ -0,0 +1,19 @@ +--- +id: iauthority +title: IAuthority +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/authority/IAuthority.sol + title: IAuthority Interface +--- + +The `IAuthority` interface defines a consensus contract controlled by a single address, the owner. + +## Description + +A consensus contract controlled by a single address, the owner. This interface combines the consensus functionality with ownership management, allowing only the owner to submit claims. + +## Related Contracts + +- [`Authority`](./authority.md): Implementation of this interface +- [`IConsensus`](../iconsensus.md): Base consensus interface +- [`IOwnable`](https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/access/IOwnable.sol): Ownership management interface \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/iconsensus.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/iconsensus.md new file mode 100644 index 00000000..48348a66 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/iconsensus.md @@ -0,0 +1,165 @@ +--- +id: iconsensus +title: IConsensus +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/IConsensus.sol + title: IConsensus Interface +--- + +The `IConsensus` interface defines the main consensus contract behavior for validating and accepting claims submitted by validators. + +## Description + +Each application has its own stream of inputs. When an input is fed to the application, it may yield several outputs. Since genesis, a Merkle tree of all outputs ever produced is maintained both inside and outside the Cartesi Machine. + +The claim that validators may submit to the consensus contract is the root of this Merkle tree after processing all base layer blocks until some height. + +A validator should be able to save transaction fees by not submitting a claim if it was: +- Already submitted by the validator (see the `ClaimSubmitted` event) or +- Already accepted by the consensus (see the `ClaimAccepted` event) + +The acceptance criteria for claims may depend on the type of consensus, and is not specified by this interface. For example, a claim may be accepted if it was: +- Submitted by an authority or +- Submitted by the majority of a quorum or +- Submitted and not proven wrong after some period of time or +- Submitted and proven correct through an on-chain tournament + +## Functions + +### `submitClaim()` + +```solidity +function submitClaim( + address appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot +) external +``` + +Submit a claim to the consensus. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | + +**Events:** +- `ClaimSubmitted`: Must be fired +- `ClaimAccepted`: MAY be fired, if the acceptance criteria is met + +### `getEpochLength()` + +```solidity +function getEpochLength() external view returns (uint256) +``` + +Get the epoch length, in number of base layer blocks. + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `uint256` | The epoch length | + +**Note:** The epoch number of a block is defined as the integer division of the block number by the epoch length. + +## Events + +### `ClaimSubmitted()` + +```solidity +event ClaimSubmitted( + address indexed submitter, + address indexed appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot +) +``` + +Must trigger when a claim is submitted. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `submitter` | `address` | The submitter address | +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | + +### `ClaimAccepted()` + +```solidity +event ClaimAccepted( + address indexed appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot +) +``` + +Must trigger when a claim is accepted. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | + +**Note:** For each application and lastProcessedBlockNumber, there can be at most one accepted claim. + +## Errors + +### `NotEpochFinalBlock()` + +```solidity +error NotEpochFinalBlock(uint256 lastProcessedBlockNumber, uint256 epochLength) +``` + +The claim contains the number of a block that is not at the end of an epoch (its modulo epoch length is not epoch length - 1). + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `epochLength` | `uint256` | The epoch length | + +### `NotPastBlock()` + +```solidity +error NotPastBlock(uint256 lastProcessedBlockNumber, uint256 currentBlockNumber) +``` + +The claim contains the number of a block in the future (it is greater or equal to the current block number). + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `currentBlockNumber` | `uint256` | The number of the current block | + +### `NotFirstClaim()` + +```solidity +error NotFirstClaim(address appContract, uint256 lastProcessedBlockNumber) +``` + +A claim for that application and epoch was already submitted by the validator. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | + +## Related Contracts + +- [`AbstractConsensus`](./abstract-consensus.md): Abstract implementation of this interface +- [`IOutputsMerkleRootValidator`](./ioutputs-merkle-root-validator.md): Interface for validating outputs Merkle roots \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/ioutputs-merkle-root-validator.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/ioutputs-merkle-root-validator.md new file mode 100644 index 00000000..2fdadf48 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/ioutputs-merkle-root-validator.md @@ -0,0 +1,34 @@ +--- +id: ioutputs-merkle-root-validator +title: IOutputsMerkleRootValidator +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/IOutputsMerkleRootValidator.sol + title: IOutputsMerkleRootValidator Interface +--- + +The `IOutputsMerkleRootValidator` interface provides valid outputs Merkle roots for validation. + +## Description + +This interface provides functionality to check whether an outputs Merkle root is valid. ERC-165 can be used to determine whether this contract also supports any other interface (e.g. for submitting claims). + +## Functions + +### `isOutputsMerkleRootValid` +```solidity +function isOutputsMerkleRootValid(address appContract, bytes32 outputsMerkleRoot) external view returns (bool) +``` + +Check whether an outputs Merkle root is valid. + +**Parameters:** +- `appContract` (address): The application contract address +- `outputsMerkleRoot` (bytes32): The outputs Merkle root + +**Returns:** +- (bool): True if the outputs Merkle root is valid + +## Related Contracts + +- [`IConsensus`](./iconsensus.md): Interface that inherits from this interface +- [`AbstractConsensus`](./abstract-consensus.md): Abstract implementation that implements this interface \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/overview.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/overview.md index 4e69c587..c928237c 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/overview.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/overview.md @@ -2,30 +2,38 @@ id: overview title: Overview resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1 - title: Smart Contracts for Cartesi Rollups + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus + title: Consensus Smart Contracts --- -The Cartesi Rollups framework consists of components on two layers: the base layer (the foundational blockchain where an application contract is deployed, such as Ethereum) and the execution layer (the Cartesi off-chain layer where the application runs its backend logic). +The consensus mechanism in Cartesi Rollups is responsible for validating and accepting claims submitted by validators. These contracts ensure the integrity of the rollup by validating outputs Merkle roots. -The frontend interacts with base layer smart contracts to send inputs to the backend, deposit assets, and process outputs. +## Consensus Contracts -To interact with an Ethereum-compatible blockchain, the application frontend must connect to a blockchain node using Ethereum's JSON-RPC API. +The framework supports different consensus mechanisms: -Clients can interact with Ethereum-compatible nodes using the JSON-RPC API in two ways: +- **[Authority](./authority/authority.md)**: Single-owner consensus controlled by one address +- **[Quorum](./quorum/quorum.md)**: Multi-validator consensus requiring majority approval -- **Querying state (read operations)** — The state can be queried by calling functions that neither alter the blockchain state nor incur gas fees. +## Core Interfaces -- **Changing state (write operations)** — The state is changed by submitting a transaction that incurs gas fees. The transaction must be cryptographically signed by an Ethereum account with sufficient funds in its wallet. +- **[IConsensus](./iconsensus.md)**: Main interface defining the consensus contract behavior +- **[IOutputsMerkleRootValidator](./ioutputs-merkle-root-validator.md)**: Interface for validating outputs Merkle roots +- **[AbstractConsensus](./abstract-consensus.md)**: Abstract implementation providing common consensus functionality -## Cartesi Rollups Smart Contracts +## Consensus Mechanism -- [`InputBox`](../input-box.md): This contract receives inputs from users who want to interact with the off-chain layer. All inputs to your application are processed through this contract. +A claim consists of: -- [`Application`](../application.md): An `Application` contract is instantiated for each dApp (i.e., each dApp has its own application address). With this address, an application can hold ownership of digital assets on the base layer, such as Ether, ERC-20 tokens, and NFTs. +- Application Contract Address: The address of the dApp being validated +- Last Processed Block Number: The block number up to which inputs have been processed +- Outputs Merkle Root: The root hash of the Merkle tree containing all outputs produced by the application -- [`ApplicationFactory`](../application-factory.md): The `ApplicationFactory` contract enables anyone to deploy [`Application`](../application.md) contracts with a simple function call. It provides greater convenience to the deployer and security to users and validators, as they can verify that the bytecode has not been maliciously altered. +The consensus contract validates that: +- The block number is at the end of an epoch (modulo epoch length equals epoch length - 1) +- The block number is in the past (not future) +- No duplicate claim has been submitted for the same application and epoch -- Portals: These contracts are used to safely transfer assets from the base layer to the execution environment of your application. Currently, Portal contracts are available for the following types of assets: [Ether (ETH)](../portals/EtherPortal.md), [ERC-20 (Fungible tokens)](../portals/ERC20Portal.md), [ERC-721 (Non-fungible tokens)](../portals/ERC721Portal.md), [ERC-1155 single transfer](../portals/ERC1155SinglePortal.md), and [ERC-1155 batch token transfers](../portals/ERC1155BatchPortal.md). +Once a claim is accepted, the outputs Merkle root becomes valid and can be used to validate individual outputs in the application contract. diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/iquorum-factory.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/iquorum-factory.md new file mode 100644 index 00000000..b4c12d3d --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/iquorum-factory.md @@ -0,0 +1,96 @@ +--- +id: iquorum-factory +title: IQuorumFactory +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/quorum/IQuorumFactory.sol + title: IQuorumFactory Interface +--- + +The **IQuorumFactory** interface defines the contract for deploying new `IQuorum` contracts. + +## Events + +### `QuorumCreated` + +```solidity +event QuorumCreated(IQuorum quorum) +``` + +A new quorum was deployed. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `quorum` | `IQuorum` | The quorum | + +## Functions + +### `newQuorum()` + +```solidity +function newQuorum(address[] calldata validators, uint256 epochLength) external returns (IQuorum) +``` + +Deploy a new quorum. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `validators` | `address[]` | The list of validators | +| `epochLength` | `uint256` | The epoch length | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IQuorum` | The quorum | + +### `newQuorum()` (with salt) + +```solidity +function newQuorum(address[] calldata validators, uint256 epochLength, bytes32 salt) external returns (IQuorum) +``` + +Deploy a new quorum deterministically. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `validators` | `address[]` | The list of validators | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the quorum address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IQuorum` | The quorum | + +### `calculateQuorumAddress()` + +```solidity +function calculateQuorumAddress( + address[] calldata validators, + uint256 epochLength, + bytes32 salt +) external view returns (address) +``` + +Calculate the address of a quorum to be deployed deterministically. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `validators` | `address[]` | The list of validators | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the quorum address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `address` | The deterministic quorum address | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/iquorum.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/iquorum.md new file mode 100644 index 00000000..660e317e --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/iquorum.md @@ -0,0 +1,140 @@ +--- +id: iquorum +title: IQuorum +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/quorum/IQuorum.sol + title: IQuorum Interface +--- + +The `IQuorum` interface defines a consensus model controlled by a small, immutable set of validators. + +## Description + +A consensus model controlled by a small, immutable set of `n` validators. You can know the value of `n` by calling the `numOfValidators` function. Upon construction, each validator is assigned a unique number between 1 and `n`. These numbers are used internally instead of addresses for gas optimization reasons. You can list the validators in the quorum by calling the `validatorById` function for each ID from 1 to `n`. + +## Functions + +### `numOfValidators` +```solidity +function numOfValidators() external view returns (uint256) +``` + +Get the number of validators. + +**Returns:** +- (uint256): The total number of validators + +### `validatorId` +```solidity +function validatorId(address validator) external view returns (uint256) +``` + +Get the ID of a validator. + +**Parameters:** +- `validator` (address): The validator address + +**Returns:** +- (uint256): The validator ID + +**Note:** Validators have IDs greater than zero. Non-validators are assigned to ID zero. + +### `validatorById` +```solidity +function validatorById(uint256 id) external view returns (address) +``` + +Get the address of a validator by its ID. + +**Parameters:** +- `id` (uint256): The validator ID + +**Returns:** +- (address): The validator address + +**Note:** Validator IDs range from 1 to `N`, the total number of validators. Invalid IDs map to address zero. + +### `numOfValidatorsInFavorOfAnyClaimInEpoch` +```solidity +function numOfValidatorsInFavorOfAnyClaimInEpoch( + address appContract, + uint256 lastProcessedBlockNumber +) external view returns (uint256) +``` + +Get the number of validators in favor of any claim in a given epoch. + +**Parameters:** +- `appContract` (address): The application contract address +- `lastProcessedBlockNumber` (uint256): The number of the last processed block + +**Returns:** +- (uint256): Number of validators in favor of any claim in the epoch + +### `isValidatorInFavorOfAnyClaimInEpoch` +```solidity +function isValidatorInFavorOfAnyClaimInEpoch( + address appContract, + uint256 lastProcessedBlockNumber, + uint256 id +) external view returns (bool) +``` + +Check whether a validator is in favor of any claim in a given epoch. + +**Parameters:** +- `appContract` (address): The application contract address +- `lastProcessedBlockNumber` (uint256): The number of the last processed block +- `id` (uint256): The ID of the validator + +**Returns:** +- (bool): Whether validator is in favor of any claim in the epoch + +**Note:** Assumes the provided ID is valid. + +### `numOfValidatorsInFavorOf` +```solidity +function numOfValidatorsInFavorOf( + address appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot +) external view returns (uint256) +``` + +Get the number of validators in favor of a claim. + +**Parameters:** +- `appContract` (address): The application contract address +- `lastProcessedBlockNumber` (uint256): The number of the last processed block +- `outputsMerkleRoot` (bytes32): The outputs Merkle root + +**Returns:** +- (uint256): Number of validators in favor of claim + +### `isValidatorInFavorOf` +```solidity +function isValidatorInFavorOf( + address appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot, + uint256 id +) external view returns (bool) +``` + +Check whether a validator is in favor of a claim. + +**Parameters:** +- `appContract` (address): The application contract address +- `lastProcessedBlockNumber` (uint256): The number of the last processed block +- `outputsMerkleRoot` (bytes32): The outputs Merkle root +- `id` (uint256): The ID of the validator + +**Returns:** +- (bool): Whether validator is in favor of claim + +**Note:** Assumes the provided ID is valid. + +## Related Contracts + +- [`Quorum`](./quorum.md): Implementation of this interface +- [`IConsensus`](../iconsensus.md): Base consensus interface \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/quorum-factory.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/quorum-factory.md new file mode 100644 index 00000000..4f0d09e6 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/quorum-factory.md @@ -0,0 +1,80 @@ +--- +id: quorum-factory +title: QuorumFactory +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/quorum/QuorumFactory.sol + title: QuorumFactory Contract +--- + +The **QuorumFactory** contract allows anyone to reliably deploy new `IQuorum` contracts. + +## Functions + +### `newQuorum()` + +```solidity +function newQuorum(address[] calldata validators, uint256 epochLength) external override returns (IQuorum) +``` + +Deploy a new quorum contract. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `validators` | `address[]` | The list of validators | +| `epochLength` | `uint256` | The epoch length | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IQuorum` | The deployed quorum contract | + +### `newQuorum()` (with salt) + +```solidity +function newQuorum(address[] calldata validators, uint256 epochLength, bytes32 salt) external override returns (IQuorum) +``` + +Deploy a new quorum contract deterministically using CREATE2. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `validators` | `address[]` | The list of validators | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the quorum address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `IQuorum` | The deployed quorum contract | + +### `calculateQuorumAddress()` + +```solidity +function calculateQuorumAddress( + address[] calldata validators, + uint256 epochLength, + bytes32 salt +) external view override returns (address) +``` + +Calculate the address of a quorum to be deployed deterministically. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `validators` | `address[]` | The list of validators | +| `epochLength` | `uint256` | The epoch length | +| `salt` | `bytes32` | The salt used to deterministically generate the quorum address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `address` | The deterministic quorum address | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/quorum.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/quorum.md new file mode 100644 index 00000000..0842e4f0 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/consensus/quorum/quorum.md @@ -0,0 +1,209 @@ +--- +id: quorum +title: Quorum +resources: + - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/consensus/quorum/Quorum.sol + title: Quorum Contract +--- + +The **Quorum** contract implements a multi-validator consensus mechanism where claims are accepted when a majority of validators vote in favor. + +## Functions + +### `submitClaim()` + +```solidity +function submitClaim( + address appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot +) external override +``` + +Submit a claim to the consensus. Only validators can call this function. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | + +### `numOfValidators()` + +```solidity +function numOfValidators() external view override returns (uint256) +``` + +Get the number of validators. + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `uint256` | The total number of validators | + +### `validatorId()` + +```solidity +function validatorId(address validator) external view override returns (uint256) +``` + +Get the ID of a validator. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `validator` | `address` | The validator address | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `uint256` | The validator ID (0 for non-validators, >0 for validators) | + +### `validatorById()` + +```solidity +function validatorById(uint256 id) external view override returns (address) +``` + +Get the address of a validator by its ID. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `id` | `uint256` | The validator ID | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `address` | The validator address (address(0) for invalid IDs) | + +### `numOfValidatorsInFavorOfAnyClaimInEpoch()` + +```solidity +function numOfValidatorsInFavorOfAnyClaimInEpoch( + address appContract, + uint256 lastProcessedBlockNumber +) external view override returns (uint256) +``` + +Get the number of validators in favor of any claim in a given epoch. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `uint256` | Number of validators in favor of any claim in the epoch | + +### `isValidatorInFavorOfAnyClaimInEpoch()` + +```solidity +function isValidatorInFavorOfAnyClaimInEpoch( + address appContract, + uint256 lastProcessedBlockNumber, + uint256 id +) external view override returns (bool) +``` + +Check whether a validator is in favor of any claim in a given epoch. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `id` | `uint256` | The ID of the validator | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `bool` | Whether validator is in favor of any claim in the epoch | + +### `numOfValidatorsInFavorOf()` + +```solidity +function numOfValidatorsInFavorOf( + address appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot +) external view override returns (uint256) +``` + +Get the number of validators in favor of a claim. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `uint256` | Number of validators in favor of claim | + +### `isValidatorInFavorOf()` + +```solidity +function isValidatorInFavorOf( + address appContract, + uint256 lastProcessedBlockNumber, + bytes32 outputsMerkleRoot, + uint256 id +) external view override returns (bool) +``` + +Check whether a validator is in favor of a claim. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `appContract` | `address` | The application contract address | +| `lastProcessedBlockNumber` | `uint256` | The number of the last processed block | +| `outputsMerkleRoot` | `bytes32` | The outputs Merkle root | +| `id` | `uint256` | The ID of the validator | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `bool` | Whether validator is in favor of claim | + +### `supportsInterface()` + +```solidity +function supportsInterface(bytes4 interfaceId) public view override(IERC165, AbstractConsensus) returns (bool) +``` + +Check if the contract supports a specific interface. + +**Parameters** + +| Name | Type | Description | +|------|------|-------------| +| `interfaceId` | `bytes4` | The interface identifier | + +**Return Values** + +| Name | Type | Description | +|------|------|-------------| +| `[0]` | `bool` | True if the interface is supported | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/input-box.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/input-box.md index d5cd8e3f..db3db8c7 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/input-box.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/input-box.md @@ -2,132 +2,99 @@ id: input-box title: InputBox resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/inputs/InputBox.sol + - url: https://github.com/cartesi/rollups-contracts/tree/prerelease/2.0.0/contracts/inputs/InputBox.sol title: InputBox contract --- -The **InputBox** is a trustless and permissionless contract that receives arbitrary data blobs (called "inputs") from any sender and adds a compound hash to an append-only list (the "input box"). +The **InputBox** is a trustless and permissionless contract that receives arbitrary blobs (called "inputs") from anyone and adds a compound hash to an append-only list (called "input box"). -The hash stored on-chain comprises the hash of the input blob, block number, timestamp, input sender address, and input index. +The hash stored on-chain comprises the hash of the input blob, the block number and timestamp, the input sender address, and the input index. -Data availability is guaranteed through the emission of `InputAdded` events on every successful call to `addInput`. This ensures that inputs can be retrieved by anyone at any time without relying on centralized data providers. +Data availability is guaranteed by the emission of `InputAdded` events on every successful call to addInput. This ensures that inputs can be retrieved by anyone at any time without relying on centralized data providers. -From this contract's perspective, inputs are encoding-agnostic byte arrays. It is the application's responsibility to interpret, validate, and act upon these inputs. +From the perspective of this contract, inputs are encoding-agnostic byte arrays. It is up to the application to interpret, validate, and act upon inputs. -This contract inherits from `IInputBox`. -## State Variables - -### `_deploymentBlockNumber` -Deployment block number +## `InputAdded()` ```solidity -uint256 immutable _deploymentBlockNumber = block.number; +event InputAdded(address indexed appContract, uint256 indexed index, bytes input) ``` -### `_inputBoxes` -Mapping of application contract addresses to arrays of input hashes. +Emitted when an input is added to an application's input box. -```solidity -mapping(address => bytes32[]) private _inputBoxes; -``` +#### Parameters -## Functions +| Name | Type | Description | +|-------------|----------|----------------------------------| +| appContract | address | The application contract address | +| index | uint256 | The input index | +| input | bytes | The input blob | -### `addInput()` +## `addInput()` ```solidity function addInput(address appContract, bytes calldata payload) external override returns (bytes32) ``` -Send an input to an application. +Add an input to an application's input box. -*MUST fire an InputAdded event.* +_MUST fire an `InputAdded` event accordingly._ -**Parameters** +#### Parameters -| Name | Type | Description | -|------|------|-------------| -| `appContract` | `address` | The application contract address | -| `payload` | `bytes` | The input payload | +| Name | Type | Description | +|-------------|----------|----------------------------------| +| appContract | address | The application contract address | +| payload | bytes | The input payload | -**Return Values** +#### Return Values -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `bytes32` | The hash of the input blob | +| Name | Type | Description | +|--------|----------|------------------------------| +| [0] | bytes32 | The hash of the input blob | -### `getNumberOfInputs()` +## `getNumberOfInputs()` ```solidity -function getNumberOfInputs(address appContract) external view override returns (uint256) +function getNumberOfInputs(address appContract) external view returns (uint256) ``` -Get the number of inputs sent to an application. - -**Parameters** +Get the number of inputs in an application's input box. -| Name | Type | Description | -|------|------|-------------| -| `appContract` | `address` | The application contract address | +#### Parameters -**Return Values** +| Name | Type | Description | +|-------------|----------|----------------------------------| +| appContract | address | The application contract address | -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `uint256` | Number of inputs in the application input box | - -### `getInputHash()` - -```solidity -function getInputHash(address appContract, uint256 index) external view override returns (bytes32) -``` - -Get the hash of an input in an application's input box. -*The provided index must be valid.* +#### Return Values -**Parameters** +| Name | Type | Description | +| ---- | ------- | ---------------------------------------- | +| [0] | uint256 | Number of inputs in the application input box | -| Name | Type | Description | -|------|------|-------------| -| `appContract` | `address` | The application contract address | -| `index` | `uint256` | The input index | - -**Return Values** - -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `bytes32` | The hash of the input at the provided index in the application input box | - -### `getDeploymentBlockNumber()` +## `getInputHash()` ```solidity -function getDeploymentBlockNumber() external view override returns (uint256) +function getInputHash(address appContract, uint256 index) external view returns (bytes32) ``` -Get number of block in which contract was deployed. - -**Return Values** - -| Name | Type | Description | -|------|------|-------------| -| `[0]` | `uint256` | The deployment block number | - -## Events +Get the hash of an input in an application's input box. -### `InputAdded()` +`index` MUST be in the interval `[0,n)` where `n` is the number of +inputs in the application input box. See the `getNumberOfInputs` function._ -```solidity -event InputAdded(address indexed appContract, uint256 indexed index, bytes input) -``` +#### Parameters -Emitted when an input is added to an application's input box. +| Name | Type | Description | +|-------------|----------|----------------------------------| +| appContract | address | The application contract address | +| index | uint256 | The input index | -**Parameters** +#### Return Values -| Name | Type | Description | -|------|------|-------------| -| `appContract` | `address` | The application contract address | -| `index` | `uint256` | The input index | -| `input` | `bytes` | The input blob | \ No newline at end of file +| Name | Type | Description | +| ---- | ------- | ------------------------------------------------------------------- | +| [0] | bytes32 | The hash of the input at the provided index in the application input box | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/overview.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/overview.md index ce2566da..d2a72352 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/overview.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/overview.md @@ -2,30 +2,30 @@ id: overview title: Overview resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1 + - url: https://github.com/cartesi/rollups-contracts/tree/prerelease/2.0.0/contracts title: Smart Contracts for Cartesi Rollups --- -The Cartesi Rollups framework consists of components on two layers: the base layer (the foundational blockchain where an application contract is deployed, such as Ethereum) and the execution layer (the Cartesi off-chain layer where the application runs its backend logic). +The Cartesi Rollups framework consists of components on the base layer (the foundational blockchain where an application contract is deployed, such as Ethereum) and the execution layer (the Cartesi off-chain layer where the application runs its backend logic). The frontend interacts with base layer smart contracts to send inputs to the backend, deposit assets, and process outputs. To interact with an Ethereum-compatible blockchain, the application frontend must connect to a blockchain node using Ethereum's JSON-RPC API. -Clients can interact with Ethereum-compatible nodes using the JSON-RPC API in two ways: +There are two ways in which clients can interact with Ethereum-compatible nodes using the JSON-RPC API: -- **Querying state (read operations)** — The state can be queried by calling functions that neither alter the blockchain state nor incur gas fees. +- **Querying state (read operations)** — The state can be queried by calling functions that do not alter the blockchain state or incur gas fees. -- **Changing state (write operations)** — The state is changed by submitting a transaction that incurs gas fees. The transaction must be cryptographically signed by an Ethereum account with sufficient funds in its wallet. +- **Changing state (write operations)** — The state is changed by submitting a transaction, which incurs gas fees. The transaction must be cryptographically signed by an Ethereum account with funds in its wallet. ## Cartesi Rollups Smart Contracts -- [`InputBox`](../contracts/input-box.md): This contract receives inputs from users who want to interact with the off-chain layer. All inputs to your application are processed through this contract. +- [`InputBox`](../contracts/input-box.md): This contract receives inputs from users who want to interact with the off-chain layer. All inputs to your application go through this contract. -- [`Application`](../contracts/application.md): An `Application` contract is instantiated for each dApp (i.e., each dApp has its own application address). With this address, an application can hold ownership of digital assets on the base layer, such as Ether, ERC-20 tokens, and NFTs. +- [`Application`](../contracts/application.md): This `Application` contract is instantiated for each dApp (i.e., each dApp has its application address). With this address, an application can hold ownership over digital assets on the base layer, like Ether, ERC-20 tokens, and NFTs. -- [`ApplicationFactory`](../contracts/application-factory.md): The `ApplicationFactory` contract enables anyone to deploy [`Application`](../contracts/application.md) contracts with a simple function call. It provides greater convenience to the deployer and security to users and validators, as they can verify that the bytecode has not been maliciously altered. +- [`ApplicationFactory`](../contracts/application-factory.md): The `ApplicationFactory` contract allows anyone to deploy [`Application`](../contracts/application.md) contracts with a simple function call. It provides greater convenience to the deployer and security to users and validators, as they know the bytecode could not have been altered maliciously. -- Portals: These contracts are used to safely transfer assets from the base layer to the execution environment of your application. Currently, Portal contracts are available for the following types of assets: [Ether (ETH)](../contracts/portals/EtherPortal.md), [ERC-20 (Fungible tokens)](../contracts/portals/ERC20Portal.md), [ERC-721 (Non-fungible tokens)](../contracts/portals/ERC721Portal.md), [ERC-1155 single transfer](../contracts/portals/ERC1155SinglePortal.md), and [ERC-1155 batch token transfers](../contracts/portals/ERC1155BatchPortal.md). +- Portals: These are a set of contracts used to safely teleport assets from the base layer to the execution environment of your application. Currently, there are Portal contracts for the following types of assets: [Ether (ETH)](../contracts/portals/EtherPortal.md), [ERC-20 (Fungible tokens)](../contracts/portals/ERC20Portal.md), [ERC-721 (Non-fungible tokens)](../contracts/portals/ERC721Portal.md), [ERC-1155 single transfer](../contracts/portals/ERC1155SinglePortal.md) and [ERC-1155 batch token transfers](../contracts/portals/ERC1155BatchPortal.md). diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155BatchPortal.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155BatchPortal.md index 6426db55..e91d657d 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155BatchPortal.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155BatchPortal.md @@ -1,6 +1,6 @@ --- resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/portals/ERC1155BatchPortal.sol + - url: https://github.com/cartesi/rollups-contracts/blob/v1.4.0/onchain/rollups/contracts/portals/ERC1155BatchPortal.sol title: ERC1155BatchPortal contract --- diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155SinglePortal.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155SinglePortal.md index 95dda15a..ad41581a 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155SinglePortal.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC1155SinglePortal.md @@ -1,6 +1,6 @@ --- resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/portals/ERC1155SinglePortal.sol + - url: https://github.com/cartesi/rollups-contracts/blob/v1.4.0/onchain/rollups/contracts/portals/ERC1155SinglePortal.sol title: ERC1155SinglePortal contract --- diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC20Portal.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC20Portal.md index df75ab82..ded704b1 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC20Portal.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC20Portal.md @@ -1,6 +1,6 @@ --- resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/portals/ERC20Portal.sol + - url: https://github.com/cartesi/rollups-contracts/blob/v1.4.0/onchain/rollups/contracts/portals/ERC20Portal.sol title: ERC20Portal contract --- diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC721Portal.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC721Portal.md index abf53dcb..443f7cd5 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC721Portal.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/ERC721Portal.md @@ -1,6 +1,6 @@ --- resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/portals/ERC721Portal.sol + - url: https://github.com/cartesi/rollups-contracts/blob/v1.4.0/onchain/rollups/contracts/portals/ERC721Portal.sol title: ERC721Portal contract --- diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/EtherPortal.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/EtherPortal.md index 73b58ebf..a39cb8c4 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/EtherPortal.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/contracts/portals/EtherPortal.md @@ -1,6 +1,6 @@ --- resources: - - url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/contracts/portals/EtherPortal.sol + - url: https://github.com/cartesi/rollups-contracts/blob/v1.2.0/onchain/rollups/contracts/portals/EtherPortal.sol title: EtherPortal contract --- diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/inputs/_category_.yml b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/inputs/_category_.yml new file mode 100644 index 00000000..9faf3ac0 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/inputs/_category_.yml @@ -0,0 +1,2 @@ +label: Inputs +link: null diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/inputs/input-filter.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/inputs/input-filter.md new file mode 100644 index 00000000..8193e1c0 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/inputs/input-filter.md @@ -0,0 +1,25 @@ +--- +id: input-filter +title: InputFilter +hide_table_of_contents: false +--- + + +Filter object to restrict results depending on input properties + +```graphql +input InputFilter { + indexLowerThan: Int + indexGreaterThan: Int +} +``` + + +## Fields + +| Name | Type | Description | +| ---- |------| ------| +| `indexLowerThan` | [`Int`](../../scalars/int) | Filter only inputs with index lower than a given value | +| `indexGreaterThan` | [`Int`](../../scalars/int) | Filter only inputs with index greater than a given value | + + diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-connection.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-connection.md index cabf1f83..f0920851 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-connection.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-connection.md @@ -4,15 +4,12 @@ title: InputConnection hide_table_of_contents: false --- -Represents a paginated list of inputs. + +Represents a paginated connection of Inputs. ```graphql type InputConnection { - "Total number of entries that match the query" - totalCount: Int! - "List of edges in the connection" edges: [InputEdge!]! - "Information about the current page" pageInfo: PageInfo! } ``` @@ -20,33 +17,10 @@ type InputConnection { ## Fields | Name | Type | Description | -| ---- |------| ----------- | -| `totalCount` | [`Int!`](../../scalars/int) | Total number of entries that match the query. | -| `edges` | [`[InputEdge!]!`](../../objects/input-edge) | List of edges in the connection. | -| `pageInfo` | [`PageInfo!`](../../objects/page-info) | Information about the current page. | +| ---- |------| ------| +| `edges`| [`InputEdge`](../../objects/input-edge) | A list of `InputEdge` objects. Each edge contains an `Input` object and a cursor for pagination. | +| `pageInfo`| [`PageInfo`](../../objects/page-info) | Metadata about the pagination. | + + -## Example Query -```graphql -query { - inputs(first: 10) { - totalCount - edges { - node { - id - index - status - msgSender - payload - } - cursor - } - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-edge.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-edge.md index 2f500b71..c757528a 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-edge.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input-edge.md @@ -4,39 +4,24 @@ title: InputEdge hide_table_of_contents: false --- -Represents a single input in a paginated list. + +Pagination entry. ```graphql type InputEdge { - "The input at this edge" node: Input! - "A cursor for use in pagination" cursor: String! } ``` + ## Fields | Name | Type | Description | -| ---- |------| ----------- | -| `node` | [`Input!`](../../objects/input) | The input at this edge. | -| `cursor` | [`String!`](../../scalars/string) | A cursor for use in pagination. | +| ---- | ---- | ----------- | +| `node` | [`Input!`](../../objects/input) | The Input object. | +| `cursor` | [`String!`](../../scalars/string) | A string that serves as a pagination cursor for this particular edge. | + + -## Example Query -```graphql -query { - inputs(first: 10) { - edges { - node { - id - index - status - msgSender - payload - } - cursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input.md index a04ba1cf..49e0ac9b 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/input.md @@ -4,119 +4,36 @@ title: Input hide_table_of_contents: false --- -Request submitted to the application to advance its state. + +Request submitted to the application to advance its state ```graphql type Input { - "id of the input" - id: String! - "Input index starting from genesis" index: Int! - "Status of the input" status: CompletionStatus! - "Address responsible for submitting the input" + timestamp: DateTime! msgSender: String! - "Timestamp associated with the input submission, as defined by the base layer's block in which it was recorded" - timestamp: BigInt! @deprecated(reason: "Use `blockTimestamp` instead") - "Number of the base layer block in which the input was recorded" - blockNumber: BigInt! - "Input payload in Ethereum hex binary format, starting with '0x'" + blockNumber: Int! payload: String! - "Get vouchers from this particular input with support for pagination" - vouchers(first: Int, last: Int, after: String, before: String): VoucherConnection! - "Get DELEGATECALL vouchers from this particular input with support for pagination" - delegateCallVouchers(first: Int, last: Int, after: String, before: String): DelegateCallVoucherConnection! - "Get notices from this particular input with support for pagination" - notices(first: Int, last: Int, after: String, before: String): NoticeConnection! - "Get reports from this particular input with support for pagination" - reports(first: Int, last: Int, after: String, before: String): ReportConnection! - "Timestamp associated with the Espresso input submission" - espressoTimestamp: String @deprecated(reason: "Will be removed") - "Number of the Espresso block in which the input was recorded" - espressoBlockNumber: String @deprecated(reason: "Will be removed") - "Input index in the Input Box" - inputBoxIndex: String - "Block timestamp" - blockTimestamp: BigInt - "Previous RANDAO value" - prevRandao: String - "The application that produced the input" - application: Application! + notices: NoticeConnection! + vouchers: VoucherConnection! + reports: ReportConnection! } ``` -## Fields +### Fields | Name | Type | Description | -| ---- |------| ----------- | -| `id` | [`String!`](../../scalars/string) | ID of the input. | -| `index` | [`Int!`](../../scalars/int) | Input index starting from genesis. | -| `status` | [`CompletionStatus!`](../../enums/completion-status) | Status of the input. | -| `msgSender` | [`String!`](../../scalars/string) | Address responsible for submitting the input. | -| `timestamp` | [`BigInt!`](../../scalars/bigint) | Timestamp associated with the input submission, as defined by the base layer's block in which it was recorded. | -| `blockNumber` | [`BigInt!`](../../scalars/bigint) | Number of the base layer block in which the input was recorded. | -| `payload` | [`String!`](../../scalars/string) | Input payload in Ethereum hex binary format, starting with '0x'. | -| `vouchers` | [`VoucherConnection!`](../../objects/voucher-connection) | Get vouchers from this particular input with support for pagination. | -| `delegateCallVouchers` | [`DelegateCallVoucherConnection!`](../../objects/delegate-call-voucher-connection) | Get DELEGATECALL vouchers from this particular input with support for pagination. | -| `notices` | [`NoticeConnection!`](../../objects/notice-connection) | Get notices from this particular input with support for pagination. | -| `reports` | [`ReportConnection!`](../../objects/report-connection) | Get reports from this particular input with support for pagination. | -| `espressoTimestamp` | [`String`](../../scalars/string) | Timestamp associated with the Espresso input submission. | -| `espressoBlockNumber` | [`String`](../../scalars/string) | Number of the Espresso block in which the input was recorded. | -| `inputBoxIndex` | [`String`](../../scalars/string) | Input index in the Input Box. | -| `blockTimestamp` | [`BigInt`](../../scalars/bigint) | Block timestamp. | -| `prevRandao` | [`String`](../../scalars/string) | Previous RANDAO value. | -| `application` | [`Application!`](../../objects/application) | The application that produced the input. | +| ---- | ---- | ----------- | +| `index` | [`Int!`](../../scalars/int) | Unique identifier for the input. | +| `status` | [`CompletionStatus!`](../../objects/completion-status) | Current status of the input processing. | +| `timestamp` | [`DateTime!`](../../scalars/date-time) | Timestamp associated with the input submission. | +| `msgSender` | [`String!`](../../scalars/string) | Address of the account that submitted the input. | +| `blockNumber` | [`Int!`](../../scalars/int) | Number of the base layer block in which the input was recorded. | +| `payload` | [`String!`](../../scalars/string) | The actual data/content of the input. | +| `notices` | [`NoticeConnection!`](../../objects/notice-connection) | List of notices associated with this input. | +| `vouchers` | [`VoucherConnection!`](../../objects/voucher-connection) | List of vouchers associated with this input. | +| `reports` | [`ReportConnection!`](../../objects/report-connection) | List of reports associated with this input. | + -## Example Query -```graphql -query { - input(outputIndex: 1) { - id - index - status - msgSender - timestamp - blockNumber - payload - vouchers(first: 10) { - edges { - node { - index - destination - payload - } - } - } - delegateCallVouchers(first: 10) { - edges { - node { - index - destination - payload - } - } - } - notices(first: 10) { - edges { - node { - index - payload - } - } - } - reports(first: 10) { - edges { - node { - index - payload - } - } - } - application { - address - name - } - } -} -``` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-connection.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-connection.md index 4e6117cd..7bdf6b88 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-connection.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-connection.md @@ -4,15 +4,12 @@ title: NoticeConnection hide_table_of_contents: false --- -Represents a paginated list of notices. + +Represents a paginated connection of Notices. ```graphql type NoticeConnection { - "Total number of entries that match the query" - totalCount: Int! - "List of edges in the connection" edges: [NoticeEdge!]! - "Information about the current page" pageInfo: PageInfo! } ``` @@ -20,34 +17,11 @@ type NoticeConnection { ## Fields | Name | Type | Description | -| ---- |------| ----------- | -| `totalCount` | [`Int!`](../../scalars/int) | Total number of entries that match the query. | -| `edges` | [`[NoticeEdge!]!`](../../objects/notice-edge) | List of edges in the connection. | -| `pageInfo` | [`PageInfo!`](../../objects/page-info) | Information about the current page. | +| ---- |------| ------| +| `edges`| [`NoticeEdge`](../../objects/notice-edge) | A list of `Notice` objects. Each edge contains a `Notice` object and a cursor for pagination. | +| `pageInfo`| [`PageInfo`](../../objects/page-info) | Metadata about the pagination. | + + + -## Example Query -```graphql -query { - notices(first: 10) { - totalCount - edges { - node { - index - payload - proof { - outputIndex - outputHashesSiblings - } - } - cursor - } - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-edge.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-edge.md index 63188fb6..09af6d6a 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-edge.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice-edge.md @@ -4,13 +4,12 @@ title: NoticeEdge hide_table_of_contents: false --- -Represents a single notice in a paginated list. + +Pagination entry ```graphql type NoticeEdge { - "The notice at this edge" node: Notice! - "A cursor for use in pagination" cursor: String! } ``` @@ -18,26 +17,11 @@ type NoticeEdge { ## Fields | Name | Type | Description | -| ---- |------| ----------- | -| `node` | [`Notice!`](../../objects/notice) | The notice at this edge. | -| `cursor` | [`String!`](../../scalars/string) | A cursor for use in pagination. | +| ---- | ---- | ----------- | +| `node` | [`Notice!`](../../objects/notice) | The Notice object. | +| `cursor` | [`String!`](../../scalars/string) | A string that serves as a pagination cursor for this particular edge. | + + + -## Example Query -```graphql -query { - notices(first: 10) { - edges { - node { - index - payload - proof { - outputIndex - outputHashesSiblings - } - } - cursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice.md index 165b9566..1bc7bf07 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/notice.md @@ -4,51 +4,30 @@ title: Notice hide_table_of_contents: false --- + Informational statement that can be validated in the base layer blockchain. ```graphql type Notice { - "Notice index within the context of the input that produced it" index: Int! - "Input whose processing produced the notice" input: Input! - "Notice data as a payload in Ethereum hex binary format, starting with '0x'" payload: String! - "Proof object that allows this notice to be validated by the base layer blockchain" proof: Proof - "The application that produced the notice" - application: Application! } ``` + ## Fields | Name | Type | Description | | ---- |------| ----------- | -| `index` | [`Int!`](../../scalars/int) | Notice index within the context of the input that produced it. | -| `input` | [`Input!`](../../objects/input) | Input whose processing produced the notice. | -| `payload` | [`String!`](../../scalars/string) | Notice data as a payload in Ethereum hex binary format, starting with '0x'. | -| `proof` | [`Proof`](../../objects/proof) | Proof object that allows this notice to be validated by the base layer blockchain. | -| `application` | [`Application!`](../../objects/application) | The application that produced the notice. | +| `index`| [`Int!`](../../scalars/int) | Unique identifier for the notice. | +| `input`| [`Input!`](../../objects/input) | The input associated with this notice. | +| `payload`| [`String!`](../../scalars/string) |The actual data/content of the notice. | +| `proof`| [`Proof`](../../objects/proof) | Proof of the notice's validity (if available). | + + + + -## Example Query -```graphql -query { - notice(outputIndex: 1) { - index - input { - index - } - payload - proof { - outputIndex - outputHashesSiblings - } - application { - address - name - } - } -} -``` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/proof.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/proof.md index 57f3f671..2f96f7dd 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/proof.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/proof.md @@ -4,33 +4,24 @@ title: Proof hide_table_of_contents: false --- -Data that can be used as proof to validate notices and execute vouchers on the base layer blockchain. +Represents the proof of validity for a notice or voucher. ```graphql type Proof { - "Index of the output in the output box" - outputIndex: BigInt! - "Array of sibling hashes in the output box merkle tree" - outputHashesSiblings: [String]! + validity: OutputValidityProof! + context: String! } ``` + ## Fields | Name | Type | Description | | ---- |------| ----------- | -| `outputIndex` | [`BigInt!`](../../scalars/bigint) | Index of the output in the output box. | -| `outputHashesSiblings` | [`[String]!`](../../scalars/string) | Array of sibling hashes in the output box merkle tree. | +| `validity`| [`OutputValidityProof!`](../../objects/output-validity-proof) | Validity proof for an output. | +| `context`| [`String!`](../../scalars/string) | Data that allows the validity proof to be contextualized within submitted claims, given as a payload in Ethereum hex binary format, starting with '0x'. | + + + -## Example Query -```graphql -query { - voucher(outputIndex: 1) { - proof { - outputIndex - outputHashesSiblings - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-connection.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-connection.md index c7c90c0c..a79b44fc 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-connection.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-connection.md @@ -4,46 +4,26 @@ title: ReportConnection hide_table_of_contents: false --- -Represents a paginated list of reports. + +Represents a paginated connection of Reports. ```graphql type ReportConnection { - "Total number of entries that match the query" - totalCount: Int! - "List of edges in the connection" edges: [ReportEdge!]! - "Information about the current page" pageInfo: PageInfo! } ``` + ## Fields | Name | Type | Description | -| ---- |------| ----------- | -| `totalCount` | [`Int!`](../../scalars/int) | Total number of entries that match the query. | -| `edges` | [`[ReportEdge!]!`](../../objects/report-edge) | List of edges in the connection. | -| `pageInfo` | [`PageInfo!`](../../objects/page-info) | Information about the current page. | +| ---- |------| ------| +| `edges`| [`ReportEdge`](../../objects/report-edge) | A list of `ReportEdge` objects. Each edge contains an `Input` object and a cursor for pagination. | +| `pageInfo`| [`PageInfo`](../../objects/page-info) | Metadata about the pagination. | + + + + -## Example Query -```graphql -query { - reports(first: 10) { - totalCount - edges { - node { - index - payload - } - cursor - } - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-edge.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-edge.md index 91959d2f..a6fba549 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-edge.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report-edge.md @@ -4,36 +4,26 @@ title: ReportEdge hide_table_of_contents: false --- -Represents a single report in a paginated list. + +Pagination entry ```graphql type ReportEdge { - "The report at this edge" node: Report! - "A cursor for use in pagination" cursor: String! } ``` -## Fields + +### Fields + | Name | Type | Description | -| ---- |------| ----------- | -| `node` | [`Report!`](../../objects/report) | The report at this edge. | -| `cursor` | [`String!`](../../scalars/string) | A cursor for use in pagination. | +| ---- | ---- | ----------- | +| `node` | [`Report!`](../../objects/report) | The Report object. | +| `cursor` | [`String!`](../../scalars/string) | A string that serves as a pagination cursor for this particular edge. | + + + -## Example Query -```graphql -query { - reports(first: 10) { - edges { - node { - index - payload - } - cursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report.md index 8d8fd8f5..ba904c27 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/report.md @@ -4,44 +4,28 @@ title: Report hide_table_of_contents: false --- -Application log or diagnostic information. + +Represents application log or diagnostic information. ```graphql type Report { - "Report index within the context of the input that produced it" index: Int! - "Input whose processing produced the report" input: Input! - "Report data as a payload in Ethereum hex binary format, starting with '0x'" payload: String! - "The application that produced the report" - application: Application! } ``` + ## Fields | Name | Type | Description | | ---- |------| ----------- | -| `index` | [`Int!`](../../scalars/int) | Report index within the context of the input that produced it. | -| `input` | [`Input!`](../../objects/input) | Input whose processing produced the report. | -| `payload` | [`String!`](../../scalars/string) | Report data as a payload in Ethereum hex binary format, starting with '0x'. | -| `application` | [`Application!`](../../objects/application) | The application that produced the report. | +| `index`| [`Int!`](../../scalars/int) | Unique identifier for the report. | +| `input`| [`Input!`](../../objects/input) | The input associated with this report. | +| `payload`| [`String!`](../../scalars/string) | The actual data/content of the report. | + + + + -## Example Query -```graphql -query { - report(reportIndex: 1) { - index - input { - index - } - payload - application { - address - name - } - } -} -``` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-connection.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-connection.md index 1f7eaec2..02c05225 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-connection.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-connection.md @@ -4,50 +4,26 @@ title: VoucherConnection hide_table_of_contents: false --- -Represents a paginated list of vouchers. + +Represents a paginated connection of Vouchers. ```graphql type VoucherConnection { - "Total number of entries that match the query" - totalCount: Int! - "List of edges in the connection" edges: [VoucherEdge!]! - "Information about the current page" pageInfo: PageInfo! } ``` + ## Fields | Name | Type | Description | -| ---- |------| ----------- | -| `totalCount` | [`Int!`](../../scalars/int) | Total number of entries that match the query. | -| `edges` | [`[VoucherEdge!]!`](../../objects/voucher-edge) | List of edges in the connection. | -| `pageInfo` | [`PageInfo!`](../../objects/page-info) | Information about the current page. | +| ---- | ---- | ----------- | +| `edges` | [`[VoucherEdge!]!`](../../objects/voucher-edge) | A list of `VoucherEdge` objects. Each edge contains a `Voucher` object and a cursor for pagination. | +| `pageInfo` | [`PageInfo!`](../../objects/page-info) | Pagination metadata. | + + + + -## Example Query -```graphql -query { - vouchers(first: 10) { - totalCount - edges { - node { - index - destination - payload - value - executed - transactionHash - } - cursor - } - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-edge.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-edge.md index 0e5a8e8a..99d42d30 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-edge.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher-edge.md @@ -4,40 +4,26 @@ title: VoucherEdge hide_table_of_contents: false --- -Represents a single voucher in a paginated list. + +Pagination entry. ```graphql type VoucherEdge { - "The voucher at this edge" node: Voucher! - "A cursor for use in pagination" cursor: String! } ``` + ## Fields | Name | Type | Description | -| ---- |------| ----------- | -| `node` | [`Voucher!`](../../objects/voucher) | The voucher at this edge. | -| `cursor` | [`String!`](../../scalars/string) | A cursor for use in pagination. | +| ---- | ---- | ----------- | +| `node` | [`Voucher!`](../../objects/voucher) | The `Voucher` object. | +| `cursor` | [`String!`](../../scalars/string) | A string that serves as a pagination cursor for this particular edge. | + + + + -## Example Query -```graphql -query { - vouchers(first: 10) { - edges { - node { - index - destination - payload - value - executed - transactionHash - } - cursor - } - } -} -``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher.md index b2959d38..6713e671 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/objects/voucher.md @@ -4,67 +4,30 @@ title: Voucher hide_table_of_contents: false --- + Representation of a transaction that can be carried out on the base layer blockchain, such as a transfer of assets. ```graphql type Voucher { - "Voucher index within the context of the input that produced it" index: Int! - "Input whose processing produced the voucher" input: Input! - "Transaction destination address in Ethereum hex binary format (20 bytes), starting with '0x'" destination: String! - "Transaction payload in Ethereum hex binary format, starting with '0x'" payload: String! - "Proof object that allows this voucher to be validated and executed on the base layer blockchain" proof: Proof - "Value to be sent with the transaction" - value: BigInt - "Indicates whether the voucher has been executed on the base layer blockchain" - executed: Boolean - "The hash of executed transaction" - transactionHash: String - "The application that produced the voucher" - application: Application! } ``` + ## Fields | Name | Type | Description | | ---- |------| ----------- | -| `index` | [`Int!`](../../scalars/int) | Voucher index within the context of the input that produced it. | -| `input` | [`Input!`](../../objects/input) | Input whose processing produced the voucher. | -| `destination` | [`String!`](../../scalars/string) | Transaction destination address in Ethereum hex binary format (20 bytes), starting with '0x'. | -| `payload` | [`String!`](../../scalars/string) | Transaction payload in Ethereum hex binary format, starting with '0x'. | -| `proof` | [`Proof`](../../objects/proof) | Proof object that allows this voucher to be validated and executed on the base layer blockchain. | -| `value` | [`BigInt`](../../scalars/bigint) | Value to be sent with the transaction. | -| `executed` | [`Boolean`](../../scalars/boolean) | Indicates whether the voucher has been executed on the base layer blockchain. | -| `transactionHash` | [`String`](../../scalars/string) | The hash of executed transaction. | -| `application` | [`Application!`](../../objects/application) | The application that produced the voucher. | +| `index`| [`Int!`](../../scalars/int) | Unique identifier for the voucher. | +| `input`| [`Input!`](../../objects/input) | The input associated with this voucher. | +| `destination`| [`String!`](../../scalars/string) | The address or identifier of the voucher's destination. | +| `payload`| [`String!`](../../scalars/string) | The actual data/content of the voucher. | +| `proof`| [`Proof`](../../objects/proof) | Proof object that allows this voucher to be validated and executed on the base layer blockchain(if available). | + + -## Example Query -```graphql -query { - voucher(address: "0x123...") { - index - input { - index - } - destination - payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } - } -} -``` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/notices.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/notices.md index abc5c2c8..92c5749a 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/notices.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/notices.md @@ -11,32 +11,28 @@ Notices are informational statements that can be validated in the base layer blo Retrieve a specific notice based on its index and associated input index. ```graphql -query notice($outputIndex: Int!) { - notice(outputIndex: $outputIndex) { +query notice($noticeIndex: Int!, $inputIndex: Int!) { + notice(noticeIndex: $noticeIndex, inputIndex: $inputIndex) { index input { - id index - status + timestamp msgSender - blockTimestamp blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } } payload proof { - outputIndex - outputHashesSiblings - } - application { - address - name + validity { + inputIndexWithinEpoch + outputIndexWithinInput + outputHashesRootHash + vouchersEpochRootHash + noticesEpochRootHash + machineStateHash + outputHashInOutputHashesSiblings + outputHashesInEpochSiblings + } + context } } } @@ -46,9 +42,10 @@ For notices, the API provides access to proof data that can be used for validati ### Arguments -| Name | Type | Description | -| ------------ | --------------------------- | ---------------------------------------------- | -| `outputIndex` | [`Int!`](../../scalars/int) | Index of the notice to retrieve. | +| Name | Type | Description | +| ------------- | --------------------------- | ---------------------------------------------- | +| `noticeIndex` | [`Int!`](../../scalars/int) | Index of the notice to retrieve. | +| `inputIndex` | [`Int!`](../../scalars/int) | Index of the input associated with the notice. | ### Response Type @@ -65,35 +62,13 @@ query notices { node { index input { - id index - status + timestamp msgSender - blockTimestamp blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } } payload - proof { - outputIndex - outputHashesSiblings - } - application { - address - name - } } - cursor - } - pageInfo { - hasNextPage - endCursor } } } @@ -118,21 +93,14 @@ query noticesByInput($inputIndex: Int!) { edges { node { index - payload - proof { - outputIndex - outputHashesSiblings - } - application { - address - name + input { + index + timestamp + msgSender + blockNumber } + payload } - cursor - } - pageInfo { - hasNextPage - endCursor } } } @@ -156,31 +124,15 @@ query noticesByInput($inputIndex: Int!) { ```graphql query { - notice(outputIndex: 1) { + notice(noticeIndex: 3, inputIndex: 2) { index - input { - id - index - status - msgSender - blockTimestamp - blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } - } payload proof { - outputIndex - outputHashesSiblings - } - application { - address - name + validity { + inputIndexWithinEpoch + outputIndexWithinInput + } + context } } } @@ -195,29 +147,10 @@ query { node { index input { - id index - status - msgSender - blockTimestamp - blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } + timestamp } payload - proof { - outputIndex - outputHashesSiblings - } - application { - address - name - } } cursor } @@ -239,14 +172,6 @@ query { node { index payload - proof { - outputIndex - outputHashesSiblings - } - application { - address - name - } } cursor } @@ -258,80 +183,3 @@ query { } } ``` - -4. Listing notices with proof data and application information: - -```graphql -query { - notices(first: 10) { - edges { - node { - index - input { - id - index - status - msgSender - blockTimestamp - blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } - } - payload - proof { - outputIndex - outputHashesSiblings - } - application { - address - name - } - } - cursor - } - pageInfo { - hasNextPage - endCursor - } - } -} -``` - -5. Fetching a specific notice by output index: - -```graphql -query { - notice(outputIndex: 1) { - index - input { - id - index - status - msgSender - blockTimestamp - blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } - } - payload - proof { - outputIndex - outputHashesSiblings - } - application { - address - name - } - } -} -``` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/vouchers.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/vouchers.md index c5bbf344..9e4e2560 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/vouchers.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/graphql/queries/vouchers.md @@ -12,36 +12,29 @@ Vouchers represent transactions that can be carried out on the base layer blockc Retrieve a specific voucher based on its index and associated input index. ```graphql -query voucher($outputIndex: Int!) { - voucher(outputIndex: $outputIndex) { +query voucher($voucherIndex: Int!, $inputIndex: Int!) { + voucher(voucherIndex: $voucherIndex, inputIndex: $inputIndex) { index input { - id index - status + timestamp msgSender - blockTimestamp blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } } destination payload proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name + validity { + inputIndexWithinEpoch + outputIndexWithinInput + outputHashesRootHash + vouchersEpochRootHash + noticesEpochRootHash + machineStateHash + outputHashInOutputHashesSiblings + outputHashesInEpochSiblings + } + context } } } @@ -52,7 +45,8 @@ For vouchers, the API provides access to proof data that can be used for validat | Name | Type | Description | | ---- | ---- | ----------- | -| `outputIndex` | [`Int!`](../../scalars/int) | The index of the voucher to retrieve. | +| `voucherIndex` | [`Int!`](../../scalars/int) | The index of the voucher to retrieve. | +| `inputIndex` | [`Int!`](../../scalars/int) | The index of the associated input. | @@ -72,33 +66,13 @@ query vouchers($first: Int, $after: String) { node { index input { - id index - status + timestamp msgSender - blockTimestamp blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } } destination payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } } cursor } @@ -136,17 +110,6 @@ query vouchersByInput($inputIndex: Int!, $first: Int, $after: String) { index destination payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } } cursor } @@ -178,39 +141,20 @@ query vouchersByInput($inputIndex: Int!, $first: Int, $after: String) { 1. Fetching a specific voucher: ```graphql - query { - voucher(outputIndex: 1) { - index - input { - id + query { + voucher(voucherIndex: 3, inputIndex: 2) { index - status - msgSender - blockTimestamp - blockNumber + destination payload - inputBoxIndex - prevRandao - application { - address - name + proof { + validity { + inputIndexWithinEpoch + outputIndexWithinInput + } + context } } - destination - payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } } - } ``` 2. Listing earlier(first 5) vouchers: @@ -222,33 +166,11 @@ query vouchersByInput($inputIndex: Int!, $first: Int, $after: String) { node { index input { - id index - status - msgSender - blockTimestamp - blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } + timestamp } destination payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } } cursor } @@ -271,17 +193,6 @@ query vouchersByInput($inputIndex: Int!, $first: Int, $after: String) { index destination payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } } cursor } @@ -292,88 +203,4 @@ query vouchersByInput($inputIndex: Int!, $first: Int, $after: String) { } } } - ``` - -4. Listing all vouchers with proof data: - - ```graphql - query { - vouchers(first: 10) { - edges { - node { - index - input { - id - index - status - msgSender - blockTimestamp - blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } - } - destination - payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } - } - } - pageInfo { - hasNextPage - endCursor - } - } - } - ``` - -5. Fetching a specific voucher by output index: - - ```graphql - query { - voucher(outputIndex: 1) { - index - input { - id - index - status - msgSender - blockTimestamp - blockNumber - payload - inputBoxIndex - prevRandao - application { - address - name - } - } - destination - payload - proof { - outputIndex - outputHashesSiblings - } - value - executed - transactionHash - application { - address - name - } - } - } ``` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/index.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/index.md index 21839187..66c72559 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/index.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/index.md @@ -12,7 +12,7 @@ resources: In a Cartesi dApp, the frontend and backend components communicate through the Rollups framework using HTTP and GraphQL APIs. -When designing the APIs for this communication framework, we aimed to ensure that developers could create their applications without excessive concern about the low-level components of Cartesi Rollups. +When designing the APIs for this communication with the framework, we wanted to ensure developers could create their applications without worrying too much about the low-level components of Cartesi Rollups. ## Backend APIs @@ -20,29 +20,30 @@ In a typical Cartesi dApp, the backend contains the application's state and veri The dApp's backend interacts with the Cartesi Rollups framework by retrieving processing requests and submitting corresponding outputs. -This interaction occurs through a set of HTTP endpoints, as illustrated in the figure below: +This is accomplished by calling a set of HTTP endpoints, as illustrated by the figure below: ![img](../../../static/img/v1.3/backend.jpg) -You can send two types of requests to an application depending on whether you want to change or read the state: +You can send two requests to an application depending on whether you want to change or read the state. -- **Advance**: With this request, input data changes the state of the dApp. +- **Advance**: In this request, any input data changes the state of the dApp. + +- **Inspect**: This involves making an external HTTP API call to the Cartesi Node to read the dApp state without changing it. -- **Inspect**: This involves making an external HTTP API call to the Cartesi Node to read the dApp state without modifying it. ## Base Layer Contracts The frontend component of the dApp needs to access the Cartesi Rollups framework to submit user requests and retrieve the corresponding outputs produced by the backend. -The figure below illustrates the main use cases for these interactions: +The figure below details some of the main use cases for these interactions: ![img](../../../static/img/v1.3/frontend.jpg) -- [`addInput()`](./contracts/input-box/#addinput) — This function submits input data to the InputBox smart contract on the base layer as a regular JSON-RPC blockchain transaction. When the transaction is mined and executed, it emits an event containing the submitted input's index, which the frontend can later use to query associated outputs. +- [`addInput()`](./contracts/input-box/#addinput) — This function submits input data to the InputBox smart contract on the base layer as a regular JSON-RPC blockchain transaction. When that transaction is mined and executed, an event containing the submitted input’s index is emitted, which the frontend can later use to query associated outputs. -- [`executeOutput()`](./contracts/application/#executeoutput) — Submits a JSON-RPC blockchain transaction to request the execution of a given voucher or notice by the [`Application`](./contracts/application.md) smart contract on the base layer. Vouchers can only be executed when an epoch is closed. +- [`executeOutput()`](./contracts/application/#executeoutput) — Submits a JSON-RPC blockchain transaction to request that a given voucher or notice be executed by the [`Application`](./contracts/application.md) smart contract on the base layer. Vouchers can only be executed when an epoch is closed. -- Query outputs — You can submit a query to a Cartesi node to retrieve vouchers, notices, and reports as specified by the Cartesi Rollups GraphQL schema. +- Query outputs — You can submit a query to a Cartesi node to retrieve vouchers, notices, and reports, as specified by the Cartesi Rollups GraphQL schema. - Inspect state — You can make an HTTP call to the Cartesi node to retrieve arbitrary dApp-specific application state. diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/get.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/get.md index 02eff86f..daff9086 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/get.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/get.md @@ -33,7 +33,7 @@ The `cartesi_getApplication` method retrieves detailed information about a speci "jsonrpc": "2.0", "result": { "data": { - "name": "calculator", + "name": "calculator", "iapplication_address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F", "iconsensus_address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F", "iinputbox_address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F", @@ -46,9 +46,9 @@ The `cartesi_getApplication` method retrieves detailed information about a speci "last_input_check_block": "0x1", "last_output_check_block": "0x1", "processed_inputs": "0x1", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "execution_parameters": { + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "execution_parameters": { "snapshot_policy": "NONE", "advance_inc_cycles": "0x1000", "advance_max_cycles": "0x10000", @@ -118,4 +118,4 @@ The `cartesi_getApplication` method retrieves detailed information about a speci |---------|------------------------|--------------------------------------------------| | -32602 | Invalid params | Invalid parameter values | | -32000 | Application not found | The specified application does not exist | -| -32603 | Internal error | An internal error occurred | \ No newline at end of file +| -32603 | Internal error | An internal error occurred | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/list.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/list.md index 35fd2964..55abab6e 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/list.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/applications/list.md @@ -136,4 +136,4 @@ The `cartesi_listApplications` method returns a paginated list of applications r | Code | Message | Description | |---------|------------------------|--------------------------------------------------| | -32602 | Invalid params | Invalid parameter values | -| -32603 | Internal error | An internal error occurred | \ No newline at end of file +| -32603 | Internal error | An internal error occurred | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/get.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/get.md index 27801cc4..9fe4d132 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/get.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/get.md @@ -42,9 +42,9 @@ The `cartesi_getEpoch` method retrieves detailed information about a specific ep "claim_transaction_hash": null, "status": "OPEN", "virtual_index": "0x1", - "created_at": "2024-01-01T00:00:00Z", + "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" - } + } }, "id": 1 } @@ -71,4 +71,4 @@ The `cartesi_getEpoch` method retrieves detailed information about a specific ep | -32602 | Invalid params | Invalid parameter values | | -32000 | Application not found | The specified application does not exist | | -32001 | Epoch not found | The specified epoch does not exist | -| -32603 | Internal error | An internal error occurred | \ No newline at end of file +| -32603 | Internal error | An internal error occurred | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/last-accepted.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/last-accepted.md index 6a462a13..1b56d9e0 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/last-accepted.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/epochs/last-accepted.md @@ -50,4 +50,4 @@ The `cartesi_getLastAcceptedEpochIndex` method retrieves the latest accepted epo |---------|------------------------|--------------------------------------------------| | -32602 | Invalid params | Invalid parameter values | | -32000 | Application not found | The specified application does not exist | -| -32603 | Internal error | An internal error occurred | \ No newline at end of file +| -32603 | Internal error | An internal error occurred | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/get.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/get.md index 564321c9..abfd335c 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/get.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/get.md @@ -49,13 +49,13 @@ The `cartesi_getInput` method retrieves detailed information about a specific in "index": "0x1", "payload": "0x48656c6c6f" }, - "status": "ACCEPTED", + "status": "ACCEPTED", "machine_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "outputs_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "transaction_reference": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" - } + } }, "id": 1 } @@ -97,4 +97,4 @@ The `cartesi_getInput` method retrieves detailed information about a specific in | -32602 | Invalid params | Invalid parameter values | | -32000 | Application not found | The specified application does not exist | | -32002 | Input not found | The specified input does not exist | -| -32603 | Internal error | An internal error occurred | \ No newline at end of file +| -32603 | Internal error | An internal error occurred | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/list.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/list.md index a23a2435..b19f93d1 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/list.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/list.md @@ -104,4 +104,4 @@ The `cartesi_listInputs` method returns a paginated list of inputs for a specifi |---------|------------------------|--------------------------------------------------| | -32602 | Invalid params | Invalid parameter values | | -32603 | Internal error | An internal error occurred | -| -32000 | Application not found | The specified application does not exist | \ No newline at end of file +| -32000 | Application not found | The specified application does not exist | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/processed-count.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/processed-count.md index c0519eaf..22cc6d0c 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/processed-count.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/inputs/processed-count.md @@ -50,4 +50,4 @@ The `cartesi_getProcessedInputCount` method returns the total number of inputs t |---------|------------------------|--------------------------------------------------| | -32602 | Invalid params | Invalid parameter values | | -32000 | Application not found | The specified application does not exist | -| -32603 | Internal error | An internal error occurred | \ No newline at end of file +| -32603 | Internal error | An internal error occurred | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/outputs/list.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/outputs/list.md index 645ce816..e791300a 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/outputs/list.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/outputs/list.md @@ -100,4 +100,4 @@ The `cartesi_listOutputs` method returns a paginated list of outputs for a speci |---------|------------------------|--------------------------------------------------| | -32602 | Invalid params | Invalid parameter values | | -32603 | Internal error | An internal error occurred | -| -32000 | Application not found | The specified application does not exist | \ No newline at end of file +| -32000 | Application not found | The specified application does not exist | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/get.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/get.md index 7422c649..427790c2 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/get.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/get.md @@ -65,4 +65,4 @@ The `cartesi_getReport` method retrieves detailed information about a specific r | -32602 | Invalid params | Invalid parameter values | | -32000 | Application not found | The specified application does not exist | | -32004 | Report not found | The specified report does not exist | -| -32603 | Internal error | An internal error occurred | \ No newline at end of file +| -32603 | Internal error | An internal error occurred | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/list.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/list.md index 4c101f50..2f76c7c7 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/list.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/methods/reports/list.md @@ -85,4 +85,4 @@ The `cartesi_listReports` method returns a paginated list of reports for a speci |---------|------------------------|--------------------------------------------------| | -32602 | Invalid params | Invalid parameter values | | -32603 | Internal error | An internal error occurred | -| -32000 | Application not found | The specified application does not exist | \ No newline at end of file +| -32000 | Application not found | The specified application does not exist | \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/types.md b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/types.md index 02000203..a5d13cb0 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/types.md +++ b/cartesi-rollups_versioned_docs/version-2.0/api-reference/jsonrpc/types.md @@ -9,14 +9,78 @@ This page documents the data types used in the Cartesi Rollups Node API. These t ## Basic Types -### HexString -A string representing a hexadecimal value, prefixed with "0x". Used for addresses, hashes, and other binary data. +### EthereumAddress +A string representing an Ethereum address in hexadecimal format, prefixed with "0x". + +Pattern: `^0x[a-fA-F0-9]{40}$` Example: ```json "0x71C7656EC7ab88b098defB751B7401B5f6d8976F" ``` +### Hash +A string representing a hash value in hexadecimal format, prefixed with "0x". + +Pattern: `^0x[a-fA-F0-9]{64}$` + +Example: +```json +"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" +``` + +### ByteArray +A string representing binary data in hexadecimal format, prefixed with "0x". + +Pattern: `^0x[a-fA-F0-9]*$` + +Example: +```json +"0x1234567890abcdef" +``` + +### UnsignedInteger +A string representing an unsigned integer in hexadecimal format, prefixed with "0x". + +Pattern: `^0x[a-fA-F0-9]{1,16}$` + +Example: +```json +"0x1" +``` + +### FunctionSelector +A string representing a function selector in hexadecimal format, prefixed with "0x". + +Pattern: `^0x[a-fA-F0-9]{8}$` + +Example: +```json +"0xa9059cbb" +``` + +### ApplicationName +A string representing an application name. + +Pattern: `^[a-z0-9_-]+$` + +Example: +```json +"my-application" +``` + +### NameOrAddress +Either an ApplicationName or an EthereumAddress. + +Example: +```json +"my-application" +``` +or +```json +"0x71C7656EC7ab88b098defB751B7401B5f6d8976F" +``` + ### Timestamp A string representing a timestamp in ISO 8601 format. @@ -33,7 +97,7 @@ The current state of an application. Values: - `ENABLED`: The application is enabled and processing inputs - `DISABLED`: The application is disabled and not processing inputs -- `ERROR`: The application encountered an error and is not processing inputs +- `INOPERABLE`: The application is inoperable Example: ```json @@ -46,20 +110,30 @@ The current status of an epoch. Values: - `OPEN`: The epoch is open and accepting inputs - `CLOSED`: The epoch is closed and not accepting inputs -- `PROCESSED`: The epoch has been processed +- `INPUTS_PROCESSED`: The epoch inputs have been processed +- `CLAIM_COMPUTED`: The epoch claim has been computed +- `CLAIM_SUBMITTED`: The epoch claim has been submitted +- `CLAIM_ACCEPTED`: The epoch claim has been accepted +- `CLAIM_REJECTED`: The epoch claim has been rejected Example: ```json "OPEN" ``` -### InputStatus +### InputCompletionStatus The current status of an input. Values: +- `NONE`: No status assigned - `ACCEPTED`: The input has been accepted and processed - `REJECTED`: The input has been rejected -- `PENDING`: The input is pending processing +- `EXCEPTION`: The input processing resulted in an exception +- `MACHINE_HALTED`: The machine halted during input processing +- `OUTPUTS_LIMIT_EXCEEDED`: The outputs limit was exceeded +- `CYCLE_LIMIT_EXCEEDED`: The cycle limit was exceeded +- `TIME_LIMIT_EXCEEDED`: The time limit was exceeded +- `PAYLOAD_LENGTH_LIMIT_EXCEEDED`: The payload length limit was exceeded Example: ```json @@ -71,8 +145,8 @@ The snapshot policy for an application. Values: - `NONE`: No snapshots are taken -- `EVERY_EPOCH`: A snapshot is taken at the end of each epoch - `EVERY_INPUT`: A snapshot is taken after each input +- `EVERY_EPOCH`: A snapshot is taken at the end of each epoch Example: ```json @@ -86,19 +160,19 @@ Represents a Cartesi Rollups application. ```typescript interface Application { - name: string; - iapplication_address: HexString; - iconsensus_address: HexString; - iinputbox_address: HexString; - template_hash: HexString; - epoch_length: HexString; - data_availability: HexString; + name: ApplicationName; + iapplication_address: EthereumAddress; + iconsensus_address: EthereumAddress; + iinputbox_address: EthereumAddress; + template_hash: Hash; + epoch_length: UnsignedInteger; + data_availability: ByteArray; state: ApplicationState; reason: string; - iinputbox_block: HexString; - last_input_check_block: HexString; - last_output_check_block: HexString; - processed_inputs: HexString; + iinputbox_block: UnsignedInteger; + last_input_check_block: UnsignedInteger; + last_output_check_block: UnsignedInteger; + processed_inputs: UnsignedInteger; created_at: Timestamp; updated_at: Timestamp; execution_parameters: ExecutionParameters; @@ -111,17 +185,17 @@ Configuration parameters for application execution. ```typescript interface ExecutionParameters { snapshot_policy: SnapshotPolicy; - advance_inc_cycles: HexString; - advance_max_cycles: HexString; - inspect_inc_cycles: HexString; - inspect_max_cycles: HexString; - advance_inc_deadline: HexString; - advance_max_deadline: HexString; - inspect_inc_deadline: HexString; - inspect_max_deadline: HexString; - load_deadline: HexString; - store_deadline: HexString; - fast_deadline: HexString; + advance_inc_cycles: UnsignedInteger; + advance_max_cycles: UnsignedInteger; + inspect_inc_cycles: UnsignedInteger; + inspect_max_cycles: UnsignedInteger; + advance_inc_deadline: UnsignedInteger; // Duration in nanoseconds + advance_max_deadline: UnsignedInteger; // Duration in nanoseconds + inspect_inc_deadline: UnsignedInteger; // Duration in nanoseconds + inspect_max_deadline: UnsignedInteger; // Duration in nanoseconds + load_deadline: UnsignedInteger; // Duration in nanoseconds + store_deadline: UnsignedInteger; // Duration in nanoseconds + fast_deadline: UnsignedInteger; // Duration in nanoseconds max_concurrent_inspects: number; created_at: Timestamp; updated_at: Timestamp; @@ -133,13 +207,13 @@ Represents a Cartesi Rollups epoch. ```typescript interface Epoch { - index: HexString; - first_block: HexString; - last_block: HexString; - claim_hash: HexString | null; - claim_transaction_hash: HexString | null; + index: UnsignedInteger; + first_block: UnsignedInteger; + last_block: UnsignedInteger; + claim_hash: Hash | null; + claim_transaction_hash: Hash | null; status: EpochStatus; - virtual_index: HexString; + virtual_index: UnsignedInteger; created_at: Timestamp; updated_at: Timestamp; } @@ -150,33 +224,33 @@ Represents a Cartesi Rollups input. ```typescript interface Input { - epoch_index: HexString; - index: HexString; - block_number: HexString; - raw_data: HexString; - decoded_data: DecodedInput; - status: InputStatus; - machine_hash: HexString; - outputs_hash: HexString; - transaction_reference: HexString; + epoch_index: UnsignedInteger; + index: UnsignedInteger; + block_number: UnsignedInteger; + raw_data: ByteArray; + decoded_data: EvmAdvance | null; + status: InputCompletionStatus; + machine_hash: Hash | null; + outputs_hash: Hash | null; + transaction_reference: ByteArray; created_at: Timestamp; updated_at: Timestamp; } ``` -### DecodedInput -The decoded data of an input. +### EvmAdvance +The decoded data of an EVM advance input. ```typescript -interface DecodedInput { - chain_id: HexString; - application_contract: HexString; - sender: HexString; - block_number: HexString; - block_timestamp: HexString; - prev_randao: HexString; - index: HexString; - payload: HexString; +interface EvmAdvance { + chain_id: UnsignedInteger; + application_contract: EthereumAddress; + sender: EthereumAddress; + block_number: UnsignedInteger; + block_timestamp: UnsignedInteger; + prev_randao: ByteArray; + index: UnsignedInteger; + payload: ByteArray; } ``` @@ -185,27 +259,57 @@ Represents a Cartesi Rollups output (notice, voucher, or DELEGATECALL voucher). ```typescript interface Output { - epoch_index: HexString; - input_index: HexString; - index: HexString; - raw_data: HexString; - decoded_data: DecodedOutput; - hash: HexString; - output_hashes_siblings: HexString[]; - execution_transaction_hash: HexString; + epoch_index: UnsignedInteger; + input_index: UnsignedInteger; + index: UnsignedInteger; + raw_data: ByteArray; + decoded_data: DecodedOutput | null; + hash: Hash | null; + output_hashes_siblings: Hash[] | null; + execution_transaction_hash: Hash | null; created_at: Timestamp; updated_at: Timestamp; } ``` +### Notice +Represents a notice output. + +```typescript +interface Notice { + type: FunctionSelector; + payload: ByteArray; +} +``` + +### Voucher +Represents a voucher output. + +```typescript +interface Voucher { + type: FunctionSelector; + destination: EthereumAddress; + value: string; + payload: ByteArray; +} +``` + +### DelegateCallVoucher +Represents a DELEGATECALL voucher output. + +```typescript +interface DelegateCallVoucher { + type: FunctionSelector; + destination: EthereumAddress; + payload: ByteArray; +} +``` + ### DecodedOutput The decoded data of an output. ```typescript -interface DecodedOutput { - type: HexString; - payload: HexString; -} +type DecodedOutput = Notice | Voucher | DelegateCallVoucher; ``` ### Report @@ -213,10 +317,10 @@ Represents a Cartesi Rollups report. ```typescript interface Report { - epoch_index: HexString; - input_index: HexString; - index: HexString; - raw_data: HexString; + epoch_index: UnsignedInteger; + input_index: UnsignedInteger; + index: UnsignedInteger; + raw_data: ByteArray; created_at: Timestamp; updated_at: Timestamp; } @@ -233,12 +337,134 @@ interface Pagination { } ``` -### PaginatedResponse -A generic interface for paginated responses. +## Result Types + +### ApplicationListResult +Result for listing applications. + +```typescript +interface ApplicationListResult { + data: Application[]; + pagination: Pagination; +} +``` + +### ApplicationGetResult +Result for getting a single application. + +```typescript +interface ApplicationGetResult { + data: Application; +} +``` + +### EpochListResult +Result for listing epochs. + +```typescript +interface EpochListResult { + data: Epoch[]; + pagination: Pagination; +} +``` + +### EpochGetResult +Result for getting a single epoch. + +```typescript +interface EpochGetResult { + data: Epoch; +} +``` + +### InputListResult +Result for listing inputs. ```typescript -interface PaginatedResponse { - data: T[]; +interface InputListResult { + data: Input[]; pagination: Pagination; } -``` \ No newline at end of file +``` + +### InputGetResult +Result for getting a single input. + +```typescript +interface InputGetResult { + data: Input; +} +``` + +### LastAcceptedEpochIndexResult +Result for getting the last accepted epoch index. + +```typescript +interface LastAcceptedEpochIndexResult { + data: UnsignedInteger; +} +``` + +### ProcessedInputCountResult +Result for getting the processed input count. + +```typescript +interface ProcessedInputCountResult { + data: UnsignedInteger; +} +``` + +### OutputListResult +Result for listing outputs. + +```typescript +interface OutputListResult { + data: Output[]; + pagination: Pagination; +} +``` + +### OutputGetResult +Result for getting a single output. + +```typescript +interface OutputGetResult { + data: Output; +} +``` + +### ReportListResult +Result for listing reports. + +```typescript +interface ReportListResult { + data: Report[]; + pagination: Pagination; +} +``` + +### ReportGetResult +Result for getting a single report. + +```typescript +interface ReportGetResult { + data: Report; +} +``` + +### ChainIdResult +Result for getting the chain ID. + +```typescript +interface ChainIdResult { + data: UnsignedInteger; +} +``` + +### NodeVersionResult +Result for getting the node version. + +```typescript +interface NodeVersionResult { + data: string; // Semantic version format +} \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/deployment/introduction.md b/cartesi-rollups_versioned_docs/version-2.0/deployment/introduction.md index b19a76ce..ac75b55d 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/deployment/introduction.md +++ b/cartesi-rollups_versioned_docs/version-2.0/deployment/introduction.md @@ -9,11 +9,15 @@ resources: Applications built on Cartesi Rollups are intended to be deployed to public blockchains so users can access them. This can be done by taking advantage of a cloud-based infrastructure. -Deploying a Cartesi dApp involves two steps: deploying a smart contract that defines your dApp on-chain and then instantiating a node that runs the application’s intended backend logic. +Deploying a Cartesi dApp involves two steps: deploying a smart contract that defines your dApp on-chain and then instantiating a node that runs the application's intended backend logic. To facilitate the instantiation of such nodes, Cartesi provides an infrastructure for quickly getting them running in the cloud so the node can be run 24/7. This server will expose a single port to the internet so client applications can communicate with the node. -The Cartesi rollups node is distributed as a Docker image. Any popular cloud provider, like AWS, GCP, Azure, Digital Ocean, or Linode, can run docker containers and hence can be used to host the rollups node. +## Public snapshots + +For production deployments, applications must use **public snapshots** that are built through public workflows and published as public releases. This ensures transparency, reproducibility, trust, and auditability - essential for the trustless nature of blockchain applications. + +[Learn more about public snapshots](./snapshot.md) ## Deployment process @@ -27,19 +31,18 @@ The smart contract that represents the application on the base layer can be depl There are two methods to deploy an application: -1. [Self-hosted deployment](../deployment/self-hosted.md): Deploy the application node using your infrastructure. - -2. Third-party service provider: Outsource running the application node to a service provider. +1. [Self-hosted deployment](./self-hosted.md): Deploy the application node using your infrastructure +2. Third-party service provider: Outsource running the application node to a service provider :::caution important -Deployment with a third-party service provider is under development and will be available in a future release. +Deployment with a third-party service provider is under development and will be available soon. ::: ## Supported networks As stated above, the first step in deploying a new Cartesi dApp to a blockchain requires creating a smart contract on that network that uses the Cartesi Rollups smart contracts. Cartesi has already deployed the Rollups smart contracts to several networks for convenience. -The table below shows the list of all [networks that are currently supported](https://github.com/cartesi/rollups-contracts/tree/v1.4.0/onchain/rollups/deployments) in the latest release: +The table below shows the list of all [networks that are currently supported](https://usecannon.com/packages/cartesi-rollups) in the latest release: | Network Name | Chain ID | | ---------------- | -------- | diff --git a/cartesi-rollups_versioned_docs/version-2.0/deployment/self-hosted.md b/cartesi-rollups_versioned_docs/version-2.0/deployment/self-hosted.md index e6573e49..e4f85dc3 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/deployment/self-hosted.md +++ b/cartesi-rollups_versioned_docs/version-2.0/deployment/self-hosted.md @@ -1,27 +1,14 @@ --- id: self-hosted title: Self-hosted deployment -resources: - - url: https://www.codecademy.com/article/installing-and-using-postgresql-locally - title: Installing and Using PostgreSQL Locally - - url: https://docs.digitalocean.com/products/databases/postgresql/how-to/create/ - title: How to Create PostgreSQL Database Clusters - - url: https://www.amazonaws.cn/en/getting-started/tutorials/deploy-docker-containers/ - title: How to Deploy Docker Container - AWS - - url: https://www.digitalocean.com/solutions/docker-hosting - title: Deploy Docker Containers on Digital Ocean - - url: https://docs.docker.com/reference/cli/docker/image/tag/ - title: Docker Tag --- -The self-hosted deployment involves running your infrastructure locally or on a remote cloud server to host your application node. +This guide explains how to run a Cartesi Rollups node locally on your machine for development and testing purposes on **testnet**. -Here are the requirements: +:::warning Production Warning +**This self-hosted approach should NOT be used in *production*.** -- Wallet with sufficient funds on the chosen network. -- A cloud server -- A PostgreSQL database -- A web3 provider for interacting with the selected network +While this setup works with testnet environments, it's designed exclusively for development purposes. It lacks critical production requirements such as: ## Initiating deployment @@ -115,57 +102,95 @@ Fly.io is a platform where you can conveniently deploy applications packaged as If deploying to Fly.io from macOS with Apple Silicon, create a Docker image for `linux/amd64` with: `cartesi deploy build --platform linux/amd64` ::: -1. [Install the flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/) +## Prerequisites -1. [Create an account](https://fly.io/docs/hands-on/sign-up-sign-in/) +Before starting, ensure you have the following installed: -1. Create an application: +- Cartesi CLI: An easy-to-use tool for developing and deploying your dApps. + +- Docker Desktop 4.x: The required tool to distribute the Cartesi Rollups framework and its dependencies. + +For more details about the installation process for each of these tools, please refer to the [this section](../development/installation.md). + +## Configuration + +Before running the node, you need to configure your `.env` file with the following environment variables: + +```shell +BLOCKCHAIN_ID= +AUTH_KIND="private_key_file" +PRIVATE_KEY_FILE="/run/secrets/pk" +BLOCKCHAIN_WS_ENDPOINT="" +BLOCKCHAIN_HTTP_ENDPOINT="" +``` + +**Important notes:** + +| Variable | Description | +|----------|-------------| +| `BLOCKCHAIN_ID` | Replace `` with your blockchain network ID | +| `BLOCKCHAIN_WS_ENDPOINT` | Replace `` with your WebSocket endpoint | +| `BLOCKCHAIN_HTTP_ENDPOINT` | Replace `` with your HTTP endpoint | +| `PRIVATE_KEY_FILE` | Points to the private key file created in [**step 2**](#setting-up-the-local-node) | +| `AUTH_KIND` | Set to `"private_key_file"` for local development | + +## Setting up the local node + +1. **Download the Cartesi Rollups Node docker compose file in your project root:** ```shell - $ fly app create - New app created: + curl -L https://raw.githubusercontent.com/cartesi/docs/refs/heads/docs/deployment/cartesi-rollups_versioned_docs/version-2.0/deployment/src/compose.local.yaml -o compose.local.yaml ``` -1. Create a Postgres database application: +2. **Create a secret for private key storage:** ```shell - fly postgres create --initial-cluster-size 1 --name -database --vm-size shared-cpu-1x --volume-size 1 + mkdir -p secrets + echo "YOUR_PRIVATE_KEY" > secrets/pk ``` - Save the connection string provided by the command output. + :::danger Security + Ensure the `secrets/` directory is in a secure location and has restricted permissions, different from the project root to avoid leaking your private key. + ::: -1. Attach database to the node application: +3. **Build the application with the Cartesi CLI:** ```shell - fly postgres attach -database -a + cartesi build ``` -1. Download `fly.toml` file from deploying the contracts and move it to your application directory: + This command compiles your application into RISC-V architecture and creates a Cartesi machine snapshot locally. - ![deploy self-hosted config](../../../static/img/v1.3/fly.png) - -1. Edit the `fly.toml` file to change all occurrences of `` to the name of your application - -1. Create secrets for sensitive configuration with the actual values: +4. **Run the Cartesi Rollups Node with the application's initial snapshot attached:** ```shell - fly secrets set -a CARTESI_BLOCKCHAIN_HTTP_ENDPOINT= - fly secrets set -a CARTESI_BLOCKCHAIN_WS_ENDPOINT= - fly secrets set -a CARTESI_AUTH_MNEMONIC=`` - fly secrets set -a CARTESI_POSTGRES_ENDPOINT= + docker compose -f compose.local.yaml --env-file .env up -d ``` - Set value of the `connection_string` as provided by step 4. + This starts the local node using the configuration from your `.env` file. -1. Deploy the node: +5. **Deploy and register the application to the node:** + + ```shell + docker compose --project-name cartesi-rollups-node \ + exec advancer cartesi-rollups-cli deploy application /var/lib/cartesi-rollups-node/snapshot \ + --epoch-length 720 \ + --self-hosted \ + --salt \ + --json + ``` - Tag the image produced at the beginning of the process and push it to the Fly.io registry: + Replace `` with your application name and `` with a unique identifier. The salt must be unique for each deployment and cannot be repeated. You can generate a unique salt using: ```shell - flyctl auth docker - docker image tag registry.fly.io/ - docker image push registry.fly.io/ - fly deploy -a + cast keccak256 "your-unique-string" ``` - + After this process, you'll have your application deployed and registered to the node. + +## Accessing the node + +Once running, your local Cartesi Rollups Node will be accessible through the standard APIs: + +- Inspect endpoint: `http://localhost:10012` +- JSON-RPC endpoint: `http://localhost:10011` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/deployment/snapshot.md b/cartesi-rollups_versioned_docs/version-2.0/deployment/snapshot.md new file mode 100644 index 00000000..2b79b0c0 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/deployment/snapshot.md @@ -0,0 +1,184 @@ +--- +id: snapshot +title: Public snapshot +--- + +A Cartesi snapshot is a compressed representation of your application's machine state that can be deployed to rollups nodes. This process involves: + +1. Building your application with the Cartesi CLI +2. Creating a compressed snapshot archive +3. Generating checksums for verification +4. Publishing releases with snapshot artifacts + +Public snapshots are crucial for applications developed with the Cartesi Rollups framework because they enable **anyone to validate the respective application**. This transparency is fundamental to the trustless nature of blockchain applications. + +### Validation Process + +When a snapshot is public, validators can: + +1. Download the snapshot from the release +2. Verify the checksum to ensure integrity +3. Extract and inspect the machine state +4. Reproduce the build process locally +5. Compare results to ensure consistency + +This process ensures that the application behaves exactly as intended and hasn't been tampered with during deployment. + +:::danger +**Note**: Always download snapshots from verified public GitHub releases, never from local builds or private sources. +::: + +## Prerequisites + +Before building snapshots, ensure you have: + +- Cartesi CLI: An easy-to-use tool for developing and deploying your dApps. + +- Docker Desktop 4.x: The required tool to distribute the Cartesi Rollups framework and its dependencies. + +- Node and NPM: A JavaScript runtime needed to install Cartesi CLI and run various scripts. We recommend installing the LTS version to ensure best compatibility. + +For more details about the installation process for each of these tools, please refer to the [this section](../development/installation.md). + +## GitHub Actions Workflow + +The following workflow automates the snapshot building and release process: + +```yaml +name: build-and-release + +on: + push: + tags: + - "*" + pull_request: + branches: [main] + workflow_dispatch: + +jobs: + build: + name: build + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + attestations: write + id-token: write + + env: + REGISTRY: ghcr.io + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: current + + - name: Install Cartesi CLI + run: npm install -g @cartesi/cli@2.0.0-alpha.16 + + - name: Log in to GHCR + if: startsWith(github.ref, 'refs/tags/') + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Docker image and Cartesi snapshot + run: cartesi build + env: + DOCKER_BUILDKIT: 1 + BUILDKIT_INLINE_CACHE: 1 + + - name: Create compressed snapshot + if: startsWith(github.ref, 'refs/tags/') + run: | + tar -czf snapshot.tar.gz -C .cartesi/image . + sha256sum snapshot.tar.gz > snapshot.tar.gz.sha256 + + - name: Upload snapshot artifacts + if: startsWith(github.ref, 'refs/tags/') + uses: actions/upload-artifact@v4 + with: + name: snapshot + path: | + snapshot.tar.gz + snapshot.tar.gz.sha256 + + release: + name: release + if: startsWith(github.ref, 'refs/tags/v') + needs: build + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - name: Download snapshot artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Prepare release assets + run: | + mkdir -p release-assets + find artifacts -name "*.tar.gz" -exec cp {} release-assets/ \; + find artifacts -name "*.sha256" -exec cp {} release-assets/ \; + + - name: Publish GitHub release + uses: softprops/action-gh-release@v2 + with: + files: release-assets/* + prerelease: ${{ contains(github.ref, '-rc') }} + fail_on_unmatched_files: true +``` + +## Workflow Breakdown + +### Triggers + +The workflow is triggered by: + +- **Tag pushes**: Any tag push triggers a build +- **Pull requests**: Builds on PRs to main branch +- **Manual dispatch**: Manual workflow execution + +### Build Job + +The build job sets up the environment with Docker Buildx, QEMU, and Node.js, installs the Cartesi CLI globally, and uses `cartesi build` to create the Cartesi machine snapshot. It then compresses the snapshot as `snapshot.tar.gz`, generates a SHA256 checksum for verification, and uploads the artifacts for the release job. + +### Release Job + +The release job downloads the build artifacts, prepares the release assets, and creates a GitHub release with the tag. It attaches the snapshot files and checksums, marking the release as prerelease if the tag contains `-rc`. + +## Release Management + +### Creating Releases + +1. **Tag your release**: + + ```shell + git tag v1.0.0 + git push origin v1.0.0 + ``` + +2. **Prereleases**: Use tags like `v1.0.0-rc` for release candidates + +3. **Release artifacts** will include: + + - `snapshot.tar.gz` - Compressed snapshot + - `snapshot.tar.gz.sha256` - Checksum file \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/deployment/src/compose.local.yaml b/cartesi-rollups_versioned_docs/version-2.0/deployment/src/compose.local.yaml new file mode 100644 index 00000000..ded253ea --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/deployment/src/compose.local.yaml @@ -0,0 +1,118 @@ +name: cartesi-rollups-node +x-env: &env + CARTESI_LOG_LEVEL: info + CARTESI_AUTH_KIND: ${AUTH_KIND} + CARTESI_BLOCKCHAIN_ID: ${BLOCKCHAIN_ID} + CARTESI_AUTH_PRIVATE_KEY_FILE: ${PRIVATE_KEY_FILE} + CARTESI_BLOCKCHAIN_WS_ENDPOINT: ${BLOCKCHAIN_WS_ENDPOINT} + CARTESI_BLOCKCHAIN_HTTP_ENDPOINT: ${BLOCKCHAIN_HTTP_ENDPOINT} + CARTESI_SNAPSHOTS_DIR: "/var/lib/cartesi-rollups-node/snapshot" + CARTESI_CONTRACTS_INPUT_BOX_ADDRESS: 0xc70074BDD26d8cF983Ca6A5b89b8db52D5850051 + CARTESI_CONTRACTS_AUTHORITY_FACTORY_ADDRESS: 0xC7003566dD09Aa0fC0Ce201aC2769aFAe3BF0051 + CARTESI_CONTRACTS_APPLICATION_FACTORY_ADDRESS: 0xc7006f70875BaDe89032001262A846D3Ee160051 + CARTESI_CONTRACTS_SELF_HOSTED_APPLICATION_FACTORY_ADDRESS: 0xc700285Ab555eeB5201BC00CFD4b2CC8DED90051 + CARTESI_DATABASE_CONNECTION: postgres://postgres:password@database:5432/rollupsdb?sslmode=disable + +secrets: + pk: + file: ./secrets/pk # TODO: change to the path of the your private key file + +services: + database: + container_name: database + image: cartesi/rollups-database:0.12.0-alpha.20 + environment: + POSTGRES_PASSWORD: password + networks: + - default + healthcheck: + test: + - CMD-SHELL + - pg_isready -U postgres || exit 1 + timeout: 1s + interval: 10s + retries: 5 + start_period: 10s + start_interval: 200ms + + evm-reader: + container_name: evm-reader + image: cartesi/rollups-runtime:0.12.0-alpha.20 + command: cartesi-rollups-evm-reader + depends_on: + database: + condition: service_healthy + networks: + - default + ports: + - "10001:10001" + environment: + <<: *env + + advancer: + container_name: advancer + image: cartesi/rollups-runtime:0.12.0-alpha.20 + command: cartesi-rollups-advancer + depends_on: + database: + condition: service_healthy + volumes: + - data:/var/lib/cartesi-rollups-node/data + - .cartesi/image:/var/lib/cartesi-rollups-node/snapshot/ + networks: + - default + ports: + - "10002:10002" + - "10012:10012" + environment: + <<: *env + secrets: + - pk + + validator: + container_name: validator + image: cartesi/rollups-runtime:0.12.0-alpha.20 + command: cartesi-rollups-validator + depends_on: + database: + condition: service_healthy + networks: + - default + ports: + - "10003:10003" + environment: + <<: *env + + claimer: + container_name: claimer + image: cartesi/rollups-runtime:0.12.0-alpha.20 + command: cartesi-rollups-claimer + depends_on: + database: + condition: service_healthy + networks: + - default + ports: + - "10004:10004" + environment: + <<: *env + secrets: + - pk + + jsonrpc-api: + container_name: jsonrpc-api + image: cartesi/rollups-runtime:0.12.0-alpha.20 + command: cartesi-rollups-jsonrpc-api + depends_on: + database: + condition: service_healthy + networks: + - default + ports: + - "10005:10005" + - "10011:10011" + environment: + <<: *env + +volumes: + data: \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/asset-handling.md b/cartesi-rollups_versioned_docs/version-2.0/development/asset-handling.md index 76f71e24..11f8ab01 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/asset-handling.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/asset-handling.md @@ -8,7 +8,7 @@ resources: Assets exist on the base layer, where they have actual meaning and value. -As with any execution layer solution, a Cartesi dApp that wants to manipulate assets needs a secure way of "teleporting" the assets from the base layer to the execution layer and then a way to "teleport" them back to the base layer. +As with any execution layer solution, a Cartesi Application that wants to manipulate assets needs a secure way of "teleporting" the assets from the base layer to the execution layer and when necessary, back to the base layer. Currently, Cartesi Rollups support the following types of assets: @@ -22,9 +22,9 @@ Currently, Cartesi Rollups support the following types of assets: ## Deposits -Portals enable the safe transfer of assets from the base layer to the execution layer. Users authorize portals to deduct assets from their accounts and initiate transfers to dApps. +Portals enable the safe transfer of assets from the base layer to the execution layer. Users authorize portals to deduct assets from their accounts and initiate transfers to the Application contract. -When an asset is deposited, it is on the base layer but gains a representation in the execution layer. The corresponding Portal contract sends an input via the `InputBox` contract describing the type of asset, amount, and some data the depositor might want the dApp to read. The off-chain machine will then interpret and validate the input payload. +When an asset is deposited, it is on the base layer but gains a representation in the execution layer. The corresponding Portal contract sends an input via the `InputBox` contract describing the type of asset, amount, and some data the depositor might want the application to read. The off-chain machine will then interpret and validate the input payload. Deposit input payloads are always specified as packed ABI-encoded parameters, as detailed below. @@ -42,13 +42,13 @@ Deposit input payloads are always specified as packed ABI-encoded parameters, as ## Withdrawing assets -Users can deposit assets to a Cartesi dApp, but only the dApp can initiate withdrawals. When a withdrawal request is made, it’s processed and interpreted off-chain by the Cartesi Machine running the dApp’s code. Subsequently, the Cartesi Machine creates a voucher containing the necessary instructions for withdrawal, which is executable when an epoch has settled. +Users can deposit assets to a Cartesi Application, but only the Application can initiate withdrawals. When a withdrawal request is made, it’s processed and interpreted off-chain by the Cartesi Machine running the application’s code. Subsequently, the Cartesi Machine creates a voucher containing the necessary instructions for withdrawal, which is executable when an epoch has settled. -Vouchers are crucial in allowing dApps in the execution layer to interact with contracts in the base layer through message calls. They are emitted by the off-chain machine and executed by any participant in the base layer. Each voucher includes a destination address and a payload, typically encoding a function call for Solidity contracts. +### Withdrawing Tokens -The dApp’s off-chain layer often requires knowledge of its address to facilitate on-chain interactions for withdrawals, for example: `transferFrom(sender, recipient, amount)`. In this case, the sender is the dApp itself. +Vouchers are crucial in allowing applications in the execution layer to interact with contracts in the base layer through message calls. They are emitted by the off-chain machine and executed by any participant in the base layer. Each voucher includes a destination address and a payload, typically encoding a function call for Solidity contracts. -Next, the off-chain machine uses the address of the application on the base layer to generate a voucher for execution at the [`executeVoucher()`](../api-reference/contracts/application.md/#executevoucher) function of the `CartesiDApp` contract. This address is known to the offchain machine because it is embedded in the metadata of every input sent to the application, though the developer will need to implement extra logic fetch this address from the metadata then properly store and retrieve it when needed in situations like generating the above Voucher. +By calling [`relayDAppAddress()`](../api-reference/json-rpc/relays/relays.md), function of the `DAppAddressRelay` contract, it adds the dApp’s address as a new input for the Cartesi dApp to process. Next, the off-chain machine uses this address to generate a voucher for execution at the [`executeVoucher()`](../api-reference/json-rpc/application.md/#executevoucher) function of the `CartesiDApp` contract. :::note epoch length By default, Cartesi nodes close one epoch every 7200 blocks. You can [manually set the epoch length](./cli-commands.md/#run) to facilitate quicker asset-handling methods. @@ -58,7 +58,7 @@ Here are the function signatures used by vouchers to withdraw the different type | Asset | Destination | Function signature | | :------- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------ | -| Ether | dApp contract | `withdrawEther(address,uint256)` [:page_facing_up:](../api-reference/contracts/application.md/#withdrawether) | +| Ether | dApp contract | `withdrawEther(address,uint256)` [:page_facing_up:](../api-reference/json-rpc/application.md/#withdrawether) | | ERC-20 | Token contract | `transfer(address,uint256)` [:page_facing_up:](https://eips.ethereum.org/EIPS/eip-20#methods) | | ERC-20 | Token contract | `transferFrom(address,address,uint256)` [:page_facing_up:](https://eips.ethereum.org/EIPS/eip-20#methods) | | ERC-721 | Token contract | `safeTransferFrom(address,address,uint256)` [:page_facing_up:](https://eips.ethereum.org/EIPS/eip-721#specification) | diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/creating-an-application.md b/cartesi-rollups_versioned_docs/version-2.0/development/creating-an-application.md new file mode 100644 index 00000000..7adef785 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/development/creating-an-application.md @@ -0,0 +1,177 @@ +--- +id: creating-an-application +title: Creating an Application +resources: + - url: https://cartesiscan.io/ + title: CartesiScan +--- + + + +Cartesi CLI simplifies creating applications on Cartesi. To create a new application, run: + +```shell +cartesi create --template +``` + +For example, create a Javascript project. + +```shell +cartesi create new-app --template javascript +``` + +This command creates a `new-app` directory with essential files for your application development. + +- `Dockerfile`: Contains configurations to build a complete Cartesi machine with your app's dependencies. Your backend code will run in this environment. + +- `README.md`: A markdown file with basic information and instructions about your application. + +- `src/index.js`: A javascript file with template backend code that serves as your application's entry point. + +- `package.json`: A list of dependencies required for your application along with the name, version and description of your application. + +Cartesi CLI has templates for the following languages – `cpp`, `cpp-low-level`, `go`, `java`, `javascript`, `lua`, `python`, `ruby`, `rust`, and `typescript`. + +:::note Libraries for simplifying development +We have high-level framework and alternative templates that simplify development and enhances input management, providing a smoother and more efficient experience. +For Go use Rollmelette, for Rust use Crabrolls, for Python use python-Cartesi and for Typescript/Javascrips use Deroll. +Visit this [page](../resources/community-tools.md) to learn more about these and other available tools. +::: + +## Implementing your application Logic + +After creating your application, you can begin building your application by adding your logic to the index.js file. This file serves as the entry point of your application. While your project can include multiple files and directories, the default application file should remain the entry point of your application. + +It’s important not to modify or remove existing code in index.js unless you fully understand its purpose, as doing so may prevent your application from functioning correctly. Instead, you are encouraged to extend the file by adding your own logic and implementations alongside the default code. + +The default application template includes two primary functions; `handle_advance` and `handle_inspect`. These act as entry points for different types of operations within your application. + +### handle_advance function + +The `handle_advance` function is the entry point for state modifying logic, you can think of this like handling "write" requests in traditional web context. It is intended to carry out computations, updates, and other logic that changes the state of the application. Where appropriate, it can emit outputs such as `notices`, `vouchers`, or `reports`. + +### handle_inspect function + +On the other hand, the `handle_inspect` function serves as the entry point for read only operations, similar to "read" requests in a typical web context. This function should be implemented to accept user input, perform any necessary lookups or calculations based on the current state, and return the results by emitting a `report`. It's important to understand that handle_inspect is designed strictly for reading the application's state, it should not perform any modifications. + +## Implementing Outputs + +If your application needs to emit Outputs like; notices, vouchers, or reports, make sure to implement the corresponding logic within your codebase to properly handle these outputs. You can check out the respective pages for [Notice](../api-reference/backend/notices.md), [Vouchers](../api-reference/backend/vouchers.md) or [Report](../api-reference/backend/reports.md) for better understanding of what they are and how to implement them. + +Below is a sample application that has been modified to include the logic to simply receive an input from a user in both inspect and advance route then, emits a notice, voucher and a report. For your application you'll need to include your personal logic and also emit outputs when necessary: + +```javascript + +import { stringToHex, encodeFunctionData, erc20Abi, hexToString, zeroHash } from "viem"; + +const rollup_server = process.env.ROLLUP_HTTP_SERVER_URL; +console.log("HTTP rollup_server url is " + rollup_server); + +async function handle_advance(data) { + console.log("Received advance request data " + JSON.stringify(data)); + + const sender = data["metadata"]["msg_sender"]; + const payload = hexToString(data.payload); + const erc20Token = "0x784f0c076CC55EAD0a585a9A13e57c467c91Dc3a"; // Sample ERC20 token address + + await emitNotice(payload); + await emitReport(payload); + + const call = encodeFunctionData({ + abi: erc20Abi, + functionName: "transfer", + args: [sender, BigInt(10)], + }); + + let voucher = { + destination: erc20Token, + payload: call, + value: zeroHash, + }; + + await emitVoucher(voucher); + return "accept"; +} + +async function handle_inspect(data) { + console.log("Received inspect request data " + JSON.stringify(data)); + const payload = data.payload; + await emitReport(payload); + return "accept"; +} + +const emitNotice = async (inputPayload) => { + let hexPayload = stringToHex(inputPayload); + try { + await fetch(rollup_server + "/notice", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ payload: hexPayload }), + }); + } catch (error) { + //Do something when there is an error + } +} + +const emitVoucher = async (voucher) => { + try { + await fetch(rollup_server + "/voucher", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(voucher), + }); + } catch (error) { + //Do something when there is an error + } +}; + +const emitReport = async (payload) => { + let hexPayload = stringToHex(payload); + try { + await fetch(rollup_server + "/report", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ payload: hexPayload }), + }); + } catch (error) { + //Do something when there is an error + } +}; + +var handlers = { + advance_state: handle_advance, + inspect_state: handle_inspect, +}; + +var finish = { status: "accept" }; + +(async () => { + while (true) { + const finish_req = await fetch(rollup_server + "/finish", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ status: "accept" }), + }); + + console.log("Received finish status " + finish_req.status); + + if (finish_req.status == 202) { + console.log("No pending rollup request, trying again"); + } else { + const rollup_req = await finish_req.json(); + var handler = handlers[rollup_req["request_type"]]; + finish["status"] = await handler(rollup_req["data"]); + } + } +})(); + + +``` \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/installation.md b/cartesi-rollups_versioned_docs/version-2.0/development/installation.md index 7a1ca506..3749d327 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/installation.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/installation.md @@ -1,7 +1,7 @@ --- id: installation title: Installation -resources: +resources: - url: https://www.docker.com/products/docker-desktop/ title: Install Docker Desktop - url: https://nodejs.org/en/download/ @@ -82,11 +82,9 @@ import TabItem from '@theme/TabItem'; - Cartesi CLI doctor is a diagnostic tool that declares whether your system is ready and set up for development. ```shell $ cartesi doctor ✔ Your system is ready for cartesi. ``` - diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/query-outputs.md b/cartesi-rollups_versioned_docs/version-2.0/development/query-outputs.md index c028964c..a82e4735 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/query-outputs.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/query-outputs.md @@ -32,11 +32,11 @@ Think of it as a digital authorization ticket that enables a dApp to perform spe A notice is a verifiable data declaration that attests to off-chain events or conditions and is accompanied by proof. Unlike vouchers, notices do not trigger direct interactions with other smart contracts. -They serve as a means for dApp to notify the blockchain about particular events. +They serve as a means for application to notify the blockchain about particular events. ### How Notices Work -- The dApp backend creates a notice containing relevant off-chain data. +- The application backend creates a notice containing relevant off-chain data. - The notice is submitted to the Rollup Server as evidence of the off-chain event. @@ -44,7 +44,7 @@ They serve as a means for dApp to notify the blockchain about particular events. ### Send a notice -Let's examine how a Cartesi dApp has its Advance request **calculating and returning the first five multiples of a given number**. +Let's examine how an Application has its Advance request **calculating and returning the first five multiples of a given number**. We will send the output to the rollup server as a notice. @@ -157,7 +157,7 @@ For example, sending an input payload of `“2”` to the application using Cast ```bash Received finish status 200 -Received advance request data {"metadata":{"msg_sender":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","epoch_index":0,"input_index":0,"block_number":11,"timestamp":1708331280},"payload":"0x32"} +Received advance request data {"metadata":{"chain_id":31337,"app_contract":"0xef34611773387750985673f94067ea22db406f72","msg_sender":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","block_number":188,"block_timestamp":1741291197,"prev_randao":"0xa8b0097138c68949870aabe7aa4dc62a91b6dd0bc2b4582eac2be9eaee280032","input_index":0},"payload":"0x32"} Adding notice with values 2, 4, 6, 8, 10 ``` @@ -176,12 +176,18 @@ Input your query in the left pane: ```graphql query notices { notices { + totalCount edges { node { index input { index } + application { + id + name + address + } payload } } @@ -196,7 +202,7 @@ Click the "Play" button (a triangular icon). The Playground will send the reques Your browser does not support video tags. --> -Alternatively, you can use a frontend client to query all the notices of a dApp running in a local environment: +Alternatively, you can use a frontend client to query all the notices of an application running in a local environment: ```javascript async function fetchNotices() { @@ -231,8 +237,12 @@ You can get notices based on their `inputIndex`: Input your query in the left pane. ```graphql -query noticesByInput($inputIndex: Int!) { - input(index: $inputIndex) { +query noticesByInput($inputIndex: String!) { + input(id: $inputIndex) { + id + index + payload + msgSender notices { edges { node { @@ -240,6 +250,11 @@ query noticesByInput($inputIndex: Int!) { input { index } + application { + id + name + address + } payload } } @@ -252,7 +267,7 @@ Then, in the bottom-left corner of the Playground, you'll find a section that pr ``` { - "inputIndex": 123 + "inputIndex": "0" } ``` @@ -267,25 +282,34 @@ With a JavaScript client, you can construct the GraphQL query and variables sepa ```javascript const query = ` - query noticesByInput($inputIndex: Int!) { - input(index: $inputIndex) { - notices { - edges { - node { +query noticesByInput($inputIndex: String!) { + input(id: $inputIndex) { + id + index + payload + msgSender + notices { + edges { + node { + index + input { index - input { - index - } - payload } + application { + id + name + address + } + payload } } } } +} `; const variables = { - inputIndex: 123, // Replace 123 with the desired value + inputIndex: "0", // Replace 0 with the desired value }; const response = await fetch( @@ -307,28 +331,24 @@ for (let edge of result.data.input.notices.edges) { You can retrieve detailed information about a notice, including its proof information: -Here is the query which takes two variables: `noticeIndex` and `inputIndex`. +Here is the query which takes the variable: `outputIndex` and returns the details of a notice. ```graphql -query notice($noticeIndex: Int!, $inputIndex: Int!) { - notice(noticeIndex: $noticeIndex, inputIndex: $inputIndex) { +query notice($outputIndex: Int!) { + notice(outputIndex: $outputIndex) { index input { index } payload proof { - validity { - inputIndexWithinEpoch - outputIndexWithinInput - outputHashesRootHash - vouchersEpochRootHash - noticesEpochRootHash - machineStateHash - outputHashInOutputHashesSiblings - outputHashesInEpochSiblings - } - context + outputIndex + outputHashesSiblings + } + application { + id + name + address } } } @@ -336,7 +356,7 @@ query notice($noticeIndex: Int!, $inputIndex: Int!) { ## Reports: Stateless logs -Reports serve as stateless logs, providing read-only information without affecting the state. They are commonly used for logging and diagnostics within the dApp. +Reports serve as stateless logs, providing read-only information without affecting the state. They are commonly used for logging and diagnostics within the application. Here is how you can write your application to send reports to the rollup server: @@ -389,7 +409,7 @@ def handle_advance(data): msg = f"Error processing data {data}\n{traceback.format_exc()}" logger.error(msg) response = requests.post( - rollup_server + "/report", json={"payload": msg)} + rollup_server + "/report", json={"payload": msg} ) logger.info( f"Received report status {response.status_code} body {response.content}" @@ -403,7 +423,7 @@ def handle_advance(data): -You can use the exposed GraphQL API to query all reports from your dApp. +You can use the exposed GraphQL API to query all reports from your application. ### Query all reports @@ -418,6 +438,7 @@ Input your query in the left pane: ```graphql query reports { reports { + totalCount edges { node { index @@ -438,15 +459,25 @@ You can retrieve reports based on their `inputIndex`. Input your query in the left pane: ```graphql -query reportsByInput($inputIndex: Int!) { - input(index: $inputIndex) { +query reportsByInput($inputIndex: String!) { + input(id: $inputIndex) { + id + index + payload + msgSender reports { + totalCount edges { node { index input { index } + application { + id + name + address + } payload } } @@ -459,26 +490,176 @@ Then, in the bottom-left corner of the Playground, you'll find a section that pr ```graphql { - "inputIndex": 123 + "inputIndex": "0" } ``` -Replace `123` with the value you want to pass for `$inputIndex`. +Replace `0` with the value you want to pass for `$inputIndex`. ### Query a single report -You can retrieve a report with its `reportIndex` and `inputIndex`. +You can retrieve a report with its `reportIndex`. ```graphql -query report($reportIndex: Int!, $inputIndex: Int!) { - report(reportIndex: $reportIndex, inputIndex: $inputIndex) { +query report($reportIndex: Int!) { + report(reportIndex: $reportIndex) { index input { index } payload + application { + id + name + address + } } } ``` Unlike Vouchers and Notices, reports are stateless and need attached proof. + +## Vouchers: On-chain actions + +A voucher in Cartesi Rollups is a mechanism for executing on-chain actions from an application. + +Think of it as a digital authorization ticket that enables an application to perform specific actions on the blockchain, such as transferring assets or approving transactions. + +### How Vouchers Work: + +- The application backend creates a voucher while executing in the Cartesi Machine. + +- The voucher specifies the action, such as a token swap, and is sent to the blockchain. + +- The [`Application`](../api-reference/contracts/application.md) contract executes the voucher using the [`executeOutput()`](../api-reference/contracts/application.md#executeoutput) function. + +- The result is recorded on the base layer through claims submitted by a consensus contract. + + :::note create a voucher + [Refer to the documentation here](./asset-handling.md) for asset handling and creating vouchers in your application. + ::: + +### Query all Vouchers + +Similar to Notices and Reports the Frontend client can use a GraphQL API exposed by the Cartesi Nodes to query for voucher details from a Cartesi Rollups instance + +You can use the interactive in-browser GraphQL playground hosted on `http://localhost:8080/graphql/{application_address}` for local development. + +Input your query in the left pane: + +```graphql +query vouchers { + vouchers { + totalCount + edges { + node { + index + input { + index + } + destination + payload + value + proof { + outputIndex + outputHashesSiblings + } + executed + application { + id + name + address + } + } + } + } +} +``` + +Click the "Play" button (a triangular icon). The Playground will send the request to the server, and you'll see the response in the right pane. + +### Query a Voucher via it's input index + +You can retrieve vouchers based on their `inputIndex`, to do that you need to, Input the below query in the left pane of the GraphQL playground: + +```graphql +query voucherByInput($inputIndex: String!) { + input(id: $inputIndex) { + id + index + payload + msgSender + vouchers { + totalCount + edges { + node { + index + input { + index + } + destination + payload + value + proof { + outputIndex + outputHashesSiblings + } + executed + application { + id + name + address + } + } + } + } + } +} +``` + +Then, in the bottom-left corner of the Playground, you'll find a section that provides variables. Click on it to expand it, and then you can input your variables like this: + +```graphql +{ + "inputIndex": "0" +} +``` + +Replace `0` with the value you want to pass for `$inputIndex`. + +### Query a single Voucher + +You can retrieve a report with its `reportIndex`. + +```graphql +query voucher($outputIndex: Int!) { + voucher(outputIndex: $outputIndex) { + index + input { + index + } + destination + payload + proof { + outputIndex + outputHashesSiblings + } + value + executed + transactionHash + application { + id + name + address + } + } +} +``` + +As always remember to add the variable `$outputIndex` to the variables tab in the bottom-left corner of the playground, like this: + +```graphql +{ + "outputIndex": 0 +} +``` diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/running-an-application.md b/cartesi-rollups_versioned_docs/version-2.0/development/running-an-application.md new file mode 100644 index 00000000..fbfbc6ea --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/development/running-an-application.md @@ -0,0 +1,91 @@ +--- +id: running-an-application +title: Running an application +resources: + - url: https://cartesiscan.io/ + title: CartesiScan +--- + +Running your application creates a docker container containing all required services, and exposes your application node on port `6751`, then an anvil network specific to your application on port `6751/anvil`. The node also logs all outputs received by your backend. + +Here are the prerequisites to run the node: + +- Docker Engine must be active. +- Cartesi machine snapshot successfully built with `cartesi build`. + +To start the node, run: + +```shell +cartesi run +``` + +Response: + +```shell +[+] Pulling 4/0 + ✔ proxy Skipped - Image is already present locally 0.0s + ✔ database Skipped - Image is already present locally 0.0s + ✔ rollups-node Skipped - Image is already present locally 0.0s + ✔ anvil Skipped - Image is already present locally 0.0s +✔ demo-application starting at http://127.0.0.1:6751 +✔ anvil service ready at http://127.0.0.1:6751/anvil +✔ rpc service ready at http://127.0.0.1:6751/rpc +✔ inspect service ready at http://127.0.0.1:6751/inspect/demo-application +✔ demo-application machine hash is 0xa3ca2e40420f3c2424ca95549b6c16fd9b11c27d76b8ef9ae9bf78cde36829fc +✔ demo-application contract deployed at 0xa083af219355288722234c47d4c8469ca9af6605 +(l) View logs (b) Build and redeploy (q) Quit +``` + +This command runs your backend compiled to RISC-V and packages it as a Cartesi machine. It is therefore important that after every code update, the application needs to be rebuilt then the run command executed again, the Cartesi CLI makes this process very easy and all you need do is hit the `` button on your keyboard to trigger a rebuild and run command. + +:::troubleshoot troubleshooting common errors + +#### Error: Depth Too High + +```shell +Attaching to 2bd74695-prompt-1, 2bd74695-validator-1 +2bd74695-validator-1 | Error: DepthTooHigh { depth: 2, latest: 1 } +2bd74695-validator-1 | Error: DepthTooHigh { depth: 2, latest: 1 } +``` + +This indicates that the node is reading blocks too far behind the current blockchain state. + +#### Solution + +Create or modify a `.cartesi.env` file in your project directory and set: + +```shell +TX_DEFAULT_CONFIRMATIONS=1 +``` + +This adjustment should align the node's block reading with the blockchain's current state. + +::: + +### Overview of Node Services + +The `cartesi run` command activates several services essential for node operation: some of these services are not activated by default and can be activated by adding them to the `--service` flag when starting your application. The below command starts your application with all available services: + +```shell +cartesi run --services explorer,graphql,bundler,paymaster,passkey +``` + +Each of these services runs independently and can be activated or deactivated at will by simply including or removing them from the list of services while running your application. Below is a breakdown of these services and their default URL's. + +- **Anvil Chain**: Runs a local blockchain available at `http://localhost:6751/anvil`. + +- **GraphQL Playground**: An interactive IDE at `http://localhost:6751/graphql` for exploring the GraphQL server. + +- **Explorer**: Monitors Rollups application activity and manages transactions via `http://localhost:6751/explorer`. + +- **Inspect**: A diagnostic tool accessible at `http://localhost:6751/inspect/` to inspect the node’s state. + +- **Bundler**: A server accessible at `http://localhost:6751/bundler/rpc` to enable account abstraction by providing an alternative mempool for receiving and bundling user operations. + +- **Paymaster**: An account abstraction implementation that works hand in hand with the bundler to sponsor gas fees for transactions handled by the bundler, available at `http://localhost:6751/paymaster`. + +- **Passkey**: Runs a local passkey server, that enables account generation and interaction with application without a traditional wallet, available at `http://localhost:6751/passkey` + +:::note Testing tools +[NoNodo](https://github.com/Calindra/nonodo) is a Cartesi Rollups testing tool that works with host machine applications, eliminating the need for Docker or RISC-V compilation. +::: diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/send-inputs.md b/cartesi-rollups_versioned_docs/version-2.0/development/send-inputs.md index 93c0efce..84545c8c 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/send-inputs.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/send-inputs.md @@ -10,13 +10,13 @@ resources: You can send two requests to an application depending on whether you want to change or read the state. -- **Advance**: In this request, any input data changes the state of the dApp. +- **Advance**: In this request, any input data changes the state of the application. -- **Inspect**: This involves making an external HTTP API call to the Cartesi Node to read the dApp state without changing it. +- **Inspect**: This involves making an external HTTP API call to the Cartesi Node to read the application state without changing it. ## Advance and Inspect Requests -Here is a simple boilerplate application that handles Advance and Inspect requests: +Here is a simple boilerplate application that shows the default implementation of the handle_advance and handle_inspect functions: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -121,9 +121,9 @@ while True: -In a typical Cartesi backend application, two functions, `handle_advance` and `handle_inspect,` are defined to handle the two different types of requests. +As stated in the [creating an application section](./creating-an-application.md#implementing-your-application-logic), a typical Cartesi backend application has two primary functions, `handle_advance` and `handle_inspect,` these are defined to handle the two different types of requests. -This script listens to rollup requests, handles them asynchronously using defined handler functions, and communicates the completion status to the rollup server. +Your application listens to rollup requests, handles them asynchronously using defined handler functions, and communicates the completion status to the rollup server. Every starter project you create has this base code as a template, ready to receive inputs! @@ -131,11 +131,11 @@ Every starter project you create has this base code as a template, ready to rece You can initiate an advance request by sending input from the CLI using Cast, Cartesi CLI, or a custom frontend client. -Advance requests involve sending input data to the L1 through a JSON-RPC call, allowing the information to reach the dApp backend and trigger a change in the application's state. +Advance requests involve sending input data to the L1 through a JSON-RPC call, allowing the information to reach the applciation backend and trigger a change in the application's state. ![img](../../../static/img/v1.3/advance.jpg) -In the dApp architecture, here is how an advance request plays out. +In the application architecture, here is how an advance request plays out. - Step 1: Send an input to the [`addInput(address, bytes)`](../api-reference/json-rpc/input-box.md/#addinput) function of the InputBox smart contract. @@ -148,54 +148,47 @@ You can send inputs to your application with [Cast](https://book.getfoundry.sh/c #### 1. Send inputs with Cast ```shell -cast send "addInput(address,bytes)" --mnemonic +cast send "addInput(address,bytes)" --mnemonic ``` This command sends the payload to the InputBox smart contract, initiating the advance request. -Replace placeholders like ``, ``, ``, and `` with the actual addresses, payload, and mnemonic for your specific use case. +Replace placeholders like ``, ``, ``, and `` with the actual addresses, payload, and mnemonic for your specific use case. You can obtain the relevant addresses by running `cartesi address-book`. #### 2. Send inputs with Cartesi CLI -Cartesi CLI provides a convenient way of sending inputs to a dApp. +Cartesi CLI provides a convenient way of sending inputs to an application. Inputs to be sent to application could in either `Hex`, `String encoding` or `ABI encoding` format. -To send an input, run: +To send an input, you could use the interactive or the direct option, for the interactive option run: ```shell cartesi send ``` +Response: + ```shell $ cartesi send -? Select send sub-command (Use arrow keys) -❯ Send DApp address input to the application. - Send ERC-20 deposit to the application. - Send ERC-721 deposit to the application. - Send ether deposit to the application. - Send generic input to the application. +? Input (Use arrow keys) +❯ String encoding + Hex string encoding + ABI encoding ``` -There are five types of inputs using a sub-command: `dapp-address`, `erc20`, `erc721`, `ether`, `generic`. - -Unlike the asset-type sub-commands (Ether, ERC20, and ERC721), the generic input command allows you to send inputs with any payload format (hex, string, and ABI). +From the response menu you proceed to select the input format then enter the input. While for the more direct option run: ```shell -$ cartesi send generic -? Chain (Use arrow keys) -❯ Foundry -? Chain Foundry -? RPC URL http://127.0.0.1:8545 -? Wallet Mnemonic -? Mnemonic test test test test test test test test test test test junk -? Account 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 9999.969240390387558666 ETH -? DApp address 0x70ac08179605AF2D9e75782b8DEcDD3c22aA4D0C -? Input String encoding -? Input (as string) Hello World -✔ Input sent: 0x27a140b65feb714342a1dda31b6bfa2f8a83518231bb3b2da4bac506e0559007 +cartesi send --encoding ``` +For the above command, you replace `` with your input format choice (either `hex`, `string` or `abi`), then replace `` with your actual input text. + +:::note Sending Input from the Cartesi CLI? +Ensure you're calling the send command from the rood directory of your project else, you would need to provide the project RPC_URL and application address to interact with the application from any random terminal. +::: + #### 3. Send inputs via a custom web app You can create a custom frontend that interacts with your application. @@ -214,10 +207,12 @@ Inspect requests are best suited for non-production use, such as debugging and t You can make a simple inspect call from your frontend client to retrieve reports. -To perform an Inspect call, use an HTTP GET request to `
/inspect/`. For example: +To perform an Inspect call, use an HTTP POST request to `
/inspect/` with a body containing the request payload. For example: ```shell -curl http://localhost:8080/inspect/mypath +curl -X POST http://localhost:8080/inspect/0xb483897a2790a5D1a1C5413690bC5933f269b3A9 \ + -H "Content-Type: application/json" \ + -d '"test"' ``` Once the call's response is received, the payload is extracted from the response data, allowing the backend code to examine it and produce outputs as **reports**. @@ -225,9 +220,45 @@ Once the call's response is received, the payload is extracted from the response From a frontend client, here is an example of extracting the payload from an inspect request: ```javascript -const response = await fetch("http://localhost:8080/inspect/mypath"); +const response = await fetch("http://localhost:8080/inspect/0xb483897a2790a5D1a1C5413690bC5933f269b3A9", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify("test") +}); + const result = await response.json(); + for (let i in result.reports) { let payload = result.reports[i].payload; + console.log("Report Payload:", payload); } + ``` + +:::note Interacting with Sample application? +Replacing the above address `0xb48..3A9` with the application address from deploying the sample application in the [creating an application](./creating-an-application.md#implementing-your-application-logic), then executing the inspect command would emit a report which would immediately be logged to the CLI and can also be quarried using the JSON RPC or GraphQl server. +::: + +## Depositing Assets + +The Cartesi CLI also enables sending/depositing assets to your application. There are currently 3 types of supported assets: `Ether`, `erc20` and `erc721`. + +To deposit assets, run: + +```shell +cartesi deposit +``` + +Response: + +```shell +? Input (Use arrow keys) +❯ String encoding + Hex string encoding + ABI encoding +Convert UTF-8 string to bytes +``` + +The `cartesi deposit` command by default uses the default anvil account, and also the default test erc20 and erc721 contract to interact with your application, but this can all be modified to fit your purpose better. diff --git a/cartesi-rollups_versioned_docs/version-2.0/getting-started/index.md b/cartesi-rollups_versioned_docs/version-2.0/getting-started/index.md index 6be846ab..46981746 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/getting-started/index.md +++ b/cartesi-rollups_versioned_docs/version-2.0/getting-started/index.md @@ -28,7 +28,7 @@ In its simplest form, the Cartesi framework integrates tightly with the base lay ## Example -Below is a simple Node.js example demonstrating how to read an input and reply with a [notice](../api-reference/backend/notices.md) (a type of output). +Below is a simple Node.js example demonstrating how to read an input and reply with a [notice](./api-reference/backend/notices.md) (a type of output). ```javascript const { ethers } = require("ethers"); @@ -54,7 +54,7 @@ let finish = { status: "accept" }; ``` -Cartesi dApps are implemented as infinite loops that manage their transaction cycles through HTTP POST requests to the `/finish` endpoint to ensure flexibility across different programming languages and stacks. You can learn more about this abstraction [here](../api-reference/backend/introduction.md). +Cartesi dApps are implemented as infinite loops that manage their transaction cycles through HTTP POST requests to the `/finish` endpoint to ensure flexibility across different programming languages and stacks. You can learn more about this abstraction [here](./api-reference/backend/introduction.md). In the Cartesi Rollup framework, all inputs sent to the base layer trigger an "advance_state" [request](../development/send-inputs.md#initiate-an-advance-request), which alters the state of the Cartesi Machine and consequently the Rollup. Since inputs originate on-chain, they are hex-encoded following the EVM message standard. diff --git a/cartesi-rollups_versioned_docs/version-2.0/resources/community-tools.md b/cartesi-rollups_versioned_docs/version-2.0/resources/community-tools.md index a400e147..c403a64c 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/resources/community-tools.md +++ b/cartesi-rollups_versioned_docs/version-2.0/resources/community-tools.md @@ -92,6 +92,27 @@ Rollmelette is a high-level framework that simplifies building Cartesi applicati --- +## Crabrolls + +Introducing Crabroll, a powerful Rust framework designed to simplify the development of rust applications on Cartesi. + +- **Features**: + - Simplifies dApp development with intuitive methods. + - Handles advance and inspect requests easily. + - Comprehensive wallet functionality for ERC20, ERC721 and ERC-1155 token standards. + +- **Getting Started**: + - Create a new crabrolls project by running: + ```bash + git clone git@github.com:crabrolls-cartesi/template.git + ``` + +- **Resources**: + - [Crabrolls Documentation](https://crabrolls-cartesi.github.io/crabrolls/) + - [Crabrolls GitHub Repository](https://github.com/crabrolls-cartesi/crabrolls) + +--- + ## Python-Cartesi Python-Cartesi is a high-level framework that simplifies the development of Cartesi applications using Python. diff --git a/cartesi-rollups_versioned_docs/version-2.0/resources/migration-guide.md b/cartesi-rollups_versioned_docs/version-2.0/resources/migration-guide.md index 997ce3c4..0df74ba7 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/resources/migration-guide.md +++ b/cartesi-rollups_versioned_docs/version-2.0/resources/migration-guide.md @@ -28,182 +28,69 @@ If your application uses a high-level framework(ex. Deroll, Rollmelette etc.) fo In SDK v1, ERC-20 token deposit inputs start with a 1-byte Boolean field which indicates whether the transfer was successful or not: -``` -{ - success: Byte[1], - tokenAddress: Byte[20], - senderAddress: Byte[20], - amount: Byte[32], - execLayerData: Byte[], -} -``` +#### 1. Define the environment variables -In SDK v2, we modified the ERC-20 portal to only accept successful transactions. With this change, the success field would always be true, so it has been removed: +- `SALT`: A random 32-byte value for the deterministic deployment functions. +- `RPC_URL`: The RPC endpoint to be used. +- `MNEMONIC`: The mnemonic phrase for the Authority owner's wallet (other wallet options may be used). +- `HISTORY_FACTORY_ADDRESS`: The address of a valid HistoryFactory instance. +- `AUTHORITY_ADDRESS`: The address of the Authority instance used by the application. -``` -{ - tokenAddress: Byte[20], - senderAddress: Byte[20], - amount: Byte[32], - execLayerData: Byte[], -} -``` + :::note environment variables + A `HistoryFactory` is deployed at `0x1f158b5320BBf677FdA89F9a438df99BbE560A26` for all supported networks, including Ethereum, Optimism, Arbitrum, Base, and their respective Sepolia-based testnets. + ::: -### Ether withdrawal vouchers +#### 2. Instantiate a New _History_ -In SDK v1, Ether withdrawals were issued as vouchers targeting the application contract, and calling the withdrawEther function: +This is a two-step process. First calculate the address of the new History. After that, the new instance of History may be created. -``` -{ - destination: applicationAddress, - payload: abi.encodeWithSignature("withdrawEther(address,uint256)", recipient, value), -} -``` +- To calculate the address of a new _History_ contract call the `calculateHistoryAddress(address,bytes32)(address)` function with the help of Foundry's Cast: -In SDK v2, we have removed this function in favor of a simpler way, which uses the newly-added value field: + ```shell + cast call \ + --trace --verbose \ + $HISTORY_FACTORY_ADDRESS \ + "calculateHistoryAddress(address,bytes32)(address)" \ + $AUTHORITY_ADDRESS \ + $SALT \ + --rpc-url "$RPC_URL" + ``` -``` -{ - destination: recipient, - payload: "0x", - value: value, -} -``` + If the command executes successfully, it will display the address of the new History contract. Store this address in the environment variable `NEW_HISTORY_ADDRESS` for later use. -:::note -This value field can be used to pass Ether to payable functions. -::: +- Create a new instance of _History_ may be created by calling function `newHistory(address,bytes32)`: -### Application address - -In SDK v1, the application address could be sent to the machine via an input through the DAppAddressRelay contract. - -In SDK v2, the application address has been added to the input metadata, making it available in every input. This change allowed us to remove the DAppAddressRelay contract. - -Here is an example of a finish request response, according to the OpenAPI interface of the Rollup HTTP server: - -```json -{ - "request_type": "advance_state", - "data": { - "metadata": { - "chain_id": 42, - "app_contract": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "msg_sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "input_index": 123, - "block_number": 10000000, - "block_timestamp": 1588598533000, - "prev_randao": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "payload": "0xdeadbeef" - } -} -``` + ```shell + cast send \ + --json \ + --mnemonic "$MNEMONIC" \ + $HISTORY_FACTORY_ADDRESS \ + "newHistory(address,bytes32)(History)" \ + $AUTHORITY_ADDRESS \ + $SALT \ + --rpc-url "$RPC_URL" + ``` -### Outputs + The `cast send` command will fail if Cast does not recognize the _History_ type during execution. In such cases, replace _History_ with `address` as the return type for `newHistory()` and execute the command again. -In SDK v2, vouchers and notices are now stored in the same buffer inside the machine and in the same tree of the proof structure. They are encoded as Solidity function calls, each with its own signature. +The `cast send` command may also fail due to gas estimation issues. To circumvent this, provide gas constraints with the `--gas-limit` parameter (e.g., `--gas-limit 7000000`). -Now, any output can be validated, not just notices. We've also added a new type of executable output: `DELEGATECALL` vouchers. +#### 3. Replace the _History_ -#### Encoding +Ensure the environment variables from the previous step are set, including `NEW_HISTORY_ADDRESS`, which should have the address of the new History. -Outputs are encoded as Solidity function calls. For supported signatures, see the Outputs interface. Here are some examples: +To replace the _History_ used by the _Authority_, run this command: +```shell +cast send \ + --json \ + --mnemonic "$MNEMONIC" \ + "$AUTHORITY_ADDRESS" \ + "setHistory(address)" \ + "$NEW_HISTORY_ADDRESS" \ + --rpc-url "$RPC_URL" ``` -// Notice with payload "Hello, World!" encoded using ASCII -Notice(hex"48656c6c6f2c20576f726c6421") // 0xc258d6e50000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20576f726c642100000000000000000000000000000000000000 - -// Voucher to WETH token contract (on Mainnet), passing 1 ETH, calling the deposit() function -Voucher(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, 1000000000000000000, hex"d0e30db0") // 0x237a816f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004d0e30db000000000000000000000000000000000000000000000000000000000 -// DELEGATECALL voucher to Safe ERC-20 library (on Sepolia) -DelegateCallVoucher(0x817b126F242B5F184Fa685b4f2F91DC99D8115F9, hex"d1660f99000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa960450000000000000000000000000000000000000000000000000de0b6b3a7640000") // 0x10321e8b000000000000000000000000817b126f242b5f184fa685b4f2f91dc99d8115f900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064d1660f99000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa960450000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000 -``` - -#### Validation - -In SDK v1, only notices could be validated through the `validateNotice` function: - -```solidity -function validateNotice( - bytes calldata notice, - Proof calldata proof -) external view returns (bool success); -``` - -In SDK v2, any output can be validated with the function `validateOutput`: - -```solidity -function validateOutput( - bytes calldata output, - OutputValidityProof calldata proof -) external view; -``` - -#### Execution - -In SDK v1, only vouchers could be executed through the `executeVoucher` function: - -```solidity -function executeVoucher( - address destination, - bytes calldata payload, - Proof calldata proof -) external returns (bool success); -``` - -In SDK v2, both `CALL` and `DELEGATECALL` vouchers can be executed through the `executeOutput` function: - -```solidity -function executeOutput( - bytes calldata output, - OutputValidityProof calldata proof -) external; -``` - -#### Execution event - -In SDK v1, whenever a voucher was executed, a `VoucherExecution` event would be emitted: - -```solidity -event VoucherExecuted(uint256 voucherId); -``` - -In SDK v2, this event was renamed as `OutputExecuted`, and the parameters have changed: - -```solidity -event OutputExecuted(uint64 outputIndex, bytes output); -``` - -#### Execution check - -In SDK v1, one could check whether a voucher has been executed already by calling the `wasVoucherExecuted` function: - -```solidity -function wasVoucherExecuted( - uint256 inputIndex, - uint256 outputIndexWithinInput -) external view returns (bool executed); -``` - -In SDK v2, outputs are no longer attached to the inputs that generated them, so the now-called `wasOutputExecuted` function just receives the output index: - -```solidity -function wasOutputExecuted( - uint256 outputIndex -) external view returns (bool executed); -``` - -### Inspect calls - -In SDK v1, the `inspect` REST API call was GET type and the endpoint was `/inspect/`. - -In SDK v2, the `inspect` REST API call is POST type and the endpoint is `/inspect//`. - -### GraphQL queries - -In SDK v1, the GraphQL server was available at `/graphql`. - -In SDK v2, the GraphQL server is available at `/graphql/`. Although, in a single app environment, the SDK v1 endpoint should still work. Application address is relevant when multiple applications are deployed in the same node. +In SDK v2, we modified the ERC-20 portal to only accept successful transactions. With this change, the success field would always be true, so it has been removed: +When the Cartesi Rollups Node restarts, it processes all existing inputs, recalculates the epochs, and sends the claims to the new _History_ based on the updated configuration. diff --git a/cartesi-rollups_versioned_docs/version-2.0/tutorials/ether-wallet.md b/cartesi-rollups_versioned_docs/version-2.0/tutorials/ether-wallet.md index 83c234d4..6520ddcc 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/tutorials/ether-wallet.md +++ b/cartesi-rollups_versioned_docs/version-2.0/tutorials/ether-wallet.md @@ -122,7 +122,10 @@ Create a file named `balance.ts` in the `src/wallet` directory and add the follo import { Address } from "viem"; export class Balance { - constructor(private readonly address: Address, private ether: bigint = 0n) {} + constructor( + private readonly address: Address, + private ether: bigint = 0n + ) {} getEther(): bigint { return this.ether; diff --git a/cartesi-rollups_versioned_docs/version-2.0/tutorials/react-frontend-application.md b/cartesi-rollups_versioned_docs/version-2.0/tutorials/react-frontend-application.md index 5ebcdbe1..e5a1ad95 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/tutorials/react-frontend-application.md +++ b/cartesi-rollups_versioned_docs/version-2.0/tutorials/react-frontend-application.md @@ -1,346 +1,638 @@ --- id: react-frontend-application -title: Build a React frontend for Cartesi dApps +title: Build a React frontend for Cartesi Apps resources: - url: https://github.com/Mugen-Builders/cartesi-frontend-tutorial title: Source code for the frontend application - - url: https://www.michaelasiedu.dev/posts/deploy-erc20-token-on-localhost/ - title: Deploying an ERC20 Token for Localhost Testing and Adding to MetaMask - - url: https://www.michaelasiedu.dev/posts/deploy-erc721-token-on-localhost/ - title: Deploying an ERC721 Token for Localhost Testing and Adding to MetaMask --- -This tutorial will focus on building a frontend for a Cartesi dApp using [React.js](https://create-react-app.dev/docs/getting-started). Our primary goal is to create a minimalistic frontend with all the functionalities for seamless interactions with any Cartesi backend. +# Building a React Frontend for Cartesi Apps -## Setting up the environment +This is a comprehensive guide for building a React frontend that interacts with the deployed Cartesi applications using Cartesi TypeScript packages, wagmi hooks and viem library. -To build a frontend for Cartesi dApps, we'll use React.js along with [Wagmi](https://wagmi.sh/), a library that simplifies blockchain interactions in React applications. +## Installation -### Creating a new React project +The fastest way to get started is using `create-wagmi` to bootstrap a new React project in TypeScript with _wagmi_ already configured: -To get started quickly with a pre-configured React project that includes Wagmi, you can use the `create-wagmi` CLI command. For detailed instructions on setting up a Wagmi project, refer to [the official Wagmi documentation](https://wagmi.sh/react/getting-started). - -Install the following dependencies: -- [TailwindCSS](https://tailwindcss.com/docs/guides/vite) -- [Axios](https://axios-http.com/docs/intro) - -Once you've set up your project, you'll have a basic structure that includes: - -- A main configuration file for blockchain interactions -- A main App component -- An entry point file - -## Connecting wallet and chains - -The `wagmi.ts` file is the main configuration file for multiple chains and an `injected` connector. +```bash +pnpm create wagmi@latest my-cartesi-webapp +cd my-cartesi-webapp +``` -- Enhance the `wagmi.ts` configuration by adding all the chains supported by Cartesi Rollups. +Install the required Cartesi packages and dependencies: -- Replace the transports property with a Viem Client integration via the `client` property to have finer control over Wagmi’s internal client creation. +```bash +# Core Cartesi packages +pnpm add @cartesi/wagmi@2.0.0-alpha.10 @cartesi/viem@2.0.0-alpha.10 +``` +:::note +This guide has been tested with Cartesi CLI 2.0.0-alpha.11 pre-release. +::: -Edit the `src/wagmi.ts` file: +## Project Structure + +```plaintext +src/ +├── components/ +│ ├── CartesiInput.tsx # To send inputs +│ ├── CartesiOutputs.tsx # To read outputs +│ └── CartesiApps.tsx # To list all applications +├── providers/ +│ └── Web3Provider.tsx # Wagmi and Cartesi providers setup +├── wagmi.ts # Wagmi configuration file +├── App.tsx # Main application component +└── .env.local # Environment variables +``` -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +## Core Components - - -

+Before we begin writing the core components, make sure to configure _Cannon_ as your local chain in `wagmi.ts` file at the root of the project. This will make sure our web app is ready to interact with locally deployed Cartesi app. 
 
-```javascript
-import { http, createConfig } from "wagmi";
-import {
-  anvil,
-  arbitrum,
-  arbitrumGoerli,
-  base,
-  baseSepolia,
-  mainnet,
-  optimism,
-  optimismGoerli,
-  sepolia,
-} from "wagmi/chains";
-import { coinbaseWallet, injected, walletConnect } from "wagmi/connectors";
-import { createClient } from "viem";
+### 1. Configure the local environment 
+Modify the existing `wagmi.ts` file with the code below. We add support for locally running with `cannon` network.
+```tsx
+import { http, createConfig } from 'wagmi'
+import { cannon, mainnet, sepolia } from 'wagmi/chains'
+import { coinbaseWallet, injected } from 'wagmi/connectors'
 
 export const config = createConfig({
-  chains: [
-    anvil,
-    mainnet,
-    sepolia,
-    arbitrum,
-    arbitrumGoerli,
-    optimismGoerli,
-    optimism,
-    base,
-    baseSepolia,
-  ],
+  chains: [cannon, mainnet, sepolia],
   connectors: [
     injected(),
     coinbaseWallet(),
-    walletConnect({ projectId: import.meta.env.VITE_WC_PROJECT_ID }),
   ],
-  client({ chain }) {
-    return createClient({ chain, transport: http() });
+  transports: {
+    [cannon.id]: http(),
+    [mainnet.id]: http(),
+    [sepolia.id]: http(),
   },
-});
+})
 
-declare module "wagmi" {
+declare module 'wagmi' {
   interface Register {
-    config: typeof config;
+    config: typeof config
   }
 }
-
 ```
 
-
-
-
- -:::note supported networks -You can find the list of supported chains and their IDs in the [deployment guide](../deployment/introduction.md/#supported-networks). +:::note +WalletConnect is removed from the default wagmi setup. You can add it as per your project requirements. For this guide, we're using only Metamask wallet. ::: -### Building the Account component +Add the deployed Cartesi app address and Cartesi RPC URL to the `.env.local` file. +``` +VITE_CARTESI_APP_ADDRESS=<0x_your_app_address> +VITE_CARTESI_RPC_URL=http://localhost:8080/rpc +``` -Let's create an implementation for easy network switching and a comprehensive wallet management interface. -Move the account connection and management logic to a separate component for a cleaner and more organized `App.tsx`. +### 2. Setting up Providers -We will add [Tailwind CSS classes](https://tailwindcss.com/docs/guides/vite) to ensure visual appeal. +Create `src/providers/Web3Provider.tsx`: -Create a new file `src/components/Account.tsx` and edit the `App.tsx`: - - -

+```tsx
+import { CartesiProvider } from '@cartesi/wagmi';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { WagmiProvider } from 'wagmi';
+import { config } from '../wagmi'; 
 
-```jsx
-import { useAccount, useConnect, useDisconnect, useSwitchChain } from "wagmi";
-import { useState } from "react";
+const queryClient = new QueryClient();
 
-const Account = () => {
-  const account = useAccount();
-  const { connectors, connect, status, error } = useConnect();
-  const { disconnect } = useDisconnect();
-  const { chains, switchChain } = useSwitchChain();
-  const [isChainDropdownOpen, setIsChainDropdownOpen] = useState(false);
+// Local Cartesi node RPC endpoint
+const CARTESI_RPC_URL = import.meta.env.VITE_CARTESI_RPC_URL || 'http://localhost:8080/rpc';
 
+export function Web3Provider({ children }: { children: React.ReactNode }) {
   return (
-  
-
-

Account

- -
-

- Status: - - {account.status.toLocaleUpperCase()} -

-

- Address:{" "} - {account.addresses?.[0]} -

-

- Chain ID: {account.chain?.name} | {account.chainId} -

-
+ + + + {children} + + + + ); +} +``` - {/* Display chain switching and disconnect options when connected */} - {account.status === "connected" && ( -
- {/* Chain switching dropdown */} -
- - {/* Dropdown menu for chain options */} - {isChainDropdownOpen && ( -
- {chains.map((chainOption) => ( - - ))} -
- )} -
- {/* Disconnect button */} - +### 3. Sending Inputs to Cartesi Application +The `InputBox` contract is a trustless and permissionless contract that receives arbitrary blobs (called "inputs") from anyone. It is deployed on all supported chains. We will use `@cartesi/viem` library to send an input to the backend via the InputBox contract. + +Create `src/components/CartesiInput.tsx`: + +```tsx +import { useState } from 'react'; +import { useAccount, useWalletClient } from 'wagmi'; +import { stringToHex, type Address } from 'viem'; +import { walletActionsL1 } from '@cartesi/viem'; + +interface CartesiInputProps { + applicationAddress: Address; + } + +export function CartesiInput({ applicationAddress }: CartesiInputProps) { +const [input, setInput] = useState(''); +const [isLoading, setIsLoading] = useState(false); +const [txHash, setTxHash] = useState(''); + +const { address } = useAccount(); +const { data: walletClient } = useWalletClient(); + +const sendInput = async () => { + if (!walletClient || !address || !input.trim()) return; + + setIsLoading(true); + setTxHash(''); + + try { + // Extend wallet client with Cartesi L1 actions + const extendedClient = walletClient.extend(walletActionsL1()); + + // Convert input string to hex + const payload = stringToHex(input); + + // Send input to Cartesi application + const hash = await extendedClient.addInput({ + account: address, + application: applicationAddress, + payload, + chain: walletClient.chain, + }); + + setTxHash(hash); + setInput(''); + + console.log('Input sent with transaction hash:', hash); + } catch (error) { + console.error('Failed to send input:', error); + } finally { + setIsLoading(false); + } +}; + +return ( +
+

Send Input

+ +
+