github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/contracts/ens/ens.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package ens 18 19 //go:generate abigen --sol contract/ens.sol --pkg contract --out contract/ens.go 20 21 import ( 22 "math/big" 23 "strings" 24 25 "github.com/atheioschain/go-atheios/accounts/abi/bind" 26 "github.com/atheioschain/go-atheios/common" 27 "github.com/atheioschain/go-atheios/contracts/ens/contract" 28 "github.com/atheioschain/go-atheios/core/types" 29 "github.com/atheioschain/go-atheios/crypto" 30 ) 31 32 // swarm domain name registry and resolver 33 type ENS struct { 34 *contract.ENSSession 35 contractBackend bind.ContractBackend 36 } 37 38 // NewENS creates a struct exposing convenient high-level operations for interacting with 39 // the Ethereum Name Service. 40 func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) { 41 ens, err := contract.NewENS(contractAddr, contractBackend) 42 if err != nil { 43 return nil, err 44 } 45 46 return &ENS{ 47 &contract.ENSSession{ 48 Contract: ens, 49 TransactOpts: *transactOpts, 50 }, 51 contractBackend, 52 }, nil 53 } 54 55 // DeployENS deploys an instance of the ENS nameservice, with a 'first in first served' root registrar. 56 func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (*ENS, error) { 57 // Deploy the ENS registry 58 ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend, transactOpts.From) 59 if err != nil { 60 return nil, err 61 } 62 63 ens, err := NewENS(transactOpts, ensAddr, contractBackend) 64 if err != nil { 65 return nil, err 66 } 67 68 // Deploy the registrar 69 regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{}) 70 if err != nil { 71 return nil, err 72 } 73 74 // Set the registrar as owner of the ENS root 75 _, err = ens.SetOwner([32]byte{}, regAddr) 76 if err != nil { 77 return nil, err 78 } 79 80 return ens, nil 81 } 82 83 func ensParentNode(name string) (common.Hash, common.Hash) { 84 parts := strings.SplitN(name, ".", 2) 85 label := crypto.Keccak256Hash([]byte(parts[0])) 86 if len(parts) == 1 { 87 return [32]byte{}, label 88 } else { 89 parentNode, parentLabel := ensParentNode(parts[1]) 90 return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label 91 } 92 } 93 94 func ensNode(name string) common.Hash { 95 parentNode, parentLabel := ensParentNode(name) 96 return crypto.Keccak256Hash(parentNode[:], parentLabel[:]) 97 } 98 99 func (self *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) { 100 resolverAddr, err := self.Resolver(node) 101 if err != nil { 102 return nil, err 103 } 104 105 resolver, err := contract.NewPublicResolver(resolverAddr, self.contractBackend) 106 if err != nil { 107 return nil, err 108 } 109 110 return &contract.PublicResolverSession{ 111 Contract: resolver, 112 TransactOpts: self.TransactOpts, 113 }, nil 114 } 115 116 func (self *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) { 117 registrarAddr, err := self.Owner(node) 118 if err != nil { 119 return nil, err 120 } 121 122 registrar, err := contract.NewFIFSRegistrar(registrarAddr, self.contractBackend) 123 if err != nil { 124 return nil, err 125 } 126 127 return &contract.FIFSRegistrarSession{ 128 Contract: registrar, 129 TransactOpts: self.TransactOpts, 130 }, nil 131 } 132 133 // Resolve is a non-transactional call that returns the content hash associated with a name. 134 func (self *ENS) Resolve(name string) (common.Hash, error) { 135 node := ensNode(name) 136 137 resolver, err := self.getResolver(node) 138 if err != nil { 139 return common.Hash{}, err 140 } 141 142 ret, err := resolver.Content(node) 143 if err != nil { 144 return common.Hash{}, err 145 } 146 147 return common.BytesToHash(ret[:]), nil 148 } 149 150 // Register registers a new domain name for the caller, making them the owner of the new name. 151 // Only works if the registrar for the parent domain implements the FIFS registrar protocol. 152 func (self *ENS) Register(name string) (*types.Transaction, error) { 153 parentNode, label := ensParentNode(name) 154 155 registrar, err := self.getRegistrar(parentNode) 156 if err != nil { 157 return nil, err 158 } 159 160 opts := self.TransactOpts 161 opts.GasLimit = big.NewInt(200000) 162 return registrar.Contract.Register(&opts, label, self.TransactOpts.From) 163 } 164 165 // SetContentHash sets the content hash associated with a name. Only works if the caller 166 // owns the name, and the associated resolver implements a `setContent` function. 167 func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) { 168 node := ensNode(name) 169 170 resolver, err := self.getResolver(node) 171 if err != nil { 172 return nil, err 173 } 174 175 opts := self.TransactOpts 176 opts.GasLimit = big.NewInt(200000) 177 return resolver.Contract.SetContent(&opts, node, hash) 178 }