mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-22 06:34:32 +00:00
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.
178 lines
5.5 KiB
Go
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)
|
|
}
|