Cartesi Rollups Contracts
The Cartesi Rollups Contracts are a set of Solidity smart contracts that provide Data Availability, Consensus and Settlement to Cartesi Rollups applications. They are completely permissionless, and can be deployed by anyone to any EVM-compatible chain. Nevertheless, the Cartesi Foundation, as a form of public good, kindly deploys them to Ethereum, Arbitrum, Optimism, Base, and their respective testnets.
Data Availability of user transactions and Consensus over their order is provided by the InputBox contract,
while Settlement is provided by the Application contract in conjunction with a settlement module.
Currently, we have implemented an authority-based module (Authority) and a quorum-based module (Quorum).
In the near future, we plan to support our very own fraud proof system, Dave.
The Cartesi Rollups Contracts are an integral part of the Cartesi Rollups SDK, and are used by the Cartesi Rollups Node, the Cartesi Rollups Explorer, and, of course, by Cartesi Rollups applications. Through simple Solidity interfaces, one can easily send and list user transactions, deposit assets, submit claims, execute asset withdrawal orders, and more.
Features
- Supports deposits and withdrawals of several types of assets:
- Supports the validation of outputs and output hashes
- Supports the execution of
CALLandDELEGATECALLvouchers - Supports Quorum and Authority-based settlement models
- Includes factory contracts for easy deployment
Getting started
First, please ensure the following dependencies are installed:
Then, you may clone the repository...
git clone https://github.com/cartesi/rollups-contracts.git
... and install the Node.js and Solidity packages.
pnpm install
forge soldeer install
Having done that, you can run a local devnet with Cannon.
It will be listening to 127.0.0.1:8545.
pnpm start
You can interact with the contracts by
pressing i on the terminal running Cannon,
or by running cast commands on another terminal.
The following command, for example,
calls the getDeploymentBlockNumber function
of the InputBox contract
deployed to the local devnet.
cast call $(jq -r .address deployments/InputBox.json) 'getDeploymentBlockNumber()(uint256)'
Documentation
A more in-depth documentation on the contracts can be found here.
Use cases
The Cartesi Rollups Contracts are used by the Cartesi Rollups SDK. They offer an extensible framework for input relays and output execution. Here are some examples of use cases:
- Trustless relaying of on-chain information
- Trustless locking of on-chain assets
- Withdrawal of on-chain assets
- Minting of on-chain assets
- Scheduling of on-chain actions
- Liquidity for on-chain assets
Related projects
The contracts are used by several other projects in the Cartesi ecosystem:
Authors
- Guilherme Dantas (guidanoli)
- Pedro Argento (pedroargento)
- Zehui Zheng (ZzzzHui)
License
The project is licensed under Apache-2.0.
Contents
IOwnable
The interface of OpenZeppelin's Ownable contract.
Functions
owner
function owner() external view returns (address);
renounceOwnership
function renounceOwnership() external;
transferOwnership
function transferOwnership(address newOwner) external;
Contents
CanonicalMachine
Defines several constants related to the reference implementation of the RISC-V machine that runs Linux, also known as the "Cartesi Machine".
State Variables
INPUT_MAX_SIZE
Maximum input size (64 kilobytes).
uint256 constant INPUT_MAX_SIZE = 1 << 16
LOG2_MAX_OUTPUTS
Log2 of maximum number of outputs.
uint256 constant LOG2_MAX_OUTPUTS = 63
DataAvailability
forge-lint: disable-start(mixed-case-function)
Defines the signatures of data availability solutions.
Functions
InputBox
The application receives inputs only from
a contract that implements the IInputBox interface.
function InputBox(IInputBox inputBox) external;
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box contract address |
InputBoxAndEspresso
The application receives inputs from
a contract that implements the IInputBox interface,
and from Espresso, starting from a given block height,
and for a given namespace ID.
function InputBoxAndEspresso(
IInputBox inputBox,
uint256 fromBlock,
uint32 namespaceId
) external;
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box contract address |
fromBlock | uint256 | Height of first Espresso block to consider |
namespaceId | uint32 | The Espresso namespace ID |
InputEncoding
Defines the encoding of inputs added by core trustless and permissionless contracts, such as portals.
Functions
encodeEtherDeposit
Encode an Ether deposit.
function encodeEtherDeposit(
address sender,
uint256 value,
bytes calldata execLayerData
) internal pure returns (bytes memory);
Parameters
| Name | Type | Description |
|---|---|---|
sender | address | The Ether sender |
value | uint256 | The amount of Wei being sent |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | The encoded input payload |
encodeERC20Deposit
Encode an ERC-20 token deposit.
function encodeERC20Deposit(
IERC20 token,
address sender,
uint256 value,
bytes calldata execLayerData
) internal pure returns (bytes memory);
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC20 | The token contract |
sender | address | The token sender |
value | uint256 | The amount of tokens being sent |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | The encoded input payload |
encodeERC721Deposit
Encode an ERC-721 token deposit.
baseLayerData should be forwarded to token.
function encodeERC721Deposit(
IERC721 token,
address sender,
uint256 tokenId,
bytes calldata baseLayerData,
bytes calldata execLayerData
) internal pure returns (bytes memory);
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC721 | The token contract |
sender | address | The token sender |
tokenId | uint256 | The token identifier |
baseLayerData | bytes | Additional data to be interpreted by the base layer |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | The encoded input payload |
encodeSingleERC1155Deposit
Encode an ERC-1155 single token deposit.
baseLayerData should be forwarded to token.
function encodeSingleERC1155Deposit(
IERC1155 token,
address sender,
uint256 tokenId,
uint256 value,
bytes calldata baseLayerData,
bytes calldata execLayerData
) internal pure returns (bytes memory);
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC1155 | The ERC-1155 token contract |
sender | address | The token sender |
tokenId | uint256 | The identifier of the token being transferred |
value | uint256 | Transfer amount |
baseLayerData | bytes | Additional data to be interpreted by the base layer |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | The encoded input payload |
encodeBatchERC1155Deposit
Encode an ERC-1155 batch token deposit.
baseLayerData should be forwarded to token.
function encodeBatchERC1155Deposit(
IERC1155 token,
address sender,
uint256[] calldata tokenIds,
uint256[] calldata values,
bytes calldata baseLayerData,
bytes calldata execLayerData
) internal pure returns (bytes memory);
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC1155 | The ERC-1155 token contract |
sender | address | The token sender |
tokenIds | uint256[] | The identifiers of the tokens being transferred |
values | uint256[] | Transfer amounts per token type |
baseLayerData | bytes | Additional data to be interpreted by the base layer |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | The encoded input payload |
Inputs
forge-lint: disable-start(mixed-case-function)
Defines the signatures of inputs.
Functions
EvmAdvance
An advance request from an EVM-compatible blockchain to a Cartesi Machine.
See EIP-4399 for safe usage of prevRandao.
function EvmAdvance(
uint256 chainId,
address appContract,
address msgSender,
uint256 blockNumber,
uint256 blockTimestamp,
uint256 prevRandao,
uint256 index,
bytes calldata payload
) external;
Parameters
| Name | Type | Description |
|---|---|---|
chainId | uint256 | The chain ID |
appContract | address | The application contract address |
msgSender | address | The address of whoever sent the input |
blockNumber | uint256 | The number of the block in which the input was added |
blockTimestamp | uint256 | The timestamp of the block in which the input was added |
prevRandao | uint256 | The latest RANDAO mix of the post beacon state of the previous block |
index | uint256 | The index of the input in the input box |
payload | bytes | The payload provided by the message sender |
OutputValidityProof
Proof of inclusion of an output in the output Merkle tree.
From the index and siblings, one can calculate the root of the Merkle tree.
The siblings array should have size equal to the log2 of the maximum number of outputs.
See the CanonicalMachine library for constants.
struct OutputValidityProof {
uint64 outputIndex;
bytes32[] outputHashesSiblings;
}
Properties
| Name | Type | Description |
|---|---|---|
outputIndex | uint64 | Index of output in the Merkle tree |
outputHashesSiblings | bytes32[] | Siblings of the output in the Merkle tree |
Outputs
forge-lint: disable-start(mixed-case-function)
Defines the signatures of outputs that can be generated by the off-chain machine and verified by the on-chain contracts.
Functions
Notice
A piece of verifiable information.
function Notice(bytes calldata payload) external;
Parameters
| Name | Type | Description |
|---|---|---|
payload | bytes | An arbitrary payload. |
Voucher
A single-use permission to execute a specific message call from the context of the application contract.
function Voucher(address destination, uint256 value, bytes calldata payload) external;
Parameters
| Name | Type | Description |
|---|---|---|
destination | address | The address that will be called |
value | uint256 | The amount of Wei to be transferred through the call |
payload | bytes | The payload, which—in the case of Solidity contracts—encodes a function call |
DelegateCallVoucher
A single-use permission to execute a specific delegate call from the context of the application contract.
function DelegateCallVoucher(address destination, bytes calldata payload) external;
Parameters
| Name | Type | Description |
|---|---|---|
destination | address | The address that will be called |
payload | bytes | The payload, which—in the case of Solidity libraries—encodes a function call |
Contents
Contents
Authority
Inherits: IAuthority, AbstractConsensus, Ownable
A consensus contract controlled by a single address, the owner.
This contract inherits from OpenZeppelin's Ownable contract.
For more information on Ownable, please consult OpenZeppelin's official documentation.
State Variables
_validatedEpochs
Epochs with a submitted (and accepted) claim, per application.
Epochs are stored in bitmap structure by their number (last processed block number / epoch length).
mapping(address => BitMaps.BitMap) _validatedEpochs
Functions
constructor
Reverts if the epoch length is zero.
constructor(address initialOwner, uint256 epochLength)
AbstractConsensus(epochLength)
Ownable(initialOwner);
Parameters
| Name | Type | Description |
|---|---|---|
initialOwner | address | The initial contract owner |
epochLength | uint256 | The epoch length |
submitClaim
Submit a claim to the consensus.
MUST fire a ClaimSubmitted event.
function submitClaim(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
) external override onlyOwner;
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
Returns the address of the current owner.
function owner() public view override(IOwnable, Ownable) returns (address);
renounceOwnership
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.
function renounceOwnership() public override(IOwnable, Ownable);
transferOwnership
Transfers ownership of the contract to a new account (newOwner).
Can only be called by the current owner.
function transferOwnership(address newOwner) public override(IOwnable, Ownable);
supportsInterface
function supportsInterface(bytes4 interfaceId)
public
view
override(IERC165, AbstractConsensus)
returns (bool);
AuthorityFactory
Inherits: IAuthorityFactory
Allows anyone to reliably deploy a new IAuthority contract.
Functions
newAuthority
function newAuthority(address authorityOwner, uint256 epochLength)
external
override
returns (IAuthority);
newAuthority
function newAuthority(address authorityOwner, uint256 epochLength, bytes32 salt)
external
override
returns (IAuthority);
calculateAuthorityAddress
function calculateAuthorityAddress(
address authorityOwner,
uint256 epochLength,
bytes32 salt
) external view override returns (address);
IAuthority
Inherits: IConsensus, IOwnable
A consensus contract controlled by a single address, the owner.
IAuthorityFactory
Functions
newAuthority
Deploy a new authority.
On success, MUST emit an AuthorityCreated event.
Reverts if the authority owner address is zero.
Reverts if the epoch length is zero.
function newAuthority(address authorityOwner, uint256 epochLength)
external
returns (IAuthority);
Parameters
| Name | Type | Description |
|---|---|---|
authorityOwner | address | The initial authority owner |
epochLength | uint256 | The epoch length |
Returns
| Name | Type | Description |
|---|---|---|
<none> | IAuthority | The authority |
newAuthority
Deploy a new authority deterministically.
On success, MUST emit an AuthorityCreated event.
Reverts if the authority owner address is zero.
Reverts if the epoch length is zero.
function newAuthority(address authorityOwner, uint256 epochLength, bytes32 salt)
external
returns (IAuthority);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | IAuthority | The authority |
calculateAuthorityAddress
Calculate the address of an authority to be deployed deterministically.
Beware that only the newAuthority function with the salt parameter
is able to deterministically deploy an authority.
function calculateAuthorityAddress(
address authorityOwner,
uint256 epochLength,
bytes32 salt
) external view returns (address);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The deterministic authority address |
Events
AuthorityCreated
A new authority was deployed.
MUST be triggered on a successful call to newAuthority.
event AuthorityCreated(IAuthority authority);
Parameters
| Name | Type | Description |
|---|---|---|
authority | IAuthority | The authority |
Contents
IQuorum
Inherits: IConsensus
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
Get the number of validators.
function numOfValidators() external view returns (uint256);
validatorId
Get the ID of a validator.
Validators have IDs greater than zero.
Non-validators are assigned to ID zero.
function validatorId(address validator) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
validator | address | The validator address |
validatorById
Get the address of a validator by its ID.
Validator IDs range from 1 to N, the total number of validators.
Invalid IDs map to address zero.
function validatorById(uint256 id) external view returns (address);
Parameters
| Name | Type | Description |
|---|---|---|
id | uint256 | The validator ID |
numOfValidatorsInFavorOfAnyClaimInEpoch
Get the number of validators in favor of any claim in a given epoch.
function numOfValidatorsInFavorOfAnyClaimInEpoch(
address appContract,
uint256 lastProcessedBlockNumber
) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Number of validators in favor of any claim in the epoch |
isValidatorInFavorOfAnyClaimInEpoch
Check whether a validator is in favor of any claim in a given epoch.
Assumes the provided ID is valid.
function isValidatorInFavorOfAnyClaimInEpoch(
address appContract,
uint256 lastProcessedBlockNumber,
uint256 id
) external view returns (bool);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | Whether validator is in favor of any claim in the epoch |
numOfValidatorsInFavorOf
Get the number of validators in favor of a claim.
function numOfValidatorsInFavorOf(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
) external view returns (uint256);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Number of validators in favor of claim |
isValidatorInFavorOf
Check whether a validator is in favor of a claim.
Assumes the provided ID is valid.
function isValidatorInFavorOf(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot,
uint256 id
) external view returns (bool);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | Whether validator is in favor of claim |
IQuorumFactory
Functions
newQuorum
Deploy a new quorum.
On success, MUST emit a QuorumCreated event.
Duplicates in the validators array are ignored.
Reverts if the epoch length is zero.
function newQuorum(address[] calldata validators, uint256 epochLength)
external
returns (IQuorum);
Parameters
| Name | Type | Description |
|---|---|---|
validators | address[] | the list of validators |
epochLength | uint256 | The epoch length |
Returns
| Name | Type | Description |
|---|---|---|
<none> | IQuorum | The quorum |
newQuorum
Deploy a new quorum deterministically.
On success, MUST emit a QuorumCreated event.
Duplicates in the validators array are ignored.
Reverts if the epoch length is zero.
function newQuorum(address[] calldata validators, uint256 epochLength, bytes32 salt)
external
returns (IQuorum);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | IQuorum | The quorum |
calculateQuorumAddress
Calculate the address of a quorum to be deployed deterministically.
Beware that only the newQuorum function with the salt parameter
is able to deterministically deploy a quorum.
function calculateQuorumAddress(
address[] calldata validators,
uint256 epochLength,
bytes32 salt
) external view returns (address);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The deterministic quorum address |
Events
QuorumCreated
A new quorum was deployed.
MUST be triggered on a successful call to newQuorum.
event QuorumCreated(IQuorum quorum);
Parameters
| Name | Type | Description |
|---|---|---|
quorum | IQuorum | The quorum |
Quorum
Inherits: IQuorum, AbstractConsensus
State Variables
_NUM_OF_VALIDATORS
The total number of validators.
See the numOfValidators function.
uint256 private immutable _NUM_OF_VALIDATORS
_validatorId
Validator IDs indexed by address.
See the validatorId function.
Non-validators are assigned to ID zero.
Validators have IDs greater than zero.
mapping(address => uint256) private _validatorId
_validatorById
Validator addresses indexed by ID.
See the validatorById function.
Invalid IDs map to address zero.
mapping(uint256 => address) private _validatorById
_allVotes
Votes indexed by application contract address, and last processed block number.
See the numOfValidatorsInFavorOfAnyClaimInEpoch
and isValidatorInFavorOfAnyClaimInEpoch functions.
mapping(address => mapping(uint256 => Votes)) private _allVotes
_votes
Votes indexed by application contract address, last processed block number and outputs Merkle root.
See the numOfValidatorsInFavorOf and isValidatorInFavorOf functions.
mapping(address => mapping(uint256 => mapping(bytes32 => Votes))) private _votes
Functions
constructor
Duplicates in the validators array are ignored.
Reverts if the epoch length is zero.
constructor(address[] memory validators, uint256 epochLength)
AbstractConsensus(epochLength);
Parameters
| Name | Type | Description |
|---|---|---|
validators | address[] | The array of validator addresses |
epochLength | uint256 | The epoch length |
submitClaim
function submitClaim(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
) external override;
numOfValidators
function numOfValidators() external view override returns (uint256);
validatorId
function validatorId(address validator) external view override returns (uint256);
validatorById
function validatorById(uint256 id) external view override returns (address);
numOfValidatorsInFavorOfAnyClaimInEpoch
function numOfValidatorsInFavorOfAnyClaimInEpoch(
address appContract,
uint256 lastProcessedBlockNumber
) external view override returns (uint256);
isValidatorInFavorOfAnyClaimInEpoch
function isValidatorInFavorOfAnyClaimInEpoch(
address appContract,
uint256 lastProcessedBlockNumber,
uint256 id
) external view override returns (bool);
numOfValidatorsInFavorOf
function numOfValidatorsInFavorOf(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
) external view override returns (uint256);
isValidatorInFavorOf
function isValidatorInFavorOf(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot,
uint256 id
) external view override returns (bool);
_getAllVotes
Get a Votes structure from storage from a given epoch.
function _getAllVotes(address appContract, uint256 lastProcessedBlockNumber)
internal
view
returns (Votes storage);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
Returns
| Name | Type | Description |
|---|---|---|
<none> | Votes | The Votes structure related to all claims in a given epoch |
_getVotes
Get a Votes structure from storage from a given claim.
function _getVotes(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
) internal view returns (Votes storage);
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 |
Returns
| Name | Type | Description |
|---|---|---|
<none> | Votes | The Votes structure related to a given claim |
supportsInterface
function supportsInterface(bytes4 interfaceId)
public
view
override(IERC165, AbstractConsensus)
returns (bool);
Structs
Votes
Votes in favor of a particular claim.
inFavorById is a bitmap indexed by validator IDs.
struct Votes {
uint256 inFavorCount;
BitMaps.BitMap inFavorById;
}
Properties
| Name | Type | Description |
|---|---|---|
inFavorCount | uint256 | The number of validators in favor of the claim |
inFavorById | BitMaps.BitMap | The set of validators in favor of the claim |
QuorumFactory
Inherits: IQuorumFactory
Allows anyone to reliably deploy a new IQuorum contract.
Functions
newQuorum
function newQuorum(address[] calldata validators, uint256 epochLength)
external
override
returns (IQuorum);
newQuorum
function newQuorum(address[] calldata validators, uint256 epochLength, bytes32 salt)
external
override
returns (IQuorum);
calculateQuorumAddress
function calculateQuorumAddress(
address[] calldata validators,
uint256 epochLength,
bytes32 salt
) external view override returns (address);
AbstractConsensus
Inherits: IConsensus, ERC165
Abstract implementation of IConsensus
State Variables
_EPOCH_LENGTH
The epoch length
uint256 internal immutable _EPOCH_LENGTH
_validOutputsMerkleRoots
Indexes accepted claims by application contract address.
mapping(address => mapping(bytes32 => bool)) private _validOutputsMerkleRoots
_numOfAcceptedClaims
Number of claims accepted by the consensus.
Must be monotonically non-decreasing in time
uint256 _numOfAcceptedClaims
Functions
constructor
Reverts if the epoch length is zero.
constructor(uint256 epochLength) ;
Parameters
| Name | Type | Description |
|---|---|---|
epochLength | uint256 | The epoch length |
isOutputsMerkleRootValid
Check whether an outputs Merkle root is valid.
function isOutputsMerkleRootValid(address appContract, bytes32 outputsMerkleRoot)
public
view
override
returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
outputsMerkleRoot | bytes32 | The outputs Merkle root |
getEpochLength
Get the epoch length, in number of base layer blocks.
The epoch number of a block is defined as the integer division of the block number by the epoch length.
function getEpochLength() public view override returns (uint256);
getNumberOfAcceptedClaims
Get the number of claims accepted by the consensus.
function getNumberOfAcceptedClaims() external view override returns (uint256);
supportsInterface
See {IERC165-supportsInterface}.
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(IERC165, ERC165)
returns (bool);
_validateLastProcessedBlockNumber
Validate a last processed block number.
function _validateLastProcessedBlockNumber(uint256 lastProcessedBlockNumber)
internal
view;
Parameters
| Name | Type | Description |
|---|---|---|
lastProcessedBlockNumber | uint256 | The number of the last processed block |
_acceptClaim
Accept a claim.
Marks the outputsMerkleRoot as valid.
Emits a ClaimAccepted event.
function _acceptClaim(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
) internal;
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
outputsMerkleRoot | bytes32 | The output Merkle root hash |
IConsensus
Inherits: IOutputsMerkleRootValidator
Each application has its own stream of inputs.
See the IInputBox interface for calldata-based on-chain data availability.
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
ClaimSubmittedevent) or; - already accepted by the consensus (see the
ClaimAcceptedevent).
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
Submit a claim to the consensus.
MUST fire a ClaimSubmitted event.
MAY fire a ClaimAccepted event, if the acceptance criteria is met.
function submitClaim(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
) external;
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 |
getEpochLength
Get the epoch length, in number of base layer blocks.
The epoch number of a block is defined as the integer division of the block number by the epoch length.
function getEpochLength() external view returns (uint256);
getNumberOfAcceptedClaims
Get the number of claims accepted by the consensus.
function getNumberOfAcceptedClaims() external view returns (uint256);
Events
ClaimSubmitted
MUST trigger when a claim is submitted.
event ClaimSubmitted(
address indexed submitter,
address indexed appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
);
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
MUST trigger when a claim is accepted.
For each application and lastProcessedBlockNumber, there can be at most one accepted claim.
event ClaimAccepted(
address indexed appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot
);
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 |
Errors
NotEpochFinalBlock
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).
error NotEpochFinalBlock(uint256 lastProcessedBlockNumber, uint256 epochLength);
Parameters
| Name | Type | Description |
|---|---|---|
lastProcessedBlockNumber | uint256 | The number of the last processed block |
epochLength | uint256 | The epoch length |
NotPastBlock
The claim contains the number of a block in the future (it is greater or equal to the current block number).
error NotPastBlock(uint256 lastProcessedBlockNumber, uint256 currentBlockNumber);
Parameters
| Name | Type | Description |
|---|---|---|
lastProcessedBlockNumber | uint256 | The number of the last processed block |
currentBlockNumber | uint256 | The number of the current block |
NotFirstClaim
A claim for that application and epoch was already submitted by the validator.
error NotFirstClaim(address appContract, uint256 lastProcessedBlockNumber);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
IOutputsMerkleRootValidator
Inherits: IERC165
Provides valid outputs Merkle roots for validation.
ERC-165 can be used to determine whether this contract also supports any other interface (e.g. for submitting claims).
Functions
isOutputsMerkleRootValid
Check whether an outputs Merkle root is valid.
function isOutputsMerkleRootValid(address appContract, bytes32 outputsMerkleRoot)
external
view
returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
outputsMerkleRoot | bytes32 | The outputs Merkle root |
Contents
- Application
- ApplicationFactory
- IApplication
- IApplicationFactory
- ISelfHostedApplicationFactory
- SelfHostedApplicationFactory
Application
Inherits: IApplication, Ownable, ERC721Holder, ERC1155Holder, ReentrancyGuard
State Variables
_DEPLOYMENT_BLOCK_NUMBER
Deployment block number
uint256 immutable _DEPLOYMENT_BLOCK_NUMBER = block.number
_TEMPLATE_HASH
The initial machine state hash.
See the getTemplateHash function.
bytes32 internal immutable _TEMPLATE_HASH
_executed
Keeps track of which outputs have been executed.
See the wasOutputExecuted function.
BitMaps.BitMap internal _executed
_outputsMerkleRootValidator
The current outputs Merkle root validator contract.
See the getOutputsMerkleRootValidator and migrateToOutputsMerkleRootValidator functions.
IOutputsMerkleRootValidator internal _outputsMerkleRootValidator
_dataAvailability
The data availability solution.
See the getDataAvailability function.
bytes internal _dataAvailability
_numOfExecutedOutputs
The number of outputs executed by the application.
See the numberOfOutputsExecuted function.
uint256 _numOfExecutedOutputs
Functions
constructor
Creates an Application contract.
Reverts if the initial application owner address is zero.
constructor(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address initialOwner,
bytes32 templateHash,
bytes memory dataAvailability
) Ownable(initialOwner);
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 |
receive
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.
receive() external payable;
executeOutput
Execute an output.
On a successful execution, emits a OutputExecuted event.
function executeOutput(bytes calldata output, OutputValidityProof calldata proof)
external
override
nonReentrant;
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 |
migrateToOutputsMerkleRootValidator
Migrate the application to a new outputs Merkle root validator.
Can only be called by the application owner.
function migrateToOutputsMerkleRootValidator(IOutputsMerkleRootValidator newOutputsMerkleRootValidator)
external
override
onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
newOutputsMerkleRootValidator | IOutputsMerkleRootValidator | The new outputs Merkle root validator |
wasOutputExecuted
Check whether an output has been executed.
function wasOutputExecuted(uint256 outputIndex)
external
view
override
returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
outputIndex | uint256 | The index of output |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | Whether the output has been executed before |
validateOutput
Validate an output.
May raise any of the errors raised by validateOutputHash.
function validateOutput(bytes calldata output, OutputValidityProof calldata proof)
public
view
override;
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
Validate an output hash.
May raise InvalidOutputHashesSiblingsArrayLength
or InvalidOutputsMerkleRoot.
function validateOutputHash(bytes32 outputHash, OutputValidityProof calldata proof)
public
view
override;
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
Get the application's template hash.
function getTemplateHash() external view override returns (bytes32);
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The application's template hash |
getOutputsMerkleRootValidator
Get the current outputs Merkle root validator.
function getOutputsMerkleRootValidator()
external
view
override
returns (IOutputsMerkleRootValidator);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IOutputsMerkleRootValidator | The current outputs Merkle root validator |
getDataAvailability
Get the data availability solution used by application.
function getDataAvailability() external view override returns (bytes memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | Solidity ABI-encoded function call that describes the source of inputs that should be fed to the application. |
getDeploymentBlockNumber
Get number of block in which contract was deployed
function getDeploymentBlockNumber() external view override returns (uint256);
getNumberOfExecutedOutputs
Get number of outputs executed by the application.
function getNumberOfExecutedOutputs() external view override returns (uint256);
owner
Returns the address of the current owner.
function owner() public view override(IOwnable, Ownable) returns (address);
renounceOwnership
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.
function renounceOwnership() public override(IOwnable, Ownable);
transferOwnership
Transfers ownership of the contract to a new account (newOwner).
Can only be called by the current owner.
function transferOwnership(address newOwner) public override(IOwnable, Ownable);
_isOutputsMerkleRootValid
Check if an outputs Merkle root is valid, according to the current outputs Merkle root validator.
function _isOutputsMerkleRootValid(bytes32 outputsMerkleRoot)
internal
view
returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
outputsMerkleRoot | bytes32 | The output Merkle root |
_executeVoucher
Executes a voucher
function _executeVoucher(bytes calldata arguments) internal;
Parameters
| Name | Type | Description |
|---|---|---|
arguments | bytes | ABI-encoded arguments |
_executeDelegateCallVoucher
Executes a delegatecall voucher
function _executeDelegateCallVoucher(bytes calldata arguments) internal;
Parameters
| Name | Type | Description |
|---|---|---|
arguments | bytes | ABI-encoded arguments |
ApplicationFactory
Inherits: IApplicationFactory
Allows anyone to reliably deploy a new IApplication contract.
Functions
newApplication
function newApplication(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability
) external override returns (IApplication);
newApplication
function newApplication(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external override returns (IApplication);
calculateApplicationAddress
function calculateApplicationAddress(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external view override returns (address);
IApplication
Inherits: IOwnable
The base layer incarnation of an application running on the execution layer.
The state of the application advances through inputs sent to an IInputBox contract.
These inputs can be sent either directly, or indirectly through portals.
Reader nodes can retrieve inputs sent to the IInputBox contract through events, and feed them into the machine.
Validator nodes can also submit claims to the IOutputsMerkleRootValidator contract (see the getOutputsMerkleRootValidator function).
Once accepted, claims can be used to validate outputs generated by the machine.
Some outputs are executable, which means they can have on-chain side effects.
Every application is subscribed to some outputs Merkle root validator, and may be governed by some owner. The outputs Merkle root validator has the power to accept claims, which, in turn, are used to validate outputs. Meanwhile, the owner can replace the outputs Merkle root validator at any time. Therefore, the users of an application must trust both the outputs Merkle root validator and the application owner.
There are several ownership models to choose from:
- no owner (address zero)
- individual signer (externally-owned account)
- multiple signers (multi-sig)
- DAO (decentralized autonomous organization)
- self-owned application (off-chain governance logic)
Functions
migrateToOutputsMerkleRootValidator
Migrate the application to a new outputs Merkle root validator.
Can only be called by the application owner.
function migrateToOutputsMerkleRootValidator(IOutputsMerkleRootValidator newOutputsMerkleRootValidator)
external;
Parameters
| Name | Type | Description |
|---|---|---|
newOutputsMerkleRootValidator | IOutputsMerkleRootValidator | The new outputs Merkle root validator |
executeOutput
Execute an output.
On a successful execution, emits a OutputExecuted event.
May raise any of the errors raised by validateOutput,
as well as OutputNotExecutable and OutputNotReexecutable.
function executeOutput(bytes calldata output, OutputValidityProof calldata proof)
external;
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 |
wasOutputExecuted
Check whether an output has been executed.
function wasOutputExecuted(uint256 outputIndex) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
outputIndex | uint256 | The index of output |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | Whether the output has been executed before |
validateOutput
Validate an output.
May raise any of the errors raised by validateOutputHash.
function validateOutput(bytes calldata output, OutputValidityProof calldata proof)
external
view;
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
Validate an output hash.
May raise InvalidOutputHashesSiblingsArrayLength
or InvalidOutputsMerkleRoot.
function validateOutputHash(bytes32 outputHash, OutputValidityProof calldata proof)
external
view;
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
Get the application's template hash.
function getTemplateHash() external view returns (bytes32);
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The application's template hash |
getOutputsMerkleRootValidator
Get the current outputs Merkle root validator.
function getOutputsMerkleRootValidator()
external
view
returns (IOutputsMerkleRootValidator);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IOutputsMerkleRootValidator | The current outputs Merkle root validator |
getDataAvailability
Get the data availability solution used by application.
function getDataAvailability() external view returns (bytes memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | Solidity ABI-encoded function call that describes the source of inputs that should be fed to the application. |
getDeploymentBlockNumber
Get number of block in which contract was deployed
function getDeploymentBlockNumber() external view returns (uint256);
getNumberOfExecutedOutputs
Get number of outputs executed by the application.
function getNumberOfExecutedOutputs() external view returns (uint256);
Events
OutputsMerkleRootValidatorChanged
MUST trigger when a new outputs Merkle root validator is chosen.
event OutputsMerkleRootValidatorChanged(IOutputsMerkleRootValidator newOutputsMerkleRootValidator);
Parameters
| Name | Type | Description |
|---|---|---|
newOutputsMerkleRootValidator | IOutputsMerkleRootValidator | The new outputs Merkle root validator |
OutputExecuted
MUST trigger when an output is executed.
event OutputExecuted(uint64 outputIndex, bytes output);
Parameters
| Name | Type | Description |
|---|---|---|
outputIndex | uint64 | The index of the output |
output | bytes | The output |
Errors
OutputNotExecutable
Could not execute an output, because the application contract doesn't know how to.
error OutputNotExecutable(bytes output);
Parameters
| Name | Type | Description |
|---|---|---|
output | bytes | The output |
OutputNotReexecutable
Could not execute an output, because it was already executed.
error OutputNotReexecutable(bytes output);
Parameters
| Name | Type | Description |
|---|---|---|
output | bytes | The output |
InsufficientFunds
Could not execute an output, because the application contract doesn't have enough Ether.
error InsufficientFunds(uint256 value, uint256 balance);
Parameters
| Name | Type | Description |
|---|---|---|
value | uint256 | The amount of Wei necessary for the execution of the output |
balance | uint256 | The current application contract balance |
InvalidOutputHashesSiblingsArrayLength
Raised when the output hashes siblings array has an invalid size.
Please consult CanonicalMachine for the maximum number of outputs.
error InvalidOutputHashesSiblingsArrayLength();
InvalidOutputsMerkleRoot
Raised when the computed outputs Merkle root is invalid, according to the current outputs Merkle root validator.
error InvalidOutputsMerkleRoot(bytes32 outputsMerkleRoot);
IApplicationFactory
Functions
newApplication
Deploy a new application.
On success, MUST emit an ApplicationCreated event.
Reverts if the application owner address is zero.
function newApplication(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability
) external returns (IApplication);
Parameters
| Name | Type | Description |
|---|---|---|
outputsMerkleRootValidator | IOutputsMerkleRootValidator | The initial outputs Merkle root validator contract |
appOwner | address | The initial application owner |
templateHash | bytes32 | The initial machine state hash |
dataAvailability | bytes |
Returns
| Name | Type | Description |
|---|---|---|
<none> | IApplication | The application |
newApplication
Deploy a new application deterministically.
On success, MUST emit an ApplicationCreated event.
Reverts if the application owner address is zero.
function newApplication(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external returns (IApplication);
Parameters
| Name | Type | Description |
|---|---|---|
outputsMerkleRootValidator | IOutputsMerkleRootValidator | The initial outputs Merkle root validator contract |
appOwner | address | The initial application owner |
templateHash | bytes32 | The initial machine state hash |
dataAvailability | bytes | |
salt | bytes32 | The salt used to deterministically generate the application contract address |
Returns
| Name | Type | Description |
|---|---|---|
<none> | IApplication | The application |
calculateApplicationAddress
Calculate the address of an application contract to be deployed deterministically.
Beware that only the newApplication function with the salt parameter
is able to deterministically deploy an application.
function calculateApplicationAddress(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external view returns (address);
Parameters
| Name | Type | Description |
|---|---|---|
outputsMerkleRootValidator | IOutputsMerkleRootValidator | The initial outputs Merkle root validator contract |
appOwner | address | The initial application owner |
templateHash | bytes32 | The initial machine state hash |
dataAvailability | bytes | |
salt | bytes32 | The salt used to deterministically generate the application contract address |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The deterministic application contract address |
Events
ApplicationCreated
A new application was deployed.
MUST be triggered on a successful call to newApplication.
event ApplicationCreated(
IOutputsMerkleRootValidator indexed outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes dataAvailability,
IApplication appContract
);
Parameters
| Name | Type | Description |
|---|---|---|
outputsMerkleRootValidator | IOutputsMerkleRootValidator | The initial outputs Merkle root validator contract |
appOwner | address | The initial application owner |
templateHash | bytes32 | The initial machine state hash |
dataAvailability | bytes | |
appContract | IApplication | The application contract |
ISelfHostedApplicationFactory
Functions
getAuthorityFactory
Get the factory used to deploy IAuthority contracts
function getAuthorityFactory() external view returns (IAuthorityFactory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IAuthorityFactory | The authority factory |
getApplicationFactory
Get the factory used to deploy IApplication contracts
function getApplicationFactory() external view returns (IApplicationFactory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IApplicationFactory | The application factory |
deployContracts
Deploy new application and authority contracts deterministically.
Reverts if the authority owner address is zero.
Reverts if the application owner address is zero.
Reverts if the epoch length is zero.
function deployContracts(
address authorityOwner,
uint256 epochLength,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external returns (IApplication, IAuthority);
Parameters
| Name | Type | Description |
|---|---|---|
authorityOwner | address | The initial authority owner |
epochLength | uint256 | The epoch length |
appOwner | address | The initial application owner |
templateHash | bytes32 | The initial machine state hash |
dataAvailability | bytes | |
salt | bytes32 | The salt used to deterministically generate the addresses |
Returns
| Name | Type | Description |
|---|---|---|
<none> | IApplication | The application contract |
<none> | IAuthority | The authority contract |
calculateAddresses
Calculate the addresses of the application and authority contracts to be deployed deterministically.
function calculateAddresses(
address authorityOwner,
uint256 epochLength,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external view returns (address, address);
Parameters
| Name | Type | Description |
|---|---|---|
authorityOwner | address | The initial authority owner |
epochLength | uint256 | The epoch length |
appOwner | address | The initial application owner |
templateHash | bytes32 | The initial machine state hash |
dataAvailability | bytes | |
salt | bytes32 | The salt used to deterministically generate the addresses |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The application address |
<none> | address | The authority address |
SelfHostedApplicationFactory
Inherits: ISelfHostedApplicationFactory
Allows anyone to reliably deploy a new IAuthority contract, along with an IApplication contract already linked to it.
State Variables
_AUTHORITY_FACTORY
IAuthorityFactory immutable _AUTHORITY_FACTORY
_APPLICATION_FACTORY
IApplicationFactory immutable _APPLICATION_FACTORY
Functions
constructor
constructor(
IAuthorityFactory authorityFactory,
IApplicationFactory applicationFactory
) ;
Parameters
| Name | Type | Description |
|---|---|---|
authorityFactory | IAuthorityFactory | The authority factory |
applicationFactory | IApplicationFactory | The application factory |
getAuthorityFactory
function getAuthorityFactory() external view override returns (IAuthorityFactory);
getApplicationFactory
function getApplicationFactory()
external
view
override
returns (IApplicationFactory);
deployContracts
function deployContracts(
address authorityOwner,
uint256 epochLength,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external returns (IApplication application, IAuthority authority);
calculateAddresses
function calculateAddresses(
address authorityOwner,
uint256 epochLength,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
bytes32 salt
) external view returns (address application, address authority);
Contents
SafeERC20Transfer
Functions
safeTransfer
function safeTransfer(IERC20 token, address to, uint256 value) external;
Contents
IInputBox
Provides data availability of inputs for applications.
Each application has its own append-only list of inputs.
Off-chain, inputs can be retrieved via events.
On-chain, only the input hashes are stored.
See LibInput for more details on how such hashes are computed.
Functions
addInput
Send an input to an application.
MUST fire an InputAdded event.
function addInput(address appContract, bytes calldata payload)
external
returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
payload | bytes | The input payload |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The hash of the input blob |
getNumberOfInputs
Get the number of inputs sent to an application.
function getNumberOfInputs(address appContract) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
getInputHash
Get the hash of an input in an application's input box.
The provided index must be valid.
function getInputHash(address appContract, uint256 index)
external
view
returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
index | uint256 | The input index |
getDeploymentBlockNumber
Get number of block in which contract was deployed
function getDeploymentBlockNumber() external view returns (uint256);
Events
InputAdded
MUST trigger when an input is added.
event InputAdded(address indexed appContract, uint256 indexed index, bytes input);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
index | uint256 | The input index |
input | bytes | The input blob |
Errors
InputTooLarge
Input is too large.
error InputTooLarge(address appContract, uint256 inputLength, uint256 maxInputLength);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
inputLength | uint256 | The input length |
maxInputLength | uint256 | The maximum input length |
InputBox
Inherits: IInputBox
State Variables
_DEPLOYMENT_BLOCK_NUMBER
Deployment block number
uint256 immutable _DEPLOYMENT_BLOCK_NUMBER = block.number
_inputBoxes
Mapping of application contract addresses to arrays of input hashes.
mapping(address => bytes32[]) private _inputBoxes
Functions
addInput
Send an input to an application.
MUST fire an InputAdded event.
function addInput(address appContract, bytes calldata payload)
external
override
returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
payload | bytes | The input payload |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The hash of the input blob |
getNumberOfInputs
Get the number of inputs sent to an application.
function getNumberOfInputs(address appContract)
external
view
override
returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
getInputHash
Get the hash of an input in an application's input box.
The provided index must be valid.
function getInputHash(address appContract, uint256 index)
external
view
override
returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
index | uint256 | The input index |
getDeploymentBlockNumber
Get number of block in which contract was deployed
function getDeploymentBlockNumber() external view override returns (uint256);
Contents
LibAddress
Functions
safeCall
Perform a low level call and raise error if failed
function safeCall(address destination, uint256 value, bytes memory payload)
internal
returns (bool, uint256);
Parameters
| Name | Type | Description |
|---|---|---|
destination | address | The address that will be called |
value | uint256 | The amount of Wei to be transferred through the call |
payload | bytes | The payload, which—in the case of Solidity contracts—encodes a function call |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | Whether the caller had enough Ether to make the call, and the balance before the call |
<none> | uint256 |
safeDelegateCall
Perform a delegate call and raise error if failed
function safeDelegateCall(address destination, bytes memory payload) internal;
Parameters
| Name | Type | Description |
|---|---|---|
destination | address | The address that will be called |
payload | bytes | The payload, which—in the case of Solidity libraries—encodes a function call |
LibError
Functions
raise
Raise error data
function raise(bytes memory errordata) internal pure;
Parameters
| Name | Type | Description |
|---|---|---|
errordata | bytes | Data returned by failed low-level call |
LibMerkle32
This library is meant for creating and verifying Merkle proofs.
Each Merkle tree is assumed to have 2^height leaves.
Nodes are concatenated pairwise and hashed with keccak256.
Siblings are in bottom-up order, from leaf to root.
Functions
merkleRoot
Compute the root of a Merkle tree from its leaves.
Raises an error if more than 2^height leaves are provided.
function merkleRoot(bytes32[] memory leaves, uint256 height)
internal
pure
returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
leaves | bytes32[] | The left-most leaves of the Merkle tree |
height | uint256 | The height of the Merkle tree |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The root hash of the Merkle tree |
siblings
Compute the siblings of the ancestors of a leaf in a Merkle tree.
Raises an error if the provided index is out of bounds.
Raises an error if more than 2^height leaves are provided.
function siblings(bytes32[] memory leaves, uint256 index, uint256 height)
internal
pure
returns (bytes32[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
leaves | bytes32[] | The left-most leaves of the Merkle tree |
index | uint256 | The index of the leaf |
height | uint256 | The height of the Merkle tree |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32[] | The siblings of the ancestors of the leaf in bottom-up order |
merkleRootAfterReplacement
Compute the root of a Merkle tree after replacing one of its leaves.
Raises an error if the provided index is out of bounds.
function merkleRootAfterReplacement(
bytes32[] calldata sibs,
uint256 index,
bytes32 leaf
) internal pure returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
sibs | bytes32[] | The siblings of the ancestors of the leaf in bottom-up order |
index | uint256 | The index of the leaf |
leaf | bytes32 | The new leaf |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The root hash of the new Merkle tree |
parent
Compute the parent of two nodes.
Uses assembly for extra performance
function parent(bytes32 leftNode, bytes32 rightNode)
internal
pure
returns (bytes32 parentNode);
Parameters
| Name | Type | Description |
|---|---|---|
leftNode | bytes32 | The left node |
rightNode | bytes32 | The right node |
Returns
| Name | Type | Description |
|---|---|---|
parentNode | bytes32 | The parent node |
parentLevel
Compute the parent level of an array of nodes.
The default node of a parent level is the parent node of two default nodes.
function parentLevel(bytes32[] memory nodes, bytes32 defaultNode)
internal
pure
returns (bytes32[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
nodes | bytes32[] | The array of left-most nodes |
defaultNode | bytes32 | The default node after the array |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32[] | The left-most nodes of the parent level |
at
Get the node at some index
function at(bytes32[] memory nodes, uint256 index, bytes32 defaultNode)
internal
pure
returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
nodes | bytes32[] | The array of left-most nodes |
index | uint256 | The index of the node |
defaultNode | bytes32 | The default node after the array |
LibOutputValidityProof
Functions
isSiblingsArrayLengthValid
function isSiblingsArrayLengthValid(OutputValidityProof calldata v)
internal
pure
returns (bool);
computeOutputsMerkleRoot
function computeOutputsMerkleRoot(OutputValidityProof calldata v, bytes32 outputHash)
internal
pure
returns (bytes32);
Contents
- ERC1155BatchPortal
- ERC1155SinglePortal
- ERC20Portal
- ERC721Portal
- EtherPortal
- IERC1155BatchPortal
- IERC1155SinglePortal
- IERC20Portal
- IERC721Portal
- IEtherPortal
- IPortal
- Portal
ERC1155BatchPortal
Inherits: IERC1155BatchPortal, Portal
This contract allows anyone to perform batch transfers of ERC-1155 tokens to an application contract while informing the off-chain machine.
Functions
constructor
Constructs the portal.
constructor(IInputBox inputBox) Portal(inputBox);
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box used by the portal |
depositBatchERC1155Token
function depositBatchERC1155Token(
IERC1155 token,
address appContract,
uint256[] calldata tokenIds,
uint256[] calldata values,
bytes calldata baseLayerData,
bytes calldata execLayerData
) external override;
ERC1155SinglePortal
Inherits: IERC1155SinglePortal, Portal
This contract allows anyone to perform single transfers of ERC-1155 tokens to an application contract while informing the off-chain machine.
Functions
constructor
Constructs the portal.
constructor(IInputBox inputBox) Portal(inputBox);
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box used by the portal |
depositSingleERC1155Token
function depositSingleERC1155Token(
IERC1155 token,
address appContract,
uint256 tokenId,
uint256 value,
bytes calldata baseLayerData,
bytes calldata execLayerData
) external override;
ERC20Portal
Inherits: IERC20Portal, Portal
This contract allows anyone to perform transfers of ERC-20 tokens to an application contract while informing the off-chain machine.
Functions
constructor
Constructs the portal.
constructor(IInputBox inputBox) Portal(inputBox);
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box used by the portal |
depositERC20Tokens
function depositERC20Tokens(
IERC20 token,
address appContract,
uint256 value,
bytes calldata execLayerData
) external override;
ERC721Portal
Inherits: IERC721Portal, Portal
This contract allows anyone to perform transfers of ERC-721 tokens to an application contract while informing the off-chain machine.
Functions
constructor
Constructs the portal.
constructor(IInputBox inputBox) Portal(inputBox);
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box used by the portal |
depositERC721Token
function depositERC721Token(
IERC721 token,
address appContract,
uint256 tokenId,
bytes calldata baseLayerData,
bytes calldata execLayerData
) external override;
EtherPortal
Inherits: IEtherPortal, Portal
This contract allows anyone to perform transfers of Ether to an application contract while informing the off-chain machine.
Functions
constructor
Constructs the portal.
constructor(IInputBox inputBox) Portal(inputBox);
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box used by the portal |
depositEther
function depositEther(address appContract, bytes calldata execLayerData)
external
payable
override;
IERC1155BatchPortal
Inherits: IPortal
Functions
depositBatchERC1155Token
Transfer a batch of ERC-1155 tokens of multiple types to an application contract
and add an input to the application's input box to signal such operation.
The caller must enable approval for the portal to manage all of their tokens
beforehand, by calling the setApprovalForAll function in the token contract.
Please make sure the arrays tokenIds and values have the same length.
function depositBatchERC1155Token(
IERC1155 token,
address appContract,
uint256[] calldata tokenIds,
uint256[] calldata values,
bytes calldata baseLayerData,
bytes calldata execLayerData
) external;
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC1155 | The ERC-1155 token contract |
appContract | address | The application contract address |
tokenIds | uint256[] | The identifiers of the tokens being transferred |
values | uint256[] | Transfer amounts per token type |
baseLayerData | bytes | Additional data to be interpreted by the base layer |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
IERC1155SinglePortal
Inherits: IPortal
Functions
depositSingleERC1155Token
Transfer ERC-1155 tokens of a single type to an application contract
and add an input to the application's input box to signal such operation.
The caller must enable approval for the portal to manage all of their tokens
beforehand, by calling the setApprovalForAll function in the token contract.
function depositSingleERC1155Token(
IERC1155 token,
address appContract,
uint256 tokenId,
uint256 value,
bytes calldata baseLayerData,
bytes calldata execLayerData
) external;
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC1155 | The ERC-1155 token contract |
appContract | address | The application contract address |
tokenId | uint256 | The identifier of the token being transferred |
value | uint256 | Transfer amount |
baseLayerData | bytes | Additional data to be interpreted by the base layer |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
IERC20Portal
Inherits: IPortal
Functions
depositERC20Tokens
Transfer ERC-20 tokens to an application contract
and add an input to the application's input box to signal such operation.
The caller must allow the portal to withdraw at least value tokens
from their account beforehand, by calling the approve function in the
token contract.
function depositERC20Tokens(
IERC20 token,
address appContract,
uint256 value,
bytes calldata execLayerData
) external;
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC20 | The ERC-20 token contract |
appContract | address | The application contract address |
value | uint256 | The amount of tokens to be transferred |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
Errors
ERC20TransferFailed
Failed to transfer ERC-20 tokens to application
error ERC20TransferFailed();
IERC721Portal
Inherits: IPortal
Functions
depositERC721Token
Transfer an ERC-721 token to an application contract
and add an input to the application's input box to signal such operation.
The caller must change the approved address for the ERC-721 token
to the portal address beforehand, by calling the approve function in the
token contract.
function depositERC721Token(
IERC721 token,
address appContract,
uint256 tokenId,
bytes calldata baseLayerData,
bytes calldata execLayerData
) external;
Parameters
| Name | Type | Description |
|---|---|---|
token | IERC721 | The ERC-721 token contract |
appContract | address | The application contract address |
tokenId | uint256 | The identifier of the token being transferred |
baseLayerData | bytes | Additional data to be interpreted by the base layer |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
IEtherPortal
Inherits: IPortal
Functions
depositEther
Transfer Ether to an application contract and add an input to the application's input box to signal such operation.
Any Ether sent through this function will be forwarded to the application contract.
If the transfer fails, an EtherTransferFailed error will be raised.
function depositEther(address appContract, bytes calldata execLayerData)
external
payable;
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
execLayerData | bytes | Additional data to be interpreted by the execution layer |
Errors
EtherTransferFailed
Failed to transfer Ether to application
error EtherTransferFailed();
IPortal
Functions
getInputBox
Get the input box used by this portal.
function getInputBox() external view returns (IInputBox);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IInputBox | The input box |
Portal
Inherits: IPortal
This contract serves as a base for all the other portals.
State Variables
_INPUT_BOX
The input box used by the portal.
IInputBox internal immutable _INPUT_BOX
Functions
constructor
Constructs the portal.
constructor(IInputBox inputBox) ;
Parameters
| Name | Type | Description |
|---|---|---|
inputBox | IInputBox | The input box used by the portal |
getInputBox
function getInputBox() external view override returns (IInputBox);