Orakl Network
  • Developer's Guide
    • Introduction
    • Verifiable Randomness Function (VRF)
    • Request-Response
    • Data Feed
    • Proof of Reserve
    • Prepayment
    • L2 Services
    • Data Availability Layer API (DAL)
    • Example Projects
      • Binary Option Example
      • Flipcoin Example
      • Mystery Box Example
  • Node Operator's Guide
    • Introduction
    • Orakl Network API
    • Orakl Network CLI
      • Chain
      • Service
      • Listener
      • VRF Keys
      • Reporter
      • Fetcher
      • Delegator
    • Orakl Network VRF
    • Orakl Network Request-Response
    • Orakl Network Data Feed
    • Orakl Network Delegator
    • Orakl Network Proof of Reserve
  • Other Resources
    • Audit
    • White paper
    • Social Media
    • Terms of Use
Powered by GitBook
On this page
  • Registry Contract
  • L2 Chain Management
  • Account and Payment Functions
  • Endpoint Contracts
  • L2Endpoint
  • How to Integrate VRF and Request-Response on L2
  • VRF
  • Request-Response
  1. Developer's Guide

L2 Services

Registering and Using Oracle Network Services on L2 Chains

PreviousPrepaymentNextData Availability Layer API (DAL)

Last updated 10 months ago

Registry Contract

This contract allows you to manage new chain and Orakl Network services.

L2 Chain Management

Please contact after you propose a new chain. We will support you to set things up.

  1. Propose New Chain and Pay proposeFee

function proposeNewChain(
    uint256 _chainID,
    string memory _jsonRpc,
    address _endpoint
) external payable {
    if (msg.value < proposeFee) {
        revert NotEnoughFee();
    }
    if (chainRegistry[_chainID].owner != address(0)) {
        revert ChainExisted();
    }
    pendingProposal[_chainID].jsonRpc = _jsonRpc;
    pendingProposal[_chainID].endpoint = _endpoint;
    pendingProposal[_chainID].owner = msg.sender;
    emit ChainProposed(msg.sender, _chainID);
}
  1. Edit Chain Info

function editChainInfo(
    uint256 _chainID,
    string memory _jsonRpc,
    address _endpoint
) external payable onlyConfirmedChainOwner(_chainID) {
    if (msg.value < proposeFee) {
        revert NotEnoughFee();
    }

    chainRegistry[_chainID].jsonRpc = _jsonRpc;
    chainRegistry[_chainID].endpoint = _endpoint;
    emit ChainEdited(_jsonRpc, _endpoint);
}

Account and Payment Functions

Before you can make a request from L2 chain, you need to create and deposit to your account.

  1. Create Account

function createAccount(uint256 _chainId) external onlyConfirmedChain(_chainId) {
    Account storage newAccount = accounts[nextAccountId];
    newAccount.accId = nextAccountId;
    newAccount.chainId = _chainId;
    newAccount.owner = msg.sender;
    newAccount.balance = 0;
    emit AccountCreated(nextAccountId, _chainId, msg.sender);
    nextAccountId++;
}
  1. Deposit Funds Into the Account

function deposit(uint256 _accId) public payable {
    accounts[_accId].balance += msg.value;
    emit BalanceIncreased(_accId, msg.value);
}
  1. Add Consumer Into Account

function addConsumer(
    uint256 _accId,
    address _consumerAddress
) external onlyAccountOwner(_accId) {
    Account storage account = accounts[_accId];
    require(account.consumerCount < MAX_CONSUMER, "Max consumers reached");

    account.consumers.push(_consumerAddress);
    account.consumerCount++;

    emit ConsumerAdded(_accId, _consumerAddress);
}
  1. Remove Consumer From Account

function removeConsumer(
    uint256 _accId,
    address _consumerAddress
) external onlyAccountOwner(_accId) {
    require(_accId > 0 && _accId < nextAccountId, "Account does not exist");
    Account storage account = accounts[_accId];

    for (uint8 i = 0; i < account.consumerCount; i++) {
        address[] storage consumers = account.consumers;
        if (consumers[i] == _consumerAddress) {
            account.consumerCount--;
            consumers[i] = consumers[account.consumerCount];
            consumers.pop();
            emit ConsumerRemoved(_accId, _consumerAddress);
            return;
        }
    }
}

The consumer address to add or remove to this account is on L2 chain, not mainnet.

Endpoint Contracts

L2Endpoint

You need to deploy this contract on your chain; it acts as a coordinator for VRF and Request-Response.

  1. Request Random Words From L2

function requestRandomWords(
    bytes32 keyHash,
    uint64 accId,
    uint32 callbackGasLimit,
    uint32 numWords
) external nonReentrant returns (uint256) {
    sNonce++;
    (uint256 requestId, uint256 preSeed) = computeRequestId(keyHash, msg.sender, accId, sNonce);
    sRequestDetail[requestId] = RequestInfo({
        owner: msg.sender,
        callbackGasLimit: callbackGasLimit
    });
    emit RandomWordsRequested(
        keyHash,
        requestId,
        preSeed,
        accId,
        callbackGasLimit,
        numWords,
        msg.sender
    );

    return requestId;
}
  1. Request Data From L2

function requestData(
    Orakl.Request memory req,
    uint32 callbackGasLimit,
    uint64 accId,
    uint8 numSubmission
) external nonReentrant returns (uint256) {
    sNonce++;
    uint256 requestId = computeRequestId(msg.sender, accId, sNonce);
    sRequestDetail[requestId] = RequestInfo({
        owner: msg.sender,
        callbackGasLimit: callbackGasLimit
    });
    emit DataRequested(
        requestId,
        req.id,
        accId,
        callbackGasLimit,
        msg.sender,
        numSubmission,
        req
    );

    return requestId;
}

How to Integrate VRF and Request-Response on L2

VRF

  1. Inherit from the VRFConsumerBase Contract

contract L2VRFConsumerMock is VRFConsumerBase
  1. Specify l2Endpoint in the Constructor

constructor(address l2Endpoint) VRFConsumerBase(l2Endpoint) {
    sOwner = msg.sender;
    L2ENDPOINT = IL2Endpoint(l2Endpoint);
}
  1. Implement the requestRandomWords Function

 function requestRandomWords(
    bytes32 keyHash,
    uint64 accId,
    uint32 callbackGasLimit,
    uint32 numWords
) public onlyOwner returns (uint256 requestId) {
    requestId = L2ENDPOINT.requestRandomWords(keyHash, accId, callbackGasLimit, numWords);
}
  1. Implement the fulfillRandomWords Function

function fulfillRandomWords(
    uint256 /* requestId */,
    uint256[] memory randomWords
) internal override {
    sRandomWord = (randomWords[0] % 50) + 1;
}

Request-Response

  1. Inherit from the Base Contract for Request Data Types

contract L2RequestResponseConsumerMock is
    RequestResponseConsumerFulfillUint128,
    RequestResponseConsumerFulfillInt256,
    RequestResponseConsumerFulfillBool,
    RequestResponseConsumerFulfillString,
    RequestResponseConsumerFulfillBytes32,
    RequestResponseConsumerFulfillBytes
  1. Specify l2Endpoint in the Constructor

constructor(address l2Endpoint) RequestResponseConsumerBase(l2Endpoint) {
    sOwner = msg.sender;
    L2ENDPOINT = IL2Endpoint(l2Endpoint);
}
  1. Implement requestData* Function

//request for uint128
function requestDataUint128(
    uint64 accId,
    uint32 callbackGasLimit,
    uint8 numSubmission
) public onlyOwner returns (uint256 requestId) {
    bytes32 jobId = keccak256(abi.encodePacked("uint128"));
    Orakl.Request memory req = buildRequest(jobId);
    //change here for your expected data
    req.add(
        "get",
        "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=KLAY&tsyms=USD"
    );
    req.add("path", "RAW,KLAY,USD,PRICE");
    req.add("pow10", "8");
    requestId = L2ENDPOINT.requestData(req, callbackGasLimit, accId, numSubmission);
}
  1. Implement the fulfillDataRequest Function

function fulfillDataRequest(uint256 /*requestId*/, uint128 response) internal override {
    sResponseUint128 = response;
}

Refer to .

Refer to .

L2 VRF mock consumer contract
L2 Request-Response mock consumer contract
Orakl Network
Registry Contract
Endpoint Contracts
How to Integrate VRF and Request-Response on L2
VRF
Request-Response