@adraffy/punycode-contracts
v0.0.1
Published
Punycode in Solidity
Downloads
5
Readme
punycode.sol
Solidity Punycode without IDNA.
- Library: Punycode.sol
- ASCII strings:
~500 gas
(fastpath) - Unicode strings:
- Decode
~1300 gas/codepoint
- Encode
~2500 gas/codepoint
- Decode
- ASCII strings:
- Reference Implementation: adraffy/punycode.js
- Demo ⭐
- Deployment:
base:0xBEfeca057ea022e7aB419670a659d32f125973C1
- Deployment:
import {Punycode} from "https://github.com/adraffy/punycode.sol/blob/main/src/Punycode.sol";
string memory unicode = Punycode.decode("xn--ls8h"); // "💩"
string memory punycode = Punycode.encode(unicode"💩"); // "xn--ls8h"
// reverts on failure
// let me know if a tryDecode() is needed
function decode(string memory s) pure returns (string memory)
// never fails
function encode(string memory s) pure returns (string memory)
Lower-level functions:
// src == dst if no encoding required
// otherwise, (dst-32) is effectively `bytes`
function decode(uint256 src, uint256 src_len) pure returns (uint256 dst, uint256 dst_len)
function encode(uint256 src, uint256 src_len) pure returns (uint256 dst, uint256 dst_len)
// example
string memory s = "abc.xn--ls8h.com";
uint256 src;
assembly { src := add(s, 32) }
(uint256 dst, uint256 len) = Punycode.decode(src + 4, 8); // "xn--ls8h"
console2.log(len); // 4 bytes
assembly { s := sub(dst, 32) }
console2.log(s); // "💩"
bytes32 h;
assembly { h := keccak256(dst, len) }
console2.logBytes32(h); // 0xba967c160905ade030f84952644a963994eeaed3881a6b8a4e9c8cbe452ad7a2
Test
foundryup
npm i
npm run test
— forge tests + random validation- (optional)
npm run validate-all
— complete validation
Gas Analysis
npm run gas
— estimate gasforge script GasEncode
— estimate gas forencode()
forge script GasDecode
— estimate gas fordecode()