Commit c2879a56 authored by tom's avatar tom

details tab desktop

parent 02da3e4b
/* eslint-disable max-len */
export const block = {
height: 15006918,
size: 1754,
timestamp: 1662623567695,
transactionsNum: 99,
miner: {
name: 'Alex Emelyanov',
address: '0xdAd49e6CbDE849353ab27DeC6319E687BFc91A41',
},
minedIn: 20,
reward: {
'static': 2,
tx_fee: 0.1550895290904872,
},
burnt_fees: 0.15116230256264004,
gas_limit: 30000000,
gas_used: 12866397,
gas_target: 14266397,
base_fee_per_gas: 11.748611718,
data: {
hex: '0x7370657468303367c18300',
utf: 'speth03g��',
},
difficulty: '14,735,262,741,740,473',
totalDifficulty: '52,307,701,288,535,570,059,059',
hash: '0x1ea365d2144796f793883534aa51bf20d23292b19478994eede23dfc599e7c34',
parent_hash: '0x4585ac59fdfd84443d93c9216e5172f57ca204639d3e68d1908088b0ebd3e709',
parent_height: 29471346,
sha3_uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
state_root: '0x434fb3f234c8cffc1d915ad26ea360b0261d183ad37af89e31b839df4dd0b00f',
nonce: '0xde80e5b4dd984384',
};
import { Grid, GridItem, Text, Icon, Link, Stat, StatArrow, Tooltip } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import { scroller, Element } from 'react-scroll';
import { block } from 'data/block';
import clockIcon from 'icons/clock.svg';
import flameIcon from 'icons/flame.svg';
import dayjs from 'lib/date/dayjs';
import { space } from 'lib/html-entities';
import useLink from 'lib/link/useLink';
import AddressLink from 'ui/shared/address/AddressLink';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import PrevNext from 'ui/shared/PrevNext';
import TextSeparator from 'ui/shared/TextSeparator';
import Utilization from 'ui/shared/Utilization';
const BlockDetails = () => {
const [ isExpanded, setIsExpanded ] = React.useState(false);
const link = useLink();
const router = useRouter();
const handleCutClick = React.useCallback(() => {
setIsExpanded((flag) => !flag);
scroller.scrollTo('BlockDetails__cutLink', {
duration: 500,
smooth: true,
});
}, []);
const gasUsedPercentage = Math.round((block.gas_used / block.gas_target - 1) * 100);
const sectionGap = <GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>;
return (
<Grid columnGap={ 8 } rowGap={{ base: 3, lg: 3 }} templateColumns={{ base: 'minmax(0, 1fr)', lg: 'auto minmax(0, 1fr)' }}>
<DetailsInfoItem
title="Block height"
hint="The block height of a particular block is defined as the number of blocks preceding it in the blockchain."
>
{ block.height }
<PrevNext ml={ 6 }/>
</DetailsInfoItem>
<DetailsInfoItem
title="Size"
hint="Size of the block in bytes."
>
{ block.size.toLocaleString('en') }
</DetailsInfoItem>
<DetailsInfoItem
title="Timestamp"
hint="Date & time at which block was produced."
>
<Icon as={ clockIcon } boxSize={ 5 } color="gray.500"/>
<Text ml={ 1 }>{ dayjs(block.timestamp).fromNow() }</Text>
<TextSeparator/>
<Text whiteSpace="normal">{ dayjs(block.timestamp).format('LLLL') }</Text>
</DetailsInfoItem>
<DetailsInfoItem
title="Transactions"
hint="The number of transactions in the block."
>
<Link href={ link('block_txs', { id: router.query.id }) }>
{ block.transactionsNum } transactions
</Link>
</DetailsInfoItem>
<DetailsInfoItem
title="Mined by"
hint="A block producer who successfully included the block onto the blockchain."
columnGap={ 1 }
>
<AddressLink hash={ block.miner.address }/>
{ block.miner.name && <Text>(Miner: { block.miner.name })</Text> }
<Text>{ dayjs.duration(block.minedIn, 'second').humanize(true) }</Text>
</DetailsInfoItem>
<DetailsInfoItem
title="Block reward"
hint="For each block, the miner is rewarded with a finite amount of Ether on top of the fees paid for all transactions in the block."
columnGap={ 1 }
>
<Text>{ block.reward.static + block.reward.tx_fee - block.burnt_fees }</Text>
<Text variant="secondary" whiteSpace="pre">(
<Tooltip label="Static block reward">
<span>{ block.reward.static }</span>
</Tooltip>
{ space }+{ space }
<Tooltip label="Txn fees">
<span>{ block.reward.tx_fee }</span>
</Tooltip>
{ space }-{ space }
<Tooltip label="Burnt fees">
<span>{ block.burnt_fees }</span>
</Tooltip>
)</Text>
</DetailsInfoItem>
{ sectionGap }
<DetailsInfoItem
title="Gas used"
hint="The total gas amount used in the block and its percentage of gas filled in the block."
>
<Text>{ block.gas_used.toLocaleString('en') }</Text>
<Utilization ml={ 4 } colorScheme="gray" value={ block.gas_used / block.gas_limit }/>
<Stat ml={ 5 }>
<StatArrow ml={ 1 } type={ gasUsedPercentage >= 0 ? 'increase' : 'decrease' }/>
<Text as="span" color={ gasUsedPercentage >= 0 ? 'green.500' : 'red.500' } fontWeight={ 600 }>{ Math.abs(gasUsedPercentage) } % Gas Target</Text>
</Stat>
</DetailsInfoItem>
<DetailsInfoItem
title="Gas limit"
hint="Total gas limit provided by all transactions in the block."
>
<Text>{ block.gas_limit.toLocaleString('en') }</Text>
</DetailsInfoItem>
<DetailsInfoItem
title="Base fee per gas"
hint="Minimum fee required per unit of gas. Fee adjusts based on network congestion."
>
<Text>{ (block.base_fee_per_gas / 10 ** 9).toLocaleString('en', { minimumFractionDigits: 18 }) } Ether </Text>
<Text variant="secondary" whiteSpace="pre">{ space }({ block.base_fee_per_gas.toLocaleString('en', { minimumFractionDigits: 9 }) } Gwei)</Text>
</DetailsInfoItem>
<DetailsInfoItem
title="Burnt fees"
hint="Amount of ETH burned from transactions included in the block. Equals Block Base Fee per Gas * Gas Used."
>
<Icon as={ flameIcon } boxSize={ 5 } color="gray.500"/>
<Text ml={ 1 }>{ block.burnt_fees.toLocaleString('en', { minimumFractionDigits: 18 }) } Ether</Text>
</DetailsInfoItem>
<DetailsInfoItem
title="Extra data"
hint="Any data that can be included by the miner in the block."
>
<Text>{ block.data.utf }</Text>
<Text variant="secondary" whiteSpace="pre"> (Hex: { block.data.hex })</Text>
</DetailsInfoItem>
{ /* CUT */ }
<GridItem colSpan={{ base: undefined, lg: 2 }}>
<Element name="BlockDetails__cutLink">
<Link
mt={ 6 }
display="inline-block"
fontSize="sm"
textDecorationLine="underline"
textDecorationStyle="dashed"
onClick={ handleCutClick }
>
{ isExpanded ? 'Hide details' : 'View details' }
</Link>
</Element>
</GridItem>
{ /* ADDITIONAL INFO */ }
{ isExpanded && (
<>
{ sectionGap }
<DetailsInfoItem
title="Difficulty"
hint="Block difficulty for miner, used to calibrate block generation time."
>
{ block.difficulty }
</DetailsInfoItem>
<DetailsInfoItem
title="Total difficulty"
hint="Total difficulty of the chain until this block."
>
{ block.totalDifficulty }
</DetailsInfoItem>
{ sectionGap }
<DetailsInfoItem
title="Hash"
hint="The SHA256 hash of the block."
>
<HashStringShortenDynamic hash={ block.hash }/>
<CopyToClipboard text={ block.hash }/>
</DetailsInfoItem>
<DetailsInfoItem
title="Parent hash"
hint="The hash of the block from which this block was generated."
>
<AddressLink hash={ block.parent_hash } type="block" id={ String(block.parent_height) }/>
<CopyToClipboard text={ block.hash }/>
</DetailsInfoItem>
<DetailsInfoItem
title="State root"
hint="The root of the state trie."
>
{ block.state_root }
</DetailsInfoItem>
<DetailsInfoItem
title="Nonce"
hint="Block nonce is a value used during mining to demonstrate proof of work for a block."
>
{ block.nonce }
</DetailsInfoItem>
</>
) }
</Grid>
);
};
export default BlockDetails;
import { useRouter } from 'next/router';
import React from 'react';
import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import BlockDetails from 'ui/block/BlockDetails';
import Page from 'ui/shared/Page';
import PageHeader from 'ui/shared/PageHeader';
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
const TABS: Array<RoutedTab> = [
{ routeName: 'block_index', title: 'Details', component: <div>Details</div> },
{ routeName: 'block_index', title: 'Details', component: <BlockDetails/> },
{ routeName: 'block_txs', title: 'Transactions', component: <div>Transactions</div> },
];
......@@ -16,9 +18,11 @@ export interface Props {
}
const BlockPageContent = ({ tab }: Props) => {
const router = useRouter();
return (
<Page>
<PageHeader text="Block"/>
<PageHeader text={ `Block #${ router.query.id || '' }` }/>
<RoutedTabs
tabs={ TABS }
defaultActiveTab={ tab }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment