编译器
0.8.20+commit.a1b79de6
文件 1 的 4:Counters.sol
pragma solidity ^0.8.0;
library Counters {
struct Counter {
uint256 _value;
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
文件 2 的 4:Inscription.sol
pragma solidity ^0.8.20;
import "./Counters.sol";
import "./JsmnSolLib.sol";
import "./inputData.sol";
contract Inscription is inputData {
address public owner;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not the contract owner");
_;
}
using Counters for Counters.Counter;
uint256 constant DECIMALS = 18;
bytes32 constant ERC20_P_HASH = keccak256(abi.encodePacked("p"));
bytes32 constant ERC20_OP_HASH = keccak256(abi.encodePacked("op"));
bytes32 constant ERC20_TICK_HASH = keccak256(abi.encodePacked("tick"));
bytes32 constant ERC20_MAX_HASH = keccak256(abi.encodePacked("max"));
bytes32 constant ERC20_LIM_HASH = keccak256(abi.encodePacked("lim"));
bytes32 constant ERC20_AMT_HASH = keccak256(abi.encodePacked("amt"));
bytes32 constant ERC20_P_HASH_ERC20 = keccak256(abi.encodePacked("erc-20"));
bytes32 constant ERC20_OP_HASH_DEPLOY =keccak256(abi.encodePacked("deploy"));
bytes32 constant ERC20_OP_HASH_MINT = keccak256(abi.encodePacked("mint"));
bytes32 constant ERC20_OP_HASH_TRANSFER = keccak256(abi.encodePacked("transfer"));
bytes32 constant ERC20_OP_HASH_TRANSFER_TO = keccak256(abi.encodePacked("to"));
bytes32 constant ERC20_OP_HASH_TRANSFER_FROM = keccak256(abi.encodePacked("from"));
bytes32 constant ERC20_MAX_MINT = keccak256(abi.encodePacked("maxMint"));
bytes32 constant ERC20_MINT_PRICE = keccak256(abi.encodePacked("mintPrice"));
bytes32 constant ERC20_RESERVE = keccak256(abi.encodePacked("reserve"));
bytes32 constant ERC20_OP_HASH_APPROVE = keccak256(abi.encodePacked("approve"));
bytes32 constant ERC20_OP_HASH_TRANSFERFROM = keccak256(abi.encodePacked("transferFrom"));
struct ERC20Token {
string name;
uint256 maxSupply;
uint256 mintLimit;
uint256 minted;
address deployer;
uint256 deployTime;
uint256 holders;
uint256 maxMintPerAddress;
uint256 mintPrice;
uint256 reserve;
}
struct MintERC20 {
string ticker;
bool deployed;
}
mapping(string => mapping(address => uint256)) public balances;
mapping(string => mapping(address => uint256)) public mintCounts;
mapping(bytes32 => MintERC20) private mintHexMap;
mapping(string => mapping(address => mapping(address => uint256))) public allowances;
mapping(string => ERC20Token) public inscriptions;
string[] public tokenNames;
Counters.Counter public totalTickers;
function deployToken(
string memory ticker,
uint256 maxSupply,
uint256 mintLimit,
uint256 maxMintPerAddress,
uint256 mintPrice,
uint256 reserve
) internal virtual {
require(msg.value >= 0.02 ether, "Insufficient deployment fee");
ERC20Token storage newToken = inscriptions[ticker];
require(newToken.deployer == address(0), "Token already exists");
newToken.name = ticker;
newToken.maxSupply = maxSupply;
newToken.mintLimit = mintLimit;
newToken.deployer = msg.sender;
newToken.deployTime = block.timestamp;
newToken.maxMintPerAddress = maxMintPerAddress;
newToken.mintPrice = mintPrice;
newToken.reserve = reserve;
totalTickers.increment();
tokenNames.push(ticker);
sendETH(payable(owner), msg.value);
if (reserve != 0) {
balances[ticker][msg.sender] += reserve;
newToken.minted += reserve;
newToken.holders += 1;
}
}
function inscribeMint(bytes32 mintHash) internal virtual {
string memory ticker = mintHexMap[mintHash].ticker;
ERC20Token storage token = inscriptions[ticker];
require(msg.value == token.mintPrice, "Incorrect mint price");
if (token.maxMintPerAddress != 0) {
require(
mintCounts[ticker][msg.sender] + token.mintLimit <= token.maxMintPerAddress,
"Exceeds max mint per address"
);
}
require(
(token.minted + token.mintLimit) <= token.maxSupply,
"Exceeds available supply"
);
token.minted += token.mintLimit;
require(token.minted <= token.maxSupply, "Minting finished");
if (balances[ticker][msg.sender] == 0) {
token.holders += 1;
}
mintCounts[ticker][msg.sender] += token.mintLimit;
balances[ticker][msg.sender] += token.mintLimit;
sendETH(payable(owner), calculatePercentage(msg.value, 10));
sendETH(payable(token.deployer), calculatePercentage(msg.value, 90));
}
function sendETH(address payable recipient, uint256 amount) private{
(bool success, ) = recipient.call{value: amount}("");
require(success, "ETH transfer failed");
}
function calculatePercentage(uint256 amount, uint256 percentage) internal pure returns (uint256) {
return (amount * percentage) / 100;
}
function transferTokens(
string memory ticker,
address from,
address to,
uint256 amount
) internal virtual {
uint256 senderBalance = balances[ticker][from];
require(senderBalance >= amount, "Insufficient balance for transfer");
unchecked {
balances[ticker][from] = senderBalance - amount;
}
if (balances[ticker][from] == 0) {
inscriptions[ticker].holders -= 1;
}
if (balances[ticker][to] == 0 && amount > 0) {
inscriptions[ticker].holders += 1;
}
balances[ticker][to] += amount;
}
function approveTokens(
string memory ticker,
address from,
address to,
uint256 amount
) internal virtual {
allowances[ticker][from][to] = amount;
}
function transferTokensFrom(
string memory ticker,
address from,
address to,
uint256 amount
) internal virtual {
require(allowances[ticker][from][msg.sender] >= 1, "Insufficient allowance");
transferTokens(ticker, from, to, amount);
}
fallback(bytes calldata input) external payable returns (bytes memory) {
string memory jsonString = string(input);
bytes32 mintHash = keccak256(abi.encodePacked(jsonString));
if (mintHexMap[mintHash].deployed) {
require(msg.sender == tx.origin, "Only EOA allowed");
inscribeMint(mintHash);
} else {
_inscribe(jsonString);
}
return "";
}
function _inscribe(string memory jsonStr) internal virtual {
uint256 returnValue;
JsmnSolLib.Token[] memory tokens;
(returnValue, tokens, ) = JsmnSolLib.parse(jsonStr, 17);
require(returnValue == JsmnSolLib.RETURN_SUCCESS, "JSON parsing failed");
{
string memory p = JsmnSolLib.getBytes(
jsonStr,
tokens[1].start,
tokens[1].end
);
string memory pVal = JsmnSolLib.getBytes(
jsonStr,
tokens[2].start,
tokens[2].end
);
string memory op = JsmnSolLib.getBytes(
jsonStr,
tokens[3].start,
tokens[3].end
);
string memory tick = JsmnSolLib.getBytes(
jsonStr,
tokens[5].start,
tokens[5].end
);
require(
keccak256(abi.encodePacked(p)) == ERC20_P_HASH &&
keccak256(abi.encodePacked(pVal)) == ERC20_P_HASH_ERC20 &&
keccak256(abi.encodePacked(op)) == ERC20_OP_HASH &&
keccak256(abi.encodePacked(tick)) == ERC20_TICK_HASH,
"Invalid ERC-20 parameters"
);
}
string memory opVal = JsmnSolLib.getBytes(
jsonStr,
tokens[4].start,
tokens[4].end
);
string memory tickVal = JsmnSolLib.getBytes(
jsonStr,
tokens[6].start,
tokens[6].end
);
if (keccak256(abi.encodePacked(opVal)) == ERC20_OP_HASH_TRANSFER) {
string memory amt = JsmnSolLib.getBytes(
jsonStr,
tokens[7].start,
tokens[7].end
);
string memory toKey = JsmnSolLib.getBytes(
jsonStr,
tokens[9].start,
tokens[9].end
);
require(
keccak256(abi.encodePacked(toKey)) ==
ERC20_OP_HASH_TRANSFER_TO &&
keccak256(abi.encodePacked(amt)) == ERC20_AMT_HASH,
"Invalid transfer parameters"
);
string memory amtVal = JsmnSolLib.getBytes(
jsonStr,
tokens[8].start,
tokens[8].end
);
string memory toVal = JsmnSolLib.getBytes(
jsonStr,
tokens[10].start,
tokens[10].end
);
transferTokens(
tickVal,
msg.sender,
JsmnSolLib.stringToAddress(toVal),
uint256(JsmnSolLib.parseInt(amtVal, DECIMALS))
);
} else if (keccak256(abi.encodePacked(opVal)) == ERC20_OP_HASH_DEPLOY) {
string memory max = JsmnSolLib.getBytes(
jsonStr,
tokens[7].start,
tokens[7].end
);
string memory lim = JsmnSolLib.getBytes(
jsonStr,
tokens[9].start,
tokens[9].end
);
string memory maxMint = JsmnSolLib.getBytes(
jsonStr,
tokens[11].start,
tokens[11].end
);
string memory mintPrice = JsmnSolLib.getBytes(
jsonStr,
tokens[13].start,
tokens[13].end
);
string memory reserve = JsmnSolLib.getBytes(
jsonStr,
tokens[15].start,
tokens[15].end
);
require(
keccak256(abi.encodePacked(max)) == ERC20_MAX_HASH &&
keccak256(abi.encodePacked(lim)) == ERC20_LIM_HASH &&
keccak256(abi.encodePacked(maxMint)) == ERC20_MAX_MINT &&
keccak256(abi.encodePacked(mintPrice)) == ERC20_MINT_PRICE &&
keccak256(abi.encodePacked(reserve)) == ERC20_RESERVE,
"Invalid deployment parameters"
);
string memory maxVal = JsmnSolLib.getBytes(
jsonStr,
tokens[8].start,
tokens[8].end
);
string memory limVal = JsmnSolLib.getBytes(
jsonStr,
tokens[10].start,
tokens[10].end
);
string memory mintVal = JsmnSolLib.getBytes(
jsonStr,
tokens[12].start,
tokens[12].end
);
string memory priceVal = JsmnSolLib.getBytes(
jsonStr,
tokens[14].start,
tokens[14].end
);
string memory reserveVal = JsmnSolLib.getBytes(
jsonStr,
tokens[16].start,
tokens[16].end
);
MintERC20 storage mintercData = mintHexMap[ keccak256(abi.encodePacked(mintString(tickVal,limVal)))];
mintercData.deployed = true;
mintercData.ticker = tickVal;
deployToken(
tickVal,
uint256(JsmnSolLib.parseInt(maxVal, DECIMALS)),
uint256(JsmnSolLib.parseInt(limVal, DECIMALS)),
uint256(JsmnSolLib.parseInt(mintVal, DECIMALS)),
uint256(JsmnSolLib.parseInt(priceVal, DECIMALS)),
uint256(JsmnSolLib.parseInt(reserveVal, DECIMALS))
);
} else if (keccak256(abi.encodePacked(opVal)) == ERC20_OP_HASH_APPROVE) {
string memory amt = JsmnSolLib.getBytes(
jsonStr,
tokens[7].start,
tokens[7].end
);
string memory toKey = JsmnSolLib.getBytes(
jsonStr,
tokens[9].start,
tokens[9].end
);
require(
keccak256(abi.encodePacked(toKey)) ==
ERC20_OP_HASH_TRANSFER_TO &&
keccak256(abi.encodePacked(amt)) == ERC20_AMT_HASH,
"Invalid approval parameters"
);
string memory amtVal = JsmnSolLib.getBytes(
jsonStr,
tokens[8].start,
tokens[8].end
);
string memory toVal = JsmnSolLib.getBytes(
jsonStr,
tokens[10].start,
tokens[10].end
);
approveTokens(
tickVal,
msg.sender,
JsmnSolLib.stringToAddress(toVal),
uint256(JsmnSolLib.parseInt(amtVal))
);
} else if (keccak256(abi.encodePacked(opVal)) == ERC20_OP_HASH_TRANSFERFROM) {
string memory amt = JsmnSolLib.getBytes(
jsonStr,
tokens[7].start,
tokens[7].end
);
string memory toKey = JsmnSolLib.getBytes(
jsonStr,
tokens[9].start,
tokens[9].end
);
string memory fromKey = JsmnSolLib.getBytes(
jsonStr,
tokens[11].start,
tokens[11].end
);
require(
keccak256(abi.encodePacked(toKey)) == ERC20_OP_HASH_TRANSFER_TO &&
keccak256(abi.encodePacked(amt)) == ERC20_AMT_HASH &&
keccak256(abi.encodePacked(fromKey)) == ERC20_OP_HASH_TRANSFER_FROM,
"Invalid transferFrom parameters"
);
string memory amtVal = JsmnSolLib.getBytes(
jsonStr,
tokens[8].start,
tokens[8].end
);
string memory toVal = JsmnSolLib.getBytes(
jsonStr,
tokens[10].start,
tokens[10].end
);
string memory fromVal = JsmnSolLib.getBytes(
jsonStr,
tokens[12].start,
tokens[12].end
);
transferTokensFrom(
tickVal,
JsmnSolLib.stringToAddress(fromVal),
JsmnSolLib.stringToAddress(toVal),
uint256(JsmnSolLib.parseInt(amtVal, DECIMALS))
);
}
}
function withdrawETH(address payable _to, uint _amount) external onlyOwner{
_to.transfer(_amount);
}
function withdrawERC20(address token, address to, uint256 value) external onlyOwner{
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
}
receive() external payable {}
}
文件 3 的 4:JsmnSolLib.sol
pragma solidity ^0.8.1;
library JsmnSolLib {
enum JsmnType {
UNDEFINED,
OBJECT,
ARRAY,
STRING,
PRIMITIVE
}
uint256 constant RETURN_SUCCESS = 0;
uint256 constant RETURN_ERROR_INVALID_JSON = 1;
uint256 constant RETURN_ERROR_PART = 2;
uint256 constant RETURN_ERROR_NO_MEM = 3;
struct Token {
JsmnType jsmnType;
uint256 start;
bool startSet;
uint256 end;
bool endSet;
uint8 size;
}
struct Parser {
uint256 pos;
uint256 toknext;
int256 toksuper;
}
function init(uint256 length)
internal
pure
returns (Parser memory, Token[] memory)
{
Parser memory p = Parser(0, 0, -1);
Token[] memory t = new Token[](length);
return (p, t);
}
function allocateToken(Parser memory parser, Token[] memory tokens)
internal
pure
returns (bool, Token memory)
{
if (parser.toknext >= tokens.length) {
return (false, tokens[tokens.length - 1]);
}
Token memory token = Token(JsmnType.UNDEFINED, 0, false, 0, false, 0);
tokens[parser.toknext] = token;
parser.toknext++;
return (true, token);
}
function fillToken(
Token memory token,
JsmnType jsmnType,
uint256 start,
uint256 end
) internal pure {
token.jsmnType = jsmnType;
token.start = start;
token.startSet = true;
token.end = end;
token.endSet = true;
token.size = 0;
}
function parseString(
Parser memory parser,
Token[] memory tokens,
bytes memory s
) internal pure returns (uint256) {
uint256 start = parser.pos;
bool success;
Token memory token;
parser.pos++;
for (; parser.pos < s.length; parser.pos++) {
bytes1 c = s[parser.pos];
if (c == '"') {
(success, token) = allocateToken(parser, tokens);
if (!success) {
parser.pos = start;
return RETURN_ERROR_NO_MEM;
}
fillToken(token, JsmnType.STRING, start + 1, parser.pos);
return RETURN_SUCCESS;
}
if (uint8(c) == 92 && parser.pos + 1 < s.length) {
parser.pos++;
if (
s[parser.pos] == '"' ||
s[parser.pos] == "/" ||
s[parser.pos] == "\\" ||
s[parser.pos] == "f" ||
s[parser.pos] == "r" ||
s[parser.pos] == "n" ||
s[parser.pos] == "b" ||
s[parser.pos] == "t"
) {
continue;
} else {
parser.pos = start;
return (RETURN_ERROR_INVALID_JSON);
}
}
}
parser.pos = start;
return RETURN_ERROR_PART;
}
function parsePrimitive(
Parser memory parser,
Token[] memory tokens,
bytes memory s
) internal pure returns (uint256) {
bool found = false;
uint256 start = parser.pos;
bytes1 c;
bool success;
Token memory token;
for (; parser.pos < s.length; parser.pos++) {
c = s[parser.pos];
if (
c == " " ||
c == "\t" ||
c == "\n" ||
c == "\r" ||
c == "," ||
c == 0x7d ||
c == 0x5d
) {
found = true;
break;
}
if (uint8(c) < 32 || uint8(c) > 127) {
parser.pos = start;
return RETURN_ERROR_INVALID_JSON;
}
}
if (!found) {
parser.pos = start;
return RETURN_ERROR_PART;
}
(success, token) = allocateToken(parser, tokens);
if (!success) {
parser.pos = start;
return RETURN_ERROR_NO_MEM;
}
fillToken(token, JsmnType.PRIMITIVE, start, parser.pos);
parser.pos--;
return RETURN_SUCCESS;
}
function parse(string memory json, uint256 numberElements)
internal
pure
returns (
uint256,
Token[] memory tokens,
uint256
)
{
bytes memory s = bytes(json);
bool success;
Parser memory parser;
(parser, tokens) = init(numberElements);
uint256 r;
uint256 count = parser.toknext;
uint256 i;
Token memory token;
for (; parser.pos < s.length; parser.pos++) {
bytes1 c = s[parser.pos];
if (c == 0x7b || c == 0x5b) {
count++;
(success, token) = allocateToken(parser, tokens);
if (!success) {
return (RETURN_ERROR_NO_MEM, tokens, 0);
}
if (parser.toksuper != -1) {
tokens[uint256(parser.toksuper)].size++;
}
token.jsmnType = (c == 0x7b ? JsmnType.OBJECT : JsmnType.ARRAY);
token.start = parser.pos;
token.startSet = true;
parser.toksuper = int256(parser.toknext - 1);
continue;
}
if (c == 0x7d || c == 0x5d) {
JsmnType tokenType = (
c == 0x7d ? JsmnType.OBJECT : JsmnType.ARRAY
);
bool isUpdated = false;
for (i = parser.toknext - 1; i >= 0; i--) {
token = tokens[i];
if (token.startSet && !token.endSet) {
if (token.jsmnType != tokenType) {
return (RETURN_ERROR_INVALID_JSON, tokens, 0);
}
parser.toksuper = -1;
tokens[i].end = parser.pos + 1;
tokens[i].endSet = true;
isUpdated = true;
break;
}
}
if (!isUpdated) {
return (RETURN_ERROR_INVALID_JSON, tokens, 0);
}
for (; i > 0; i--) {
token = tokens[i];
if (token.startSet && !token.endSet) {
parser.toksuper = int256(i);
break;
}
}
if (i == 0) {
token = tokens[i];
if (token.startSet && !token.endSet) {
parser.toksuper = int128(uint128(i));
}
}
continue;
}
if (c == '"') {
r = parseString(parser, tokens, s);
if (r != RETURN_SUCCESS) {
return (r, tokens, 0);
}
count++;
if (parser.toksuper != -1)
tokens[uint256(parser.toksuper)].size++;
continue;
}
if (c == " " || c == 0x11 || c == 0x12 || c == 0x14) {
continue;
}
if (c == ":") {
parser.toksuper = int256(parser.toknext - 1);
continue;
}
if (c == ",") {
if (
parser.toksuper != -1 &&
tokens[uint256(parser.toksuper)].jsmnType !=
JsmnType.ARRAY &&
tokens[uint256(parser.toksuper)].jsmnType != JsmnType.OBJECT
) {
for (i = parser.toknext - 1; i >= 0; i--) {
if (
tokens[i].jsmnType == JsmnType.ARRAY ||
tokens[i].jsmnType == JsmnType.OBJECT
) {
if (tokens[i].startSet && !tokens[i].endSet) {
parser.toksuper = int256(i);
break;
}
}
}
}
continue;
}
if (
(c >= "0" && c <= "9") ||
c == "-" ||
c == "f" ||
c == "t" ||
c == "n"
) {
if (parser.toksuper != -1) {
token = tokens[uint256(parser.toksuper)];
if (
token.jsmnType == JsmnType.OBJECT ||
(token.jsmnType == JsmnType.STRING && token.size != 0)
) {
return (RETURN_ERROR_INVALID_JSON, tokens, 0);
}
}
r = parsePrimitive(parser, tokens, s);
if (r != RETURN_SUCCESS) {
return (r, tokens, 0);
}
count++;
if (parser.toksuper != -1) {
tokens[uint256(parser.toksuper)].size++;
}
continue;
}
if (c >= 0x20 && c <= 0x7e) {
return (RETURN_ERROR_INVALID_JSON, tokens, 0);
}
}
return (RETURN_SUCCESS, tokens, parser.toknext);
}
function getBytes(
string memory json,
uint256 start,
uint256 end
) internal pure returns (string memory) {
bytes memory s = bytes(json);
bytes memory result = new bytes(end - start);
for (uint256 i = start; i < end; i++) {
result[i - start] = s[i];
}
return string(result);
}
function parseInt(string memory _a) internal pure returns (int256) {
return parseInt(_a, 0);
}
function parseInt(string memory _a, uint256 _b)
internal
pure
returns (int256)
{
bytes memory bresult = bytes(_a);
int256 mint = 0;
bool decimals = false;
bool negative = false;
for (uint256 i = 0; i < bresult.length; i++) {
if ((i == 0) && (bresult[i] == "-")) {
negative = true;
}
if ((uint8(bresult[i]) >= 48) && (uint8(bresult[i]) <= 57)) {
if (decimals) {
if (_b == 0) break;
else _b--;
}
mint *= 10;
mint += int256(uint256(uint8(bresult[i]) - 48));
} else if (uint8(bresult[i]) == 46) decimals = true;
}
if (_b > 0) mint *= int256(10**_b);
if (negative) mint *= -1;
return mint;
}
function uint2str(uint256 i) internal pure returns (string memory) {
if (i == 0) return "0";
uint256 j = i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len - 1;
while (i != 0) {
bstr[k--] = bytes1(uint8(48 + (i % 10)));
i /= 10;
}
return string(bstr);
}
function parseBool(string memory _a) internal pure returns (bool) {
if (strCompare(_a, "true") == 0) {
return true;
} else {
return false;
}
}
function strCompare(string memory _a, string memory _b)
internal
pure
returns (int256)
{
bytes memory a = bytes(_a);
bytes memory b = bytes(_b);
uint256 minLength = a.length;
if (b.length < minLength) minLength = b.length;
for (uint256 i = 0; i < minLength; i++)
if (a[i] < b[i]) return -1;
else if (a[i] > b[i]) return 1;
if (a.length < b.length) return -1;
else if (a.length > b.length) return 1;
else return 0;
}
function addressToString(address addr)
internal
pure
returns (string memory)
{
bytes20 value = bytes20(uint160(addr));
bytes memory strBytes = new bytes(42);
strBytes[0] = "0";
strBytes[1] = "x";
for (uint256 i = 0; i < 20; i++) {
uint8 byteValue = uint8(value[i]);
strBytes[2 + (i << 1)] = encode((byteValue >> 4) & 0x0f);
strBytes[3 + (i << 1)] = encode(byteValue & 0x0f);
}
return string(strBytes);
}
function stringToAddress(string memory data)
internal
pure
returns (address)
{
bytes memory strBytes = bytes(data);
require(
strBytes.length >= 39 && strBytes.length <= 42,
"Not hex string"
);
uint256 start = 0;
uint256 bytesBegin = 0;
if (strBytes[1] == "x" || strBytes[1] == "X") {
start = 2;
}
uint160 addrValue = 0;
uint256 effectPayloadLen = strBytes.length - start;
if (effectPayloadLen == 39) {
addrValue += decode(strBytes[start++]);
bytesBegin++;
}
for (uint256 i = bytesBegin; i < 20; i++) {
addrValue <<= 8;
uint8 tmp1 = decode(strBytes[start]);
uint8 tmp2 = decode(strBytes[start + 1]);
uint8 combined = (tmp1 << 4) + tmp2;
addrValue += combined;
start += 2;
}
return address(addrValue);
}
function decode(bytes1 asc) private pure returns (uint8) {
uint8 val = uint8(asc);
if (val >= 48 && val <= 57) {
return val - 48;
}
if (val >= 65 && val <= 70) {
return val - 55;
}
return val - 87;
}
function encode(uint8 num) private pure returns (bytes1) {
if (num >= 0 && num <= 9) {
return bytes1(num + 48);
}
return bytes1(num + 87);
}
}
文件 4 的 4:inputData.sol
pragma solidity ^0.8.20;
contract inputData {
string constant p1 = '{"p":"erc-20","op":"deploy","tick":"';
string constant m1 = '","max":"';
function mintData(string memory tick, string memory amt)
public
pure
returns (string memory json, bytes memory jsonHex)
{
json = mintString(tick,amt);
jsonHex = bytes(json);
}
function mintString(string memory tick, string memory amt)
internal
pure
returns (string memory json)
{
string memory p = '{"p":"erc-20","op":"mint","tick":"';
string memory m = '","amt":"';
string memory s = '"}';
json = string(abi.encodePacked(p, tick, m, amt, s));
}
function transferData(
string memory tick,
string memory to,
string memory amt
) public pure returns (string memory json, bytes memory jsonHex) {
string memory p = '{"p":"erc-20","op":"transfer","tick":"';
string memory m = '","amt":"';
string memory m2 = '", "to":"';
string memory s = '"}';
json = string(abi.encodePacked(p, tick, m, amt, m2, to, s));
jsonHex = bytes(json);
}
function depyoyData(
string memory tick,
string memory max,
string memory lim,
string memory maxMint,
string memory mintPrice,
string memory reserve
) public pure returns (string memory json, bytes memory jsonHex) {
string memory m2 = '","lim":"';
string memory m3 = '","maxMint":"';
string memory m4 = '","mintPrice":"';
string memory m5 = '","reserve":"';
string memory s = '"}';
bytes memory ss= abi.encodePacked(lim, m3, maxMint, m4, mintPrice, m5, reserve, s);
json = string(abi.encodePacked(p1, tick, m1, max, m2,ss));
jsonHex = bytes(json);
}
function transferFromData(
string memory tick,
string memory to,
string memory amt,
string memory from
) public pure returns (string memory json, bytes memory jsonHex) {
string memory p = '{"p":"erc-20","op":"transferFrom","tick":"';
string memory m = '","amt":"';
string memory m2 = '", "to":"';
string memory m3 = '", "from":"';
string memory s = '"}';
json = string(abi.encodePacked(p, tick, m, amt, m2, to, m3, from, s));
jsonHex = bytes(json);
}
function approveData(
string memory tick,
string memory to,
string memory amt
) public pure returns (string memory json, bytes memory jsonHex) {
string memory p = '{"p":"erc-20","op":"approve","tick":"';
string memory m = '","amt":"';
string memory m2 = '", "to":"';
string memory s = '"}';
json = string(abi.encodePacked(p, tick, m, amt, m2, to, s));
jsonHex = bytes(json);
}
}
{
"compilationTarget": {
"Inscription.sol": "Inscription"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"tick","type":"string"},{"internalType":"string","name":"to","type":"string"},{"internalType":"string","name":"amt","type":"string"}],"name":"approveData","outputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"bytes","name":"jsonHex","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"tick","type":"string"},{"internalType":"string","name":"max","type":"string"},{"internalType":"string","name":"lim","type":"string"},{"internalType":"string","name":"maxMint","type":"string"},{"internalType":"string","name":"mintPrice","type":"string"},{"internalType":"string","name":"reserve","type":"string"}],"name":"depyoyData","outputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"bytes","name":"jsonHex","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"inscriptions","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"mintLimit","type":"uint256"},{"internalType":"uint256","name":"minted","type":"uint256"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"uint256","name":"deployTime","type":"uint256"},{"internalType":"uint256","name":"holders","type":"uint256"},{"internalType":"uint256","name":"maxMintPerAddress","type":"uint256"},{"internalType":"uint256","name":"mintPrice","type":"uint256"},{"internalType":"uint256","name":"reserve","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"}],"name":"mintCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"tick","type":"string"},{"internalType":"string","name":"amt","type":"string"}],"name":"mintData","outputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"bytes","name":"jsonHex","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenNames","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTickers","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"tick","type":"string"},{"internalType":"string","name":"to","type":"string"},{"internalType":"string","name":"amt","type":"string"}],"name":"transferData","outputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"bytes","name":"jsonHex","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"tick","type":"string"},{"internalType":"string","name":"to","type":"string"},{"internalType":"string","name":"amt","type":"string"},{"internalType":"string","name":"from","type":"string"}],"name":"transferFromData","outputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"bytes","name":"jsonHex","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]