Skip to content

Instantly share code, notes, and snippets.

@PhyrexTsai
Last active August 25, 2018 10:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhyrexTsai/fbea8e4437e2a3252d1490c7c81a700b to your computer and use it in GitHub Desktop.
Save PhyrexTsai/fbea8e4437e2a3252d1490c7c81a700b to your computer and use it in GitHub Desktop.

This is the step by step to register the QCNS domain

Environment

Source Code below

These source code include:
(1) QCNS.sol, which is the interface of QCNS.
(2) QCNSRegistry.sol, which is the implementation of QCNS.sol and stores the records of the domain.
(3) QCNSRegistrar.sol, which is trying to access the QCNSRegistry.sol smart contract and interact with the methods in QCNSRegistry.sol

QCNS.sol

pragma solidity ^0.4.18;

interface QCNS {
    event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
    event Transfer(bytes32 indexed node, address owner);
    event NewResolver(bytes32 indexed node, address resolver);
    event NewTTL(bytes32 indexed node, uint64 ttl);

    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public;
    function setResolver(bytes32 node, address resolver) public;
    function setOwner(bytes32 node, address owner) public;
    function setTTL(bytes32 node, uint64 ttl) public;
    function owner(bytes32 node) public view returns (address);
    function resolver(bytes32 node) public view returns (address);
    function ttl(bytes32 node) public view returns (uint64);
}

QCNSRegistry.sol

pragma solidity ^0.4.18;

import './QCNS.sol';

contract QCNSRegistry is QCNS {
    struct Record {
        address owner;
        address resolver;
        uint64 ttl;
    }

    mapping (bytes32 => Record) records;
    
    modifier only_owner(bytes32 node) {
        require(records[node].owner == msg.sender);
        _;
    }
    
    function QCNSRegistry() public {
        records[0x0].owner = msg.sender;
    }

    function setOwner(bytes32 node, address owner) public only_owner(node) {
        Transfer(node, owner);
        records[node].owner = owner;
    }

    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public only_owner(node) {
        var subnode = keccak256(node, label);
        NewOwner(node, label, owner);
        records[subnode].owner = owner;
    }

    function setResolver(bytes32 node, address resolver) public only_owner(node) {
        NewResolver(node, resolver);
        records[node].resolver = resolver;
    }

    function setTTL(bytes32 node, uint64 ttl) public only_owner(node) {
        NewTTL(node, ttl);
        records[node].ttl = ttl;
    }

    function owner(bytes32 node) public view returns (address) {
        return records[node].owner;
    }

    function resolver(bytes32 node) public view returns (address) {
        return records[node].resolver;
    }
    
    function ttl(bytes32 node) public view returns (uint64) {
        return records[node].ttl;
    }
}

QCNSRegistry.sol ABI

[
	{
		"constant": true,
		"inputs": [
			{
				"name": "node",
				"type": "bytes32"
			}
		],
		"name": "resolver",
		"outputs": [
			{
				"name": "",
				"type": "address"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [
			{
				"name": "node",
				"type": "bytes32"
			}
		],
		"name": "owner",
		"outputs": [
			{
				"name": "",
				"type": "address"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"name": "node",
				"type": "bytes32"
			},
			{
				"name": "label",
				"type": "bytes32"
			},
			{
				"name": "owner",
				"type": "address"
			}
		],
		"name": "setSubnodeOwner",
		"outputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"name": "node",
				"type": "bytes32"
			},
			{
				"name": "ttl",
				"type": "uint64"
			}
		],
		"name": "setTTL",
		"outputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [
			{
				"name": "node",
				"type": "bytes32"
			}
		],
		"name": "ttl",
		"outputs": [
			{
				"name": "",
				"type": "uint64"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"name": "node",
				"type": "bytes32"
			},
			{
				"name": "resolver",
				"type": "address"
			}
		],
		"name": "setResolver",
		"outputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"name": "node",
				"type": "bytes32"
			},
			{
				"name": "owner",
				"type": "address"
			}
		],
		"name": "setOwner",
		"outputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "constructor"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"name": "node",
				"type": "bytes32"
			},
			{
				"indexed": true,
				"name": "label",
				"type": "bytes32"
			},
			{
				"indexed": false,
				"name": "owner",
				"type": "address"
			}
		],
		"name": "NewOwner",
		"type": "event"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"name": "node",
				"type": "bytes32"
			},
			{
				"indexed": false,
				"name": "owner",
				"type": "address"
			}
		],
		"name": "Transfer",
		"type": "event"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"name": "node",
				"type": "bytes32"
			},
			{
				"indexed": false,
				"name": "resolver",
				"type": "address"
			}
		],
		"name": "NewResolver",
		"type": "event"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"name": "node",
				"type": "bytes32"
			},
			{
				"indexed": false,
				"name": "ttl",
				"type": "uint64"
			}
		],
		"name": "NewTTL",
		"type": "event"
	}
]

QCNSRegistrar.sol

pragma solidity ^0.4.18;

import './QCNS.sol';

contract QCNSRegistrar {
    QCNS qcns;
    bytes32 rootNode;

    modifier only_owner(bytes32 subnode) {
        address currentOwner = qcns.owner(keccak256(rootNode, subnode));
        require(currentOwner == 0 || currentOwner == msg.sender);
        _;
    }
    
    function QCNSRegistrar() public {
        // This is the QCNSRegistry address, which this address is point to Ethereum Ropsten
        // QCNSRegistry on 0x55931d4077c71df7E1822f1922Ab5f6b33b4199b, shard 46)
        qcns = QCNS(0x55931d4077c71df7E1822f1922Ab5f6b33b4199b);
        rootNode = 0x594a477ed3f0b042faff347a58ea6074459e468efbb5aa3a2c51f7c3673be7cf;
    }

    function register(bytes32 subnode, address owner) public only_owner(subnode) {
        qcns.setSubnodeOwner(rootNode, subnode, owner);
    }
}

QCNSRegistrar.sol ABI

[
	{
		"constant": false,
		"inputs": [
			{
				"name": "subnode",
				"type": "bytes32"
			},
			{
				"name": "owner",
				"type": "address"
			}
		],
		"name": "register",
		"outputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "constructor"
	}
]

Register a qkc domain

  1. Copy the ABI of the QCNSRegistrar.
  2. Copy the Address of the QCNSRegistrar.
  3. Click "Access" to read the QCNSRegistrar contract.
  4. Invoke register method to register 'qkc.qkc' on QCNSRegistrar: http://testnet.quarkchain.io/tx/0xd0cc69fbdb61491f08c4604e2ed230cdff56e2738d2ae4bb82be5d3bb3d3e313ff1a972e

https://i.imgur.com/hT1Jcr5.png

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment