Skip to content

Commit a551f6c

Browse files
committed
Initial commit of kurtosis-cdk
1 parent f2ffac4 commit a551f6c

File tree

11 files changed

+369
-322
lines changed

11 files changed

+369
-322
lines changed

.gitignore

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,21 @@ templates/contract-deploy/combined.json
2828
templates/contract-deploy/dynamic-kurtosis-allocs.json
2929
templates/contract-deploy/dynamic-kurtosis-conf.json
3030
templates/contract-deploy/genesis.json
31-
anvil_state.json
31+
anvil_state.json
32+
node_modules
33+
.env
34+
35+
# Hardhat files
36+
/cache
37+
/artifacts
38+
39+
# TypeChain files
40+
/typechain
41+
/typechain-types
42+
43+
# solidity-coverage files
44+
/coverage
45+
/coverage.json
46+
47+
# Hardhat Ignition default folder for deployments against a local node
48+
ignition/deployments/chain-31337

README.md

Lines changed: 184 additions & 321 deletions
Large diffs are not rendered by default.

contracts/PrecompileWrapper.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.20;
3+
4+
contract PrecompileWrapper {
5+
address constant SHA256_PRECOMPILE = 0x0000000000000000000000000000000000000002;
6+
7+
function sha256ViaPrecompile(bytes memory input) public view returns (bytes32) {
8+
(bool success, bytes memory result) = SHA256_PRECOMPILE.staticcall(input);
9+
require(success, "Precompile call failed");
10+
11+
return abi.decode(result, (bytes32));
12+
}
13+
}

hardhat.config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { HardhatUserConfig } from "hardhat/config";
2+
import "@nomicfoundation/hardhat-toolbox";
3+
4+
const config: HardhatUserConfig = {
5+
solidity: "0.8.28",
6+
networks: {
7+
erigon: {
8+
url: "http://127.0.0.1:54906",
9+
accounts: ["0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"], // account address (from Kurtosis README)
10+
gas: 3_000_000, // fixed gas limit
11+
gasPrice: 1_000_000_000, // required to force legacy Tx (no EIP-1559)
12+
}
13+
}
14+
};
15+
16+
export default config;

ignition/modules/Lock.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// This setup uses Hardhat Ignition to manage smart contract deployments.
2+
// Learn more about it at https://hardhat.org/ignition
3+
4+
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
5+
6+
const JAN_1ST_2030 = 1893456000;
7+
const ONE_GWEI: bigint = 1_000_000_000n;
8+
9+
const LockModule = buildModule("LockModule", (m) => {
10+
const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030);
11+
const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI);
12+
13+
const lock = m.contract("Lock", [unlockTime], {
14+
value: lockedAmount,
15+
});
16+
17+
return { lock };
18+
});
19+
20+
export default LockModule;

results.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[
2+
{
3+
"stage": "1",
4+
"description": "Raw Precompile Call",
5+
"txHash": null,
6+
"receiver": "0x0000000000000000000000000000000000000002",
7+
"input": "0x47617465776179",
8+
"decodedOutput": "0x41ed52921661c7f0d68d92511589cc9d7aaeab2b5db49fb27f0be336cbfdb7df",
9+
"verdict": "pass"
10+
},
11+
{
12+
"stage": "2",
13+
"description": "Contract Wrapper Deployment",
14+
"txHash": "0x89a2aa0b4597097161faa499ba8aa1cd2d3ac752198a417707165f2682969444",
15+
"receiver": "0x62bf798EdaE1B7FDe524276864757cc424A5c3dD",
16+
"decodedOutput": null,
17+
"verdict": "pass"
18+
},
19+
{
20+
"stage": "3",
21+
"description": "Contract Invocation",
22+
"txHash": null,
23+
"receiver": "0x62bf798EdaE1B7FDe524276864757cc424A5c3dD",
24+
"input": "sha256ViaPrecompile(\"Gateway\")",
25+
"decodedOutput": "0x41ed52921661c7f0d68d92511589cc9d7aaeab2b5db49fb27f0be336cbfdb7df",
26+
"expectedOutput": "0x41ed52921661c7f0d68d92511589cc9d7aaeab2b5db49fb27f0be336cbfdb7df",
27+
"verdict": "pass"
28+
}
29+
]

results.json:Zone.Identifier

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[ZoneTransfer]
2+
ZoneId=3
3+
ReferrerUrl=https://chatgpt.com/
4+
HostUrl=https://files.oaiusercontent.com/file-KYd8rjQM3bSc2oynRBZ1ft?se=2025-05-19T13%3A15%3A34Z&sp=r&sv=2024-08-04&sr=b&rscc=max-age%3D299%2C%20immutable%2C%20private&rscd=attachment%3B%20filename%3Dresults.json&sig=0EXzjLwCg6ikMA6g7sOzqjxyA0mfwrd/7fI3DktSzyw%3D

scripts/callRawPrecompile.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { ethers } from "hardhat";
2+
3+
const provider = new ethers.JsonRpcProvider("http://localhost:54906");
4+
5+
const precompileType = {
6+
address: "0x0000000000000000000000000000000000000002",
7+
name: "SHA256"
8+
};
9+
10+
const inputData = "0x47617465776179"; // "Gateway"
11+
12+
async function callPrecompile(type: { address: string; name: string }, data: string): Promise<void> {
13+
try {
14+
const tx = {
15+
to: type.address,
16+
data: data
17+
};
18+
19+
const result: string = await provider.call(tx);
20+
console.log(`${type.name} result for ${inputData} is: ${result}`);
21+
} catch (err) {
22+
console.error("Error calling precompile:", err);
23+
}
24+
}
25+
26+
callPrecompile(precompileType, inputData);

scripts/contractInvocation.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { JsonRpcProvider, Wallet, Contract } from "ethers";
2+
import fs from "fs";
3+
import * as dotenv from "dotenv";
4+
dotenv.config();
5+
6+
// Replace with actual values
7+
const CONTRACT_ADDRESS = "0xB49fA7dD4d70F773015a9c848A8719FA86D81275";
8+
const RPC_URL = "http://127.0.0.1:54906";
9+
const PRIVATE_KEY = "0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"; // private key (from Kurtosis README)
10+
11+
const artifact = JSON.parse(fs.readFileSync("artifacts/contracts/PrecompileWrapper.sol/PrecompileWrapper.json", "utf8"));
12+
const ABI = artifact.abi;
13+
14+
async function main() {
15+
const provider = new JsonRpcProvider(RPC_URL);
16+
const wallet = new Wallet(PRIVATE_KEY, provider);
17+
const precompileWrapper = new Contract(CONTRACT_ADDRESS, ABI, wallet);
18+
19+
const input = new TextEncoder().encode("Gateway"); // "Gateway" => bytes
20+
const result = await precompileWrapper.sha256ViaPrecompile(input);
21+
22+
console.log("SHA256 of 'Gateway' via precompile:", result);
23+
}
24+
25+
main().catch((err) => {
26+
console.error("Error in script execution:", err);
27+
});

scripts/deployWrapper.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ethers } from "hardhat";
2+
3+
async function main() {
4+
const [deployer] = await ethers.getSigners();
5+
console.log("Deploying contract with:", deployer.address);
6+
7+
const Wrapper = await ethers.getContractFactory("PrecompileWrapper");
8+
9+
// Deploy with explicit gas limit and legacy type (type: 0)
10+
const txResponse = await Wrapper.deploy({ gasLimit: 1_000_000, type: 0 });
11+
const contract = await txResponse.waitForDeployment();
12+
13+
// Access from txResponse instead of contract to avoid undefined error
14+
console.log("PrecompileWrapper deployed to:", contract.target);
15+
console.log("Deployment tx hash:", txResponse.deploymentTransaction()?.hash);
16+
}
17+
18+
main().catch((error) => {
19+
console.error(error);
20+
process.exitCode = 1;
21+
});

0 commit comments

Comments
 (0)