Commit b26c40e4 authored by tom's avatar tom

more snippets and alerts

parent 455ac4bb
......@@ -12,13 +12,37 @@ export interface SmartContract {
name: string | null;
verified_at: string | null;
is_verified: boolean | null;
is_changed_bytecode: boolean | null;
// sourcify info >>>
is_verified_via_sourcify: boolean | null;
is_fully_verified: boolean | null;
is_partially_verified: boolean | null;
sourcify_repo_url: string | null;
// <<<<
source_code: string | null;
constructor_args: string | null;
decoded_constructor_args: Array<SmartContractDecodedConstructorArg> | null;
can_be_visualized_via_sol2uml: boolean | null;
is_vyper_contract: boolean | null;
file_path: string;
additional_sources: Array<{ file_path: string; source_code: string }>;
external_libraries: Array<SmartContractExternalLibrary> | null;
compiler_settings: unknown;
verified_twin_address_hash: string | null;
}
export type SmartContractDecodedConstructorArg = [
string,
{
internalType: string;
name: string;
type: string;
}
]
export interface SmartContractExternalLibrary {
address_hash: string;
name: string;
}
export interface SmartContractMethodBase {
......
import { Flex, Skeleton, Button, Grid, GridItem, Text, Alert, Link, chakra } from '@chakra-ui/react';
import { Flex, Skeleton, Button, Grid, GridItem, Text, Alert, Link, chakra, Box } from '@chakra-ui/react';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -69,27 +69,71 @@ const ContractCode = () => {
</Button>
);
const constructorArgs = (() => {
if (!data.decoded_constructor_args) {
return data.constructor_args;
}
const decoded = data.decoded_constructor_args
.map(([ value, { name, type } ], index) => {
const valueEl = type === 'address' ? <Link href={ link('address_index', { id: value }) }>{ value }</Link> : <span>{ value }</span>;
return (
<Box key={ index }>
<span>Arg [{ index }] { name || '' } ({ type }): </span>
{ valueEl }
</Box>
);
});
return (
<>
<span>{ data.constructor_args }</span>
<br/><br/>
{ decoded }
</>
);
})();
const externalLibraries = (() => {
if (!data.external_libraries || data.external_libraries.length === 0) {
return null;
}
return data.external_libraries.map((item) => (
<Box key={ item.address_hash }>
<chakra.span fontWeight={ 500 }>{ item.name }: </chakra.span>
<Link href={ link('address_index', { id: item.address_hash }, { tab: 'contract' }) }>{ item.address_hash }</Link>
</Box>
));
})();
return (
<>
<Flex flexDir="column" rowGap={ 2 } mb={ 6 }>
<Alert status="success">Contract Source Code Verified (Exact Match)</Alert>
<Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap">
<span>This contract has been partially verified via Sourcify. </span>
<ExternalLink href="https://repo.sourcify.dev/" title="View contract in Sourcify repository" fontSize="md"/>
</Alert>
<Alert status="warning">
Warning! Contract bytecode has been changed and does not match the verified one. Therefore, interaction with this smart contract may be risky.
</Alert>
<Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap">
<span>Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB </span>
<Address>
<AddressIcon address={{ hash: addressHash || '', is_contract: false, implementation_name: null }}/>
<AddressLink hash={ addressHash || '' } truncation="constant" ml={ 2 }/>
</Address>
<chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span>
<Link>Verify & Publish</Link>
<span> page</span>
</Alert>
<Flex flexDir="column" rowGap={ 2 } mb={ 6 } _empty={{ display: 'none' }}>
{ data.is_verified && <Alert status="success">Contract Source Code Verified (Exact Match)</Alert> }
{ data.is_verified_via_sourcify && (
<Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap">
<span>This contract has been { data.is_partially_verified ? 'partially ' : '' }verified via Sourcify. </span>
{ data.sourcify_repo_url && <ExternalLink href={ data.sourcify_repo_url } title="View contract in Sourcify repository" fontSize="md"/> }
</Alert>
) }
{ data.is_changed_bytecode && (
<Alert status="warning">
Warning! Contract bytecode has been changed and does not match the verified one. Therefore, interaction with this smart contract may be risky.
</Alert>
) }
{ !data.is_verified && data.verified_twin_address_hash && (
<Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap">
<span>Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB </span>
<Address>
<AddressIcon address={{ hash: data.verified_twin_address_hash, is_contract: false, implementation_name: null }}/>
<AddressLink hash={ data.verified_twin_address_hash } truncation="constant" ml={ 2 }/>
</Address>
<chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span>
<Link href={ link('address_contract_verification', { id: data.verified_twin_address_hash }) }>Verify & Publish</Link>
<span> page</span>
</Alert>
) }
</Flex>
{ data.is_verified && (
<Grid templateColumns={{ base: '1fr', lg: '1fr 1fr' }} rowGap={ 4 } columnGap={ 6 } mb={ 8 }>
......@@ -102,10 +146,11 @@ const ContractCode = () => {
</Grid>
) }
<Flex flexDir="column" rowGap={ 6 }>
{ data.constructor_args && (
{ constructorArgs && (
<RawDataSnippet
data={ data.constructor_args }
data={ constructorArgs }
title="Constructor Arguments"
textareaMaxHeight="200px"
/>
) }
{ data.source_code && (
......@@ -122,14 +167,14 @@ const ContractCode = () => {
<RawDataSnippet
data={ JSON.stringify(data.compiler_settings) }
title="Compiler Settings"
textareaMinHeight="200px"
textareaMaxHeight="200px"
/>
) }
{ data.abi && (
<RawDataSnippet
data={ JSON.stringify(data.abi) }
title="Contract ABI"
textareaMinHeight="200px"
textareaMaxHeight="200px"
/>
) }
{ data.creation_bytecode && (
......@@ -137,20 +182,27 @@ const ContractCode = () => {
data={ data.creation_bytecode }
title="Contract creation code"
rightSlot={ data.is_verified ? null : verificationButton }
beforeSlot={ (
beforeSlot={ data.is_self_destructed ? (
<Alert status="info" whiteSpace="pre-wrap" mb={ 3 }>
Contracts that self destruct in their constructors have no contract code published and cannot be verified.
Displaying the init data provided of the creating transaction.
</Alert>
) }
textareaMinHeight="200px"
) : null }
textareaMaxHeight="200px"
/>
) }
{ data.deployed_bytecode && (
<RawDataSnippet
data={ data.deployed_bytecode }
title="Deployed ByteCode"
textareaMinHeight="200px"
textareaMaxHeight="200px"
/>
) }
{ externalLibraries && (
<RawDataSnippet
data={ externalLibraries }
title="External Libraries"
textareaMaxHeight="200px"
/>
) }
</Flex>
......
import { Box, Flex, Text, Textarea, chakra } from '@chakra-ui/react';
import { Box, Flex, Text, chakra, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import CopyToClipboard from './CopyToClipboard';
interface Props {
data: string;
data: React.ReactNode;
title?: string;
className?: string;
rightSlot?: React.ReactNode;
beforeSlot?: React.ReactNode;
textareaMinHeight?: string;
textareaMaxHeight?: string;
}
const RawDataSnippet = ({ data, className, title, rightSlot, beforeSlot, textareaMinHeight }: Props) => {
const RawDataSnippet = ({ data, className, title, rightSlot, beforeSlot, textareaMaxHeight }: Props) => {
// see issue in theme/components/Textarea.ts
const bgColor = useColorModeValue('#f5f5f6', '#1a1b1b');
return (
<Box className={ className }>
<Flex justifyContent={ title ? 'space-between' : 'flex-end' } alignItems="center" mb={ 3 }>
{ title && <Text fontWeight={ 500 }>{ title }</Text> }
{ rightSlot }
<CopyToClipboard text={ data }/>
{ typeof data === 'string' && <CopyToClipboard text={ data }/> }
</Flex>
{ beforeSlot }
<Textarea
variant="filledInactive"
<Box
p={ 4 }
minHeight={ textareaMinHeight || '400px' }
value={ data }
bgColor={ bgColor }
maxH={ textareaMaxHeight || '400px' }
fontSize="sm"
borderRadius="md"
readOnly
/>
wordBreak="break-all"
whiteSpace="pre-wrap"
overflowY="auto"
>
{ data }
</Box>
</Box>
);
};
......
......@@ -90,6 +90,10 @@ const RoutedTabs = ({ tabs, tabListProps, rightSlot, stickyEnabled, className, .
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ activeTabIndex, isMobile ]);
if (tabs.length === 1) {
return <div>{ tabs[0].component }</div>;
}
return (
<Tabs
className={ className }
......
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