Skip to content

Commit 0ab3868

Browse files
Merge pull request #137 from ethscriptions-protocol/fix_collections
Refactor Ethscription Content Handling and Metadata Storage
2 parents fb2b911 + 847d5de commit 0ab3868

34 files changed

Lines changed: 998 additions & 215 deletions

app/models/ethscription_transaction.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ def build_create_calldata
187187
)
188188

189189
# Hash the content for protocol uniqueness
190-
content_uri_hash_hex = Digest::SHA256.hexdigest(content_uri)
191-
content_uri_hash = [content_uri_hash_hex].pack('H*')
190+
content_uri_sha_hex = Digest::SHA256.hexdigest(content_uri)
191+
content_uri_sha = [content_uri_sha_hex].pack('H*')
192192

193193
# Convert hex strings to binary for ABI encoding
194194
tx_hash_bin = hex_to_bin(eth_transaction.transaction_hash)
@@ -204,7 +204,7 @@ def build_create_calldata
204204
# Encode parameters
205205
params = [
206206
tx_hash_bin, # bytes32 ethscriptionId (L1 tx hash)
207-
content_uri_hash, # bytes32 contentUriHash
207+
content_uri_sha, # bytes32 contentUriHash
208208
owner_bin, # address
209209
raw_content, # bytes content
210210
mimetype.b, # string

contracts/script/L2Genesis.s.sol

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {L2GenesisConfig} from "./L2GenesisConfig.sol";
66
import {Predeploys} from "../src/libraries/Predeploys.sol";
77
import {Constants} from "../src/libraries/Constants.sol";
88
import {Ethscriptions} from "../src/Ethscriptions.sol";
9+
import {MetaStoreLib} from "../src/libraries/MetaStoreLib.sol";
910
import "forge-std/console.sol";
1011

1112
/// @title GenesisEthscriptions
@@ -32,28 +33,37 @@ contract GenesisEthscriptions is Ethscriptions {
3233
require(ethscriptions[params.ethscriptionId].creator == address(0), "Ethscription already exists");
3334

3435
// Check protocol uniqueness using content URI hash
35-
if (firstEthscriptionByContentUri[params.contentUriHash] != bytes32(0)) {
36+
if (firstEthscriptionByContentUri[params.contentUriSha] != bytes32(0)) {
3637
if (!params.esip6) revert DuplicateContentUri();
3738
}
3839

39-
// Store content and get content SHA (reusing parent's helper)
40-
bytes32 contentSha = _storeContent(params.content);
40+
// Store content and get content hash (reusing parent's helper)
41+
bytes32 contentHash = _storeContent(params.content);
4142

4243
// Mark content URI as used by storing this ethscription's tx hash
43-
firstEthscriptionByContentUri[params.contentUriHash] = params.ethscriptionId;
44+
firstEthscriptionByContentUri[params.contentUriSha] = params.ethscriptionId;
45+
46+
// Store metadata (mimetype, protocol, operation)
47+
// Genesis ethscriptions have no protocol parameters
48+
bytes32 metaRef = MetaStoreLib.store(
49+
params.mimetype,
50+
params.protocolParams.protocolName,
51+
params.protocolParams.operation,
52+
metadataStorage
53+
);
4454

4555
// Set all values including genesis-specific ones
4656
ethscriptions[params.ethscriptionId] = EthscriptionStorage({
4757
// Fixed-size fields
48-
contentUriHash: params.contentUriHash,
49-
contentSha: contentSha,
58+
contentUriSha: params.contentUriSha,
59+
contentHash: contentHash,
5060
l1BlockHash: l1BlockHash,
5161
// Packed slot 3
5262
creator: creator,
5363
createdAt: uint48(createdAt),
5464
l1BlockNumber: uint48(l1BlockNumber),
55-
// Dynamic field
56-
mimetype: params.mimetype,
65+
// Metadata reference
66+
metaRef: metaRef,
5767
// Packed slot N
5868
initialOwner: params.initialOwner,
5969
ethscriptionNumber: uint48(totalSupply()),
@@ -333,7 +343,7 @@ contract L2Genesis is Script {
333343
// The JSON already has all the properly processed data
334344
Ethscriptions.CreateEthscriptionParams memory params;
335345
params.ethscriptionId = vm.parseJsonBytes32(json, string.concat(basePath, ".transaction_hash"));
336-
params.contentUriHash = vm.parseJsonBytes32(json, string.concat(basePath, ".content_uri_hash"));
346+
params.contentUriSha = vm.parseJsonBytes32(json, string.concat(basePath, ".content_uri_hash"));
337347
params.initialOwner = initialOwner;
338348
params.content = vm.parseJsonBytes(json, string.concat(basePath, ".content"));
339349
params.mimetype = vm.parseJsonString(json, string.concat(basePath, ".mimetype"));

contracts/script/TestTokenUri.s.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ contract TestTokenUri is Script {
1818
vm.prank(address(0x1111));
1919
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
2020
ethscriptionId: keccak256("text1"),
21-
contentUriHash: keccak256("data:text/plain,Hello World!"),
21+
contentUriSha: keccak256("data:text/plain,Hello World!"),
2222
initialOwner: address(0x1111),
2323
content: bytes("Hello World!"),
2424
mimetype: "text/plain",
@@ -30,7 +30,7 @@ contract TestTokenUri is Script {
3030
vm.prank(address(0x2222));
3131
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
3232
ethscriptionId: keccak256("json1"),
33-
contentUriHash: keccak256('data:application/json,{"p":"erc-20","op":"mint","tick":"test","amt":"1000"}'),
33+
contentUriSha: keccak256('data:application/json,{"p":"erc-20","op":"mint","tick":"test","amt":"1000"}'),
3434
initialOwner: address(0x2222),
3535
content: bytes('{"p":"erc-20","op":"mint","tick":"test","amt":"1000"}'),
3636
mimetype: "application/json",
@@ -42,7 +42,7 @@ contract TestTokenUri is Script {
4242
vm.prank(address(0x3333));
4343
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
4444
ethscriptionId: keccak256("html1"),
45-
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>'),
45+
contentUriSha: 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>'),
4646
initialOwner: address(0x3333),
4747
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>'),
4848
mimetype: "text/html",
@@ -55,7 +55,7 @@ contract TestTokenUri is Script {
5555
vm.prank(address(0x4444));
5656
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
5757
ethscriptionId: keccak256("image1"),
58-
contentUriHash: keccak256("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAm0lEQVR42mNgGITgPxTTxvBleTo0swBsOK0s+N8aJkczC1AMR7KAKpb8v72xAY5hFsD4lFoCN+j56ZUoliBbSoklGIZjwxRbQAjT1YK7d+82kGUBeuQii5FrAYYrL81NwCpGFQtoEUT/6RoHWAyknQV0S6ZI5RE6Jt8CZIOOHTuGgR9Fq5FkCf19QM3wx5rZKHEtsRZQt5qkhgUAR6cGaUehOD4AAAAASUVORK5CYII="),
58+
contentUriSha: keccak256("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAm0lEQVR42mNgGITgPxTTxvBleTo0swBsOK0s+N8aJkczC1AMR7KAKpb8v72xAY5hFsD4lFoCN+j56ZUoliBbSoklGIZjwxRbQAjT1YK7d+82kGUBeuQii5FrAYYrL81NwCpGFQtoEUT/6RoHWAyknQV0S6ZI5RE6Jt8CZIOOHTuGgR9Fq5FkCf19QM3wx5rZKHEtsRZQt5qkhgUAR6cGaUehOD4AAAAASUVORK5CYII="),
5959
initialOwner: address(0x4444),
6060
content: redPixelPng,
6161
mimetype: "image/png",
@@ -67,7 +67,7 @@ contract TestTokenUri is Script {
6767
vm.prank(address(0x5555));
6868
eth.createEthscription(Ethscriptions.CreateEthscriptionParams({
6969
ethscriptionId: keccak256("css1"),
70-
contentUriHash: keccak256("data:text/css,body { background: #000; color: #0f0; font-family: 'Courier New'; }"),
70+
contentUriSha: keccak256("data:text/css,body { background: #000; color: #0f0; font-family: 'Courier New'; }"),
7171
initialOwner: address(0x5555),
7272
content: bytes("body { background: #000; color: #0f0; font-family: 'Courier New'; }"),
7373
mimetype: "text/css",

contracts/script/process_genesis_json.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
content_uri = ethscription['content_uri']
1414

1515
# Calculate content URI hash (as hex string with 0x prefix for JSON)
16-
content_uri_hash = '0x' + Digest::SHA256.hexdigest(content_uri)
17-
ethscription['content_uri_hash'] = content_uri_hash
16+
content_uri_sha = '0x' + Digest::SHA256.hexdigest(content_uri)
17+
ethscription['content_uri_sha'] = content_uri_sha
1818

1919
# Parse the data URI
2020
if content_uri.start_with?('data:')
@@ -56,4 +56,4 @@
5656
File.write(json_path, JSON.pretty_generate(data))
5757

5858
puts "Processed #{data['ethscriptions'].length} ethscriptions"
59-
puts "Added content_uri_hash and content fields"
59+
puts "Added content_uri_sha and content fields"

0 commit comments

Comments
 (0)