Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/backmerge-hhv3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"create-eth": patch
---

- hardhat v3 migration (https://github.com/scaffold-eth/scaffold-eth-2/pull/1272)
- up rocketh/deploy (https://github.com/scaffold-eth/scaffold-eth-2/pull/1290)
- Update hh artifacts and compilers (https://github.com/scaffold-eth/scaffold-eth-2/pull/1292)
- fix(nextjs): stop excluding contracts/ from format script (https://github.com/scaffold-eth/scaffold-eth-2/pull/1291)
- Fix blockexplorer pagination when auto mining is set (https://github.com/scaffold-eth/scaffold-eth-2/pull/1295)
4 changes: 2 additions & 2 deletions .github/workflows/lint-instances.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ jobs:
git config --global user.name "Dummy User"
git config --global user.email "dummy@example.com"

- name: Setup Node.js 20.x
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
node-version: lts/*

- name: Install Dependencies
run: yarn
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ CLI to create decentralized applications (dapps) using Scaffold-ETH 2.

Before you begin, you need to install the following tools:

- [Node (>= v20.18.3)](https://nodejs.org/en/download/)
- [Node (>= v22.10.0)](https://nodejs.org/en/download/)
- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))
- [Git](https://git-scm.com/downloads)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const publicClient = createPublicClient({
});

export const ContractTabs = ({ address, contractData }: PageProps) => {
const { blocks, transactionReceipts, currentPage, totalBlocks, setCurrentPage } = useFetchBlocks();
const { blocks, transactionReceipts, currentPage, totalTransactions, setCurrentPage } = useFetchBlocks();
const [activeTab, setActiveTab] = useState("transactions");
const [isContract, setIsContract] = useState(false);

Expand Down Expand Up @@ -85,11 +85,7 @@ export const ContractTabs = ({ address, contractData }: PageProps) => {
{activeTab === "transactions" && (
<div className="pt-4">
<TransactionsTable blocks={filteredBlocks} transactionReceipts={transactionReceipts} />
<PaginationButton
currentPage={currentPage}
totalItems={Number(totalBlocks)}
setCurrentPage={setCurrentPage}
/>
<PaginationButton currentPage={currentPage} totalItems={totalTransactions} setCurrentPage={setCurrentPage} />
</div>
)}
{activeTab === "code" && contractData && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,76 @@ import { TransactionsTableProps } from "~~/utils/scaffold-eth/";

export const TransactionsTable = ({ blocks, transactionReceipts }: TransactionsTableProps) => {
const { targetNetwork } = useTargetNetwork();
const hasTransactions = blocks.some(block => block.transactions.length > 0);

return (
<div className="flex justify-center px-4 md:px-0">
<div className="overflow-x-auto w-full shadow-2xl rounded-xl">
<table className="table text-xl bg-base-100 table-zebra w-full md:table-md table-sm">
<thead>
<tr className="rounded-xl text-sm text-base-content">
<th className="bg-primary">Transaction Hash</th>
<th className="bg-primary">Function Called</th>
<th className="bg-primary">Block Number</th>
<th className="bg-primary">Time Mined</th>
<th className="bg-primary">From</th>
<th className="bg-primary">To</th>
<th className="bg-primary text-end">Value ({targetNetwork.nativeCurrency.symbol})</th>
</tr>
</thead>
<tbody>
{blocks.map(block =>
(block.transactions as TransactionWithFunction[]).map(tx => {
const receipt = transactionReceipts[tx.hash];
const timeMined = new Date(Number(block.timestamp) * 1000).toLocaleString();
const functionCalled = tx.input.substring(0, 10);
{!hasTransactions ? (
<div className="bg-base-100 rounded-xl p-8 text-center text-base-content/70">
No transactions found on this page.
</div>
) : (
<table className="table text-xl bg-base-100 table-zebra w-full md:table-md table-sm">
<thead>
<tr className="rounded-xl text-sm text-base-content">
<th className="bg-primary">Transaction Hash</th>
<th className="bg-primary">Function Called</th>
<th className="bg-primary">Block Number</th>
<th className="bg-primary">Time Mined</th>
<th className="bg-primary">From</th>
<th className="bg-primary">To</th>
<th className="bg-primary text-end">Value ({targetNetwork.nativeCurrency.symbol})</th>
</tr>
</thead>
<tbody>
{blocks.map(block =>
(block.transactions as TransactionWithFunction[]).map(tx => {
const receipt = transactionReceipts[tx.hash];
const timeMined = new Date(Number(block.timestamp) * 1000).toLocaleString();
const functionCalled = tx.input.substring(0, 10);

return (
<tr key={tx.hash} className="hover text-sm">
<td className="w-1/12 md:py-4">
<TransactionHash hash={tx.hash} />
</td>
<td className="w-2/12 md:py-4">
{tx.functionName === "0x" ? "" : <span className="mr-1">{tx.functionName}</span>}
{functionCalled !== "0x" && (
<span className="badge badge-primary font-bold text-xs">{functionCalled}</span>
)}
</td>
<td className="w-1/12 md:py-4">{block.number?.toString()}</td>
<td className="w-2/12 md:py-4">{timeMined}</td>
<td className="w-2/12 md:py-4">
<Address address={tx.from} size="sm" onlyEnsOrAddress chain={targetNetwork} />
</td>
<td className="w-2/12 md:py-4">
{!receipt?.contractAddress ? (
tx.to && <Address address={tx.to} size="sm" onlyEnsOrAddress chain={targetNetwork} />
) : (
<div className="relative">
<Address address={receipt.contractAddress} size="sm" onlyEnsOrAddress chain={targetNetwork} />
<small className="absolute top-4 left-4">(Contract Creation)</small>
</div>
)}
</td>
<td className="text-right md:py-4">
{formatEther(tx.value)} {targetNetwork.nativeCurrency.symbol}
</td>
</tr>
);
}),
)}
</tbody>
</table>
return (
<tr key={tx.hash} className="hover text-sm">
<td className="w-1/12 md:py-4">
<TransactionHash hash={tx.hash} />
</td>
<td className="w-2/12 md:py-4">
{tx.functionName === "0x" ? "" : <span className="mr-1">{tx.functionName}</span>}
{functionCalled !== "0x" && (
<span className="badge badge-primary font-bold text-xs">{functionCalled}</span>
)}
</td>
<td className="w-1/12 md:py-4">{block.number?.toString()}</td>
<td className="w-2/12 md:py-4">{timeMined}</td>
<td className="w-2/12 md:py-4">
<Address address={tx.from} size="sm" onlyEnsOrAddress chain={targetNetwork} />
</td>
<td className="w-2/12 md:py-4">
{!receipt?.contractAddress ? (
tx.to && <Address address={tx.to} size="sm" onlyEnsOrAddress chain={targetNetwork} />
) : (
<div className="relative">
<Address
address={receipt.contractAddress}
size="sm"
onlyEnsOrAddress
chain={targetNetwork}
/>
<small className="absolute top-4 left-4">(Contract Creation)</small>
</div>
)}
</td>
<td className="text-right md:py-4">
{formatEther(tx.value)} {targetNetwork.nativeCurrency.symbol}
</td>
</tr>
);
}),
)}
</tbody>
</table>
)}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ ${
return { bytecode, assembly };
}`
: `async function fetchByteCodeAndAssembly(buildInfoDirectory: string, contractName: string) {
const contractPath = \`contracts/\${contractName}.sol\`;
const buildInfoFiles = fs.readdirSync(buildInfoDirectory);
const contractPath = \`project/contracts/\${contractName}.sol\`;
const buildInfoFiles = fs.readdirSync(buildInfoDirectory).filter(f => f.endsWith(".output.json"));
let bytecode = "";
let assembly = "";

Expand All @@ -60,7 +60,7 @@ ${

const buildInfo = JSON.parse(fs.readFileSync(filePath, "utf8"));

if (buildInfo.output.contracts[contractPath]) {
if (buildInfo.output?.contracts?.[contractPath]) {
for (const contract in buildInfo.output.contracts[contractPath]) {
bytecode = buildInfo.output.contracts[contractPath][contract].evm.bytecode.object;
assembly = buildInfo.output.contracts[contractPath][contract].evm.bytecode.opcodes;
Expand Down
4 changes: 2 additions & 2 deletions templates/base/packages/nextjs/app/blockexplorer/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
import { notification } from "~~/utils/scaffold-eth";

const BlockExplorer: NextPage = () => {
const { blocks, transactionReceipts, currentPage, totalBlocks, setCurrentPage, error } = useFetchBlocks();
const { blocks, transactionReceipts, currentPage, totalTransactions, setCurrentPage, error } = useFetchBlocks();
const { targetNetwork } = useTargetNetwork();
const [isLocalNetwork, setIsLocalNetwork] = useState(true);
const [hasError, setHasError] = useState(false);
Expand Down Expand Up @@ -75,7 +75,7 @@ const BlockExplorer: NextPage = () => {
<div className="container mx-auto my-10">
<SearchBar />
<TransactionsTable blocks={blocks} transactionReceipts={transactionReceipts} />
<PaginationButton currentPage={currentPage} totalItems={Number(totalBlocks)} setCurrentPage={setCurrentPage} />
<PaginationButton currentPage={currentPage} totalItems={totalTransactions} setCurrentPage={setCurrentPage} />
</div>
);
};
Expand Down
Loading
Loading