Skip to content

Phala-Network/phat-offchain-rollup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Phat Offchain Rollup

Phat Offchain Rollup is an SDK designed to simplify the process of connecting Phat Contracts to a wide range of blockchains. Its primary focus is on providing transactional and atomic cross-blockchain operations for seamless integration and interaction.

Table of Contents

The Challenge

Developing Phat Contracts that interact with blockchains can be a common but challenging task, especially when it comes to handling concurrency issues in off-chain programs. Without a proper synchronization mechanism, Phat Contract instances may end up conflicting with each other.

Consider a real-world scenario: a smart contract distributes computation tasks to Phat Contract workers. These workers compete with each other when claiming tasks from the blockchain. Ideally, each task should only be claimed once. However, without coordination among the workers, they might send transactions simultaneously to claim the same task, resulting in inconsistent smart contract states.

Consistent state management is crucial when developing a Phat Contract that communicates with a blockchain. Developers need a reliable and transactional way to perform operations, where read and write tasks are combined into a single unit and executed atomically on the blockchain. This approach aligns with the ACID principle found in transactional database management systems.

Offchain Rollup is here to simplify Phat Contract development by providing a stable, ACID-compliant connection to various blockchains. This eliminates concurrency issues and enables a request-response programming model for seamless interaction between Phat Contracts and on-chain smart contracts.

Key Benefits

  • An on-chain gateway contract that enables seamless connectivity to Phat Contracts
  • Reliable kv-store on blockchains for durable state management
    • Transactional (ACID) on-chain kv-store designed for stateful Phat Contracts
    • ACID-compliant read, write, and contract call operations for consistent data handling
  • Request-response programming model that simplifies interactions between Phat Contracts and on-chain smart contracts
  • Compatibility with EVM, Substrate, and ink!-powered blockchains for enhanced flexibility

Getting Started

To successfully use the Phat Offchain Rollup, follow these three steps illustrated in the diagram:

TODO: actor refactor

  1. Integrate the rollup client within the Phat Contract to establish a connection with the anchor.
  2. Deploy the Anchor contract onto the target blockchain.
  3. Integrate the anchor with your consumer contract (the smart contract that interacts with the Phat Contract).

The rest of this section will focus on the Rollup Client integration and provide a detailed explanation on how to utilize the Phat Contract. Deployment of the anchor contract and its integration with the consumer contract will be covered in the Integration section later.

Add the Cargo Dependency

If you are not familiar with developing Phat Contracts, you can start with the Setup Wiki Page for more information.

Update the Cargo.toml file in your Phat Contract project to include the phat-offchain-rollup dependency under the [dependencies] section:

phat_offchain_rollup = { git = "https://github.com/Phala-Network/phat-offchain-rollup.git", branch = "main", default-features = false, features = ["evm", "substrate"] }

Then, append the std feature to the [features] section as shown:

[features]
default = ["std"]
std = [
    "phat_offchain_rollup/std",
]

The features attribute allows you to control the rollup target chain activation. By default, all target chains are disabled to minimize the binary size. Enable them manually using the features attribute. The supported features include:

  • evm: enables the client to connect to the EVM rollup anchor contracts.
  • substrate: allows the client to connect to the Substrate rollup anchor pallet.
  • ink: enables the client to connect to the Ink! rollup anchor contracts.

Additionally, the logging feature can be utilized to display internal logs, including internet access, to the logger. This can be helpful for debugging purposes.

Using the Rollup Client

In this section, we will use the EvmRollupClient as an example. It's straightforward to replace it with Substrate or ink! rollup clients, if needed.

To work with Offchain Rollup, follow these steps:

1. Create an offchain rollup client:

let rpc = "http://localhost:8545";
let anchor_addr: H160 = hex!["e7f1725E7734CE288F8367e1Bb143E90bb3F0512"].into();
let client = EvmRollupClient::new(rpc, anchor_addr)
    .expect("failed to create rollup client");

The parameters represent:

  • rpc: The JSON-RPC endpoint of the target EVM compatible chain. It must be HTTPS or HTTP (for testing only).
  • anchor_addr: The deployed anchor contract address.

2. Access the core functionalities:

Read values from the KV store:

let key = b"some-key";
let value: Vec<u8> = client.session.get(key)
    .expect("failed to get value");

Write values to the KV store:

let key = b"some-key";
let value = b"some-value".to_vec();
client.session.put(key, value);

Remove an entry in the KV store:

let key = b"some-key";
client.session.delete(key);

Note that read operations may fail due to network issues when accessing the remote RPC endpoint. Write operations are temporarily saved to the rollup client in memory and will not be applied to the blockchain until committed.

3. Commit changes and submit the rollup transaction:

let maybe_submittable = client
    .commit()
    .expect("failed to commit");
if let Some(submittable) = maybe_submittable {
    let tx_id = submittable
        .submit(pair)
        .expect("failed to submit rollup tx");
}

Upon a successful submission, the client will broadcast the transaction and return the tx_id for future reference. Note that submitting a transaction doesn't guarantee that the transaction will be included in the blockchain.

Request-Response Programming Model

TODO: actor refactor

A common use case of offchain rollup is to establish a stable Request-Response connection between the Phat Contract and the blockchain. The anchor contract enables developers to push arbitrary messages to the request queue. For instance, in the EVM Rollup Anchor contract, this can be done as follows:

uint id = 1000;
string tradingPair = "polkadot/usd";
bytes message = abi.encode(id, tradingPair);
uint256 reqId = _pushMessage(message);

On the Phat Contract side, the rollup client can connect to the anchor, check the queue, and potentially reply to the requests.

// Get a request if available
if let Some(raw_req) = client
    .session()
    .pop()
    .expect("failed to read queue") {
    // let action: Vec<u8> = ... Create your response based on the raw_req ...
    client.action(Action::Reply(action));
}

The rollup client provides features to handle requests:

  • client.session().pop(): Returns an unprocessed request from the queue. Otherwise, returns None.
  • client.action(Action::Reply(action)): Adds a reply action to send an arbitrary Vec<u8> data blob back to the anchor contract.

The Reply actions should be paired with the pop(). Once a reply is committed and submitted to the target blockchain, the anchor contract will pop the pending request accordingly in an ACID way. If the Phat Contract fails in this process, developers can retry execution multiple times until successful.

Note that the error handling in the sample code above is simplified. In real-world scenarios, developers should carefully handle both retry-able and non-retry-able errors. For instance, retries might help with network problems, but not with decoding an invalid request.

Finally, the consumer contract can be configured to receive responses as shown below.

Solidity side:

function _onMessageReceived(bytes calldata message) internal override {
    emit MsgReceived(message);
}

Ink! side

fn _on_message_received(&mut self, action: Vec<u8>) -> Result<(), RollupAnchorError> {
    // do you business logic
}

Integration

To build an end-to-end project with offchain rollup, follow these steps to deploy the Offchain Rollup Anchor contract or pallet to the target blockchain and integrate it with the Consumer Contract. The rollup anchor is provided in this repository, while the consumer contract refers to the dApp that communicates with the Phat Contract.

Deploy Offchain Rollup Anchor

TODO: actor refactor

To deploy the EVM rollup anchor, follow these steps:

  1. Deploy the Phat Contract with a pre-generated ECDSA key pair (called submission key)
  2. (FIXIT) Deploy the contract: PhatRollupAnchor with the following parameters
    • PhatRollupAnchor()
    • attestor: The H160 address of the submission key
    • actionCallback: The address of the consumer contract to receive the response
  3. Transfer the ownership of PhatRollupAnchor to the consumer contract by calling anchor.transferOwnership(consumerContract)

Find a reference script here.

To deploy the Ink rollup anchor, follow these steps:

  1. Deploy the Phat Contract
    • Sample code: InkPriceFeed
    • During the instantiation, a sr2519 key pair is generated (called attestor key). This key is used to sign the messages sent to Ink! smart contract
  2. Deploy the Ink! smart contract:
    • Sample code: TestOracle
    • register the phat contract as attestor
  3. Configure the Phat Contract by sending a config() transaction with the arguments below:
    • rpc: The Substrate RPC for Phat Contract to send transaction. It must be a http endpoint.
    • pallet_id: The pallet id for Phat Contract to send transaction.
    • call_id: The call id for Phat Contract to send transaction. 6 in many cases.
    • contract id: The anchor Ink! contract you deployed on substrate node, with "0x".
    • sender_key: The sr25519 private key you used to pay the transaction fees, with "0x". Find a more detailed documentation here.

The Substrate pallet anchor deployment docs are currently under development (TODO).

Integrate with Your Contract

Detailed instructions for consumer contract integration are coming soon (TODO). In the meantime, please refer to provided examples:

Integration Resources

Through these steps and resources, developers can seamlessly integrate Offchain Rollup with their projects and create powerful Phat Contracts that interact with various blockchains efficiently and securely.

Technical Details

For an in-depth explanation of the project's technical aspects, please refer to the Technical Details page.

Examples and Use Cases

Explore various examples and use cases of Phat Offchain Rollup in action:

API Reference

Find API documentation for key components of the Phat Offchain Rollup SDK below:

As more features and integrations are developed, this README file will be updated accordingly to provide comprehensive documentation and resources for developers to make the most of the Phat Offchain Rollup SDK.

Contributing

See Development Notes.

License

The project is released under the Apache-2.0 license. This open-source license allows for the free use, modification, distribution, and commercial implementation of the software, while also ensuring that future contributions maintain the same level of open access. For more information about the specifics of the Apache-2.0 license, please visit Apache License 2.0.