编译器
0.8.25+commit.b61c2a91
文件 1 的 4:Create2.sol
pragma solidity ^0.8.20;
library Create2 {
error Create2InsufficientBalance(uint256 balance, uint256 needed);
error Create2EmptyBytecode();
error Create2FailedDeployment();
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Create2InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
if (addr == address(0)) {
revert Create2FailedDeployment();
}
}
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer)
let start := add(ptr, 0x0b)
mstore8(start, 0xff)
addr := keccak256(start, 85)
}
}
}
文件 2 的 4:ERC6551BytecodeLib.sol
pragma solidity ^0.8.0;
library ERC6551BytecodeLib {
function getCreationCode(
address implementation_,
uint256 chainId_,
address tokenContract_,
uint256 tokenId_,
uint256 salt_
) internal pure returns (bytes memory) {
return
abi.encodePacked(
hex"3d60ad80600a3d3981f3363d3d373d3d3d363d73",
implementation_,
hex"5af43d82803e903d91602b57fd5bf3",
abi.encode(salt_, chainId_, tokenContract_, tokenId_)
);
}
}
文件 3 的 4:ERC6551RegistryNTP.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Create2.sol";
import "./IERC6551Registry.sol";
import "./ERC6551BytecodeLib.sol";
interface ContractNTP {
function ownerOf(uint256 _tokenId) external view returns (address);
function walletOfOwner(address _address)
external
view
returns (uint256[] memory);
}
interface ContractStake {
function getUserStakedTokensNTP(address _address)
external
view
returns (uint256[] memory);
}
contract ERC6551RegistryNTP is IERC6551Registry {
error InitializationFailed();
mapping(uint256 => bool) public created;
address private ContractAddressNTP =
0xA65bA71d653f62c64d97099b58D25a955Eb374a0;
address private ContractAddressStake =
0x493ed2537Be3a2AA380d63f943220616f27b6a78;
function sortAscending(uint256[] memory arr) internal pure {
for (uint256 i = 0; i < arr.length; i++) {
for (uint256 j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
uint256 temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
function getHoldNTP(address _address)
public
view
returns (uint256[] memory)
{
uint256[] memory holdToken = getWalletOfOwnerNTP(_address);
uint256[] memory stakeToken = getWalletOfStakeToken(_address);
uint256[] memory result = new uint256[](
holdToken.length + stakeToken.length
);
uint256 index = 0;
for (uint256 i = 0; i < holdToken.length; i++) {
result[index] = holdToken[i];
index++;
}
for (uint256 j = 0; j < stakeToken.length; j++) {
result[index] = stakeToken[j];
index++;
}
sortAscending(result);
return result;
}
function getOwnerOfNTP(uint256 _tokenId) public view returns (address) {
address holder = ContractNTP(ContractAddressNTP).ownerOf(_tokenId);
return holder;
}
function getWalletOfOwnerNTP(address _address)
public
view
returns (uint256[] memory)
{
uint256[] memory walletOfOwner = ContractNTP(ContractAddressNTP)
.walletOfOwner(_address);
return walletOfOwner;
}
function getWalletOfStakeToken(address _address)
public
view
returns (uint256[] memory)
{
uint256[] memory walletOfStake = ContractStake(ContractAddressStake)
.getUserStakedTokensNTP(_address);
return walletOfStake;
}
function createAccount(
address implementation,
uint256 chainId,
address tokenContract,
uint256 tokenId,
uint256 salt,
bytes calldata initData
) external returns (address) {
bytes memory code = ERC6551BytecodeLib.getCreationCode(
implementation,
chainId,
tokenContract,
tokenId,
salt
);
address _account = Create2.computeAddress(bytes32(salt), keccak256(code));
if (_account.code.length != 0) return _account;
emit AccountCreated(_account, implementation, chainId, tokenContract, tokenId, salt);
created[tokenId] = true;
_account = Create2.deploy(0, bytes32(salt), code);
if (initData.length != 0) {
(bool success, ) = _account.call(initData);
if (!success) revert InitializationFailed();
}
return _account;
}
function account(
address implementation,
uint256 chainId,
address tokenContract,
uint256 tokenId,
uint256 salt
) external view returns (address) {
bytes32 bytecodeHash = keccak256(
ERC6551BytecodeLib.getCreationCode(
implementation,
chainId,
tokenContract,
tokenId,
salt
)
);
return Create2.computeAddress(bytes32(salt), bytecodeHash);
}
}
文件 4 的 4:IERC6551Registry.sol
pragma solidity ^0.8.0;
interface IERC6551Registry {
event AccountCreated(
address account,
address implementation,
uint256 chainId,
address tokenContract,
uint256 tokenId,
uint256 salt
);
function createAccount(
address implementation,
uint256 chainId,
address tokenContract,
uint256 tokenId,
uint256 seed,
bytes calldata initData
) external returns (address);
function account(
address implementation,
uint256 chainId,
address tokenContract,
uint256 tokenId,
uint256 salt
) external view returns (address);
}
{
"compilationTarget": {
"contracts/ERC6551RegistryNTP.sol": "ERC6551RegistryNTP"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"name":"Create2EmptyBytecode","type":"error"},{"inputs":[],"name":"Create2FailedDeployment","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"Create2InsufficientBalance","type":"error"},{"inputs":[],"name":"InitializationFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"implementation","type":"address"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"salt","type":"uint256"}],"name":"AccountCreated","type":"event"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"initData","type":"bytes"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"created","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getHoldNTP","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getOwnerOfNTP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getWalletOfOwnerNTP","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getWalletOfStakeToken","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"}]