Skip to content

Instantly share code, notes, and snippets.

@ardislu
Created May 29, 2024 06:13
Show Gist options
  • Save ardislu/fb834e881b9475f32ae12ce1556705cc to your computer and use it in GitHub Desktop.
Save ardislu/fb834e881b9475f32ae12ce1556705cc to your computer and use it in GitHub Desktop.
JavaScript implementation of ERC-7201 ("Namespaced Storage Layout") using noble-hashes.
// JavaScript implementation of ERC-7201 ("Namespaced Storage Layout") using noble-hashes
// https://ercs.ethereum.org/ERCS/erc-7201
// https://github.com/paulmillr/noble-hashes
// import { keccak_256 } from '@noble/hashes/sha3';
const { keccak_256 } = await import('https://esm.sh/@noble/hashes@1.4.0/esm/sha3.js');
function arrToBigInt(arr) {
const hex = `0x${[...arr].map(b => b.toString(16).padStart(2, '0')).join('')}`;
return BigInt(hex);
}
function bigIntToHex(bigInt) {
const str = bigInt.toString(16);
return `0x${str.padStart(str.length + (str.length % 2), '0')}`;
}
function bigIntToArr(bigInt) {
const str = bigInt.toString(16);
return Uint8Array.from(str.padStart(str.length + (str.length % 2), '0').match(/.{2}/g), v => parseInt(v, 16));
}
// erc7201(id: string) = keccak256(keccak256(id) - 1) & ~0xff
function erc7201(id) {
const hash = keccak_256(id);
const minusOne = bigIntToArr(arrToBigInt(hash) - 1n);
const hash2 = keccak_256(minusOne);
const result = arrToBigInt(hash2) & ~BigInt(0xff);
return bigIntToHex(result);
}
function extractCustomStorageLocation(str) {
const [formulaId, namespaceId] = str.substring(str.indexOf('@custom:storage-location')).split(' ')[1].split(':');
if (formulaId.trim() === 'erc7201') {
return erc7201(namespaceId.trim());
}
else {
throw new Error(`Formula ID "${formulaId}" not supported.`);
}
}
// extractCustomStorageLocation(' /// @custom:storage-location erc7201:example.main ');
// '0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment