go-ethereum/contracts/ens/ens.go
Daniel Liu fbecb8c5a5 all: fix staticcheck warning ST1006: don't use generic name self
The name of a method’s receiver should be a reflection of its identity;
often a one or two letter abbreviation of its type suffices (such as
“c” or “cl” for “Client”). Don’t use generic names such as “me”, “this”
or “self”, identifiers typical of object-oriented languages that place
more emphasis on methods as opposed to functions. The name need not be
as descriptive as that of a method argument, as its role is obvious and
serves no documentary purpose. It can be very short as it will appear
on almost every line of every method of the type; familiarity admits
brevity. Be consistent, too: if you call the receiver “c” in one method,
don’t call it “cl” in another.
2024-10-25 21:30:54 +08:00

178 lines
5.5 KiB
Go

// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package ens
//go:generate abigen --sol contract/ENS.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/ens.go
//go:generate abigen --sol contract/FIFSRegistrar.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/fifsregistrar.go
//go:generate abigen --sol contract/PublicResolver.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/publicresolver.go
import (
"strings"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/contracts/ens/contract"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
MainNetAddress = common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b")
TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010")
)
// swarm domain name registry and resolver
type ENS struct {
*contract.ENSSession
contractBackend bind.ContractBackend
}
// NewENS creates a struct exposing convenient high-level operations for interacting with
// the Ethereum Name Service.
func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) {
ens, err := contract.NewENS(contractAddr, contractBackend)
if err != nil {
return nil, err
}
return &ENS{
&contract.ENSSession{
Contract: ens,
TransactOpts: *transactOpts,
},
contractBackend,
}, nil
}
// DeployENS deploys an instance of the ENS nameservice, with a 'first-in, first-served' root registrar.
func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *ENS, error) {
// Deploy the ENS registry.
ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend)
if err != nil {
return ensAddr, nil, err
}
ens, err := NewENS(transactOpts, ensAddr, contractBackend)
if err != nil {
return ensAddr, nil, err
}
// Deploy the registrar.
regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{})
if err != nil {
return ensAddr, nil, err
}
// Set the registrar as owner of the ENS root.
if _, err = ens.SetOwner([32]byte{}, regAddr); err != nil {
return ensAddr, nil, err
}
return ensAddr, ens, nil
}
func ensParentNode(name string) (common.Hash, common.Hash) {
parts := strings.SplitN(name, ".", 2)
label := crypto.Keccak256Hash([]byte(parts[0]))
if len(parts) == 1 {
return [32]byte{}, label
} else {
parentNode, parentLabel := ensParentNode(parts[1])
return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label
}
}
func ensNode(name string) common.Hash {
parentNode, parentLabel := ensParentNode(name)
return crypto.Keccak256Hash(parentNode[:], parentLabel[:])
}
func (e *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) {
resolverAddr, err := e.Resolver(node)
if err != nil {
return nil, err
}
resolver, err := contract.NewPublicResolver(resolverAddr, e.contractBackend)
if err != nil {
return nil, err
}
return &contract.PublicResolverSession{
Contract: resolver,
TransactOpts: e.TransactOpts,
}, nil
}
func (e *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) {
registrarAddr, err := e.Owner(node)
if err != nil {
return nil, err
}
registrar, err := contract.NewFIFSRegistrar(registrarAddr, e.contractBackend)
if err != nil {
return nil, err
}
return &contract.FIFSRegistrarSession{
Contract: registrar,
TransactOpts: e.TransactOpts,
}, nil
}
// Resolve is a non-transactional call that returns the content hash associated with a name.
func (e *ENS) Resolve(name string) (common.Hash, error) {
node := ensNode(name)
resolver, err := e.getResolver(node)
if err != nil {
return common.Hash{}, err
}
ret, err := resolver.Content(node)
if err != nil {
return common.Hash{}, err
}
return common.BytesToHash(ret[:]), nil
}
// Register registers a new domain name for the caller, making them the owner of the new name.
// Only works if the registrar for the parent domain implements the FIFS registrar protocol.
func (e *ENS) Register(name string) (*types.Transaction, error) {
parentNode, label := ensParentNode(name)
registrar, err := e.getRegistrar(parentNode)
if err != nil {
return nil, err
}
return registrar.Contract.Register(&e.TransactOpts, label, e.TransactOpts.From)
}
// SetContentHash sets the content hash associated with a name. Only works if the caller
// owns the name, and the associated resolver implements a `setContent` function.
func (e *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) {
node := ensNode(name)
resolver, err := e.getResolver(node)
if err != nil {
return nil, err
}
opts := e.TransactOpts
opts.GasLimit = 200000
return resolver.Contract.SetContent(&opts, node, hash)
}