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
b2b9b3b567
commit
3aac38f60f
8 changed files with 200 additions and 43 deletions
|
|
@ -781,22 +781,22 @@ func (js *jsre) newRegistry(call otto.FunctionCall) otto.Value {
|
|||
|
||||
if len(call.ArgumentList) != 1 {
|
||||
fmt.Println("requires 1 argument: admin.contractInfo.newRegistry(adminaddress)")
|
||||
return otto.FalseValue()
|
||||
return otto.UndefinedValue()
|
||||
}
|
||||
addr, err := call.Argument(0).ToString()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return otto.FalseValue()
|
||||
return otto.UndefinedValue()
|
||||
}
|
||||
|
||||
var hashReg, urlHint string
|
||||
registry := resolver.New(js.xeth)
|
||||
err = registry.CreateContracts(common.HexToAddress(addr))
|
||||
hashReg, urlHint, err = registry.CreateContracts(common.HexToAddress(addr))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return otto.FalseValue()
|
||||
return otto.UndefinedValue()
|
||||
}
|
||||
|
||||
return otto.TrueValue()
|
||||
return js.re.ToVal([]string{hashReg, urlHint})
|
||||
}
|
||||
|
||||
// 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"
|
||||
)
|
||||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/docserver"
|
||||
"github.com/ethereum/go-ethereum/common/natspec"
|
||||
"github.com/ethereum/go-ethereum/common/resolver"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
re "github.com/ethereum/go-ethereum/jsre"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
|
@ -141,7 +142,7 @@ var net = web3.net;
|
|||
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("/")
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ func TestContract(t *testing.T) {
|
|||
checkEvalJSON(
|
||||
t, repl,
|
||||
`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"}]');
|
||||
|
|
@ -331,7 +331,7 @@ multiply7 = Multiply7.at(contractaddress);
|
|||
|
||||
checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`)
|
||||
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 {
|
||||
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))
|
||||
|
||||
// use resolver to register codehash->dochash->url
|
||||
// test if globalregistry works
|
||||
// resolver.HashRefContractAddress = "0x0"
|
||||
// resolver.UrlHintContractAddress = "0x0"
|
||||
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 {
|
||||
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
|
||||
var UrlHintContractAddress, HashRegContractAddress string
|
||||
var (
|
||||
UrlHintContractAddress = "0x0"
|
||||
HashRegContractAddress = "0x0"
|
||||
)
|
||||
|
||||
const (
|
||||
txValue = "0"
|
||||
|
|
@ -28,42 +31,167 @@ const (
|
|||
txGasPrice = "1000000000000"
|
||||
)
|
||||
|
||||
func abi(s string) string {
|
||||
func abiSignature(s string) string {
|
||||
return common.ToHex(crypto.Sha3([]byte(s))[:4])
|
||||
}
|
||||
|
||||
var (
|
||||
registerContentHashAbi = abi("register(uint256,uint256)")
|
||||
registerUrlAbi = abi("register(uint256,uint8,uint256)")
|
||||
setOwnerAbi = abi("setowner()")
|
||||
HashReg = "HashReg"
|
||||
UrlHint = "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 = string(make([]byte, 24))
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
type Resolver struct {
|
||||
backend Backend
|
||||
}
|
||||
|
||||
func New(eth Backend) *Resolver {
|
||||
return &Resolver{eth}
|
||||
func New(eth Backend) (res *Resolver) {
|
||||
res = &Resolver{eth}
|
||||
res.setContracts()
|
||||
return
|
||||
}
|
||||
|
||||
// for testing and play temporarily
|
||||
// ideally the HashReg and UrlHint contracts should be in the genesis block
|
||||
// if we got build-in support for natspec/contract info
|
||||
// there should be only one of these officially endorsed
|
||||
// addresses as constants
|
||||
// TODO: could get around this with namereg, check
|
||||
func (self *Resolver) CreateContracts(addr common.Address) (err error) {
|
||||
HashRegContractAddress, err = self.backend.Transact(addr.Hex(), "", "", txValue, txGas, txGasPrice, ContractCodeHashReg)
|
||||
func (self *Resolver) setContracts() {
|
||||
var err error
|
||||
if HashRegContractAddress != "0x0" {
|
||||
return
|
||||
}
|
||||
// reset iff error anywhere
|
||||
defer func() {
|
||||
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 {
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +266,7 @@ func (self *Resolver) RegisterUrl(address common.Address, hash common.Hash, url
|
|||
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)
|
||||
if err != nil {
|
||||
|
|
@ -151,7 +279,7 @@ func (self *Resolver) Register(address common.Address, codehash, dochash common.
|
|||
// implemented as direct retrieval from db
|
||||
func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, err error) {
|
||||
// look up in hashReg
|
||||
at := common.Bytes2Hex(common.FromHex(HashRegContractAddress))
|
||||
at := HashRegContractAddress[2:]
|
||||
key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:]))
|
||||
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 {
|
||||
mapaddr := storageMapping(storageIdx2Addr(1), chash[:])
|
||||
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:]))
|
||||
l := len(str)
|
||||
for (l > 0) && (str[l-1] == 0) {
|
||||
|
|
@ -230,3 +358,18 @@ func storageFixedArray(addr, idx []byte) []byte {
|
|||
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) (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 {
|
||||
HashRegContractAddress = common.BigToAddress(common.Big0).Hex()[2:]
|
||||
UrlHintContractAddress = common.BigToAddress(common.Big1).Hex()[2:]
|
||||
HashRegContractAddress = common.BigToAddress(common.Big0).Hex() //[2:]
|
||||
UrlHintContractAddress = common.BigToAddress(common.Big1).Hex() //[2:]
|
||||
self := &testBackend{}
|
||||
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[:]))
|
||||
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[:])
|
||||
|
||||
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)))
|
||||
self.contracts[UrlHintContractAddress][key] = "0x00"
|
||||
self.contracts[UrlHintContractAddress[2:]][key] = "0x0"
|
||||
return self
|
||||
}
|
||||
|
||||
|
|
@ -52,6 +52,20 @@ func (self *testBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, ga
|
|||
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) {
|
||||
b := NewTestBackend()
|
||||
res := New(b)
|
||||
|
|
@ -71,7 +85,7 @@ func TestContentHashToUrl(t *testing.T) {
|
|||
res := New(b)
|
||||
got, err := res.ContentHashToUrl(hash)
|
||||
if err != nil {
|
||||
t.Errorf("expected no error, got %v", err)
|
||||
t.Errorf("expected error, got %v", err)
|
||||
} else {
|
||||
if got != url {
|
||||
t.Errorf("incorrect result, expected '%v', got '%s'", url, got)
|
||||
|
|
|
|||
Loading…
Reference in a new issue