diff --git a/mocks/address/address.ts b/mocks/address/address.ts
index fbc81bf171..c6358afc0e 100644
--- a/mocks/address/address.ts
+++ b/mocks/address/address.ts
@@ -81,6 +81,7 @@ export const token: Address = {
coin_balance: '1',
creation_transaction_hash: '0xc38cf7377bf72d6436f63c37b01b24d032101f20ec1849286dc703c712f10c98',
creator_address_hash: '0x34A9c688512ebdB575e82C50c9803F6ba2916E72',
+ creation_status: 'success',
exchange_rate: '0.04311',
has_logs: false,
has_token_transfers: true,
@@ -94,6 +95,7 @@ export const eoa: Address = {
coin_balance: '2782650189688719421432220500',
creation_transaction_hash: '0xf2aff6501b632604c39978b47d309813d8a1bcca721864bbe86abf59704f195e',
creator_address_hash: '0x803ad3F50b9e1fF68615e8B053A186e1be288943',
+ creation_status: null,
exchange_rate: '0.04311',
has_logs: true,
has_token_transfers: false,
@@ -117,6 +119,7 @@ export const contract: Address = {
coin_balance: '27826501896887194214322205',
creation_transaction_hash: '0xf2aff6501b632604c39978b47d309813d8a1bcca721864bbe86abf59704f195e',
creator_address_hash: '0x803ad3F50b9e1fF68615e8B053A186e1be288943',
+ creation_status: 'success',
exchange_rate: '0.04311',
has_logs: true,
has_token_transfers: false,
@@ -142,6 +145,7 @@ export const validator: Address = {
coin_balance: '22910462800601256910890',
creation_transaction_hash: null,
creator_address_hash: null,
+ creation_status: null,
exchange_rate: '0.00432018',
has_logs: false,
has_token_transfers: false,
diff --git a/mocks/contract/info.ts b/mocks/contract/info.ts
index b9a06aa243..bcaf60f901 100644
--- a/mocks/contract/info.ts
+++ b/mocks/contract/info.ts
@@ -7,6 +7,7 @@ export const verified: SmartContract = {
compiler_version: 'v0.5.16+commit.9c3226ce',
constructor_args: 'constructor_args',
creation_bytecode: 'creation_bytecode',
+ creation_status: 'success',
deployed_bytecode: 'deployed_bytecode',
compiler_settings: {
evmVersion: 'london',
@@ -33,7 +34,6 @@ export const verified: SmartContract = {
],
language: 'solidity',
license_type: 'gnu_gpl_v3',
- is_self_destructed: false,
is_verified_via_eth_bytecode_db: null,
is_changed_bytecode: null,
is_verified_via_sourcify: null,
@@ -88,7 +88,7 @@ export const withProxyAddress: SmartContract = {
export const selfDestructed: SmartContract = {
...verified,
- is_self_destructed: true,
+ creation_status: 'selfdestructed',
};
export const withChangedByteCode: SmartContract = {
@@ -122,7 +122,7 @@ export const nonVerified: SmartContract = {
is_blueprint: false,
creation_bytecode: 'creation_bytecode',
deployed_bytecode: 'deployed_bytecode',
- is_self_destructed: false,
+ creation_status: 'success',
abi: null,
compiler_version: null,
evm_version: null,
diff --git a/stubs/address.ts b/stubs/address.ts
index 07c8ce2734..e66e9b41ee 100644
--- a/stubs/address.ts
+++ b/stubs/address.ts
@@ -21,6 +21,7 @@ export const ADDRESS_INFO: Address = {
coin_balance: '810941268802273085757',
creation_transaction_hash: null,
creator_address_hash: ADDRESS_HASH,
+ creation_status: 'success',
exchange_rate: null,
has_logs: true,
has_token_transfers: false,
diff --git a/stubs/contract.ts b/stubs/contract.ts
index 90b3429d27..271b0f1efd 100644
--- a/stubs/contract.ts
+++ b/stubs/contract.ts
@@ -10,7 +10,7 @@ import { STATS_COUNTER } from './stats';
export const CONTRACT_CODE_UNVERIFIED = {
creation_bytecode: '0x60806040526e',
deployed_bytecode: '0x608060405233',
- is_self_destructed: false,
+ creation_status: 'success',
} as SmartContract;
export const CONTRACT_CODE_VERIFIED = {
diff --git a/types/api/address.ts b/types/api/address.ts
index 14e7c10647..30fc260c88 100644
--- a/types/api/address.ts
+++ b/types/api/address.ts
@@ -2,7 +2,7 @@ import type { Transaction } from 'types/api/transaction';
import type { UserTags, AddressImplementation, AddressParam, AddressFilecoinParams } from './addressParams';
import type { Block, EpochRewardsType } from './block';
-import type { SmartContractProxyType } from './contract';
+import type { SmartContractCreationStatus, SmartContractProxyType } from './contract';
import type { InternalTransaction } from './internalTransaction';
import type { MudWorldSchema, MudWorldTable } from './mudWorlds';
import type { NFTTokenType, TokenInfo, TokenInstance, TokenType } from './token';
@@ -14,6 +14,7 @@ export interface Address extends UserTags {
creator_address_hash: string | null;
creator_filecoin_robust_address?: string | null;
creation_transaction_hash: string | null;
+ creation_status: SmartContractCreationStatus | null;
exchange_rate: string | null;
ens_domain_name: string | null;
filecoin?: AddressFilecoinParams;
diff --git a/types/api/contract.ts b/types/api/contract.ts
index 4b8cf23059..ac3ee7f519 100644
--- a/types/api/contract.ts
+++ b/types/api/contract.ts
@@ -3,6 +3,8 @@ import type { Abi, AbiType } from 'abitype';
export type SmartContractMethodArgType = AbiType;
export type SmartContractMethodStateMutability = 'view' | 'nonpayable' | 'payable';
+export type SmartContractCreationStatus = 'success' | 'failed' | 'selfdestructed';
+
export type SmartContractLicenseType =
'none' |
'unlicense' |
@@ -39,7 +41,7 @@ export type SmartContractProxyType =
export interface SmartContract {
deployed_bytecode: string | null;
creation_bytecode: string | null;
- is_self_destructed: boolean;
+ creation_status: SmartContractCreationStatus | null;
abi: Abi | null;
compiler_version: string | null;
evm_version: string | null;
diff --git a/ui/address/AddressDetails.tsx b/ui/address/AddressDetails.tsx
index caec177a10..0fb15010f0 100644
--- a/ui/address/AddressDetails.tsx
+++ b/ui/address/AddressDetails.tsx
@@ -17,6 +17,7 @@ import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponso
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
+import ContractCreationStatus from 'ui/shared/statusTag/ContractCreationStatus';
import AddressAlternativeFormat from './details/AddressAlternativeFormat';
import AddressBalance from './details/AddressBalance';
@@ -152,6 +153,7 @@ const AddressDetails = ({ addressQuery, isLoading }: Props) => {
/>
at txn
+ { data.creation_status && }
>
) }
diff --git a/ui/address/__screenshots__/AddressDetails.pw.tsx_default_contract-1.png b/ui/address/__screenshots__/AddressDetails.pw.tsx_default_contract-1.png
index d6c75b8200..b3c741f692 100644
Binary files a/ui/address/__screenshots__/AddressDetails.pw.tsx_default_contract-1.png and b/ui/address/__screenshots__/AddressDetails.pw.tsx_default_contract-1.png differ
diff --git a/ui/address/__screenshots__/AddressDetails.pw.tsx_default_mobile-contract-1.png b/ui/address/__screenshots__/AddressDetails.pw.tsx_default_mobile-contract-1.png
index 5f3e2d0098..debd75ae7b 100644
Binary files a/ui/address/__screenshots__/AddressDetails.pw.tsx_default_mobile-contract-1.png and b/ui/address/__screenshots__/AddressDetails.pw.tsx_default_mobile-contract-1.png differ
diff --git a/ui/address/contract/ContractDetailsByteCode.tsx b/ui/address/contract/ContractDetailsByteCode.tsx
new file mode 100644
index 0000000000..0e1a91688a
--- /dev/null
+++ b/ui/address/contract/ContractDetailsByteCode.tsx
@@ -0,0 +1,69 @@
+import { Flex } from '@chakra-ui/react';
+import React from 'react';
+
+import type { Address } from 'types/api/address';
+import type { SmartContract } from 'types/api/contract';
+
+import { Alert } from 'toolkit/chakra/alert';
+import RawDataSnippet from 'ui/shared/RawDataSnippet';
+
+import ContractDetailsVerificationButton from './ContractDetailsVerificationButton';
+
+interface Props {
+ data: SmartContract;
+ isLoading: boolean;
+ addressData: Address;
+}
+
+const ContractDetailsByteCode = ({ data, isLoading, addressData }: Props) => {
+ const canBeVerified = ![ 'selfdestructed', 'failed' ].includes(data.creation_status || '') && !data?.is_verified && addressData.proxy_type !== 'eip7702';
+
+ const verificationButton = (
+
+ );
+
+ const creationStatusText = (() => {
+ switch (data.creation_status) {
+ case 'selfdestructed':
+ return 'This contract self-destructed after deployment and there is no runtime bytecode. Below is the raw creation bytecode.';
+ case 'failed':
+ return 'Contract creation failed and there is no runtime bytecode. Below is the raw creation bytecode.';
+ default:
+ return null;
+ }
+ })();
+
+ return (
+
+ { data?.creation_bytecode && (
+
+ { creationStatusText }
+
+ ) : null }
+ textareaMaxHeight="300px"
+ isLoading={ isLoading }
+ />
+ ) }
+ { data?.deployed_bytecode && (
+
+ ) }
+
+ );
+};
+
+export default React.memo(ContractDetailsByteCode);
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_dark-color-mode_full-view-source-code-dark-mode-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_dark-color-mode_full-view-source-code-dark-mode-1.png
index 538bcf6e89..72e82b233d 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_dark-color-mode_full-view-source-code-dark-mode-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_dark-color-mode_full-view-source-code-dark-mode-1.png differ
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-abi-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-abi-1.png
index e7b1772fb6..1e9d0fb79c 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-abi-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-abi-1.png differ
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-bytecode-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-bytecode-1.png
index a999d45939..ea5ef79280 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-bytecode-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-bytecode-1.png differ
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-compiler-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-compiler-1.png
index 24c7955e64..a8e0ebf70a 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-compiler-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-compiler-1.png differ
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-source-code-dark-mode-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-source-code-dark-mode-1.png
index 2d840ff7c7..e3619c6ec3 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-source-code-dark-mode-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_full-view-source-code-dark-mode-1.png differ
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_mobile-view-source-code-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_mobile-view-source-code-1.png
index 6772283e9c..7b687be72d 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_mobile-view-source-code-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_mobile-view-source-code-1.png differ
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_non-verified-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_non-verified-1.png
index b3c60bd9c6..7ac6f202e3 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_non-verified-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_non-verified-1.png differ
diff --git a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_self-destructed-1.png b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_self-destructed-1.png
index c15b922be6..fd8098cf68 100644
Binary files a/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_self-destructed-1.png and b/ui/address/contract/__screenshots__/ContractDetails.pw.tsx_default_self-destructed-1.png differ
diff --git a/ui/address/contract/useContractDetailsTabs.tsx b/ui/address/contract/useContractDetailsTabs.tsx
index 836ba74713..47f21cb06d 100644
--- a/ui/address/contract/useContractDetailsTabs.tsx
+++ b/ui/address/contract/useContractDetailsTabs.tsx
@@ -4,12 +4,10 @@ import React from 'react';
import type { Address } from 'types/api/address';
import type { SmartContract } from 'types/api/contract';
-import { Alert } from 'toolkit/chakra/alert';
import CodeViewSnippet from 'ui/shared/CodeViewSnippet';
-import RawDataSnippet from 'ui/shared/RawDataSnippet';
+import ContractDetailsByteCode from './ContractDetailsByteCode';
import ContractDetailsConstructorArgs from './ContractDetailsConstructorArgs';
-import ContractDetailsVerificationButton from './ContractDetailsVerificationButton';
import ContractSourceCode from './ContractSourceCode';
import type { CONTRACT_DETAILS_TAB_IDS } from './utils';
@@ -28,16 +26,7 @@ interface Props {
export default function useContractDetailsTabs({ data, isLoading, addressData, sourceAddress }: Props): Array {
- const canBeVerified = !data?.is_self_destructed && !data?.is_verified && addressData?.proxy_type !== 'eip7702';
-
return React.useMemo(() => {
- const verificationButton = (
-
- );
return [
(data?.constructor_args || data?.source_code) ? {
@@ -87,36 +76,9 @@ export default function useContractDetailsTabs({ data, isLoading, addressData, s
(data?.creation_bytecode || data?.deployed_bytecode) ? {
id: 'contract_bytecode' as const,
- title: 'ByteCode',
- component: (
-
- { data?.creation_bytecode && (
-
- 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.
-
- ) : null }
- textareaMaxHeight="300px"
- isLoading={ isLoading }
- />
- ) }
- { data?.deployed_bytecode && (
-
- ) }
-
- ),
+ title: 'Bytecode',
+ component: ,
} : undefined,
].filter(Boolean);
- }, [ isLoading, addressData, data, sourceAddress, canBeVerified ]);
+ }, [ isLoading, addressData, data, sourceAddress ]);
}
diff --git a/ui/address/utils/useAddressQuery.ts b/ui/address/utils/useAddressQuery.ts
index 99794de944..29f43bf395 100644
--- a/ui/address/utils/useAddressQuery.ts
+++ b/ui/address/utils/useAddressQuery.ts
@@ -75,6 +75,7 @@ export default function useAddressQuery({ hash, isEnabled = true }: Params): Add
coin_balance: balance.toString(),
creator_address_hash: null,
creation_transaction_hash: null,
+ creation_status: null,
exchange_rate: null,
ens_domain_name: null,
has_logs: false,
diff --git a/ui/shared/statusTag/ContractCreationStatus.tsx b/ui/shared/statusTag/ContractCreationStatus.tsx
new file mode 100644
index 0000000000..62ac35d166
--- /dev/null
+++ b/ui/shared/statusTag/ContractCreationStatus.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+
+import type { SmartContractCreationStatus } from 'types/api/contract';
+
+import type { BadgeProps } from 'toolkit/chakra/badge';
+import { Badge } from 'toolkit/chakra/badge';
+import { Tooltip } from 'toolkit/chakra/tooltip';
+
+import StatusTag from './StatusTag';
+
+interface Props extends BadgeProps {
+ status: SmartContractCreationStatus;
+}
+
+const ContractCreationStatus = ({ status, ...rest }: Props) => {
+ switch (status) {
+ case 'success':
+ return (
+
+
+
+ );
+ case 'failed':
+ return (
+
+
+
+ );
+ case 'selfdestructed':
+ return (
+
+ Self-destructed
+
+ );
+ default:
+ return null;
+ }
+};
+
+export default React.memo(ContractCreationStatus);