Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ENS integration workshop at Winding Tree hackathon

Makoto Inoue
October 24, 2018
30

ENS integration workshop at Winding Tree hackathon

Makoto Inoue

October 24, 2018
Tweet

Transcript

  1. Agenda - 1. Intro & What can you do with

    ENS? - 2. ENS contracts and API overview - 3. Issuing subdomain to new users for your dapp
  2. More than just names ENS names contracts and accounts, but

    also… • Swarm & IPFS records • Legacy DNS records - IP addresses, mail exchangers • Identity attestation • Stores contract interfaces
  3. Contract MyResolver { address me; function MyResolver() { me =

    msg.sender; } function addr(bytes32 node) constant returns (address) { return me; } } ENS by example: Resolvers
  4. Reverse resolution const addr = ‘0x112234455...’ const name = await

    ens.reverse(‘0x112234455...’).name() //for security const addr2 = await ens.resolver(name) if(addr === addr2){ …. }
  5. Signup flow example Make sure - User is on the

    right network - Metamask is unlocked
  6. Getting ENS subdomain Check if the ENS subdomain already exists

    - If yes, then check if it is owned by the address currently on metamask - If yes then its a sign in, make them sign a message to prove they actually hold the acount they are signing up for. If it doesnt exist then they can have it!
  7. Verify account Signing a message to verify they hold the

    account A nounce to prevent replay attacks
  8. Account Users are logged in regardless of the status of

    transactions. (UX comment) Since Zinc sends the transactions and the messages are verified on chain, they are also verified off chain to prevent sending transactions which are guaranteed to fail.
  9. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code
  10. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code web3.utils.sha3(“makoto”)
  11. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code keccak256(abi.encodePacked(“yourdomain.eth”, label))
  12. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code web3.utils.sha3(“makoto.yourdomain.eth”)
  13. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code Check the name is not taken yet
  14. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code Set the contract to own “makoto.yourdomain.eth”
  15. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code Set the default resolver to “makoto.yourdomain.eth”
  16. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code Set the sender address to “makoto.yourdomain.eth”
  17. Contract MyAweSomeApp { function register(bytes32 label) public { bytes32 node

    = getNode(label); require(ens.owner(node) == address(0)) ens.setSubnodeOwner(rootNode, label, this); ens.setResolver(node, resolver); resolver.setAddr(node, msg.sender); ens.setOwner(node, msg.sender); } } The code Give the ownership of the node to the sender
  18. - Reverse record can be only set by the owner

    of the address - You can still have a button on dapp to call `reverseRegistrar.setName(‘jefflau.eth’)` to set reverse record. - However, should your Dapp enforce setting reverse record as it may override previous setting? 1. Assigning reverse record
  19. 2. Assigning subdomain costs gas Solutions - Dapp pay for

    the gass (Gitcoin/zinc) - Make it optional (Gitcoin) - Do nothing (Kickback) <= shit