Inscriptions
0x98fefc530d4242b25d2209ee57348de8dfb064f0
Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
12,576 bytes
ABI entries
49
20 read · 6 write
License
none
Contract information
- Address
- 0x98fefc530d4242b25d2209ee57348de8dfb064f0
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.26+commit.8a97fa7a
- Optimization
- Enabled
- Creator
- 0x65068B2b8D…8653FB8224
- Creation tx
- 0xabe49d9f60…12f5d918b1
Token
- Name
- —
- Symbol
- —
- Decimals
- —
- Holders
- 31
- Market
- View token page →
Read contract (20)
DEPLOY_FEE_WEI() → uint256
MAX_SUPPLY() → uint128
MINT_FEE_WEI() → uint256
MINT_PER_CALL() → uint128
RBNH_TICK() → bytes4
ROYALTY_BPS() → uint256
TOKEN_ID() → uint256
balanceOf(address, uint256) → uint256
balanceOfBatch(address[], uint256[]) → uint256[]
feeRecipient() → address
getRemainingSupply(uint256) → uint128
getTotalMinted(uint256) → uint128
idToTick(uint256) → bytes4
isApprovedForAll(address, address) → bool
nextTokenId() → uint256
royaltyInfo(uint256, uint256) → address, uint256
supportsInterface(bytes4) → bool
tickInfo(uint256) → uint128, uint128, uint128, address, uint64
tickToId(bytes4) → uint256
uri(uint256) → string
Events (8)
ApprovalForAllDeployedInscriptionInscriptionTransferredMintedTransferBatchTransferSingleURI
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "_feeRecipient",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AccountBalanceOverflow",
"type": "error"
},
{
"inputs": [],
"name": "ArrayLengthsMismatch",
"type": "error"
},
{
"inputs": [],
"name": "BadParams",
"type": "error"
},
{
"inputs": [],
"name": "BadRecipient",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientBalance",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientFee",
"type": "error"
},
{
"inputs": [],
"name": "LowBalance",
"type": "error"
},
{
"inputs": [],
"name": "NotOwnerNorApproved",
"type": "error"
},
{
"inputs": [],
"name": "Reentrancy",
"type": "error"
},
{
"inputs": [],
"name": "SoldOut",
"type": "error"
},
{
"inputs": [],
"name": "TickExists",
"type": "error"
},
{
"inputs": [],
"name": "TransferToNonERC1155ReceiverImplementer",
"type": "error"
},
{
"inputs": [],
"name": "TransferToZeroAddress",
"type": "error"
},
{
"inputs": [],
"name": "UnknownTick",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "isApproved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes4",
"name": "tick",
"type": "bytes4"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "deployer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint128",
"name": "max",
"type": "uint128"
},
{
"indexed": false,
"internalType": "uint128",
"name": "lim",
"type": "uint128"
}
],
"name": "Deployed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "enum Op",
"name": "op",
"type": "uint8"
},
{
"indexed": false,
"internalType": "string",
"name": "data",
"type": "string"
}
],
"name": "Inscription",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes4",
"name": "tick",
"type": "bytes4"
},
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount",
"type": "uint128"
}
],
"name": "InscriptionTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes4",
"name": "tick",
"type": "bytes4"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount",
"type": "uint128"
},
{
"indexed": false,
"internalType": "uint128",
"name": "totalMinted",
"type": "uint128"
}
],
"name": "Minted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "ids",
"type": "uint256[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"name": "TransferBatch",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "TransferSingle",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "value",
"type": "string"
},
{
"indexed": true,
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "URI",
"type": "event"
},
{
"inputs": [],
"name": "DEPLOY_FEE_WEI",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_SUPPLY",
"outputs": [
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MINT_FEE_WEI",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MINT_PER_CALL",
"outputs": [
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "RBNH_TICK",
"outputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "ROYALTY_BPS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TOKEN_ID",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "result",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "owners",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "ids",
"type": "uint256[]"
}
],
"name": "balanceOfBatch",
"outputs": [
{
"internalType": "uint256[]",
"name": "balances",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "tick",
"type": "bytes4"
},
{
"internalType": "uint128",
"name": "max",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "lim",
"type": "uint128"
}
],
"name": "deploy",
"outputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "feeRecipient",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "getRemainingSupply",
"outputs": [
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "getTotalMinted",
"outputs": [
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "idToTick",
"outputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"internalType": "bool",
"name": "result",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "tick",
"type": "bytes4"
}
],
"name": "mint",
"outputs": [
{
"internalType": "uint128",
"name": "toMint",
"type": "uint128"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "nextTokenId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salePrice",
"type": "uint256"
}
],
"name": "royaltyInfo",
"outputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint256",
"name": "royaltyAmount",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256[]",
"name": "ids",
"type": "uint256[]"
},
{
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "safeBatchTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "isApproved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "tickInfo",
"outputs": [
{
"internalType": "uint128",
"name": "max",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "lim",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "minted",
"type": "uint128"
},
{
"internalType": "address",
"name": "deployer",
"type": "address"
},
{
"internalType": "uint64",
"name": "deployedAt",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"name": "tickToId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "tick",
"type": "bytes4"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint128",
"name": "amt",
"type": "uint128"
}
],
"name": "transfer",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "uri",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {ERC1155} from "solady/tokens/ERC1155.sol";
import {Base64} from "solady/utils/Base64.sol";
import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";
import {ReentrancyGuard} from "solady/utils/ReentrancyGuard.sol";
// RBNH-20 inscriptions on Robinhood Chain — BRC-20-style fungible inscriptions
// (DEPLOY / MINT / TRANSFER over an ERC-1155 tick registry, on-chain SVG metadata).
// Each op emits a `data:`-URI event so an indexer can rebuild state from logs,
// while ERC-1155 balances stay live on-chain for the P2P Market.
enum Op {
DEPLOY,
MINT,
TRANSFER
}
struct TickInfo {
uint128 max; // DEPLOY: max supply
uint128 lim; // DEPLOY: amount minted per mint() call
uint128 minted; // running total
address deployer;
uint64 deployedAt;
}
contract Inscriptions is ERC1155, ReentrancyGuard {
using SafeTransferLib for address;
// ── Constants ──────────────────────────────────────────────────────────
bytes4 public constant RBNH_TICK = bytes4("RBNH");
uint128 public constant MAX_SUPPLY = 21_000_000;
uint128 public constant MINT_PER_CALL = 1_000;
uint256 public constant TOKEN_ID = 1;
uint256 public constant MINT_FEE_WEI = 0.000167 ether;
uint256 public constant DEPLOY_FEE_WEI = 0.001 ether;
uint256 public constant ROYALTY_BPS = 250; // 2.5%
bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
// ── Immutables ─────────────────────────────────────────────────────────
address public immutable feeRecipient;
// ── Tick registry ──────────────────────────────────────────────────────
mapping(bytes4 => uint256) public tickToId;
mapping(uint256 => bytes4) public idToTick;
mapping(uint256 => TickInfo) public tickInfo;
uint256 public nextTokenId;
// ── Events ─────────────────────────────────────────────────────────────
event Deployed(bytes4 indexed tick, uint256 indexed tokenId, address indexed deployer, uint128 max, uint128 lim);
event Minted(bytes4 indexed tick, uint256 indexed tokenId, address indexed to, uint128 amount, uint128 totalMinted);
event InscriptionTransferred(bytes4 indexed tick, address indexed from, address indexed to, uint128 amount);
// Raw inscription payload — lets an indexer rebuild state from logs alone.
event Inscription(address indexed from, Op indexed op, string data);
// ── Errors ─────────────────────────────────────────────────────────────
error UnknownTick();
error TickExists();
error BadParams();
error SoldOut();
error InsufficientFee();
error LowBalance();
error BadRecipient();
// ── Constructor ────────────────────────────────────────────────────────
constructor(address _feeRecipient) {
if (_feeRecipient == address(0)) revert BadParams();
feeRecipient = _feeRecipient;
// Pre-register RBNH as token ID 1 — the canonical tick for this launch.
tickToId[RBNH_TICK] = TOKEN_ID;
idToTick[TOKEN_ID] = RBNH_TICK;
tickInfo[TOKEN_ID] = TickInfo({
max: MAX_SUPPLY,
lim: MINT_PER_CALL,
minted: 0,
deployer: msg.sender,
deployedAt: uint64(block.timestamp)
});
nextTokenId = 2;
emit Deployed(RBNH_TICK, TOKEN_ID, msg.sender, MAX_SUPPLY, MINT_PER_CALL);
}
// ── DEPLOY ─────────────────────────────────────────────────────────────
/// @notice Register a new tick. Pays DEPLOY_FEE_WEI; excess is refunded.
function deploy(bytes4 tick, uint128 max, uint128 lim)
external
payable
nonReentrant
returns (uint256 id)
{
if (msg.value < DEPLOY_FEE_WEI) revert InsufficientFee();
if (max == 0 || lim == 0 || lim > max) revert BadParams();
if (tickToId[tick] != 0) revert TickExists();
id = nextTokenId++;
tickToId[tick] = id;
idToTick[id] = tick;
tickInfo[id] = TickInfo({
max: max,
lim: lim,
minted: 0,
deployer: msg.sender,
deployedAt: uint64(block.timestamp)
});
_payFee(DEPLOY_FEE_WEI);
emit Deployed(tick, id, msg.sender, max, lim);
emit Inscription(
msg.sender,
Op.DEPLOY,
string(abi.encodePacked(
'data:,{"p":"rbnh-20","op":"deploy","tick":"', _tickStr(tick),
'","max":"', _u128(max), '","lim":"', _u128(lim), '"}'
))
);
}
// ── MINT ───────────────────────────────────────────────────────────────
/// @notice Mint `lim` of a tick to msg.sender. Pays MINT_FEE_WEI; excess refunded.
function mint(bytes4 tick) external payable nonReentrant returns (uint128 toMint) {
if (msg.value < MINT_FEE_WEI) revert InsufficientFee();
uint256 id = tickToId[tick];
if (id == 0) revert UnknownTick();
TickInfo storage info = tickInfo[id];
if (info.minted >= info.max) revert SoldOut();
toMint = info.lim;
if (info.minted + toMint > info.max) {
toMint = info.max - info.minted;
}
info.minted += toMint;
_mint(msg.sender, id, toMint, "");
_payFee(MINT_FEE_WEI);
emit Minted(tick, id, msg.sender, toMint, info.minted);
emit Inscription(
msg.sender,
Op.MINT,
string(abi.encodePacked(
'data:,{"p":"rbnh-20","op":"mint","tick":"', _tickStr(tick),
'","amt":"', _u128(toMint), '"}'
))
);
}
// ── TRANSFER ───────────────────────────────────────────────────────────
/// @notice Inscription-style transfer (no fee). Plain ERC-1155 safeTransferFrom
/// also works; this variant additionally emits the raw inscription log.
function transfer(bytes4 tick, address to, uint128 amt) external nonReentrant {
uint256 id = tickToId[tick];
if (id == 0) revert UnknownTick();
if (to == address(0) || to == msg.sender || amt == 0) revert BadRecipient();
if (balanceOf(msg.sender, id) < amt) revert LowBalance();
_safeTransfer(msg.sender, to, id, uint256(amt), "");
emit InscriptionTransferred(tick, msg.sender, to, amt);
emit Inscription(
msg.sender,
Op.TRANSFER,
string(abi.encodePacked(
'data:,{"p":"rbnh-20","op":"transfer","tick":"', _tickStr(tick),
'","amt":"', _u128(amt), '","to":"', _addr(to), '"}'
))
);
}
// ── Views ──────────────────────────────────────────────────────────────
function getTotalMinted(uint256 id) external view returns (uint128) {
return tickInfo[id].minted;
}
function getRemainingSupply(uint256 id) external view returns (uint128) {
TickInfo memory info = tickInfo[id];
return info.max - info.minted;
}
// ── ERC-1155 metadata (on-chain SVG) ────────────────────────────────────
function uri(uint256 id) public view override returns (string memory) {
TickInfo memory info = tickInfo[id];
bytes4 tick = idToTick[id];
string memory tickStr = _tickStr(tick);
string memory mintedStr = _u128(info.minted);
string memory maxStr = _u128(info.max);
string memory limStr = _u128(info.lim);
string memory svg = string(abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">',
'<rect width="400" height="400" fill="#000"/>',
'<text x="200" y="160" text-anchor="middle" font-family="monospace" ',
'font-size="64" font-weight="bold" fill="#fff">', tickStr, '</text>',
'<text x="200" y="230" text-anchor="middle" font-family="monospace" ',
'font-size="18" fill="#888">inscription</text>',
'<text x="200" y="280" text-anchor="middle" font-family="monospace" ',
'font-size="16" fill="#fff">', mintedStr, ' / ', maxStr, '</text>',
'<text x="200" y="320" text-anchor="middle" font-family="monospace" ',
'font-size="13" fill="#00C805">Robinhood Chain inscription</text>',
'</svg>'
));
string memory json = string(abi.encodePacked(
'{"name":"RBNH Inscription #', mintedStr,
'","description":"RBNH-20 BRC-20-style fungible inscription on Robinhood Chain (Arbitrum Orbit L2).",',
'"image":"data:image/svg+xml;base64,', Base64.encode(bytes(svg)), '",',
'"attributes":[',
'{"trait_type":"Standard","value":"rbnh-20"},',
'{"trait_type":"Tick","value":"', tickStr, '"},',
'{"trait_type":"Minted","value":', mintedStr, '},',
'{"trait_type":"Max Supply","value":', maxStr, '},',
'{"trait_type":"Mint Per Call","value":"', limStr, '"}',
']}'
));
return string(abi.encodePacked("data:application/json;base64,", Base64.encode(bytes(json))));
}
// ── ERC-2981 ───────────────────────────────────────────────────────────
function royaltyInfo(uint256, uint256 salePrice)
external view returns (address receiver, uint256 royaltyAmount)
{
receiver = feeRecipient;
royaltyAmount = salePrice * ROYALTY_BPS / 10_000;
}
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return super.supportsInterface(interfaceId) || interfaceId == _INTERFACE_ID_ERC2981;
}
// ── Internal ───────────────────────────────────────────────────────────
/// @dev Forward the protocol fee and refund any overpayment to the caller.
function _payFee(uint256 fee) private {
feeRecipient.forceSafeTransferETH(fee);
uint256 refund = msg.value - fee;
if (refund > 0) msg.sender.forceSafeTransferETH(refund);
}
function _tickStr(bytes4 b) private pure returns (string memory) {
uint256 len = 4;
while (len > 0 && b[len - 1] == 0) len--;
bytes memory trimmed = new bytes(len);
for (uint256 i = 0; i < len; i++) trimmed[i] = b[i];
return string(trimmed);
}
function _u128(uint128 v) private pure returns (string memory) {
if (v == 0) return "0";
uint128 temp = v;
uint256 digits;
while (temp != 0) { digits++; temp /= 10; }
bytes memory buf = new bytes(digits);
while (v != 0) {
digits--;
buf[digits] = bytes1(uint8(48 + uint256(v % 10)));
v /= 10;
}
return string(buf);
}
function _addr(address a) private pure returns (string memory) {
bytes16 hexd = "0123456789abcdef";
bytes memory s = new bytes(42);
s[0] = "0"; s[1] = "x";
for (uint256 i = 0; i < 20; i++) {
uint8 b = uint8(uint160(a) >> (8 * (19 - i)));
s[2 + i * 2] = hexd[b >> 4];
s[2 + i * 2 + 1] = hexd[b & 0x0f];
}
return string(s);
}
}
Chain explorer2326msChain node92ms