ENS_Permissions: Immutable domains, immutable key-value pairs, and immutable ownership
This here is an example of a permission contract that could own an ENS name and set permissions,
https://gist.github.com/resilience-me/9332efe8a877fd717ba73dbd8353c3bb
lockOwnership()
can lock the ownership of the ENS name, lockAddress()
can lock the address the name points to, and lockTextKey()
can set the value for "ipfs", or some other key-value pair, to be locked for a period of time. struct Permissions
keeps track of how long the ownership, address, and text-keys are locked.
I deployed a contract here, and will test it on the main net with some random ENS name, bidding on a disposable name at the moment so that will take a few days,
https://etherscan.io/address/0x907240eade494397e0721bb7c4de67bd1205d236#code
Very possible that there are bugs.
contract Registry {
function owner(bytes32 node) public view returns (address) {}
}
contract Registrar {
modifier onlyOwner(bytes32 _hash) { _; }
function transfer(bytes32 _hash, address newOwner) onlyOwner(_hash) {}
}
contract PublicResolver {
modifier only_owner(bytes32 node) { _; }
function setAddr(bytes32 node, address addr) only_owner(node) {}
function setContent(bytes32 node, bytes32 hash) only_owner(node) {}
function setName(bytes32 node, string name) only_owner(node) {}
function setABI(bytes32 node, uint256 contentType, bytes data) only_owner(node) {}
function setPubkey(bytes32 node, bytes32 x, bytes32 y) only_owner(node) {}
function setText(bytes32 node, string key, string value) only_owner(node) {}
}
contract ENS_Permissions {
Registry registry = Registry(0x314159265dD8dbb310642f98f50C066173C1259b);
Registrar registrar = Registrar(0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef);
PublicResolver publicResolver = PublicResolver(0x5FfC014343cd971B7eb70732021E26C35B744cc4);
address owner;
bytes32 labelhash;
bytes32 namehash;
constructor(address _owner) {
owner = _owner;
}
modifier only_owner {
require(owner == msg.sender);
_;
}
struct Permissions {
uint ownerMutability;
uint addressMutability;
mapping(string => uint) textKeyMutability;
}
Permissions permissions;
function setOwner(address _newOwner) only_owner {
owner = _newOwner;
}
function activatePermissionsBot(bytes32 _namehash, bytes32 _labelhash) only_owner {
require(registry.owner(_namehash) == address(this));
require(labelhash == 0 && namehash == 0);
labelhash = _labelhash;
namehash = _namehash;
}
function lockOwnership(uint _date) only_owner {
require(permissions.ownerMutability < block.timestamp);
require(_date > block.timestamp);
permissions.ownerMutability == _date;
}
function lockAddress(uint _date) only_owner {
require(permissions.addressMutability < block.timestamp);
require(_date > block.timestamp);
permissions.addressMutability == _date;
}
function lockTextKey(string _key, uint _date) only_owner {
require(permissions.textKeyMutability[_key] < block.timestamp);
require(_date > block.timestamp);
permissions.textKeyMutability[_key] == _date;
}
// Transferring ownership from this contract also destroys the contract
function transfer(address _newOwner) only_owner {
require(permissions.ownerMutability < block.timestamp);
registrar.transfer(labelhash, _newOwner);
selfdestruct(msg.sender);
}
function setAddr(address _addr) only_owner {
require(permissions.addressMutability < block.timestamp);
publicResolver.setAddr(namehash, _addr);
}
function setText(string _key, string _value) only_owner {
require(permissions.textKeyMutability[_key] < block.timestamp);
publicResolver.setText(namehash, _key, _value);
}
}
contract Factory {
function createPermissionsBot(address _owner) returns (address) {
return ENS_Permissions permissionsBot = new ENS_Permissions(_owner);
}
}
Great technical blog post and i am so happy to see after a long time.