Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion app/models/ethscription_transaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def build_create_calldata

# Encode parameters
params = [
tx_hash_bin, # bytes32 transactionHash
tx_hash_bin, # bytes32 ethscriptionId (L1 tx hash)
content_uri_hash, # bytes32 contentUriHash
owner_bin, # address
raw_content, # bytes content
Expand Down
22 changes: 11 additions & 11 deletions contracts/script/L2Genesis.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import "forge-std/console.sol";
/// @dev Used only during genesis, then replaced with the real Ethscriptions contract
contract GenesisEthscriptions is Ethscriptions {

/// @notice Store a genesis ethscription transaction hash for later event emission
/// @notice Store a genesis ethscription ID for later event emission
/// @dev Internal function only used during genesis setup
/// @param transactionHash The transaction hash to store
function _storePendingGenesisEvent(bytes32 transactionHash) internal {
pendingGenesisEvents.push(transactionHash);
/// @param ethscriptionId The ethscription ID (L1 tx hash) to store
function _storePendingGenesisEvent(bytes32 ethscriptionId) internal {
pendingGenesisEvents.push(ethscriptionId);
}

/// @notice Create an ethscription with all values explicitly set for genesis
Expand All @@ -29,7 +29,7 @@ contract GenesisEthscriptions is Ethscriptions {
bytes32 l1BlockHash
) public returns (uint256 tokenId) {
require(creator != address(0), "Invalid creator");
require(ethscriptions[params.transactionHash].creator == address(0), "Ethscription already exists");
require(ethscriptions[params.ethscriptionId].creator == address(0), "Ethscription already exists");

// Check protocol uniqueness using content URI hash
if (firstEthscriptionByContentUri[params.contentUriHash] != bytes32(0)) {
Expand All @@ -40,10 +40,10 @@ contract GenesisEthscriptions is Ethscriptions {
bytes32 contentSha = _storeContent(params.content);

// Mark content URI as used by storing this ethscription's tx hash
firstEthscriptionByContentUri[params.contentUriHash] = params.transactionHash;
firstEthscriptionByContentUri[params.contentUriHash] = params.ethscriptionId;

// Set all values including genesis-specific ones
ethscriptions[params.transactionHash] = Ethscription({
ethscriptions[params.ethscriptionId] = Ethscription({
// Fixed-size fields
contentUriHash: params.contentUriHash,
contentSha: contentSha,
Expand All @@ -66,8 +66,8 @@ contract GenesisEthscriptions is Ethscriptions {
// Use ethscription number as token ID
tokenId = totalSupply();

// Store the mapping from token ID to transaction hash
tokenIdToTransactionHash[tokenId] = params.transactionHash;
// Store the mapping from token ID to ethscription ID
tokenIdToEthscriptionId[tokenId] = params.ethscriptionId;

// Token count is automatically tracked by enumerable's _update

Expand All @@ -82,7 +82,7 @@ contract GenesisEthscriptions is Ethscriptions {
// Store the transaction hash so all events can be emitted later
// The emission logic in _emitPendingGenesisEvents will figure out
// what events to emit based on the ethscription data
_storePendingGenesisEvent(params.transactionHash);
_storePendingGenesisEvent(params.ethscriptionId);

// Skip token handling for genesis
}
Expand Down Expand Up @@ -333,7 +333,7 @@ contract L2Genesis is Script {
// Create params struct with parsed data from JSON
// The JSON already has all the properly processed data
Ethscriptions.CreateEthscriptionParams memory params;
params.transactionHash = vm.parseJsonBytes32(json, string.concat(basePath, ".transaction_hash"));
params.ethscriptionId = vm.parseJsonBytes32(json, string.concat(basePath, ".transaction_hash"));
params.contentUriHash = vm.parseJsonBytes32(json, string.concat(basePath, ".content_uri_hash"));
params.initialOwner = initialOwner;
params.content = vm.parseJsonBytes(json, string.concat(basePath, ".content"));
Expand Down
12 changes: 6 additions & 6 deletions contracts/script/TestTokenUri.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract TestTokenUri is Script {
// Test case 1: Plain text (should use viewer)
vm.prank(address(0x1111));
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
transactionHash: keccak256("text1"),
ethscriptionId: keccak256("text1"),
contentUriHash: keccak256("data:text/plain,Hello World!"),
initialOwner: address(0x1111),
content: bytes("Hello World!"),
Expand All @@ -29,7 +29,7 @@ contract TestTokenUri is Script {
// Test case 2: JSON content (should use viewer with pretty print)
vm.prank(address(0x2222));
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
transactionHash: keccak256("json1"),
ethscriptionId: keccak256("json1"),
contentUriHash: keccak256('data:application/json,{"p":"erc-20","op":"mint","tick":"test","amt":"1000"}'),
initialOwner: address(0x2222),
content: bytes('{"p":"erc-20","op":"mint","tick":"test","amt":"1000"}'),
Expand All @@ -41,7 +41,7 @@ contract TestTokenUri is Script {
// Test case 3: HTML content (should pass through directly)
vm.prank(address(0x3333));
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
transactionHash: keccak256("html1"),
ethscriptionId: keccak256("html1"),
contentUriHash: keccak256('data:text/html,<html><body style="background:linear-gradient(45deg,#ff006e,#8338ec);color:white;font-family:monospace;display:flex;align-items:center;justify-content:center;height:100vh;margin:0"><h1>Ethscriptions Rule!</h1></body></html>'),
initialOwner: address(0x3333),
content: bytes('<html><body style="background:linear-gradient(45deg,#ff006e,#8338ec);color:white;font-family:monospace;display:flex;align-items:center;justify-content:center;height:100vh;margin:0"><h1>Ethscriptions Rule!</h1></body></html>'),
Expand All @@ -54,7 +54,7 @@ contract TestTokenUri is Script {
bytes memory redPixelPng = Base64.decode("iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAm0lEQVR42mNgGITgPxTTxvBleTo0swBsOK0s+N8aJkczC1AMR7KAKpb8v72xAY5hFsD4lFoCN+j56ZUoliBbSoklGIZjwxRbQAjT1YK7d+82kGUBeuQii5FrAYYrL81NwCpGFQtoEUT/6RoHWAyknQV0S6ZI5RE6Jt8CZIOOHTuGgR9Fq5FkCf19QM3wx5rZKHEtsRZQt5qkhgUAR6cGaUehOD4AAAAASUVORK5CYII=");
vm.prank(address(0x4444));
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
transactionHash: keccak256("image1"),
ethscriptionId: keccak256("image1"),
contentUriHash: keccak256("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAm0lEQVR42mNgGITgPxTTxvBleTo0swBsOK0s+N8aJkczC1AMR7KAKpb8v72xAY5hFsD4lFoCN+j56ZUoliBbSoklGIZjwxRbQAjT1YK7d+82kGUBeuQii5FrAYYrL81NwCpGFQtoEUT/6RoHWAyknQV0S6ZI5RE6Jt8CZIOOHTuGgR9Fq5FkCf19QM3wx5rZKHEtsRZQt5qkhgUAR6cGaUehOD4AAAAASUVORK5CYII="),
initialOwner: address(0x4444),
content: redPixelPng,
Expand All @@ -66,7 +66,7 @@ contract TestTokenUri is Script {
// Test case 5: CSS content (should use viewer)
vm.prank(address(0x5555));
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
transactionHash: keccak256("css1"),
ethscriptionId: keccak256("css1"),
contentUriHash: keccak256("data:text/css,body { background: #000; color: #0f0; font-family: 'Courier New'; }"),
initialOwner: address(0x5555),
content: bytes("body { background: #000; color: #0f0; font-family: 'Courier New'; }"),
Expand Down Expand Up @@ -110,4 +110,4 @@ contract TestTokenUri is Script {

console.log("=== PASTE ANY OF THE ABOVE data: URIs INTO YOUR BROWSER ===");
}
}
}
8 changes: 4 additions & 4 deletions contracts/src/CollectionsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ contract CollectionsManager is IProtocolHandler {
// Runtime state for a collection (separate from metadata)
struct CollectionState {
address collectionContract;
bytes32 createTxHash;
bytes32 createEthscriptionId;
uint256 currentSize;
bool locked;
}
Expand Down Expand Up @@ -135,7 +135,7 @@ contract CollectionsManager is IProtocolHandler {
event CollectionLocked(bytes32 indexed collectionId);

// Mirror success signaling so indexers can detect success without relying on router
event ProtocolHandlerSuccess(bytes32 indexed transactionHash, string protocol);
event ProtocolHandlerSuccess(bytes32 indexed ethscriptionId, string protocol);

modifier onlyEthscriptions() {
require(msg.sender == ethscriptions, "Only Ethscriptions contract");
Expand Down Expand Up @@ -169,7 +169,7 @@ contract CollectionsManager is IProtocolHandler {
// Store collection state
collectionState[collectionId] = CollectionState({
collectionContract: collectionContract,
createTxHash: txHash,
createEthscriptionId: txHash,
currentSize: 0,
locked: false
});
Expand Down Expand Up @@ -408,7 +408,7 @@ contract CollectionsManager is IProtocolHandler {
/// @notice Handle transfer notification from Ethscriptions contract
/// @dev When an ethscription that's part of a collection is transferred, sync the ERC721
function onTransfer(
bytes32 txHash,
bytes32 ethscriptionId,
address from,
address to
) external override onlyEthscriptions {
Expand Down
Loading