文件 1 的 1:WnsRegistrar.sol
pragma solidity 0.8.7;
interface WnsRegistryInterface {
function owner() external view returns (address);
function getWnsAddress(string memory _label) external view returns (address);
function setRecord(bytes32 _hash, uint256 _tokenId, string memory _name) external;
function setRecord(uint256 _tokenId, string memory _name) external;
function getRecord(bytes32 _hash) external view returns (uint256);
}
pragma solidity 0.8.7;
interface WnsErc721Interface {
function mintErc721(address to) external;
function getNextTokenId() external view returns (uint256);
function ownerOf(uint256 tokenId) external view returns (address);
}
pragma solidity 0.8.7;
contract Computation {
function computeNamehash(string memory _name) public pure returns (bytes32 namehash) {
namehash = 0x0000000000000000000000000000000000000000000000000000000000000000;
namehash = keccak256(
abi.encodePacked(namehash, keccak256(abi.encodePacked('eth')))
);
namehash = keccak256(
abi.encodePacked(namehash, keccak256(abi.encodePacked(_name)))
);
}
}
pragma solidity 0.8.7;
abstract contract Signatures {
struct Register {
string name;
string extension;
address registrant;
uint256 cost;
uint256 expiration;
address[] splitAddresses;
uint256[] splitAmounts;
}
function verifySignature(Register memory _register, bytes memory sig) internal pure returns(address) {
bytes32 message = keccak256(abi.encode(_register.name, _register.extension, _register.registrant, _register.cost, _register.expiration, _register.splitAddresses, _register.splitAmounts));
return recoverSigner(message, sig);
}
function recoverSigner(bytes32 message, bytes memory sig)
public
pure
returns (address)
{
uint8 v;
bytes32 r;
bytes32 s;
(v, r, s) = splitSignature(sig);
return ecrecover(message, v, r, s);
}
function splitSignature(bytes memory sig)
internal
pure
returns (uint8, bytes32, bytes32)
{
require(sig.length == 65);
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
}
return (v, r, s);
}
}
pragma solidity 0.8.7;
contract WnsRegistrar is Computation, Signatures {
address private WnsRegistry;
WnsRegistryInterface wnsRegistry;
constructor(address registry_) {
WnsRegistry = registry_;
wnsRegistry = WnsRegistryInterface(WnsRegistry);
}
function setRegistry(address _registry) public {
require(msg.sender == wnsRegistry.owner(), "Not authorized.");
WnsRegistry = _registry;
wnsRegistry = WnsRegistryInterface(WnsRegistry);
}
bool public isActive = false;
function wnsRegister(Register[] memory register, bytes[] memory sig) public payable {
require(isActive, "Registration must be active.");
require(register.length == sig.length, "Invalid parameters.");
require(calculateCost(register) <= msg.value, "Ether value is not correct.");
for(uint256 i=0; i<register.length; i++) {
_register(register[i], sig[i]);
}
}
function _register(Register memory register, bytes memory sig) internal {
WnsErc721Interface wnsErc721 = WnsErc721Interface(wnsRegistry.getWnsAddress("_wnsErc721"));
require(verifySignature(register,sig) == wnsRegistry.getWnsAddress("_wnsSigner"), "Not authorized.");
require(register.expiration >= block.timestamp, "Expired credentials.");
bytes32 _hash = computeNamehash(register.name);
require(wnsRegistry.getRecord(_hash) == 0, "Name already exists.");
wnsErc721.mintErc721(register.registrant);
wnsRegistry.setRecord(_hash, wnsErc721.getNextTokenId(), string(abi.encodePacked(register.name, register.extension)));
settleSplits(register.splitAddresses, register.splitAmounts);
}
function migrateExtension(string memory _name, string memory _extension, bytes memory sig) public {
WnsErc721Interface wnsErc721 = WnsErc721Interface(wnsRegistry.getWnsAddress("_wnsErc721"));
bytes32 message = keccak256(abi.encode(_name, _extension));
require(recoverSigner(message, sig) == wnsRegistry.getWnsAddress("_wnsSigner"), "Not authorized.");
uint256 _tokenId = wnsRegistry.getRecord(computeNamehash(_name)) - 1;
require(wnsErc721.ownerOf(_tokenId) == msg.sender, "Not owned by caller");
wnsRegistry.setRecord(_tokenId + 1, string(abi.encodePacked(_name, _extension)));
}
function calculateCost(Register[] memory register) internal pure returns (uint256) {
uint256 cost;
for(uint256 i=0; i<register.length; i++) {
cost = cost + register[i].cost;
}
return cost;
}
function settleSplits(address[] memory splitAddresses, uint256[] memory splitAmounts) internal {
uint256 addLength = splitAddresses.length;
uint256 amountLength = splitAmounts.length;
require(addLength == amountLength, "Invalid parameters.");
if(addLength > 0) {
for(uint256 i=0; i<addLength; i++) {
payable(splitAddresses[i]).transfer(splitAmounts[i]);
}
}
}
function withdraw(address to, uint256 amount) public {
require(msg.sender == wnsRegistry.owner());
require(amount <= address(this).balance);
payable(to).transfer(amount);
}
function flipActiveState() public {
require(msg.sender == wnsRegistry.owner());
isActive = !isActive;
}
}
{
"compilationTarget": {
"WnsRegistrar.sol": "WnsRegistrar"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}