aboutsummaryrefslogtreecommitdiffstats
path: root/common/registrar/registrar.go
diff options
context:
space:
mode:
Diffstat (limited to 'common/registrar/registrar.go')
-rw-r--r--common/registrar/registrar.go436
1 files changed, 0 insertions, 436 deletions
diff --git a/common/registrar/registrar.go b/common/registrar/registrar.go
deleted file mode 100644
index 0606f6985..000000000
--- a/common/registrar/registrar.go
+++ /dev/null
@@ -1,436 +0,0 @@
-// Copyright 2015 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 registrar
-
-import (
- "encoding/binary"
- "fmt"
- "math/big"
- "regexp"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/logger/glog"
-)
-
-/*
-Registrar implements the Ethereum name registrar services mapping
-- arbitrary strings to ethereum addresses
-- hashes to hashes
-- hashes to arbitrary strings
-(likely will provide lookup service for all three)
-
-The Registrar is used by
-* the roundtripper transport implementation of
-url schemes to resolve domain names and services that register these names
-* contract info retrieval (NatSpec).
-
-The Registrar uses 3 contracts on the blockchain:
-* GlobalRegistrar: Name (string) -> Address (Owner)
-* HashReg : Key Hash (hash of domain name or contract code) -> Content Hash
-* UrlHint : Content Hash -> Url Hint
-
-These contracts are (currently) not included in the genesis block.
-Each Set<X> needs to be called once on each blockchain/network once.
-
-Contract addresses need to be set the first time any Registrar method is called
-in a client session.
-This is done for frontier by default, otherwise the caller needs to make sure
-the relevant environment initialised the desired contracts
-*/
-var (
- // GlobalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b" // olympic
- GlobalRegistrarAddr = "0x33990122638b9132ca29c723bdf037f1a891a70c" // frontier
- HashRegAddr = "0x23bf622b5a65f6060d855fca401133ded3520620" // frontier
- UrlHintAddr = "0x73ed5ef6c010727dfd2671dbb70faac19ec18626" // frontier
-
- zero = regexp.MustCompile("^(0x)?0*$")
-)
-
-const (
- trueHex = "0000000000000000000000000000000000000000000000000000000000000001"
- falseHex = "0000000000000000000000000000000000000000000000000000000000000000"
-)
-
-func abiSignature(s string) string {
- return common.ToHex(crypto.Keccak256([]byte(s))[:4])
-}
-
-var (
- HashRegName = "HashReg"
- UrlHintName = "UrlHint"
-
- registerContentHashAbi = abiSignature("register(uint256,uint256)")
- registerUrlAbi = abiSignature("register(uint256,uint8,uint256)")
- setOwnerAbi = abiSignature("setowner()")
- reserveAbi = abiSignature("reserve(bytes32)")
- resolveAbi = abiSignature("addr(bytes32)")
- registerAbi = abiSignature("setAddress(bytes32,address,bool)")
- addressAbiPrefix = falseHex[:24]
-)
-
-// Registrar's backend is defined as an interface (implemented by xeth, but could be remote)
-type Backend interface {
- StorageAt(string, string) string
- Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error)
- Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, string, error)
-}
-
-// TODO Registrar should also just implement The Resolver and Registry interfaces
-// Simplify for now.
-type VersionedRegistrar interface {
- Resolver(*big.Int) *Registrar
- Registry() *Registrar
-}
-
-type Registrar struct {
- backend Backend
-}
-
-func New(b Backend) (res *Registrar) {
- res = &Registrar{b}
- return
-}
-
-func (self *Registrar) SetGlobalRegistrar(namereg string, addr common.Address) (txhash string, err error) {
- if namereg != "" {
- GlobalRegistrarAddr = namereg
- return
- }
- if zero.MatchString(GlobalRegistrarAddr) {
- if (addr == common.Address{}) {
- err = fmt.Errorf("GlobalRegistrar address not found and sender for creation not given")
- return
- } else {
- txhash, err = self.backend.Transact(addr.Hex(), "", "", "", "800000", "", GlobalRegistrarCode)
- if err != nil {
- err = fmt.Errorf("GlobalRegistrar address not found and sender for creation failed: %v", err)
- return
- }
- }
- }
- return
-}
-
-func (self *Registrar) SetHashReg(hashreg string, addr common.Address) (txhash string, err error) {
- if hashreg != "" {
- HashRegAddr = hashreg
- } else {
- if !zero.MatchString(HashRegAddr) {
- return
- }
- nameHex, extra := encodeName(HashRegName, 2)
- hashRegAbi := resolveAbi + nameHex + extra
- glog.V(logger.Detail).Infof("\ncall HashRegAddr %v with %v\n", GlobalRegistrarAddr, hashRegAbi)
- var res string
- res, _, err = self.backend.Call("", GlobalRegistrarAddr, "", "", "", hashRegAbi)
- if len(res) >= 40 {
- HashRegAddr = "0x" + res[len(res)-40:len(res)]
- }
- if err != nil || zero.MatchString(HashRegAddr) {
- if (addr == common.Address{}) {
- err = fmt.Errorf("HashReg address not found and sender for creation not given")
- return
- }
-
- txhash, err = self.backend.Transact(addr.Hex(), "", "", "", "", "", HashRegCode)
- if err != nil {
- err = fmt.Errorf("HashReg address not found and sender for creation failed: %v", err)
- }
- glog.V(logger.Detail).Infof("created HashRegAddr @ txhash %v\n", txhash)
- } else {
- glog.V(logger.Detail).Infof("HashRegAddr found at @ %v\n", HashRegAddr)
- return
- }
- }
-
- return
-}
-
-func (self *Registrar) SetUrlHint(urlhint string, addr common.Address) (txhash string, err error) {
- if urlhint != "" {
- UrlHintAddr = urlhint
- } else {
- if !zero.MatchString(UrlHintAddr) {
- return
- }
- nameHex, extra := encodeName(UrlHintName, 2)
- urlHintAbi := resolveAbi + nameHex + extra
- glog.V(logger.Detail).Infof("UrlHint address query data: %s to %s", urlHintAbi, GlobalRegistrarAddr)
- var res string
- res, _, err = self.backend.Call("", GlobalRegistrarAddr, "", "", "", urlHintAbi)
- if len(res) >= 40 {
- UrlHintAddr = "0x" + res[len(res)-40:len(res)]
- }
- if err != nil || zero.MatchString(UrlHintAddr) {
- if (addr == common.Address{}) {
- err = fmt.Errorf("UrlHint address not found and sender for creation not given")
- return
- }
- txhash, err = self.backend.Transact(addr.Hex(), "", "", "", "210000", "", UrlHintCode)
- if err != nil {
- err = fmt.Errorf("UrlHint address not found and sender for creation failed: %v", err)
- }
- glog.V(logger.Detail).Infof("created UrlHint @ txhash %v\n", txhash)
- } else {
- glog.V(logger.Detail).Infof("UrlHint found @ %v\n", HashRegAddr)
- return
- }
- }
-
- return
-}
-
-// ReserveName(from, name) reserves name for the sender address in the globalRegistrar
-// the tx needs to be mined to take effect
-func (self *Registrar) ReserveName(address common.Address, name string) (txh string, err error) {
- if zero.MatchString(GlobalRegistrarAddr) {
- return "", fmt.Errorf("GlobalRegistrar address is not set")
- }
- nameHex, extra := encodeName(name, 2)
- abi := reserveAbi + nameHex + extra
- glog.V(logger.Detail).Infof("Reserve data: %s", abi)
- return self.backend.Transact(
- address.Hex(),
- GlobalRegistrarAddr,
- "", "", "", "",
- abi,
- )
-}
-
-// SetAddressToName(from, name, addr) will set the Address to address for name
-// in the globalRegistrar using from as the sender of the transaction
-// the tx needs to be mined to take effect
-func (self *Registrar) SetAddressToName(from common.Address, name string, address common.Address) (txh string, err error) {
- if zero.MatchString(GlobalRegistrarAddr) {
- return "", fmt.Errorf("GlobalRegistrar address is not set")
- }
-
- nameHex, extra := encodeName(name, 6)
- addrHex := encodeAddress(address)
-
- abi := registerAbi + nameHex + addrHex + trueHex + extra
- glog.V(logger.Detail).Infof("SetAddressToName data: %s to %s ", abi, GlobalRegistrarAddr)
-
- return self.backend.Transact(
- from.Hex(),
- GlobalRegistrarAddr,
- "", "", "", "",
- abi,
- )
-}
-
-// NameToAddr(from, name) queries the registrar for the address on name
-func (self *Registrar) NameToAddr(from common.Address, name string) (address common.Address, err error) {
- if zero.MatchString(GlobalRegistrarAddr) {
- return address, fmt.Errorf("GlobalRegistrar address is not set")
- }
-
- nameHex, extra := encodeName(name, 2)
- abi := resolveAbi + nameHex + extra
- glog.V(logger.Detail).Infof("NameToAddr data: %s", abi)
- res, _, err := self.backend.Call(
- from.Hex(),
- GlobalRegistrarAddr,
- "", "", "",
- abi,
- )
- if err != nil {
- return
- }
- address = common.HexToAddress(res)
- return
-}
-
-// called as first step in the registration process on HashReg
-func (self *Registrar) SetOwner(address common.Address) (txh string, err error) {
- if zero.MatchString(HashRegAddr) {
- return "", fmt.Errorf("HashReg address is not set")
- }
- return self.backend.Transact(
- address.Hex(),
- HashRegAddr,
- "", "", "", "",
- setOwnerAbi,
- )
-}
-
-// registers some content hash to a key/code hash
-// e.g., the contract Info combined Json Doc's ContentHash
-// to CodeHash of a contract or hash of a domain
-func (self *Registrar) SetHashToHash(address common.Address, codehash, dochash common.Hash) (txh string, err error) {
- if zero.MatchString(HashRegAddr) {
- return "", fmt.Errorf("HashReg address is not set")
- }
-
- _, err = self.SetOwner(address)
- if err != nil {
- return
- }
- codehex := common.Bytes2Hex(codehash[:])
- dochex := common.Bytes2Hex(dochash[:])
-
- data := registerContentHashAbi + codehex + dochex
- glog.V(logger.Detail).Infof("SetHashToHash data: %s sent to %v\n", data, HashRegAddr)
- return self.backend.Transact(
- address.Hex(),
- HashRegAddr,
- "", "", "", "",
- data,
- )
-}
-
-// SetUrlToHash(from, hash, url) registers a url to a content hash so that the content can be fetched
-// address is used as sender for the transaction and will be the owner of a new
-// registry entry on first time use
-// FIXME: silently doing nothing if sender is not the owner
-// note that with content addressed storage, this step is no longer necessary
-func (self *Registrar) SetUrlToHash(address common.Address, hash common.Hash, url string) (txh string, err error) {
- if zero.MatchString(UrlHintAddr) {
- return "", fmt.Errorf("UrlHint address is not set")
- }
-
- hashHex := common.Bytes2Hex(hash[:])
- var urlHex string
- urlb := []byte(url)
- var cnt byte
- n := len(urlb)
-
- for n > 0 {
- if n > 32 {
- n = 32
- }
- urlHex = common.Bytes2Hex(urlb[:n])
- urlb = urlb[n:]
- n = len(urlb)
- bcnt := make([]byte, 32)
- bcnt[31] = cnt
- data := registerUrlAbi +
- hashHex +
- common.Bytes2Hex(bcnt) +
- common.Bytes2Hex(common.Hex2BytesFixed(urlHex, 32))
- txh, err = self.backend.Transact(
- address.Hex(),
- UrlHintAddr,
- "", "", "", "",
- data,
- )
- if err != nil {
- return
- }
- cnt++
- }
- return
-}
-
-// HashToHash(key) resolves contenthash for key (a hash) using HashReg
-// resolution is costless non-transactional
-// implemented as direct retrieval from db
-func (self *Registrar) HashToHash(khash common.Hash) (chash common.Hash, err error) {
- if zero.MatchString(HashRegAddr) {
- return common.Hash{}, fmt.Errorf("HashReg address is not set")
- }
-
- // look up in hashReg
- at := HashRegAddr[2:]
- key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:]))
- hash := self.backend.StorageAt(at, key)
-
- if hash == "0x0" || len(hash) < 3 || (hash == common.Hash{}.Hex()) {
- err = fmt.Errorf("HashToHash: content hash not found for '%v'", khash.Hex())
- return
- }
- copy(chash[:], common.Hex2BytesFixed(hash[2:], 32))
- return
-}
-
-// HashToUrl(contenthash) resolves the url for contenthash using UrlHint
-// resolution is costless non-transactional
-// implemented as direct retrieval from db
-// if we use content addressed storage, this step is no longer necessary
-func (self *Registrar) HashToUrl(chash common.Hash) (uri string, err error) {
- if zero.MatchString(UrlHintAddr) {
- return "", fmt.Errorf("UrlHint address is not set")
- }
- // look up in URL reg
- var str string = " "
- var idx uint32
- for len(str) > 0 {
- mapaddr := storageMapping(storageIdx2Addr(1), chash[:])
- key := storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(idx)))
- hex := self.backend.StorageAt(UrlHintAddr[2:], key)
- str = string(common.Hex2Bytes(hex[2:]))
- l := 0
- for (l < len(str)) && (str[l] == 0) {
- l++
- }
-
- str = str[l:]
- uri = uri + str
- idx++
- }
-
- if len(uri) == 0 {
- err = fmt.Errorf("HashToUrl: URL hint not found for '%v'", chash.Hex())
- }
- return
-}
-
-func storageIdx2Addr(varidx uint32) []byte {
- data := make([]byte, 32)
- binary.BigEndian.PutUint32(data[28:32], varidx)
- return data
-}
-
-func storageMapping(addr, key []byte) []byte {
- data := make([]byte, 64)
- copy(data[0:32], key[0:32])
- copy(data[32:64], addr[0:32])
- sha := crypto.Keccak256(data)
- return sha
-}
-
-func storageFixedArray(addr, idx []byte) []byte {
- var carry byte
- for i := 31; i >= 0; i-- {
- var b byte = addr[i] + idx[i] + carry
- if b < addr[i] {
- carry = 1
- } else {
- carry = 0
- }
- addr[i] = b
- }
- return addr
-}
-
-func storageAddress(addr []byte) string {
- return common.ToHex(addr)
-}
-
-func encodeAddress(address common.Address) string {
- return addressAbiPrefix + address.Hex()[2:]
-}
-
-func encodeName(name string, index uint8) (string, string) {
- extra := common.Bytes2Hex([]byte(name))
- if len(name) > 32 {
- return fmt.Sprintf("%064x", index), extra
- }
- return extra + falseHex[len(extra):], ""
-}