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  }