Skip to content

Commit c6d238e

Browse files
Merge pull request #141 from ethscriptions-protocol/fix_collections
Enhance Ethscriptions Metadata Handling and URI Resolution
2 parents 6d02714 + 9e9b9c8 commit c6d238e

File tree

8 files changed

+550
-22
lines changed

8 files changed

+550
-22
lines changed

contracts/script/L2Genesis.s.sol

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ contract L2Genesis is Script {
212212
bool isProxiedContract = addr == Predeploys.ETHSCRIPTIONS ||
213213
addr == Predeploys.ERC20_FIXED_DENOMINATION_MANAGER ||
214214
addr == Predeploys.ETHSCRIPTIONS_PROVER ||
215-
addr == Predeploys.ERC721_ETHSCRIPTIONS_COLLECTION_MANAGER;
215+
addr == Predeploys.ERC721_ETHSCRIPTIONS_COLLECTION_MANAGER ||
216+
addr == Predeploys.NAME_REGISTRY;
216217
if (isProxiedContract) {
217218
address impl = Predeploys.predeployToCodeNamespace(addr);
218219
setImplementation(addr, impl);
@@ -223,10 +224,10 @@ contract L2Genesis is Script {
223224
_setImplementationCodeNamed(Predeploys.ERC20_FIXED_DENOMINATION_MANAGER, "ERC20FixedDenominationManager");
224225
_setImplementationCodeNamed(Predeploys.ERC721_ETHSCRIPTIONS_COLLECTION_MANAGER, "ERC721EthscriptionsCollectionManager");
225226
_setImplementationCodeNamed(Predeploys.ETHSCRIPTIONS_PROVER, "EthscriptionsProver");
226-
// Templates live directly at their implementation addresses (no proxy wrapping)
227+
_setImplementationCodeNamed(Predeploys.NAME_REGISTRY, "NameRegistry");
228+
// Templates live directly at their addresses (no proxy wrapping)
227229
_setCodeAt(Predeploys.ERC20_FIXED_DENOMINATION_IMPLEMENTATION, "ERC20FixedDenomination");
228230
_setCodeAt(Predeploys.ERC721_ETHSCRIPTIONS_COLLECTION_IMPLEMENTATION, "ERC721EthscriptionsCollection");
229-
_setCodeAt(Predeploys.NAME_REGISTRY, "NameRegistry");
230231

231232
// Create genesis Ethscriptions (writes via proxy to proxy storage)
232233
createGenesisEthscriptions();

contracts/src/ERC721EthscriptionsCollection.sol

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,25 @@ contract ERC721EthscriptionsCollection is ERC721EthscriptionsEnumerableUpgradeab
101101
manager.getCollectionItem(collectionId, tokenId);
102102
if (item.ethscriptionId == bytes32(0)) revert("Token not in collection");
103103

104+
// Get the ethscription data to extract the ethscription number
105+
Ethscriptions.Ethscription memory ethscription = ethscriptions.getEthscription(item.ethscriptionId, false);
106+
104107
(string memory mediaType, string memory mediaUri) = ethscriptions.getMediaUri(item.ethscriptionId);
105108

109+
// Convert ethscriptionId to hex string (0x prefixed)
110+
string memory ethscriptionIdHex = uint256(item.ethscriptionId).toHexString(32);
111+
106112
string memory jsonStart = string.concat('{"name":"', item.name.escapeJSON(), '"');
107113
if (bytes(item.description).length > 0) {
108114
jsonStart = string.concat(jsonStart, ',"description":"', item.description.escapeJSON(), '"');
109115
}
110116

117+
// Add ethscription ID and number
118+
string memory ethscriptionFields = string.concat(
119+
',"ethscription_id":"', ethscriptionIdHex, '"',
120+
',"ethscription_number":', ethscription.ethscriptionNumber.toString()
121+
);
122+
111123
string memory mediaField = string.concat(
112124
',"',
113125
mediaType,
@@ -135,7 +147,7 @@ contract ERC721EthscriptionsCollection is ERC721EthscriptionsEnumerableUpgradeab
135147
}
136148
attributesJson = string.concat(attributesJson, ']');
137149

138-
string memory json = string.concat(jsonStart, mediaField, bgColor, attributesJson, '}');
150+
string memory json = string.concat(jsonStart, ethscriptionFields, mediaField, bgColor, attributesJson, '}');
139151

140152
return string.concat("data:application/json;base64,", Base64.encode(bytes(json)));
141153
}

contracts/src/NameRegistry.sol

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,23 @@ contract NameRegistry is ERC721EthscriptionsEnumerableUpgradeable, IProtocolHand
189189
if (record.ethscriptionId == bytes32(0)) revert TokenDoesNotExist();
190190
string memory name = LibString.unpackOne(record.packedName);
191191

192+
// Get the ethscription data to extract the ethscription number
193+
Ethscriptions.Ethscription memory ethscription = ethscriptions.getEthscription(record.ethscriptionId, false);
194+
195+
// Convert ethscriptionId to hex string (0x prefixed)
196+
string memory ethscriptionIdHex = uint256(record.ethscriptionId).toHexString(32);
197+
192198
bytes memory json = abi.encodePacked(
193199
'{"name":"',
194200
name,
195-
'","description":"Dotless word domain","attributes":[',
201+
'","description":"Dotless word domain"',
202+
',"ethscription_id":"',
203+
ethscriptionIdHex,
204+
'","ethscription_number":',
205+
ethscription.ethscriptionNumber.toString(),
206+
',"attributes":[',
196207
'{"trait_type":"Name","value":"',
197208
name,
198-
'"},',
199-
'{"trait_type":"Ethscription","value":"',
200-
_bytes32ToHex(record.ethscriptionId),
201209
'"}',
202210
']}'
203211
);
@@ -212,10 +220,6 @@ contract NameRegistry is ERC721EthscriptionsEnumerableUpgradeable, IProtocolHand
212220
return super._update(to, tokenId, auth);
213221
}
214222

215-
function _bytes32ToHex(bytes32 data) internal pure returns (string memory) {
216-
return Strings.toHexString(uint256(data), 32);
217-
}
218-
219223
function _domainInfo(bytes32 nameKey) internal view returns (DomainInfo memory info) {
220224
DomainRecord storage record = domains[nameKey];
221225
if (record.ethscriptionId == bytes32(0)) revert DomainNotFound();

contracts/src/libraries/EthscriptionsRendererLib.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ library EthscriptionsRendererLib {
3232
// Build in chunks to avoid stack too deep
3333
string memory part1 = string.concat(
3434
'[{"trait_type":"Ethscription ID","value":"',
35-
uint256(ethscriptionId).toHexString(),
35+
uint256(ethscriptionId).toHexString(32),
3636
'"},{"trait_type":"Ethscription Number","display_type":"number","value":',
3737
etsc.ethscriptionNumber.toString(),
3838
'},{"trait_type":"Creator","value":"',
@@ -43,7 +43,7 @@ library EthscriptionsRendererLib {
4343

4444
string memory part2 = string.concat(
4545
'"},{"trait_type":"Content Hash","value":"',
46-
uint256(etsc.contentHash).toHexString(),
46+
uint256(etsc.contentHash).toHexString(32),
4747
'"},{"trait_type":"MIME Type","value":"',
4848
mimetype.escapeJSON(),
4949
'"},{"trait_type":"ESIP-6","value":"',

contracts/test/CollectionURIResolution.t.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ contract CollectionURIResolutionTest is TestSetup {
7272
// Create collection with esc:// reference to the image
7373
string memory escUri = string.concat(
7474
"esc://ethscriptions/",
75-
uint256(IMAGE_ETSC_TX_HASH).toHexString(),
75+
uint256(IMAGE_ETSC_TX_HASH).toHexString(32),
7676
"/data"
7777
);
7878

@@ -99,7 +99,7 @@ contract CollectionURIResolutionTest is TestSetup {
9999
bytes32 fakeId = keccak256("nonexistent");
100100
string memory escUri = string.concat(
101101
"esc://ethscriptions/",
102-
uint256(fakeId).toHexString(),
102+
uint256(fakeId).toHexString(32),
103103
"/data"
104104
);
105105

0 commit comments

Comments
 (0)