From 683da61778e8101ad107fbe4a50a3d480472ee99 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 17 Jul 2021 15:58:33 -0300 Subject: [PATCH] Initial tracking ot self-destructs --- src/Transaction.tsx | 15 +++-- src/components/InternalSelfDestruct.tsx | 82 +++++++++++++++++++++++++ src/nodeFunctions.ts | 23 ++++++- src/params.ts | 2 +- src/transaction/Details.tsx | 26 +++++--- src/types.ts | 5 ++ src/useErigonHooks.ts | 22 +++++-- 7 files changed, 152 insertions(+), 23 deletions(-) create mode 100644 src/components/InternalSelfDestruct.tsx diff --git a/src/Transaction.tsx b/src/Transaction.tsx index 773901e..96b7bf9 100644 --- a/src/Transaction.tsx +++ b/src/Transaction.tsx @@ -105,19 +105,24 @@ const Transaction: React.FC = () => { readBlock(); }, [provider, txhash]); - const transfers = useInternalTransfers(provider, txData); + const intTransfers = useInternalTransfers(provider, txData); const sendsEthToMiner = useMemo(() => { - if (!txData || !transfers) { + if (!txData || !intTransfers) { return false; } - for (const t of transfers) { + for (const t of intTransfers.transfers) { + if (t.to === txData.miner) { + return true; + } + } + for (const t of intTransfers.selfDestructs) { if (t.to === txData.miner) { return true; } } return false; - }, [txData, transfers]); + }, [txData, intTransfers]); const selectionCtx = useSelection(); @@ -136,7 +141,7 @@ const Transaction: React.FC = () => {
diff --git a/src/components/InternalSelfDestruct.tsx b/src/components/InternalSelfDestruct.tsx new file mode 100644 index 0000000..862eac8 --- /dev/null +++ b/src/components/InternalSelfDestruct.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import { ethers } from "ethers"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faAngleRight, + faBomb, + faCoins, +} from "@fortawesome/free-solid-svg-icons"; +import AddressHighlighter from "./AddressHighlighter"; +import AddressLink from "./AddressLink"; +import { TransactionData, Transfer } from "../types"; + +type InternalSelfDestructProps = { + txData: TransactionData; + transfer: Transfer; +}; + +const InternalSelfDestruct: React.FC = ({ + txData, + transfer, +}) => { + const fromMiner = + txData.miner !== undefined && transfer.from === txData.miner; + const toMiner = txData.miner !== undefined && transfer.to === txData.miner; + + return ( + <> +
+ + + + {" "} + SELF DESTRUCT + + Contract +
+ +
+ {fromMiner && ( + + + + )} + +
+
+
+
+ {!transfer.value.isZero() && ( +
+ + TRANSFER + + {ethers.utils.formatEther(transfer.value)} Ether +
+ To + +
+ {toMiner && ( + + + + )} + +
+
+
+
+ )} + + ); +}; + +export default React.memo(InternalSelfDestruct); diff --git a/src/nodeFunctions.ts b/src/nodeFunctions.ts index 9ddd788..b3ff583 100644 --- a/src/nodeFunctions.ts +++ b/src/nodeFunctions.ts @@ -5,12 +5,31 @@ export const getTransactionTransfers = async ( provider: ethers.providers.JsonRpcProvider, txData: TransactionData ) => { - const r = await provider.send("ots_getTransactionTransfers", [ + const rawTransfers = await provider.send("ots_getTransactionTransfers", [ txData.transactionHash, ]); const _transfers: Transfer[] = []; - for (const t of r) { + for (const t of rawTransfers) { + _transfers.push({ + from: ethers.utils.getAddress(t.from), + to: ethers.utils.getAddress(t.to), + value: t.value, + }); + } + return _transfers; +}; + +export const getTransactionSelfDestructs = async ( + provider: ethers.providers.JsonRpcProvider, + txData: TransactionData +) => { + const rawTransfers = await provider.send("ots_getTransactionSelfDestructs", [ + txData.transactionHash, + ]); + + const _transfers: Transfer[] = []; + for (const t of rawTransfers) { _transfers.push({ from: ethers.utils.getAddress(t.from), to: ethers.utils.getAddress(t.to), diff --git a/src/params.ts b/src/params.ts index 75d31c3..2bfd757 100644 --- a/src/params.ts +++ b/src/params.ts @@ -1,3 +1,3 @@ -export const MIN_API_LEVEL = 1; +export const MIN_API_LEVEL = 2; export const PAGE_SIZE = 25; diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index f5022da..614c32f 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -13,21 +13,22 @@ import AddressOrENSName from "../components/AddressOrENSName"; import Copy from "../components/Copy"; import Timestamp from "../components/Timestamp"; import InternalTransfer from "../components/InternalTransfer"; +import InternalSelfDestruct from "../components/InternalSelfDestruct"; import MethodName from "../components/MethodName"; import GasValue from "../components/GasValue"; import FormattedBalance from "../components/FormattedBalance"; import TokenTransferItem from "../TokenTransferItem"; -import { TransactionData, Transfer } from "../types"; +import { InternalTransfers, TransactionData } from "../types"; type DetailsProps = { txData: TransactionData; - transfers?: Transfer[]; + internalTransfers?: InternalTransfers; sendsEthToMiner: boolean; }; const Details: React.FC = ({ txData, - transfers, + internalTransfers, sendsEthToMiner, }) => ( @@ -76,12 +77,19 @@ const Details: React.FC = ({ - {transfers && ( -
- {transfers.map((t, i) => ( - - ))} -
+ {internalTransfers && ( + <> +
+ {internalTransfers.transfers.map((t, i) => ( + + ))} +
+
+ {internalTransfers.selfDestructs.map((t, i) => ( + + ))} +
+ )} diff --git a/src/types.ts b/src/types.ts index 9ee8d3d..2e572bd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -68,6 +68,11 @@ export type Transfer = { value: BigNumber; }; +export type InternalTransfers = { + transfers: Transfer[]; + selfDestructs: Transfer[]; +}; + export type TokenTransfer = { token: string; from: string; diff --git a/src/useErigonHooks.ts b/src/useErigonHooks.ts index 2d3aa9b..589ec34 100644 --- a/src/useErigonHooks.ts +++ b/src/useErigonHooks.ts @@ -1,13 +1,16 @@ import { ethers } from "ethers"; import { useState, useEffect } from "react"; -import { getTransactionTransfers } from "./nodeFunctions"; -import { TransactionData, Transfer } from "./types"; +import { + getTransactionSelfDestructs, + getTransactionTransfers, +} from "./nodeFunctions"; +import { InternalTransfers, TransactionData } from "./types"; export const useInternalTransfers = ( provider: ethers.providers.JsonRpcProvider | undefined, txData: TransactionData | undefined -) => { - const [transfers, setTransfers] = useState(); +): InternalTransfers | undefined => { + const [intTransfers, setIntTransfers] = useState(); useEffect(() => { const traceTransfers = async () => { @@ -16,10 +19,17 @@ export const useInternalTransfers = ( } const _transfers = await getTransactionTransfers(provider, txData); - setTransfers(_transfers); + const _selfDestructs = await getTransactionSelfDestructs( + provider, + txData + ); + for (const s of _selfDestructs) { + s.value = provider.formatter.bigNumber(s.value); + } + setIntTransfers({ transfers: _transfers, selfDestructs: _selfDestructs }); }; traceTransfers(); }, [provider, txData]); - return transfers; + return intTransfers; };