mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
Resolver: registries use global registrar
* global registrar now in resolver, console jsre refers to resolver.abi/addr, geth/contracts.go removed * add Call to resolver backend interface * global registrar name registry interface in resolver * the hashReg and UrlHing contracts now initialised from global registry * if not registered one can call the CreateContracts which creates them, reserved and registers them * tests * newRegistry returns the contract addresses for HashReg and UrlHint
This commit is contained in:
parent
27e0d2a973
commit
9e538ed6f7
8 changed files with 201 additions and 43 deletions
|
|
@ -815,22 +815,23 @@ func (js *jsre) newRegistry(call otto.FunctionCall) otto.Value {
|
||||||
|
|
||||||
if len(call.ArgumentList) != 1 {
|
if len(call.ArgumentList) != 1 {
|
||||||
fmt.Println("requires 1 argument: admin.contractInfo.newRegistry(adminaddress)")
|
fmt.Println("requires 1 argument: admin.contractInfo.newRegistry(adminaddress)")
|
||||||
return otto.FalseValue()
|
return otto.UndefinedValue()
|
||||||
}
|
}
|
||||||
addr, err := call.Argument(0).ToString()
|
addr, err := call.Argument(0).ToString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return otto.FalseValue()
|
return otto.UndefinedValue()
|
||||||
}
|
}
|
||||||
|
var hashReg, urlHint string
|
||||||
registry := resolver.New(js.xeth)
|
registry := resolver.New(js.xeth)
|
||||||
err = registry.CreateContracts(common.HexToAddress(addr))
|
hashReg, urlHint, err = registry.CreateContracts(common.HexToAddress(addr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return otto.FalseValue()
|
return otto.UndefinedValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
return otto.TrueValue()
|
v, _ := call.Otto.ToValue([]string{hashReg, urlHint})
|
||||||
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal transaction type which will allow us to resend transactions using `eth.resend`
|
// internal transaction type which will allow us to resend transactions using `eth.resend`
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
var (
|
|
||||||
globalRegistrar = `var GlobalRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]);`
|
|
||||||
globalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
|
||||||
)
|
|
||||||
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/docserver"
|
"github.com/ethereum/go-ethereum/common/docserver"
|
||||||
"github.com/ethereum/go-ethereum/common/natspec"
|
"github.com/ethereum/go-ethereum/common/natspec"
|
||||||
|
"github.com/ethereum/go-ethereum/common/resolver"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
re "github.com/ethereum/go-ethereum/jsre"
|
re "github.com/ethereum/go-ethereum/jsre"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
@ -143,7 +144,7 @@ var net = web3.net;
|
||||||
utils.Fatalf("Error setting namespaces: %v", err)
|
utils.Fatalf("Error setting namespaces: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");")
|
js.re.Eval(resolver.GlobalRegistrar + "registrar = GlobalRegistrar.at(\"" + resolver.GlobalRegistrarAddr + "\");")
|
||||||
}
|
}
|
||||||
|
|
||||||
var ds, _ = docserver.New("/")
|
var ds, _ = docserver.New("/")
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ func TestContract(t *testing.T) {
|
||||||
checkEvalJSON(
|
checkEvalJSON(
|
||||||
t, repl,
|
t, repl,
|
||||||
`contractaddress = eth.sendTransaction({from: primary, data: contract.code })`,
|
`contractaddress = eth.sendTransaction({from: primary, data: contract.code })`,
|
||||||
`"0x5dcaace5982778b409c524873b319667eba5d074"`,
|
`"0x291293d57e0a0ab47effe97c02577f90d9211567"`,
|
||||||
)
|
)
|
||||||
|
|
||||||
callSetup := `abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]');
|
callSetup := `abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]');
|
||||||
|
|
@ -333,7 +333,7 @@ multiply7 = Multiply7.at(contractaddress);
|
||||||
|
|
||||||
checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`)
|
checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`)
|
||||||
checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary, gas: "1000000", gasPrice: "100000" })`, `undefined`)
|
checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary, gas: "1000000", gasPrice: "100000" })`, `undefined`)
|
||||||
expNotice = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x87e2802265838c7f14bb69eecd2112911af6767907a702eeaa445239fb20711b'): {"params":[{"to":"0x5dcaace5982778b409c524873b319667eba5d074","data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}]}`
|
expNotice = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x87e2802265838c7f14bb69eecd2112911af6767907a702eeaa445239fb20711b'): {"params":[{"to":"0x291293d57e0a0ab47effe97c02577f90d9211567","data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}]}`
|
||||||
if repl.lastConfirm != expNotice {
|
if repl.lastConfirm != expNotice {
|
||||||
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm)
|
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -197,8 +197,11 @@ func TestNatspecE2E(t *testing.T) {
|
||||||
codehash := common.BytesToHash(crypto.Sha3(codeb))
|
codehash := common.BytesToHash(crypto.Sha3(codeb))
|
||||||
|
|
||||||
// use resolver to register codehash->dochash->url
|
// use resolver to register codehash->dochash->url
|
||||||
|
// test if globalregistry works
|
||||||
|
// resolver.HashRefContractAddress = "0x0"
|
||||||
|
// resolver.UrlHintContractAddress = "0x0"
|
||||||
registry := resolver.New(tf.xeth)
|
registry := resolver.New(tf.xeth)
|
||||||
_, err := registry.Register(tf.coinbase, codehash, dochash, "file:///"+testFileName)
|
_, err := registry.RegisterAddrWithUrl(tf.coinbase, codehash, dochash, "file:///"+testFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error registering: %v", err)
|
t.Errorf("error registering: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,4 +33,6 @@ const ( // built-in contracts address and code
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
GlobalRegistrar = `var GlobalRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]);`
|
||||||
|
GlobalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@ of a url scheme
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// // contract addresses will be hardcoded after they're created
|
// // contract addresses will be hardcoded after they're created
|
||||||
var UrlHintContractAddress, HashRegContractAddress string
|
var (
|
||||||
|
UrlHintContractAddress = "0x0"
|
||||||
|
HashRegContractAddress = "0x0"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
txValue = "0"
|
txValue = "0"
|
||||||
|
|
@ -28,42 +31,167 @@ const (
|
||||||
txGasPrice = "1000000000000"
|
txGasPrice = "1000000000000"
|
||||||
)
|
)
|
||||||
|
|
||||||
func abi(s string) string {
|
func abiSignature(s string) string {
|
||||||
return common.ToHex(crypto.Sha3([]byte(s))[:4])
|
return common.ToHex(crypto.Sha3([]byte(s))[:4])
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
registerContentHashAbi = abi("register(uint256,uint256)")
|
HashReg = "HashReg"
|
||||||
registerUrlAbi = abi("register(uint256,uint8,uint256)")
|
UrlHint = "UrlHint"
|
||||||
setOwnerAbi = abi("setowner()")
|
|
||||||
|
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 = string(make([]byte, 24))
|
||||||
)
|
)
|
||||||
|
|
||||||
type Backend interface {
|
type Backend interface {
|
||||||
StorageAt(string, string) string
|
StorageAt(string, string) string
|
||||||
Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error)
|
Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error)
|
||||||
|
Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resolver struct {
|
type Resolver struct {
|
||||||
backend Backend
|
backend Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(eth Backend) *Resolver {
|
func New(eth Backend) (res *Resolver) {
|
||||||
return &Resolver{eth}
|
res = &Resolver{eth}
|
||||||
|
res.setContracts()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// for testing and play temporarily
|
func (self *Resolver) setContracts() {
|
||||||
// ideally the HashReg and UrlHint contracts should be in the genesis block
|
var err error
|
||||||
// if we got build-in support for natspec/contract info
|
if HashRegContractAddress != "0x0" {
|
||||||
// there should be only one of these officially endorsed
|
return
|
||||||
// addresses as constants
|
}
|
||||||
// TODO: could get around this with namereg, check
|
// reset iff error anywhere
|
||||||
func (self *Resolver) CreateContracts(addr common.Address) (err error) {
|
defer func() {
|
||||||
HashRegContractAddress, err = self.backend.Transact(addr.Hex(), "", "", txValue, txGas, txGasPrice, ContractCodeHashReg)
|
if err != nil {
|
||||||
|
HashRegContractAddress = "0x0"
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
hashRegAbi := registerAbi + string(common.Hex2BytesFixed(HashRegContractAddress[2:], 32))
|
||||||
|
HashRegContractAddress, _, err = self.backend.Call("", GlobalRegistrarAddr, "", "", "", hashRegAbi)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("HashReg address not found: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if UrlHintContractAddress != "0x0" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// reset iff error anywhere
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
UrlHintContractAddress = "0x0"
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
urlHintAbi := registerAbi + string(common.Hex2BytesFixed(UrlHintContractAddress[2:], 32))
|
||||||
|
UrlHintContractAddress, _, err = self.backend.Call("", GlobalRegistrarAddr, "", "", "", urlHintAbi)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("UrlHint address not found: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
glog.V(logger.Detail).Infof("HashReg @ %v\nUrlHint @ %v\n", HashRegContractAddress, UrlHintContractAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This can be safely called from tests to or private chains to create
|
||||||
|
// new HashReg and UrlHint contracts (requires transaction)
|
||||||
|
// It does nothing if addresses are set
|
||||||
|
func (self *Resolver) CreateContracts(addr common.Address) (hashReg, urlHint string, err error) {
|
||||||
|
if HashRegContractAddress != "0x0" {
|
||||||
|
err = fmt.Errorf("HashReg already exists at %v", HashRegContractAddress)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hashReg, err = self.backend.Transact(addr.Hex(), "", "", txValue, txGas, txGasPrice, ContractCodeHashReg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
UrlHintContractAddress, err = self.backend.Transact(addr.Hex(), "", "", txValue, txGas, txGasPrice, ContractCodeURLhint)
|
_, err = self.Reserve(addr, HashReg)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = self.RegisterAddress(addr, HashReg, common.HexToAddress(hashReg))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if UrlHintContractAddress != "0x0" {
|
||||||
|
err = fmt.Errorf("UrlHint already exists at %v", UrlHintContractAddress)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
urlHint, err = self.backend.Transact(addr.Hex(), "", "", txValue, txGas, txGasPrice, ContractCodeURLhint)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = self.Reserve(addr, UrlHint)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = self.RegisterAddress(addr, UrlHint, common.HexToAddress(urlHint))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
HashRegContractAddress = hashReg
|
||||||
|
UrlHintContractAddress = urlHint
|
||||||
glog.V(logger.Detail).Infof("HashReg @ %v\nUrlHint @ %v\n", HashRegContractAddress, UrlHintContractAddress)
|
glog.V(logger.Detail).Infof("HashReg @ %v\nUrlHint @ %v\n", HashRegContractAddress, UrlHintContractAddress)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserve(from, name) reserves name for the sender address in the globalRegistrar
|
||||||
|
// the tx needs to be mined to take effect
|
||||||
|
func (self *Resolver) Reserve(address common.Address, name string) (txh string, err error) {
|
||||||
|
nameHex, extra := encodeName(name, 6)
|
||||||
|
abi := reserveAbi + nameHex + extra
|
||||||
|
return self.backend.Transact(
|
||||||
|
address.Hex(),
|
||||||
|
GlobalRegistrarAddr,
|
||||||
|
"", txValue, txGas, txGasPrice,
|
||||||
|
abi,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterAddress(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 *Resolver) RegisterAddress(from common.Address, name string, address common.Address) (txh string, err error) {
|
||||||
|
nameHex, extra := encodeName(name, 6)
|
||||||
|
addrHex := encodeAddress(address)
|
||||||
|
|
||||||
|
trueHex := make([]byte, 64)
|
||||||
|
trueHex[63] = 1
|
||||||
|
|
||||||
|
abi := registerAbi + nameHex + addrHex + extra
|
||||||
|
return self.backend.Transact(
|
||||||
|
from.Hex(),
|
||||||
|
GlobalRegistrarAddr,
|
||||||
|
"", txValue, txGas, txGasPrice,
|
||||||
|
abi,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameToAddr(from, name) queries the registrar for the address on
|
||||||
|
func (self *Resolver) NameToAddr(from common.Address, name string) (address common.Address, err error) {
|
||||||
|
nameHex, extra := encodeName(name, 2)
|
||||||
|
abi := resolveAbi + nameHex + extra
|
||||||
|
res, _, err := self.backend.Call(
|
||||||
|
from.Hex(),
|
||||||
|
GlobalRegistrarAddr,
|
||||||
|
txValue, txGas, txGasPrice,
|
||||||
|
abi,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
address = common.HexToAddress(res)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,7 +266,7 @@ func (self *Resolver) RegisterUrl(address common.Address, hash common.Hash, url
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Resolver) Register(address common.Address, codehash, dochash common.Hash, url string) (txh string, err error) {
|
func (self *Resolver) RegisterAddrWithUrl(address common.Address, codehash, dochash common.Hash, url string) (txh string, err error) {
|
||||||
|
|
||||||
_, err = self.RegisterContentHash(address, codehash, dochash)
|
_, err = self.RegisterContentHash(address, codehash, dochash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -151,7 +279,7 @@ func (self *Resolver) Register(address common.Address, codehash, dochash common.
|
||||||
// implemented as direct retrieval from db
|
// implemented as direct retrieval from db
|
||||||
func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, err error) {
|
func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, err error) {
|
||||||
// look up in hashReg
|
// look up in hashReg
|
||||||
at := common.Bytes2Hex(common.FromHex(HashRegContractAddress))
|
at := HashRegContractAddress[2:]
|
||||||
key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:]))
|
key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:]))
|
||||||
hash := self.backend.StorageAt(at, key)
|
hash := self.backend.StorageAt(at, key)
|
||||||
|
|
||||||
|
|
@ -172,7 +300,7 @@ func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error
|
||||||
for len(str) > 0 {
|
for len(str) > 0 {
|
||||||
mapaddr := storageMapping(storageIdx2Addr(1), chash[:])
|
mapaddr := storageMapping(storageIdx2Addr(1), chash[:])
|
||||||
key := storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(idx)))
|
key := storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(idx)))
|
||||||
hex := self.backend.StorageAt(UrlHintContractAddress, key)
|
hex := self.backend.StorageAt(UrlHintContractAddress[2:], key)
|
||||||
str = string(common.Hex2Bytes(hex[2:]))
|
str = string(common.Hex2Bytes(hex[2:]))
|
||||||
l := len(str)
|
l := len(str)
|
||||||
for (l > 0) && (str[l-1] == 0) {
|
for (l > 0) && (str[l-1] == 0) {
|
||||||
|
|
@ -230,3 +358,18 @@ func storageFixedArray(addr, idx []byte) []byte {
|
||||||
func storageAddress(addr []byte) string {
|
func storageAddress(addr []byte) string {
|
||||||
return common.ToHex(addr)
|
return common.ToHex(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeAddress(address common.Address) string {
|
||||||
|
return addressAbiPrefix + address.Hex()[2:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeName(name string, index uint8) (nameHex, extra string) {
|
||||||
|
nameHexBytes := make([]byte, 64)
|
||||||
|
if len(name) > 32 {
|
||||||
|
nameHexBytes[63] = byte(index)
|
||||||
|
extra = common.Bytes2Hex([]byte(name))
|
||||||
|
} else {
|
||||||
|
copy(nameHexBytes, []byte(name))
|
||||||
|
}
|
||||||
|
return string(nameHexBytes), extra
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,22 +20,22 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTestBackend() *testBackend {
|
func NewTestBackend() *testBackend {
|
||||||
HashRegContractAddress = common.BigToAddress(common.Big0).Hex()[2:]
|
HashRegContractAddress = common.BigToAddress(common.Big0).Hex() //[2:]
|
||||||
UrlHintContractAddress = common.BigToAddress(common.Big1).Hex()[2:]
|
UrlHintContractAddress = common.BigToAddress(common.Big1).Hex() //[2:]
|
||||||
self := &testBackend{}
|
self := &testBackend{}
|
||||||
self.contracts = make(map[string](map[string]string))
|
self.contracts = make(map[string](map[string]string))
|
||||||
|
|
||||||
self.contracts[HashRegContractAddress] = make(map[string]string)
|
self.contracts[HashRegContractAddress[2:]] = make(map[string]string)
|
||||||
key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:]))
|
key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:]))
|
||||||
self.contracts[HashRegContractAddress][key] = hash.Hex()
|
self.contracts[HashRegContractAddress[2:]][key] = hash.Hex()
|
||||||
|
|
||||||
self.contracts[UrlHintContractAddress] = make(map[string]string)
|
self.contracts[UrlHintContractAddress[2:]] = make(map[string]string)
|
||||||
mapaddr := storageMapping(storageIdx2Addr(1), hash[:])
|
mapaddr := storageMapping(storageIdx2Addr(1), hash[:])
|
||||||
|
|
||||||
key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0)))
|
key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0)))
|
||||||
self.contracts[UrlHintContractAddress][key] = common.ToHex([]byte(url))
|
self.contracts[UrlHintContractAddress[2:]][key] = common.ToHex([]byte(url))
|
||||||
key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1)))
|
key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1)))
|
||||||
self.contracts[UrlHintContractAddress][key] = "0x00"
|
self.contracts[UrlHintContractAddress[2:]][key] = "0x0"
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,6 +52,20 @@ func (self *testBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, ga
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *testBackend) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, string, error) {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateContractsExists(t *testing.T) {
|
||||||
|
b := NewTestBackend()
|
||||||
|
res := New(b)
|
||||||
|
_, _, err := res.CreateContracts(common.BigToAddress(common.Big0))
|
||||||
|
exp := "HashReg already exists at 0x0000000000000000000000000000000000000000"
|
||||||
|
if err == nil || err.Error() != exp {
|
||||||
|
t.Errorf("expected error '%s', got '%v'", exp, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestKeyToContentHash(t *testing.T) {
|
func TestKeyToContentHash(t *testing.T) {
|
||||||
b := NewTestBackend()
|
b := NewTestBackend()
|
||||||
res := New(b)
|
res := New(b)
|
||||||
|
|
@ -71,7 +85,7 @@ func TestContentHashToUrl(t *testing.T) {
|
||||||
res := New(b)
|
res := New(b)
|
||||||
got, err := res.ContentHashToUrl(hash)
|
got, err := res.ContentHashToUrl(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected no error, got %v", err)
|
t.Errorf("expected error, got %v", err)
|
||||||
} else {
|
} else {
|
||||||
if got != url {
|
if got != url {
|
||||||
t.Errorf("incorrect result, expected '%v', got '%s'", url, got)
|
t.Errorf("incorrect result, expected '%v', got '%s'", url, got)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue