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  }