Skip to content

Instantly share code, notes, and snippets.

View ardislu's full-sized avatar

Ardis Lu ardislu

View GitHub Profile
@ardislu
ardislu / erc-7201.js
Created May 29, 2024 06:13
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);
@ardislu
ardislu / rot13.js
Created May 8, 2024 04:26
Golfed ROT13 in JavaScript.
// Ignores input casing, output will be all lowercase.
const r=s=>s.replace(/[a-z]/gi,c=>(((parseInt(c,36)+3)%26)+10).toString(36));
// r('the quick brown fox jumps over the lazy dog')
// 'gur dhvpx oebja sbk whzcf bire gur ynml qbt'
// r('gur dhvpx oebja sbk whzcf bire gur ynml qbt')
// 'the quick brown fox jumps over the lazy dog'
@ardislu
ardislu / littleEndian64ToBigInt.js
Created April 21, 2024 05:43
Convert a hex string of 8 bytes into a BigInt.
// Converts a hex string of 8 bytes into a BigInt.
// Useful for converting Ethereum's Beacon Deposit Contract get_deposit_count().
// https://etherscan.io/address/0x00000000219ab540356cBB839Cbe05303d7705Fa
function littleEndian64ToBigInt(bytes) {
bytes = bytes.replace('0x', '').replaceAll(/\s/g, '');
return new DataView(Uint8Array.from(bytes.matchAll(/.{2}/g), b => parseInt(b, 16)).buffer).getBigUint64(0, true);
}
// Example:
// littleEndian64ToBigInt('0x0519160000000000')
@ardislu
ardislu / erc-7673.js
Last active June 19, 2024 07:14
Minimal JavaScript implementation of ERC-7673.
// Utility functions to convert an Ethereum hexadecimal address to base256emoji and vice versa.
// https://ercs.ethereum.org/ERCS/erc-7673
const toEmoji = [
'🚀', '🪐', '☄', '🛰', '🌌', '🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘', '🌍', '🌏', '🌎',
'🐉', '☀', '💻', '🖥', '💾', '💿', '😂', '❤', '😍', '🤣', '😊', '🙏', '💕', '😭', '😘', '👍',
'😅', '👏', '😁', '🔥', '🥰', '💔', '💖', '💙', '😢', '🤔', '😆', '🙄', '💪', '😉', '☺', '👌',
'🤗', '💜', '😔', '😎', '😇', '🌹', '🤦', '🎉', '💞', '✌', '✨', '🤷', '😱', '😌', '🌸', '🙌',
'😋', '💗', '💚', '😏', '💛', '🙂', '💓', '🤩', '😄', '😀', '🖤', '😃', '💯', '🙈', '👇', '🎶',
'😒', '🤭', '❣', '😜', '💋', '👀', '😪', '😑', '💥', '🙋', '😞', '😩', '😡', '🤪', '👊', '🥳',
@ardislu
ardislu / minimal-endianness.js
Created March 27, 2024 06:27
This is the minimum amount of JavaScript (74 characters) to detect the endianness of a platform.
// The magic number 0xFEFF is selected for familiarity with the commonly-used
// byte-order mark (BOM) character (https://en.wikipedia.org/wiki/Byte_order_mark).
const isLE = new Uint8Array(new Uint16Array([0xFEFF]).buffer)[0] === 0xFF;
// Golfed (-12 characters; 62 total characters):
// const isLE=new Uint8Array(new Uint16Array([256]).buffer)[0]<1;
@ardislu
ardislu / copy-all-code.js
Created February 21, 2024 07:10
Simple script to copy all the code blocks at once from an Etherscan smart contract code page.
// Simple script to copy all the code blocks at once from an Etherscan smart contract code page
// (example: https://etherscan.io/address/0x43506849d7c04f9138d1a2050bbf3a0c054402dd#code).
// Uses a hardcoded CSS selector, must update if Etherscan updates its frontend markup
// (this script was last updated February 2024).
// References:
// 1. Etherscan uses Ace for code blocks (https://ace.c9.io/)
// - API reference: https://ajaxorg.github.io/ace-api-docs/
// 2. Etherscan's "Copy source to clipboard" button is implemented in `copySourceCodeBtn`,
@ardislu
ardislu / erc-55.js
Last active May 29, 2024 05:42
JavaScript implementation of ERC-55 ("Mixed-case checksum address encoding") using noble-hashes.
// JavaScript implementation of ERC-55 ("Mixed-case checksum address encoding") using noble-hashes
// https://ercs.ethereum.org/ERCS/erc-55
// 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 toChecksumAddress(address) {
address = address.toLowerCase().replace('0x', '');
// Hash the address (treat it as UTF-8) and return as a hex string
@ardislu
ardislu / ethereum-address-from-signature.js
Last active September 23, 2023 05:15
This is the minimum amount of JavaScript code to derive an Ethereum address from a signature, using the low-level noble-crypto libraries to minimize dependencies.
import { Signature } from '@noble/secp256k1';
import { keccak_256 } from '@noble/hashes/sha3';
// The message that will be signed
const message = 'Any arbitrary message here. 🏴‍☠️💯😂';
const encodedMessage = new TextEncoder().encode(message);
// Assuming "signature" has been acquired from the user and is in string hex form.
// Note that MetaMask and most other high-level tools will automatically inject the ERC-191 prefix to messages.
// For example, here's the minimal code to request a signature from MetaMask (assuming the below code is run in a frontend):
@ardislu
ardislu / camelCaseToTitleCase.js
Created June 2, 2023 04:35
Simple utility function to convert a camelCase string into Title Case With Spaces for human readability.
/**
* Converts a camelCase string into Title Case With Spaces for human readability.
* @param {string} str - A string in camelCase.
* @returns {string} The input string converted into Title Case With Spaces.
*/
function camelCaseToTitleCase(str) {
str = str[0].toLocaleUpperCase() + str.slice(1);
return str.replaceAll(/([A-Z]+)/g, ' $1').slice(1);
}
@ardislu
ardislu / archive-dns-issue.md
Last active March 17, 2024 21:02
Reference note about archive.today and Cloudflare DNS.

Problem

If you use Cloudflare's DNS (1.1.1.1), then the popular web archive archive.today (and the related sites archive.ph, archive.is, archive.li, archive.vn, archive.md, and archive.fo) will either fail to resolve, or show an infinite CAPTCHA loop. If it does resolve when you're on Cloudflare's DNS, you may have the domain locally cached.

Solution

Fix this problem by:

  • Configuring dnsmasq on your local DNS server to use an alternate DNS server for archive.today (see comment from @joshenders below), or
  • Connecting to a VPN before connecting to archive.today (only works if the VPN uses different DNS servers), or