getCurrentEpoch
curl --request POST \
--url https://api.example.com/eth_callimport requests
url = "https://api.example.com/eth_call"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/eth_call', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/eth_call",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/eth_call"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/eth_call")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/eth_call")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"result": {}
}eth_* Methods
getCurrentEpoch
Get the current epoch number
POST
eth_call
getCurrentEpoch
curl --request POST \
--url https://api.example.com/eth_callimport requests
url = "https://api.example.com/eth_call"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/eth_call', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/eth_call",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/eth_call"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/eth_call")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/eth_call")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"result": {}
}Overview
Queries the FenineSystem contract to get the current epoch number. Epochs are periods of 200 blocks where validator set updates and reward distributions occur.Contract Call Details
address
required
0x0000000000000000000000000000000000001000 (FenineSystem)bytes
required
Function call:
getCurrentEpoch()Response
uint256
Current epoch number (0-indexed)
Examples
const Web3 = require('web3');
const web3 = new Web3('https://rpc.fene.app');
const abi = JSON.parse(await web3.getSystemContractABI());
const contract = new web3.eth.Contract(
abi,
'0x0000000000000000000000000000000000001000'
);
const epoch = await contract.methods.getCurrentEpoch().call();
console.log('Current epoch:', epoch);
// Also calculate manually from block number
const currentBlock = await web3.eth.getBlockNumber();
const EPOCH_BLOCKS = 200;
const calculatedEpoch = Math.floor(currentBlock / EPOCH_BLOCKS);
console.log('Block:', currentBlock);
console.log('Calculated epoch:', calculatedEpoch);
console.log('Match:', epoch == calculatedEpoch);
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('https://rpc.fene.app');
const abiJson = await provider.send('fenine_getSystemContractABI', []);
const abi = JSON.parse(abiJson);
const contract = new ethers.Contract(
'0x0000000000000000000000000000000000001000',
abi,
provider
);
const epoch = await contract.getCurrentEpoch();
console.log('Current epoch:', Number(epoch));
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('https://rpc.fene.app'))
system_contract = w3.eth.contract(
address='0x0000000000000000000000000000000000001000',
abi=system_abi
)
epoch = system_contract.functions.getCurrentEpoch().call()
print(f'Current epoch: {epoch}')
Epoch Calculation
You can also calculate the epoch from the current block number:const currentBlock = await web3.eth.getBlockNumber();
const EPOCH_BLOCKS = 200;
const currentEpoch = Math.floor(currentBlock / EPOCH_BLOCKS);
const blockInEpoch = currentBlock % EPOCH_BLOCKS;
const blocksUntilNextEpoch = EPOCH_BLOCKS - blockInEpoch;
console.log({
currentBlock,
currentEpoch,
blockInEpoch,
blocksUntilNextEpoch,
estimatedTimeUntilNext: (blocksUntilNextEpoch * 3 / 60).toFixed(1) + ' minutes'
});
Use Cases
Monitor Epoch Transitions
Monitor Epoch Transitions
async function monitorEpochTransitions() {
let lastEpoch = await contract.methods.getCurrentEpoch().call();
setInterval(async () => {
const currentEpoch = await contract.methods.getCurrentEpoch().call();
if (currentEpoch != lastEpoch) {
console.log('='.repeat(50));
console.log('NEW EPOCH:', currentEpoch);
console.log('='.repeat(50));
// Fetch updated data
const validators = await contract.methods.getActiveValidators().call();
const totalStake = await contract.methods.totalNetworkStake().call();
console.log('Active validators:', validators.length);
console.log('Total stake:', web3.utils.fromWei(totalStake, 'ether'), 'FEN');
lastEpoch = currentEpoch;
// Trigger your application logic
// e.g., refresh dashboard, recalculate rewards, etc.
}
}, 3000); // Check every block (~3s)
}
Calculate Time Until Next Epoch
Calculate Time Until Next Epoch
async function getTimeUntilNextEpoch() {
const currentBlock = await web3.eth.getBlockNumber();
const EPOCH_BLOCKS = 200;
const BLOCK_TIME = 3; // seconds
const currentEpoch = Math.floor(currentBlock / EPOCH_BLOCKS);
const blockInEpoch = currentBlock % EPOCH_BLOCKS;
const blocksRemaining = EPOCH_BLOCKS - blockInEpoch;
const secondsRemaining = blocksRemaining * BLOCK_TIME;
const minutesRemaining = secondsRemaining / 60;
return {
currentEpoch,
currentBlock,
blockInEpoch: `${blockInEpoch}/${EPOCH_BLOCKS}`,
progress: ((blockInEpoch / EPOCH_BLOCKS) * 100).toFixed(1) + '%',
blocksRemaining,
timeRemaining: {
seconds: secondsRemaining,
minutes: minutesRemaining.toFixed(1),
formatted: `${Math.floor(minutesRemaining)}m ${secondsRemaining % 60}s`
}
};
}
Build Epoch History
Build Epoch History
async function buildEpochHistory(epochCount = 10) {
const currentEpoch = await contract.methods.getCurrentEpoch().call();
const currentBlock = await web3.eth.getBlockNumber();
const history = [];
for (let i = 0; i < epochCount; i++) {
const epoch = parseInt(currentEpoch) - i;
if (epoch < 0) break;
const epochStartBlock = epoch * 200;
const epochEndBlock = epochStartBlock + 199;
// Get block timestamps (if needed)
// const startBlockData = await web3.eth.getBlock(epochStartBlock);
history.push({
epoch,
startBlock: epochStartBlock,
endBlock: epochEndBlock,
isComplete: currentBlock > epochEndBlock,
isCurrent: epoch == currentEpoch
});
}
return history;
}
Schedule Action at Next Epoch
Schedule Action at Next Epoch
async function scheduleAtNextEpoch(callback) {
const currentBlock = await web3.eth.getBlockNumber();
const EPOCH_BLOCKS = 200;
const nextEpochBlock = Math.ceil(currentBlock / EPOCH_BLOCKS) * EPOCH_BLOCKS;
const blocksToWait = nextEpochBlock - currentBlock;
console.log(`Waiting ${blocksToWait} blocks until next epoch...`);
console.log(`Estimated time: ${(blocksToWait * 3 / 60).toFixed(1)} minutes`);
// Subscribe to new blocks
const subscription = web3.eth.subscribe('newBlockHeaders');
subscription.on('data', async (blockHeader) => {
if (blockHeader.number >= nextEpochBlock) {
console.log('Next epoch reached!');
subscription.unsubscribe();
await callback();
}
});
return subscription;
}
// Usage
await scheduleAtNextEpoch(async () => {
console.log('Refreshing validator data...');
const validators = await contract.methods.getActiveValidators().call();
console.log('Updated validators:', validators);
});
Epoch Information
async function getFullEpochInfo() {
const [currentEpoch, currentBlock, constants] = await Promise.all([
contract.methods.getCurrentEpoch().call(),
web3.eth.getBlockNumber(),
web3.getContractConstants()
]);
const EPOCH_BLOCKS = constants.blockEpoch;
const blockInEpoch = currentBlock % EPOCH_BLOCKS;
const epochStartBlock = Math.floor(currentBlock / EPOCH_BLOCKS) * EPOCH_BLOCKS;
const epochEndBlock = epochStartBlock + EPOCH_BLOCKS - 1;
const nextEpochBlock = epochEndBlock + 1;
return {
current: {
epoch: currentEpoch,
block: currentBlock
},
thisEpoch: {
startBlock: epochStartBlock,
endBlock: epochEndBlock,
currentBlock: blockInEpoch,
progress: ((blockInEpoch / EPOCH_BLOCKS) * 100).toFixed(1) + '%'
},
nextEpoch: {
epoch: parseInt(currentEpoch) + 1,
startBlock: nextEpochBlock,
blocksUntil: nextEpochBlock - currentBlock,
estimatedTime: ((nextEpochBlock - currentBlock) * 3 / 60).toFixed(1) + ' minutes'
}
};
}
Related Methods
getContractConstants
Get EPOCH_BLOCKS constant (200)
getNextEpochReward
Get reward pool for next epoch
updateValidatorCandidates
System TX at epoch boundary
⌘I