Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
aabc034f
Commit
aabc034f
authored
Nov 30, 2023
by
isstuev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
soliditycheck report
parent
3d3b2515
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
270 additions
and
4 deletions
+270
-4
score-not-ok.svg
icons/score/score-not-ok.svg
+4
-0
score-ok.svg
icons/score/score-ok.svg
+3
-0
resources.ts
lib/api/resources.ts
+6
-1
solidityscanReport.ts
mocks/contract/solidityscanReport.ts
+21
-0
contract.ts
stubs/contract.ts
+23
-1
contract.ts
types/api/contract.ts
+22
-0
SolidityscanReport.pw.tsx
ui/address/SolidityscanReport.pw.tsx
+27
-0
SolidityscanReport.tsx
ui/address/SolidityscanReport.tsx
+159
-0
SolidityscanReport.pw.tsx_dark-color-mode_base-view-dark-mode-mobile-1.png
...t.pw.tsx_dark-color-mode_base-view-dark-mode-mobile-1.png
+0
-0
SolidityscanReport.pw.tsx_default_base-view-dark-mode-mobile-1.png
...canReport.pw.tsx_default_base-view-dark-mode-mobile-1.png
+0
-0
SolidityscanReport.pw.tsx_mobile_base-view-dark-mode-mobile-1.png
...scanReport.pw.tsx_mobile_base-view-dark-mode-mobile-1.png
+0
-0
Address.tsx
ui/pages/Address.tsx
+5
-2
No files found.
icons/score/score-not-ok.svg
0 → 100644
View file @
aabc034f
<svg
viewBox=
"0 0 20 20"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<path
fill-rule=
"evenodd"
clip-rule=
"evenodd"
d=
"M3 3.6v4.812c0 6.447 5.414 8.703 6.79 9.17 1.377-.467 6.791-2.723 6.791-9.17V3.6H3ZM1.506 2.091A1.714 1.714 0 0 1 2.708 1.6h14.165c.448 0 .88.175 1.202.491.322.317.506.75.506 1.206v5.115c0 8.015-6.912 10.66-8.246 11.097a1.647 1.647 0 0 1-1.089 0C7.912 19.072 1 16.427 1 8.412V3.297c0-.455.184-.889.506-1.206Z"
fill=
"currentColor"
/>
<path
fill-rule=
"evenodd"
clip-rule=
"evenodd"
d=
"M9.9 5.4a1.1 1.1 0 0 0-1.1 1.1v3.8a1.1 1.1 0 0 0 2.2 0V6.5a1.1 1.1 0 0 0-1.1-1.1Zm1.1 8.343a1.1 1.1 0 1 1-2.2 0 1.1 1.1 0 0 1 2.2 0Z"
fill=
"currentColor"
/>
</svg>
icons/score/score-ok.svg
0 → 100644
View file @
aabc034f
<svg
viewBox=
"0 0 20 20"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<path
fill-rule=
"evenodd"
clip-rule=
"evenodd"
d=
"M3 8.412V3.6h13.581v4.812c0 6.447-5.414 8.703-6.79 9.17C8.414 17.115 3 14.86 3 8.412ZM2.708 1.6c-.448 0-.88.175-1.202.491-.322.317-.506.75-.506 1.206v5.115c0 8.015 6.912 10.66 8.246 11.097.352.123.737.123 1.089 0 1.334-.437 8.246-3.082 8.246-11.097V3.297c0-.455-.184-.889-.506-1.206a1.714 1.714 0 0 0-1.202-.491H2.708ZM14.37 8.208a1 1 0 1 0-1.369-1.458L8.49 10.986 6.58 9.191a1 1 0 1 0-1.37 1.457l2.594 2.44a1 1 0 0 0 1.37 0l5.196-4.88Z"
fill=
"currentColor"
/>
</svg>
lib/api/resources.ts
View file @
aabc034f
...
@@ -31,7 +31,7 @@ import type { AddressesResponse } from 'types/api/addresses';
...
@@ -31,7 +31,7 @@ import type { AddressesResponse } from 'types/api/addresses';
import
type
{
BlocksResponse
,
BlockTransactionsResponse
,
Block
,
BlockFilters
,
BlockWithdrawalsResponse
}
from
'
types/api/block
'
;
import
type
{
BlocksResponse
,
BlockTransactionsResponse
,
Block
,
BlockFilters
,
BlockWithdrawalsResponse
}
from
'
types/api/block
'
;
import
type
{
ChartMarketResponse
,
ChartTransactionResponse
}
from
'
types/api/charts
'
;
import
type
{
ChartMarketResponse
,
ChartTransactionResponse
}
from
'
types/api/charts
'
;
import
type
{
BackendVersionConfig
}
from
'
types/api/configs
'
;
import
type
{
BackendVersionConfig
}
from
'
types/api/configs
'
;
import
type
{
SmartContract
,
SmartContractReadMethod
,
SmartContractWriteMethod
,
SmartContractVerificationConfig
}
from
'
types/api/contract
'
;
import
type
{
SmartContract
,
SmartContractReadMethod
,
SmartContractWriteMethod
,
SmartContractVerificationConfig
,
SolidityscanReport
}
from
'
types/api/contract
'
;
import
type
{
VerifiedContractsResponse
,
VerifiedContractsFilters
,
VerifiedContractsCounters
}
from
'
types/api/contracts
'
;
import
type
{
VerifiedContractsResponse
,
VerifiedContractsFilters
,
VerifiedContractsCounters
}
from
'
types/api/contracts
'
;
import
type
{
IndexingStatus
}
from
'
types/api/indexingStatus
'
;
import
type
{
IndexingStatus
}
from
'
types/api/indexingStatus
'
;
import
type
{
InternalTransactionsResponse
}
from
'
types/api/internalTransaction
'
;
import
type
{
InternalTransactionsResponse
}
from
'
types/api/internalTransaction
'
;
...
@@ -343,6 +343,10 @@ export const RESOURCES = {
...
@@ -343,6 +343,10 @@ export const RESOURCES = {
path
:
'
/api/v2/smart-contracts/:hash/verification/via/:method
'
,
path
:
'
/api/v2/smart-contracts/:hash/verification/via/:method
'
,
pathParams
:
[
'
hash
'
as
const
,
'
method
'
as
const
],
pathParams
:
[
'
hash
'
as
const
,
'
method
'
as
const
],
},
},
contract_solidityscan_report
:
{
path
:
'
/api/v2/smart-contracts/:hash/solidityscan-report
'
,
pathParams
:
[
'
hash
'
as
const
],
},
verified_contracts
:
{
verified_contracts
:
{
path
:
'
/api/v2/smart-contracts
'
,
path
:
'
/api/v2/smart-contracts
'
,
...
@@ -659,6 +663,7 @@ Q extends 'contract_methods_read' ? Array<SmartContractReadMethod> :
...
@@ -659,6 +663,7 @@ Q extends 'contract_methods_read' ? Array<SmartContractReadMethod> :
Q
extends
'
contract_methods_read_proxy
'
?
Array
<
SmartContractReadMethod
>
:
Q
extends
'
contract_methods_read_proxy
'
?
Array
<
SmartContractReadMethod
>
:
Q
extends
'
contract_methods_write
'
?
Array
<
SmartContractWriteMethod
>
:
Q
extends
'
contract_methods_write
'
?
Array
<
SmartContractWriteMethod
>
:
Q
extends
'
contract_methods_write_proxy
'
?
Array
<
SmartContractWriteMethod
>
:
Q
extends
'
contract_methods_write_proxy
'
?
Array
<
SmartContractWriteMethod
>
:
Q
extends
'
contract_solidityscan_report
'
?
SolidityscanReport
:
Q
extends
'
verified_contracts
'
?
VerifiedContractsResponse
:
Q
extends
'
verified_contracts
'
?
VerifiedContractsResponse
:
Q
extends
'
verified_contracts_counters
'
?
VerifiedContractsCounters
:
Q
extends
'
verified_contracts_counters
'
?
VerifiedContractsCounters
:
Q
extends
'
visualize_sol2uml
'
?
VisualizedContract
:
Q
extends
'
visualize_sol2uml
'
?
VisualizedContract
:
...
...
mocks/contract/solidityscanReport.ts
0 → 100644
View file @
aabc034f
export
const
solidityscanReport
=
{
scan_report
:
{
scan_status
:
'
scan_done
'
,
scan_summary
:
{
issue_severity_distribution
:
{
critical
:
0
,
gas
:
1
,
high
:
0
,
informational
:
0
,
low
:
2
,
medium
:
0
,
},
lines_analyzed_count
:
18
,
scan_time_taken
:
1
,
score
:
'
3.61
'
,
score_v2
:
'
72.22
'
,
threat_score
:
'
94.74
'
,
},
scanner_reference_url
:
'
https://solidityscan.com/quickscan/0xc1EF7811FF2ebFB74F80ed7423f2AdAA37454be2/blockscout/eth-goerli?ref=blockscout
'
,
},
};
stubs/contract.ts
View file @
aabc034f
import
type
{
SmartContract
}
from
'
types/api/contract
'
;
import
type
{
SmartContract
,
SolidityscanReport
}
from
'
types/api/contract
'
;
import
type
{
VerifiedContract
}
from
'
types/api/contracts
'
;
import
type
{
VerifiedContract
}
from
'
types/api/contracts
'
;
import
{
ADDRESS_PARAMS
}
from
'
./addressParams
'
;
import
{
ADDRESS_PARAMS
}
from
'
./addressParams
'
;
...
@@ -53,3 +53,25 @@ export const VERIFIED_CONTRACT_INFO: VerifiedContract = {
...
@@ -53,3 +53,25 @@ export const VERIFIED_CONTRACT_INFO: VerifiedContract = {
tx_count
:
565058
,
tx_count
:
565058
,
verified_at
:
'
2023-04-10T13:16:33.884921Z
'
,
verified_at
:
'
2023-04-10T13:16:33.884921Z
'
,
};
};
export
const
SOLIDITYSCAN_REPORT
:
SolidityscanReport
=
{
scan_report
:
{
scan_status
:
'
scan_done
'
,
scan_summary
:
{
issue_severity_distribution
:
{
critical
:
0
,
gas
:
1
,
high
:
0
,
informational
:
0
,
low
:
2
,
medium
:
0
,
},
lines_analyzed_count
:
18
,
scan_time_taken
:
1
,
score
:
'
3.61
'
,
score_v2
:
'
72.22
'
,
threat_score
:
'
94.74
'
,
},
scanner_reference_url
:
'
https://solidityscan.com/quickscan/0xc1EF7811FF2ebFB74F80ed7423f2AdAA37454be2/blockscout/eth-goerli?ref=blockscout
'
,
},
};
types/api/contract.ts
View file @
aabc034f
...
@@ -156,3 +156,25 @@ export interface SmartContractVerificationError {
...
@@ -156,3 +156,25 @@ export interface SmartContractVerificationError {
constructor_arguments
?:
Array
<
string
>
;
constructor_arguments
?:
Array
<
string
>
;
name
?:
Array
<
string
>
;
name
?:
Array
<
string
>
;
}
}
export
type
SolidityscanReport
=
{
scan_report
:
{
scan_status
:
string
;
scan_summary
:
{
issue_severity_distribution
:
{
critical
:
number
;
gas
:
number
;
high
:
number
;
informational
:
number
;
low
:
number
;
medium
:
number
;
};
lines_analyzed_count
:
number
;
scan_time_taken
:
number
;
score
:
string
;
score_v2
:
string
;
threat_score
:
string
;
};
scanner_reference_url
:
string
;
};
}
ui/address/SolidityscanReport.pw.tsx
0 → 100644
View file @
aabc034f
import
{
test
,
expect
}
from
'
@playwright/experimental-ct-react
'
;
import
React
from
'
react
'
;
import
{
solidityscanReport
as
solidityscanReportMock
}
from
'
mocks/contract/solidityscanReport
'
;
import
TestApp
from
'
playwright/TestApp
'
;
import
buildApiUrl
from
'
playwright/utils/buildApiUrl
'
;
import
SolidityscanReport
from
'
./SolidityscanReport
'
;
const
addressHash
=
'
hash
'
;
const
REPORT_API_URL
=
buildApiUrl
(
'
contract_solidityscan_report
'
,
{
hash
:
addressHash
});
test
(
'
base view +@dark-mode +@mobile
'
,
async
({
mount
,
page
})
=>
{
await
page
.
route
(
REPORT_API_URL
,
(
route
)
=>
route
.
fulfill
({
status
:
200
,
body
:
JSON
.
stringify
(
solidityscanReportMock
),
}));
const
component
=
await
mount
(
<
TestApp
>
<
SolidityscanReport
hash=
{
addressHash
}
/>
</
TestApp
>,
);
await
component
.
getByLabel
(
'
SolidityScan score
'
).
click
();
await
expect
(
page
).
toHaveScreenshot
({
clip
:
{
x
:
0
,
y
:
0
,
width
:
400
,
height
:
500
}
});
});
ui/address/SolidityscanReport.tsx
0 → 100644
View file @
aabc034f
import
{
Box
,
Flex
,
Text
,
Grid
,
Button
,
Icon
,
chakra
,
Popover
,
PopoverTrigger
,
PopoverBody
,
PopoverContent
,
useDisclosure
,
Skeleton
,
Center
,
useColorModeValue
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
SolidityscanReport
}
from
'
types/api/contract
'
;
import
scoreNotOkIcon
from
'
icons/score/score-not-ok.svg
'
;
import
scoreOkIcon
from
'
icons/score/score-ok.svg
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
SOLIDITYSCAN_REPORT
}
from
'
stubs/contract
'
;
import
LinkExternal
from
'
ui/shared/LinkExternal
'
;
type
DistributionItem
=
{
id
:
keyof
SolidityscanReport
[
'
scan_report
'
][
'
scan_summary
'
][
'
issue_severity_distribution
'
];
name
:
string
;
color
:
string
;
}
const
DISTRIBUTION_ITEMS
:
Array
<
DistributionItem
>
=
[
{
id
:
'
critical
'
,
name
:
'
Critical
'
,
color
:
'
#891F11
'
},
{
id
:
'
high
'
,
name
:
'
High
'
,
color
:
'
#EC672C
'
},
{
id
:
'
medium
'
,
name
:
'
Medium
'
,
color
:
'
#FBE74D
'
},
{
id
:
'
low
'
,
name
:
'
Low
'
,
color
:
'
#68C88E
'
},
{
id
:
'
informational
'
,
name
:
'
Informational
'
,
color
:
'
#A3AEBE
'
},
{
id
:
'
gas
'
,
name
:
'
Gas
'
,
color
:
'
#A47585
'
},
];
interface
Props
{
className
?:
string
;
hash
:
string
;
}
const
SolidityscanReport
=
({
className
,
hash
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
const
{
data
,
isPlaceholderData
,
isError
}
=
useApiQuery
(
'
contract_solidityscan_report
'
,
{
pathParams
:
{
hash
},
queryOptions
:
{
enabled
:
Boolean
(
hash
),
placeholderData
:
SOLIDITYSCAN_REPORT
,
},
});
const
score
=
Number
(
data
?.
scan_report
.
scan_summary
.
score_v2
);
const
bgBar
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
const
chartGrayColor
=
useColorModeValue
(
'
gray.100
'
,
'
gray.700
'
);
const
yetAnotherGrayColor
=
useColorModeValue
(
'
gray.400
'
,
'
gray.500
'
);
const
popoverBgColor
=
useColorModeValue
(
'
white
'
,
'
gray.900
'
);
if
(
isError
||
!
score
)
{
return
null
;
}
let
scoreColor
;
let
scoreLevel
;
if
(
score
>=
80
)
{
scoreColor
=
'
green.600
'
;
scoreLevel
=
'
GREAT
'
;
}
else
if
(
score
>=
30
)
{
scoreColor
=
'
orange.600
'
;
scoreLevel
=
'
AVERAGE
'
;
}
else
{
scoreColor
=
'
red.600
'
;
scoreLevel
=
'
LOW
'
;
}
const
vulnerabilities
=
data
?.
scan_report
.
scan_summary
.
issue_severity_distribution
;
const
vulnerabilitiesCounts
=
vulnerabilities
?
Object
.
values
(
vulnerabilities
)
:
[];
const
vulnerabilitiesCount
=
vulnerabilitiesCounts
.
reduce
((
acc
,
val
)
=>
acc
+
val
,
0
);
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
PopoverTrigger
>
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
>
<
Button
className=
{
className
}
color=
{
scoreColor
}
size=
"sm"
variant=
"outline"
colorScheme=
"gray"
onClick=
{
onToggle
}
aria
-
label=
"SolidityScan score"
fontWeight=
{
500
}
px=
{
2
}
h=
"32px"
flexShrink=
{
0
}
>
<
Icon
as=
{
score
<
80
?
scoreNotOkIcon
:
scoreOkIcon
}
boxSize=
{
5
}
mr=
{
1
}
/>
{
score
}
</
Button
>
</
Skeleton
>
</
PopoverTrigger
>
<
PopoverContent
w=
{
{
base
:
'
100vw
'
,
lg
:
'
328px
'
}
}
>
<
PopoverBody
px=
"26px"
py=
"20px"
fontSize=
"sm"
>
<
Box
mb=
{
5
}
>
Contract analyzed for 140+ vulnerability patterns by SolidityScan
</
Box
>
<
Flex
alignItems=
"center"
mb=
{
5
}
>
<
Box
w=
{
12
}
h=
{
12
}
bgGradient=
{
`conic-gradient(${ scoreColor } 0, ${ scoreColor } ${ score }%, ${ chartGrayColor } 0, ${ chartGrayColor } 100%)`
}
borderRadius=
"24px"
position=
"relative"
mr=
{
3
}
>
<
Center
position=
"absolute"
w=
"38px"
h=
"38px"
top=
"5px"
right=
"5px"
bg=
{
popoverBgColor
}
borderRadius=
"20px"
>
<
Icon
as=
{
score
<
80
?
scoreNotOkIcon
:
scoreOkIcon
}
boxSize=
{
5
}
color=
{
scoreColor
}
/>
</
Center
>
</
Box
>
<
Box
>
<
Flex
>
<
Text
color=
{
scoreColor
}
fontSize=
"lg"
fontWeight=
{
500
}
>
{
score
}
</
Text
>
<
Text
color=
{
yetAnotherGrayColor
}
fontSize=
"lg"
fontWeight=
{
500
}
whiteSpace=
"pre"
>
/ 100
</
Text
>
</
Flex
>
<
Text
color=
{
scoreColor
}
fontWeight=
{
500
}
>
Security score is
{
scoreLevel
}
</
Text
>
</
Box
>
</
Flex
>
{
vulnerabilities
&&
vulnerabilitiesCount
&&
(
<
Box
mb=
{
5
}
>
<
Text
py=
"7px"
variant=
"secondary"
fontSize=
"xs"
fontWeight=
{
500
}
>
Vulnerabilities distribution
</
Text
>
<
Grid
templateColumns=
"20px 1fr 100px"
alignItems=
"center"
rowGap=
{
2
}
>
{
DISTRIBUTION_ITEMS
.
map
(
item
=>
(
<>
<
Box
w=
{
3
}
h=
{
3
}
bg=
{
item
.
color
}
borderRadius=
"6px"
mr=
{
2
}
></
Box
>
<
Flex
justifyContent=
"space-between"
mr=
{
3
}
>
<
Text
>
{
item
.
name
}
</
Text
>
<
Text
color=
{
vulnerabilities
[
item
.
id
]
>
0
?
'
text
'
:
yetAnotherGrayColor
}
>
{
vulnerabilities
[
item
.
id
]
}
</
Text
>
</
Flex
>
<
Box
bg=
{
bgBar
}
h=
"10px"
borderRadius=
"8px"
>
<
Box
bg=
{
item
.
color
}
w=
{
vulnerabilities
[
item
.
id
]
/
vulnerabilitiesCount
}
h=
"10px"
borderRadius=
"8px"
/>
</
Box
>
</>
))
}
</
Grid
>
</
Box
>
)
}
<
LinkExternal
href=
{
data
?.
scan_report
.
scanner_reference_url
}
>
View full report
</
LinkExternal
>
</
PopoverBody
>
</
PopoverContent
>
</
Popover
>
);
};
export
default
chakra
(
SolidityscanReport
);
ui/address/__screenshots__/SolidityscanReport.pw.tsx_dark-color-mode_base-view-dark-mode-mobile-1.png
0 → 100644
View file @
aabc034f
29.3 KB
ui/address/__screenshots__/SolidityscanReport.pw.tsx_default_base-view-dark-mode-mobile-1.png
0 → 100644
View file @
aabc034f
30.1 KB
ui/address/__screenshots__/SolidityscanReport.pw.tsx_mobile_base-view-dark-mode-mobile-1.png
0 → 100644
View file @
aabc034f
25.7 KB
ui/pages/Address.tsx
View file @
aabc034f
import
{
Box
,
Flex
,
Icon
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
,
HStack
,
Icon
}
from
'
@chakra-ui/react
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -25,6 +25,7 @@ import AddressTxs from 'ui/address/AddressTxs';
...
@@ -25,6 +25,7 @@ import AddressTxs from 'ui/address/AddressTxs';
import
AddressWithdrawals
from
'
ui/address/AddressWithdrawals
'
;
import
AddressWithdrawals
from
'
ui/address/AddressWithdrawals
'
;
import
AddressFavoriteButton
from
'
ui/address/details/AddressFavoriteButton
'
;
import
AddressFavoriteButton
from
'
ui/address/details/AddressFavoriteButton
'
;
import
AddressQrCode
from
'
ui/address/details/AddressQrCode
'
;
import
AddressQrCode
from
'
ui/address/details/AddressQrCode
'
;
import
SolidityscanReport
from
'
ui/address/SolidityscanReport
'
;
import
AccountActionsMenu
from
'
ui/shared/AccountActionsMenu/AccountActionsMenu
'
;
import
AccountActionsMenu
from
'
ui/shared/AccountActionsMenu/AccountActionsMenu
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
AddressAddToWallet
from
'
ui/shared/address/AddressAddToWallet
'
;
import
AddressAddToWallet
from
'
ui/shared/address/AddressAddToWallet
'
;
...
@@ -194,7 +195,9 @@ const AddressPageContent = () => {
...
@@ -194,7 +195,9 @@ const AddressPageContent = () => {
)
}
)
}
<
AddressQrCode
address=
{
{
hash
}
}
isLoading=
{
isLoading
}
/>
<
AddressQrCode
address=
{
{
hash
}
}
isLoading=
{
isLoading
}
/>
<
AccountActionsMenu
isLoading=
{
isLoading
}
/>
<
AccountActionsMenu
isLoading=
{
isLoading
}
/>
<
NetworkExplorers
type=
"address"
pathParam=
{
hash
}
ml=
"auto"
/>
<
HStack
ml=
"auto"
gap=
{
2
}
/>
<
SolidityscanReport
hash=
{
hash
}
/>
<
NetworkExplorers
type=
"address"
pathParam=
{
hash
}
/>
</
Flex
>
</
Flex
>
);
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment