github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/contracts/ens/ens.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:33</date>
    10  //</624342613859766272>
    11  
    12  
    13  package ens
    14  
    15  //go:生成abigen--sol contract/ens.sol--exc contract/abstractens.sol:abstractens--pkg contract--out contract/ens.go
    16  //go:生成abigen--sol contract/fifsregistrar.sol--exc contract/abstractens.sol:abstractens--pkg contract--out contract/fifsregistrar.go
    17  //go:生成abigen--sol contract/publicdolver.sol--exc contract/abstractens.sol:abstractens--pkg contract--out contract/publicdolver.go
    18  
    19  import (
    20  	"strings"
    21  
    22  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    23  	"github.com/ethereum/go-ethereum/common"
    24  	"github.com/ethereum/go-ethereum/contracts/ens/contract"
    25  	"github.com/ethereum/go-ethereum/core/types"
    26  	"github.com/ethereum/go-ethereum/crypto"
    27  )
    28  
    29  var (
    30  	MainNetAddress = common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b")
    31  	TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010")
    32  )
    33  
    34  //
    35  type ENS struct {
    36  	*contract.ENSSession
    37  	contractBackend bind.ContractBackend
    38  }
    39  
    40  //newens创建了一个结构,它公开了方便的高级操作,以便与
    41  //以太坊名称服务。
    42  func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) {
    43  	ens, err := contract.NewENS(contractAddr, contractBackend)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	return &ENS{
    49  		&contract.ENSSession{
    50  			Contract:     ens,
    51  			TransactOpts: *transactOpts,
    52  		},
    53  		contractBackend,
    54  	}, nil
    55  }
    56  
    57  //Deployeens部署ENS名称服务的一个实例,具有“先进先服务”的根注册器。
    58  func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *ENS, error) {
    59  //部署ENS注册表。
    60  	ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend)
    61  	if err != nil {
    62  		return ensAddr, nil, err
    63  	}
    64  
    65  	ens, err := NewENS(transactOpts, ensAddr, contractBackend)
    66  	if err != nil {
    67  		return ensAddr, nil, err
    68  	}
    69  
    70  //部署注册器。
    71  	regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{})
    72  	if err != nil {
    73  		return ensAddr, nil, err
    74  	}
    75  //将注册器设置为ENS根目录的所有者。
    76  	if _, err = ens.SetOwner([32]byte{}, regAddr); err != nil {
    77  		return ensAddr, nil, err
    78  	}
    79  
    80  	return ensAddr, 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  //解析是一个非事务性调用,返回与名称关联的内容哈希。
   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  //注册为调用者注册一个新域名,使其成为新名称的所有者。
   151  //仅当父域的注册器实现FIFS注册器协议时才有效。
   152  func (self *ENS) Register(name string) (*types.Transaction, error) {
   153  	parentNode, label := ensParentNode(name)
   154  	registrar, err := self.getRegistrar(parentNode)
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  	return registrar.Contract.Register(&self.TransactOpts, label, self.TransactOpts.From)
   159  }
   160  
   161  //setContentHash设置与名称关联的内容哈希。只有当呼叫方
   162  //拥有名称,关联的冲突解决程序实现了一个“setcontent”函数。
   163  func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) {
   164  	node := EnsNode(name)
   165  
   166  	resolver, err := self.getResolver(node)
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	opts := self.TransactOpts
   172  	opts.GasLimit = 200000
   173  	return resolver.Contract.SetContent(&opts, node, hash)
   174  }
   175