github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/contracts/vns/vns.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 vns 18 19 import ( 20 "strings" 21 22 "github.com/vntchain/go-vnt/accounts/abi/bind" 23 "github.com/vntchain/go-vnt/common" 24 "github.com/vntchain/go-vnt/contracts/vns/contract" 25 "github.com/vntchain/go-vnt/core/types" 26 "github.com/vntchain/go-vnt/crypto" 27 ) 28 29 var ( 30 MainNetAddress = common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b") 31 TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010") 32 ) 33 34 // swarm domain name registry and resolver 35 type VNS struct { 36 *contract.VNSSession 37 contractBackend bind.ContractBackend 38 } 39 40 // NewVNS creates a struct exposing convenient high-level operations for interacting with 41 // the VNT Name Service. 42 func NewVNS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*VNS, error) { 43 vns, err := contract.NewVNS(contractAddr, contractBackend) 44 if err != nil { 45 return nil, err 46 } 47 48 return &VNS{ 49 &contract.VNSSession{ 50 Contract: vns, 51 TransactOpts: *transactOpts, 52 }, 53 contractBackend, 54 }, nil 55 } 56 57 // DeployVNS deploys an instance of the VNS nameservice, with a 'first-in, first-served' root registrar. 58 func DeployVNS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *VNS, error) { 59 // Deploy the VNS registry. 60 vnsAddr, _, _, err := contract.DeployVNS(transactOpts, contractBackend) 61 if err != nil { 62 return vnsAddr, nil, err 63 } 64 vns, err := NewVNS(transactOpts, vnsAddr, contractBackend) 65 if err != nil { 66 return vnsAddr, nil, err 67 } 68 // Deploy the registrar. 69 regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, vnsAddr, "") 70 if err != nil { 71 return vnsAddr, nil, err 72 } 73 // Set the registrar as owner of the VNS root. 74 if _, err = vns.SetOwner("", regAddr); err != nil { 75 return vnsAddr, nil, err 76 } 77 78 return vnsAddr, vns, nil 79 } 80 81 func vnsParentNode(name string) (string, string) { 82 parts := strings.SplitN(name, ".", 2) 83 label := crypto.Keccak256Hash([]byte(parts[0])) 84 if len(parts) == 1 { 85 return "", string(label.Bytes()) 86 } else { 87 parentNode, parentLabel := vnsParentNode(parts[1]) 88 return string(crypto.Keccak256Hash([]byte(parentNode), []byte(parentLabel)).Bytes()), string(label.Bytes()) 89 } 90 } 91 92 func VnsNode(name string) string { 93 parentNode, parentLabel := vnsParentNode(name) 94 return string(crypto.Keccak256Hash([]byte(parentNode), []byte(parentLabel)).Hex()) 95 } 96 97 func (self *VNS) getResolver(node string) (*contract.PublicResolverSession, error) { 98 resolverAddr, err := self.Resolver(node) 99 if err != nil { 100 return nil, err 101 } 102 103 resolver, err := contract.NewPublicResolver(resolverAddr, self.contractBackend) 104 if err != nil { 105 return nil, err 106 } 107 108 return &contract.PublicResolverSession{ 109 Contract: resolver, 110 TransactOpts: self.TransactOpts, 111 }, nil 112 } 113 114 func (self *VNS) getRegistrar(node string) (*contract.FIFSRegistrarSession, error) { 115 registrarAddr, err := self.Owner(node) 116 if err != nil { 117 return nil, err 118 } 119 120 registrar, err := contract.NewFIFSRegistrar(registrarAddr, self.contractBackend) 121 if err != nil { 122 return nil, err 123 } 124 125 return &contract.FIFSRegistrarSession{ 126 Contract: registrar, 127 TransactOpts: self.TransactOpts, 128 }, nil 129 } 130 131 // Resolve is a non-transactional call that returns the content hash associated with a name. 132 func (self *VNS) Resolve(name string) (string, error) { 133 node := VnsNode(name) 134 135 resolver, err := self.getResolver(node) 136 if err != nil { 137 return "", err 138 } 139 140 ret, err := resolver.Content(node) 141 if err != nil { 142 return "", err 143 } 144 145 return ret, nil 146 } 147 148 // Addr is a non-transactional call that returns the address associated with a name. 149 func (self *VNS) Addr(name string) (common.Address, error) { 150 node := VnsNode(name) 151 152 resolver, err := self.getResolver(node) 153 if err != nil { 154 return common.Address{}, err 155 } 156 157 ret, err := resolver.Addr(node) 158 if err != nil { 159 return common.Address{}, err 160 } 161 162 return common.BytesToAddress(ret[:]), nil 163 } 164 165 // SetAddress sets the address associated with a name. Only works if the caller 166 // owns the name, and the associated resolver implements a `setAddress` function. 167 func (self *VNS) SetAddr(name string, addr common.Address) (*types.Transaction, error) { 168 node := VnsNode(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 = 200000 177 return resolver.Contract.SetAddr(&opts, node, addr) 178 } 179 180 // Register registers a new domain name for the caller, making them the owner of the new name. 181 // Only works if the registrar for the parent domain implements the FIFS registrar protocol. 182 func (self *VNS) Register(name string) (*types.Transaction, error) { 183 parentNode, label := vnsParentNode(name) 184 registrar, err := self.getRegistrar(parentNode) 185 if err != nil { 186 return nil, err 187 } 188 return registrar.Contract.Register(&self.TransactOpts, label, self.TransactOpts.From) 189 } 190 191 // SetContentHash sets the content hash associated with a name. Only works if the caller 192 // owns the name, and the associated resolver implements a `setContent` function. 193 func (self *VNS) SetContentHash(name string, hash string) (*types.Transaction, error) { 194 node := VnsNode(name) 195 196 resolver, err := self.getResolver(node) 197 if err != nil { 198 return nil, err 199 } 200 201 opts := self.TransactOpts 202 opts.GasLimit = 200000 203 return resolver.Contract.SetContent(&opts, node, hash) 204 }