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
72 changes: 72 additions & 0 deletions src/structs/PackageStructs.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title PackageStructs
/// @notice All data structures from EIP-2678 (EthPM v3)
/// @dev Based on https://eips.ethereum.org/EIPS/eip-2678
library PackageStructs {

/// @notice Package Meta Object from EIP-2678
struct PackageMeta {
string[] authors; // Human readable author names
string license; // SPDX format license
string description; // Package description
string[] keywords; // Relevant keywords
string website; // Primary website
string documentation; // Documentation link
string repository; // Source code location
}

/// @notice Compiler Information Object from EIP-2678
struct CompilerInfo {
string name; // Compiler name (e.g., "solc")
string version; // Semver or commit hash (e.g., "0.8.0" or "0.4.8-commit.60cc1668")
bytes settings; // Compiler settings as bytes
}

/// @notice Contract Type from EIP-2678
struct ContractType {
string contractName; // Name from source code (e.g., "Wallet")
bytes abi; // JSON ABI as bytes
bytes bytecode; // Unlinked deployment bytecode
bytes runtimeBytecode; // Unlinked runtime bytecode
string sourceId; // Reference to source file
uint256 compilerIndex; // Index in compilers array
}

/// @notice Contract Instance Object from EIP-2678
struct ContractInstance {
string contractType; // Reference to Contract Type (e.g., "Wallet" or "owned:Owned")
address instanceAddress; // Deployed contract address
bytes32 transaction; // Deployment transaction hash
uint256 blockNumber; // Deployment block number
bytes runtimeBytecode; // Linked runtime bytecode
}

/// @notice Link Reference Object from EIP-2678
struct LinkReference {
uint256[] offsets; // Start positions in bytecode (0-indexed)
uint256 length; // Length in bytes of the reference
string name; // Identifier for linking
}

/// @notice Link Value Object from EIP-2678
struct LinkValue {
uint256[] offsets; // Locations where value was written
string valueType; // "literal" for bytecode literals, "reference" for named references
string value; // 0x-prefixed hex string or contract instance name
}

/// @notice Deployment information per chain from EIP-2678
struct DeploymentInfo {
string chainURI; // BIP122 URI (e.g., blockchain://<chain_id>/block/<block_hash>)
ContractInstance[] instances; // Array of deployed contract instances
}

/// @notice Source file information from EIP-2678
struct SourceInfo {
string sourceId; // Unique identifier for source file
string content; // Source code content or IPFS hash
string license; // SPDX license (overrides package license)
}
}
106 changes: 106 additions & 0 deletions test/structs/PackageStructs.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "src/structs/PackageStructs.sol";

contract PackageStructsTest is Test {

function testPackageMeta() public {
PackageStructs.PackageMeta memory meta;
meta.authors = new string[](2);
meta.authors[0] = "Satoshi";
meta.authors[1] = "Vitalik";
meta.license = "MIT";
meta.description = "A safe math library";
meta.keywords = new string[](2);
meta.keywords[0] = "math";
meta.keywords[1] = "library";
meta.website = "https://example.com";

assertEq(meta.authors[0], "Satoshi");
assertEq(meta.license, "MIT");
assertEq(meta.keywords.length, 2);
}

function testCompilerInfo() public {
PackageStructs.CompilerInfo memory compiler;
compiler.name = "solc";
compiler.version = "0.8.0";

assertEq(compiler.name, "solc");
assertEq(compiler.version, "0.8.0");
}

function testContractType() public {
PackageStructs.ContractType memory cType;
cType.contractName = "Wallet";
cType.sourceId = "contracts/Wallet.sol";
cType.compilerIndex = 0;

assertEq(cType.contractName, "Wallet");
assertEq(cType.sourceId, "contracts/Wallet.sol");
}

function testContractInstance() public {
PackageStructs.ContractInstance memory instance;
instance.contractType = "Wallet";
instance.instanceAddress = address(0x1234567890123456789012345678901234567890);
instance.transaction = keccak256("deployment_tx");
instance.blockNumber = 12345;

assertEq(instance.contractType, "Wallet");
assertEq(instance.instanceAddress, address(0x1234567890123456789012345678901234567890));
assertEq(instance.blockNumber, 12345);
}

function testLinkReference() public {
PackageStructs.LinkReference memory ref;
ref.offsets = new uint256[](2);
ref.offsets[0] = 10;
ref.offsets[1] = 50;
ref.length = 20;
ref.name = "SafeMath";

assertEq(ref.offsets[0], 10);
assertEq(ref.offsets[1], 50);
assertEq(ref.length, 20);
assertEq(ref.name, "SafeMath");
}

function testLinkValue() public {
PackageStructs.LinkValue memory val;
val.offsets = new uint256[](1);
val.offsets[0] = 100;
val.valueType = "literal";
val.value = "0x1234";

assertEq(val.offsets[0], 100);
assertEq(val.valueType, "literal");
assertEq(val.value, "0x1234");
}

function testDeploymentInfo() public {
PackageStructs.DeploymentInfo memory deployment;
deployment.chainURI = "blockchain://1/block/0x123abc";
deployment.instances = new PackageStructs.ContractInstance[](1);

deployment.instances[0].contractType = "Token";
deployment.instances[0].instanceAddress = address(0x999);
deployment.instances[0].blockNumber = 99999;

assertEq(deployment.chainURI, "blockchain://1/block/0x123abc");
assertEq(deployment.instances.length, 1);
assertEq(deployment.instances[0].contractType, "Token");
}

function testSourceInfo() public {
PackageStructs.SourceInfo memory source;
source.sourceId = "contracts/Token.sol";
source.content = "ipfs://Qm...";
source.license = "GPL-3.0";

assertEq(source.sourceId, "contracts/Token.sol");
assertEq(source.license, "GPL-3.0");
}
}
Loading