L2 Services Registering and Using Oracle Network Services on L2 Chains
Registry Contract
This contract allows you to manage new chain and Orakl Network services.
L2 Chain Management
Please contact Orakl Network after you propose a new chain. We will support you to set things up.
Propose New Chain and Pay proposeFee
Copy 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);
}
Copy 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);
}
L2 Data Feeds Management
Copy function addAggregator (
uint256 chainID ,
address l1Aggregator ,
address l2Aggregator
) external onlyConfirmedChainOwner ( chainID ) {
AggregatorPair memory newAggregatorPair = AggregatorPair ({
aggregatorID : aggregatorCount[chainID] ++ ,
l1Aggregator : l1Aggregator ,
l2Aggregator : l2Aggregator
});
aggregators[chainID]. push (newAggregatorPair);
emit AggregatorAdded (chainID , newAggregatorPair.aggregatorID);
}
Copy function removeAggregator (
uint256 chainID ,
uint256 aggregatorID
) external onlyConfirmedChainOwner ( chainID ) {
AggregatorPair[] storage aggregatorInfo = aggregators[chainID];
for ( uint256 i = 0 ; i < aggregatorInfo.length; i ++ ) {
if (aggregatorInfo[i].aggregatorID == aggregatorID) {
// Move the last item to the current index to be removed
aggregatorInfo[i] = aggregatorInfo[aggregatorInfo.length - 1 ];
// Remove the last item from the list
aggregatorInfo. pop ();
emit AggregatorRemoved (chainID , aggregatorID);
break ; // Exit the loop once item is found and removed
}
}
}
Account and Payment Functions
Before you can make a request from L2 chain, you need to create and deposit to your account.
Copy 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 ++ ;
}
Deposit Funds Into the Account
Copy function deposit ( uint256 _accId ) public payable {
accounts[_accId].balance += msg.value;
emit BalanceIncreased (_accId , msg.value);
}
Add Consumer Into Account
Copy 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);
}
Remove Consumer From Account
Copy 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.
Copy function addAggregator ( address _newAggregator ) external onlyOwner {
if (sAggregators[_newAggregator]) revert InvalidAggregator (_newAggregator);
sAggregators[_newAggregator] = true ;
sAggregatorCount += 1 ;
emit AggregatorAdded (_newAggregator);
}
Copy function removeAggregator ( address _aggregator ) external onlyOwner {
if ( ! sAggregators[_aggregator]) revert InvalidAggregator (_aggregator);
delete sAggregators[_aggregator];
sAggregatorCount -= 1 ;
emit AggregatorRemoved (_aggregator);
}
Add L2 Data Feed Reporter
Copy function addSubmitter ( address _newSubmitter ) external onlyOwner {
if (sSubmitters[_newSubmitter]) revert InvalidSubmitter (_newSubmitter);
sSubmitters[_newSubmitter] = true ;
sSubmitterCount += 1 ;
emit SubmitterAdded (_newSubmitter);
}
Add L2 Data Feed Reporter
Copy function removeSubmitter ( address _submitter ) external onlyOwner {
if ( ! sSubmitters[_submitter]) revert InvalidSubmitter (_submitter);
delete sSubmitters[_submitter];
sSubmitterCount -= 1 ;
emit SubmitterRemoved (_submitter);
}
Request Random Words From L2
Copy 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;
}
Copy 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 Data Feed, VRF and Request-Response on L2
Data Feed
The use of Aggregator
and AggregatorProxy
smart contracts on L2 is the same as on the mainnet. Please refer to our Data Feed mock consumer contract .
VRF
Refer to L2 VRF mock consumer contract .
Inherit from the VRFConsumerBase
Contract
Copy contract L2VRFConsumerMock is VRFConsumerBase
Specify l2Endpoint
in the Constructor
Copy constructor ( address l2Endpoint) VRFConsumerBase (l2Endpoint) {
sOwner = msg.sender;
L2ENDPOINT = IL2Endpoint (l2Endpoint);
}
Implement the requestRandomWords
Function
Copy function requestRandomWords (
bytes32 keyHash ,
uint64 accId ,
uint32 callbackGasLimit ,
uint32 numWords
) public onlyOwner returns ( uint256 requestId) {
requestId = L2ENDPOINT. requestRandomWords (keyHash , accId , callbackGasLimit , numWords);
}
Implement the fulfillRandomWords
Function
Copy function fulfillRandomWords (
uint256 /* requestId */ ,
uint256 [] memory randomWords
) internal override {
sRandomWord = (randomWords[ 0 ] % 50 ) + 1 ;
}
Request-Response
Refer to L2 Request-Response mock consumer contract .
Inherit from the Base Contract for Request Data Types
Copy contract L2RequestResponseConsumerMock is
RequestResponseConsumerFulfillUint128 ,
RequestResponseConsumerFulfillInt256 ,
RequestResponseConsumerFulfillBool ,
RequestResponseConsumerFulfillString ,
RequestResponseConsumerFulfillBytes32 ,
RequestResponseConsumerFulfillBytes
Specify l2Endpoint
in the Constructor
Copy constructor ( address l2Endpoint) RequestResponseConsumerBase (l2Endpoint) {
sOwner = msg.sender;
L2ENDPOINT = IL2Endpoint (l2Endpoint);
}
Implement requestData*
Function
Copy //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);
}
Implement the fulfillDataRequest
Function
Copy function fulfillDataRequest ( uint256 /*requestId*/ , uint128 response) internal override {
sResponseUint128 = response;
}
Last updated 4 months ago