github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/contracts/ens/ens.go (about) 1 package ens 2 3 //go:generate abigen --sol contract/ENS.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/ens.go 4 //go:generate abigen --sol contract/FIFSRegistrar.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/fifsregistrar.go 5 //go:generate abigen --sol contract/PublicResolver.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/publicresolver.go 6 7 import ( 8 "strings" 9 10 "github.com/quickchainproject/quickchain/accounts/abi/bind" 11 "github.com/quickchainproject/quickchain/common" 12 "github.com/quickchainproject/quickchain/contracts/ens/contract" 13 "github.com/quickchainproject/quickchain/core/types" 14 "github.com/quickchainproject/quickchain/crypto" 15 ) 16 17 var ( 18 MainNetAddress = common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b") 19 TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010") 20 ) 21 22 // swarm domain name registry and resolver 23 type ENS struct { 24 *contract.ENSSession 25 contractBackend bind.ContractBackend 26 } 27 28 // NewENS creates a struct exposing convenient high-level operations for interacting with 29 // the Ethereum Name Service. 30 func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) { 31 ens, err := contract.NewENS(contractAddr, contractBackend) 32 if err != nil { 33 return nil, err 34 } 35 36 return &ENS{ 37 &contract.ENSSession{ 38 Contract: ens, 39 TransactOpts: *transactOpts, 40 }, 41 contractBackend, 42 }, nil 43 } 44 45 // DeployENS deploys an instance of the ENS nameservice, with a 'first-in, first-served' root registrar. 46 func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *ENS, error) { 47 // Deploy the ENS registry. 48 ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend) 49 if err != nil { 50 return ensAddr, nil, err 51 } 52 53 ens, err := NewENS(transactOpts, ensAddr, contractBackend) 54 if err != nil { 55 return ensAddr, nil, err 56 } 57 58 // Deploy the registrar. 59 regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{}) 60 if err != nil { 61 return ensAddr, nil, err 62 } 63 // Set the registrar as owner of the ENS root. 64 if _, err = ens.SetOwner([32]byte{}, regAddr); err != nil { 65 return ensAddr, nil, err 66 } 67 68 return ensAddr, ens, nil 69 } 70 71 func ensParentNode(name string) (common.Hash, common.Hash) { 72 parts := strings.SplitN(name, ".", 2) 73 label := crypto.Keccak256Hash([]byte(parts[0])) 74 if len(parts) == 1 { 75 return [32]byte{}, label 76 } else { 77 parentNode, parentLabel := ensParentNode(parts[1]) 78 return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label 79 } 80 } 81 82 func ensNode(name string) common.Hash { 83 parentNode, parentLabel := ensParentNode(name) 84 return crypto.Keccak256Hash(parentNode[:], parentLabel[:]) 85 } 86 87 func (self *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) { 88 resolverAddr, err := self.Resolver(node) 89 if err != nil { 90 return nil, err 91 } 92 93 resolver, err := contract.NewPublicResolver(resolverAddr, self.contractBackend) 94 if err != nil { 95 return nil, err 96 } 97 98 return &contract.PublicResolverSession{ 99 Contract: resolver, 100 TransactOpts: self.TransactOpts, 101 }, nil 102 } 103 104 func (self *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) { 105 registrarAddr, err := self.Owner(node) 106 if err != nil { 107 return nil, err 108 } 109 110 registrar, err := contract.NewFIFSRegistrar(registrarAddr, self.contractBackend) 111 if err != nil { 112 return nil, err 113 } 114 115 return &contract.FIFSRegistrarSession{ 116 Contract: registrar, 117 TransactOpts: self.TransactOpts, 118 }, nil 119 } 120 121 // Resolve is a non-transactional call that returns the content hash associated with a name. 122 func (self *ENS) Resolve(name string) (common.Hash, error) { 123 node := ensNode(name) 124 125 resolver, err := self.getResolver(node) 126 if err != nil { 127 return common.Hash{}, err 128 } 129 130 ret, err := resolver.Content(node) 131 if err != nil { 132 return common.Hash{}, err 133 } 134 135 return common.BytesToHash(ret[:]), nil 136 } 137 138 // Register registers a new domain name for the caller, making them the owner of the new name. 139 // Only works if the registrar for the parent domain implements the FIFS registrar protocol. 140 func (self *ENS) Register(name string) (*types.Transaction, error) { 141 parentNode, label := ensParentNode(name) 142 registrar, err := self.getRegistrar(parentNode) 143 if err != nil { 144 return nil, err 145 } 146 return registrar.Contract.Register(&self.TransactOpts, label, self.TransactOpts.From) 147 } 148 149 // SetContentHash sets the content hash associated with a name. Only works if the caller 150 // owns the name, and the associated resolver implements a `setContent` function. 151 func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) { 152 node := ensNode(name) 153 154 resolver, err := self.getResolver(node) 155 if err != nil { 156 return nil, err 157 } 158 159 opts := self.TransactOpts 160 opts.GasLimit = 200000 161 return resolver.Contract.SetContent(&opts, node, hash) 162 }