From 97a602864a485bb3a79f460077052bd76cdbff99 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 31 Mar 2015 01:57:17 +0100 Subject: add common/resolver skeleton --- common/resolver/resolver.go | 45 ++++++++++++++++++++++++++++++++++++++++ common/resolver/resolver_test.go | 17 +++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 common/resolver/resolver.go create mode 100644 common/resolver/resolver_test.go (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go new file mode 100644 index 000000000..aa54a689b --- /dev/null +++ b/common/resolver/resolver.go @@ -0,0 +1,45 @@ +package resolver + +import ( + "fmt" + "net/url" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/xeth" +) + +/* +Resolver implements the Ethereum DNS mapping +NameReg : Domain Name (or Code hash of Contract) -> Content Hash +UrlHint : Content Hash -> Url Hint +*/ +const ( + urlHintContractAddress = "urlhint" + nameRegContractAddress = "nameReg" +) + +type Resolver struct { + xeth *xeth.XEth +} + +func (self *Resolver) NameToContentHash(name string) (hash common.Hash, err error) { + // look up in nameReg + copy(hash[:], []byte(name)[:32]) + return +} + +func (self *Resolver) ContentHashToUrl(hash common.Hash) (uri *url.URL, err error) { + // look up in nameReg + rawurl := fmt.Sprintf("bzz://%x/my/path/mycontract.sud", hash[:]) + // mime type? + return url.Parse(rawurl) +} + +func (self *Resolver) NameToUrl(name string) (uri *url.URL, err error) { + // look up in urlHint + hash, err := self.NameToContentHash(name) + if err != nil { + return + } + return self.ContentHashToUrl(hash) +} diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go new file mode 100644 index 000000000..ce0116664 --- /dev/null +++ b/common/resolver/resolver_test.go @@ -0,0 +1,17 @@ +package resolver + +import ( + "testing" +) + +func TestNameToContentHash(t *testing.T) { + +} + +func TestContentHashToUrl(t *testing.T) { + +} + +func TestNameToUrl(t *testing.T) { + +} -- cgit v1.2.3 From 3a540425a3d7fc29233b5cd3e7b79b4866f35d57 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 31 Mar 2015 16:02:55 +0100 Subject: reorg: - statereg methods move to natspec/resolver/docserver - fix failing test on invalid js input --- common/resolver/resolver.go | 49 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index aa54a689b..f855aad73 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -1,10 +1,12 @@ package resolver import ( + "encoding/binary" "fmt" - "net/url" + // "net/url" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/xeth" ) @@ -12,6 +14,9 @@ import ( Resolver implements the Ethereum DNS mapping NameReg : Domain Name (or Code hash of Contract) -> Content Hash UrlHint : Content Hash -> Url Hint + +The resolver is meant to be called by the roundtripper transport implementation +of a url scheme */ const ( urlHintContractAddress = "urlhint" @@ -19,27 +24,53 @@ const ( ) type Resolver struct { - xeth *xeth.XEth + xeth *xeth.XEth + urlHintContractAddress string + nameRegContractAddress string +} + +func New(_xeth *xeth.XEth, uhca, nrca string) *Resolver { + return &Resolver{_xeth, uhca, nrca} } func (self *Resolver) NameToContentHash(name string) (hash common.Hash, err error) { // look up in nameReg - copy(hash[:], []byte(name)[:32]) + hashbytes := self.xeth.StorageAt(self.nameRegContractAddress, storageAddress(0, common.Hex2Bytes(name))) + copy(hash[:], hashbytes[:32]) return } -func (self *Resolver) ContentHashToUrl(hash common.Hash) (uri *url.URL, err error) { +func (self *Resolver) ContentHashToUrl(hash common.Hash) (uri string, err error) { // look up in nameReg - rawurl := fmt.Sprintf("bzz://%x/my/path/mycontract.sud", hash[:]) + + urlHex := self.xeth.StorageAt(self.urlHintContractAddress, storageAddress(0, hash.Bytes())) + uri = string(common.Hex2Bytes(urlHex)) + l := len(uri) + for (l > 0) && (uri[l-1] == 0) { + l-- + } + uri = uri[:l] + if l == 0 { + err = fmt.Errorf("GetURLhint: URL hint not found") + } + // rawurl := fmt.Sprintf("bzz://%x/my/path/mycontract.s ud", hash[:]) // mime type? - return url.Parse(rawurl) + return } -func (self *Resolver) NameToUrl(name string) (uri *url.URL, err error) { +func (self *Resolver) NameToUrl(name string) (uri string, hash common.Hash, err error) { // look up in urlHint - hash, err := self.NameToContentHash(name) + hash, err = self.NameToContentHash(name) if err != nil { return } - return self.ContentHashToUrl(hash) + uri, err = self.ContentHashToUrl(hash) + return +} + +func storageAddress(varidx uint32, key []byte) string { + data := make([]byte, 64) + binary.BigEndian.PutUint32(data[28:32], varidx) + copy(data[32:64], key[0:32]) + return common.Bytes2Hex(crypto.Sha3(data)) } -- cgit v1.2.3 From ac0e5e8b6de43a40bbc25f541aa2399202bbe420 Mon Sep 17 00:00:00 2001 From: zelig Date: Wed, 1 Apr 2015 12:29:16 +0100 Subject: resolver tests - add resolver tests and fix resolver to pass - statereg constructor fixed - comments added to natspec plus docserver integration for natspec userdoc fetching --- common/resolver/resolver.go | 29 +++++++++--------- common/resolver/resolver_test.go | 64 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 17 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index f855aad73..ba592feb0 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -3,11 +3,9 @@ package resolver import ( "encoding/binary" "fmt" - // "net/url" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/xeth" ) /* @@ -24,37 +22,40 @@ const ( ) type Resolver struct { - xeth *xeth.XEth + backend Backend urlHintContractAddress string nameRegContractAddress string } -func New(_xeth *xeth.XEth, uhca, nrca string) *Resolver { - return &Resolver{_xeth, uhca, nrca} +type Backend interface { + StorageAt(string, string) string } -func (self *Resolver) NameToContentHash(name string) (hash common.Hash, err error) { +func New(eth Backend, uhca, nrca string) *Resolver { + return &Resolver{eth, uhca, nrca} +} + +func (self *Resolver) NameToContentHash(name string) (chash common.Hash, err error) { // look up in nameReg - hashbytes := self.xeth.StorageAt(self.nameRegContractAddress, storageAddress(0, common.Hex2Bytes(name))) - copy(hash[:], hashbytes[:32]) + key := storageAddress(0, common.Hex2Bytes(name)) + hash := self.backend.StorageAt(self.nameRegContractAddress, key) + copy(chash[:], common.Hex2Bytes(hash)) return } -func (self *Resolver) ContentHashToUrl(hash common.Hash) (uri string, err error) { +func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error) { // look up in nameReg - - urlHex := self.xeth.StorageAt(self.urlHintContractAddress, storageAddress(0, hash.Bytes())) - uri = string(common.Hex2Bytes(urlHex)) + key := storageAddress(0, chash[:]) + uri = self.backend.StorageAt(self.urlHintContractAddress, key) l := len(uri) for (l > 0) && (uri[l-1] == 0) { l-- } uri = uri[:l] + if l == 0 { err = fmt.Errorf("GetURLhint: URL hint not found") } - // rawurl := fmt.Sprintf("bzz://%x/my/path/mycontract.s ud", hash[:]) - // mime type? return } diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go index ce0116664..a5b6c3b4f 100644 --- a/common/resolver/resolver_test.go +++ b/common/resolver/resolver_test.go @@ -2,16 +2,74 @@ package resolver import ( "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" ) -func TestNameToContentHash(t *testing.T) { +type testBackend struct { + // contracts mock + contracts map[string](map[string]string) +} + +var ( + text = "test" + codehash = common.RightPadString("1234", 64) + hash = common.Bytes2Hex(crypto.Sha3([]byte(text))) + url = "bzz://bzzhash/my/path/contr.act" +) + +func NewTestBackend() *testBackend { + self := &testBackend{} + self.contracts = make(map[string](map[string]string)) + + self.contracts[nameRegContractAddress] = make(map[string]string) + key := storageAddress(0, common.Hex2Bytes(codehash)) + self.contracts[nameRegContractAddress][key] = hash + + self.contracts[urlHintContractAddress] = make(map[string]string) + key = storageAddress(0, common.Hex2Bytes(hash)) + self.contracts[urlHintContractAddress][key] = url + return self } -func TestContentHashToUrl(t *testing.T) { +func (self *testBackend) StorageAt(ca, sa string) (res string) { + c := self.contracts[ca] + if c == nil { + return + } + res = c[sa] + return +} +func TestNameToContentHash(t *testing.T) { + b := NewTestBackend() + res := New(b, urlHintContractAddress, nameRegContractAddress) + got, err := res.NameToContentHash(codehash) + if err != nil { + t.Errorf("expected no error, got %v", err) + } else { + if common.Bytes2Hex(got[:]) != hash { + t.Errorf("incorrect result, expected %x, got %x: ", hash, common.Bytes2Hex(got[:])) + } + } } -func TestNameToUrl(t *testing.T) { +func TestContentHashToUrl(t *testing.T) { + b := NewTestBackend() + res := New(b, urlHintContractAddress, nameRegContractAddress) + chash := common.Hash{} + copy(chash[:], common.Hex2Bytes(hash)) + got, err := res.ContentHashToUrl(chash) + if err != nil { + t.Errorf("expected no error, got %v", err) + } else { + if string(got[:]) != url { + t.Errorf("incorrect result, expected %v, got %s: ", url, string(got[:])) + } + } +} +func TestNameToUrl(t *testing.T) { } -- cgit v1.2.3 From e2d333d2095edb349388433c28f4d6a381b1df62 Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Fri, 3 Apr 2015 17:37:59 +0200 Subject: NatSpec contracts in genesis block, end to end test (unfinished) --- common/resolver/resolver.go | 11 ++++++----- common/resolver/resolver_test.go | 12 ++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index ba592feb0..1d80fdb42 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" ) @@ -17,8 +18,8 @@ The resolver is meant to be called by the roundtripper transport implementation of a url scheme */ const ( - urlHintContractAddress = "urlhint" - nameRegContractAddress = "nameReg" + URLHintContractAddress = core.ContractAddrURLhint + NameRegContractAddress = core.ContractAddrHashReg ) type Resolver struct { @@ -37,7 +38,7 @@ func New(eth Backend, uhca, nrca string) *Resolver { func (self *Resolver) NameToContentHash(name string) (chash common.Hash, err error) { // look up in nameReg - key := storageAddress(0, common.Hex2Bytes(name)) + key := storageAddress(1, common.Hex2BytesFixed(name, 32)) hash := self.backend.StorageAt(self.nameRegContractAddress, key) copy(chash[:], common.Hex2Bytes(hash)) return @@ -45,8 +46,8 @@ func (self *Resolver) NameToContentHash(name string) (chash common.Hash, err err func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error) { // look up in nameReg - key := storageAddress(0, chash[:]) - uri = self.backend.StorageAt(self.urlHintContractAddress, key) + key := storageAddress(2, chash[:]) + uri = string(common.Hex2Bytes(self.backend.StorageAt(self.urlHintContractAddress, key))) l := len(uri) for (l > 0) && (uri[l-1] == 0) { l-- diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go index a5b6c3b4f..5652213f6 100644 --- a/common/resolver/resolver_test.go +++ b/common/resolver/resolver_test.go @@ -23,13 +23,13 @@ func NewTestBackend() *testBackend { self := &testBackend{} self.contracts = make(map[string](map[string]string)) - self.contracts[nameRegContractAddress] = make(map[string]string) + self.contracts[NameRegContractAddress] = make(map[string]string) key := storageAddress(0, common.Hex2Bytes(codehash)) - self.contracts[nameRegContractAddress][key] = hash + self.contracts[NameRegContractAddress][key] = hash - self.contracts[urlHintContractAddress] = make(map[string]string) + self.contracts[URLHintContractAddress] = make(map[string]string) key = storageAddress(0, common.Hex2Bytes(hash)) - self.contracts[urlHintContractAddress][key] = url + self.contracts[URLHintContractAddress][key] = url return self } @@ -45,7 +45,7 @@ func (self *testBackend) StorageAt(ca, sa string) (res string) { func TestNameToContentHash(t *testing.T) { b := NewTestBackend() - res := New(b, urlHintContractAddress, nameRegContractAddress) + res := New(b, URLHintContractAddress, NameRegContractAddress) got, err := res.NameToContentHash(codehash) if err != nil { t.Errorf("expected no error, got %v", err) @@ -58,7 +58,7 @@ func TestNameToContentHash(t *testing.T) { func TestContentHashToUrl(t *testing.T) { b := NewTestBackend() - res := New(b, urlHintContractAddress, nameRegContractAddress) + res := New(b, URLHintContractAddress, NameRegContractAddress) chash := common.Hash{} copy(chash[:], common.Hex2Bytes(hash)) got, err := res.ContentHashToUrl(chash) -- cgit v1.2.3 From 94489b2269133c545aa3e9580737b2bd93f3ead0 Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Mon, 6 Apr 2015 08:01:36 +0200 Subject: s --- common/resolver/resolver.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index 1d80fdb42..060e9dbb5 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -39,7 +39,7 @@ func New(eth Backend, uhca, nrca string) *Resolver { func (self *Resolver) NameToContentHash(name string) (chash common.Hash, err error) { // look up in nameReg key := storageAddress(1, common.Hex2BytesFixed(name, 32)) - hash := self.backend.StorageAt(self.nameRegContractAddress, key) + hash := self.backend.StorageAt("0x"+self.nameRegContractAddress, key) copy(chash[:], common.Hex2Bytes(hash)) return } @@ -47,7 +47,8 @@ func (self *Resolver) NameToContentHash(name string) (chash common.Hash, err err func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error) { // look up in nameReg key := storageAddress(2, chash[:]) - uri = string(common.Hex2Bytes(self.backend.StorageAt(self.urlHintContractAddress, key))) + hex := self.backend.StorageAt("0x"+self.urlHintContractAddress, key) + uri = string(common.Hex2Bytes(hex[2:])) l := len(uri) for (l > 0) && (uri[l-1] == 0) { l-- @@ -72,7 +73,7 @@ func (self *Resolver) NameToUrl(name string) (uri string, hash common.Hash, err func storageAddress(varidx uint32, key []byte) string { data := make([]byte, 64) - binary.BigEndian.PutUint32(data[28:32], varidx) - copy(data[32:64], key[0:32]) - return common.Bytes2Hex(crypto.Sha3(data)) + binary.BigEndian.PutUint32(data[60:64], varidx) + copy(data[0:32], key[0:32]) + return "0x" + common.Bytes2Hex(crypto.Sha3(data)) } -- cgit v1.2.3 From b635cad9fe127e6b0ca6d993ce9a3b6c61ce79c6 Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Tue, 7 Apr 2015 11:50:17 +0200 Subject: NatSpec passing end to end test --- common/resolver/resolver.go | 30 ++++++++++++++++++------------ common/resolver/resolver_test.go | 20 +++++++++++--------- 2 files changed, 29 insertions(+), 21 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index 060e9dbb5..9c71ac85f 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -11,7 +11,7 @@ import ( /* Resolver implements the Ethereum DNS mapping -NameReg : Domain Name (or Code hash of Contract) -> Content Hash +HashReg : Key Hash (hash of domain name or contract code) -> Content Hash UrlHint : Content Hash -> Url Hint The resolver is meant to be called by the roundtripper transport implementation @@ -19,13 +19,13 @@ of a url scheme */ const ( URLHintContractAddress = core.ContractAddrURLhint - NameRegContractAddress = core.ContractAddrHashReg + HashRegContractAddress = core.ContractAddrHashReg ) type Resolver struct { backend Backend urlHintContractAddress string - nameRegContractAddress string + hashRegContractAddress string } type Backend interface { @@ -36,17 +36,23 @@ func New(eth Backend, uhca, nrca string) *Resolver { return &Resolver{eth, uhca, nrca} } -func (self *Resolver) NameToContentHash(name string) (chash common.Hash, err error) { - // look up in nameReg - key := storageAddress(1, common.Hex2BytesFixed(name, 32)) - hash := self.backend.StorageAt("0x"+self.nameRegContractAddress, key) - copy(chash[:], common.Hex2Bytes(hash)) +func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, err error) { + // look up in hashReg + key := storageAddress(1, khash[:]) + hash := self.backend.StorageAt("0x"+self.hashRegContractAddress, key) + + if hash == "0x0" || len(hash) < 3 { + err = fmt.Errorf("GetHashReg: content hash not found") + return + } + + copy(chash[:], common.Hex2BytesFixed(hash[2:], 32)) return } func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error) { - // look up in nameReg - key := storageAddress(2, chash[:]) + // look up in URL reg + key := storageAddress(1, chash[:]) hex := self.backend.StorageAt("0x"+self.urlHintContractAddress, key) uri = string(common.Hex2Bytes(hex[2:])) l := len(uri) @@ -61,9 +67,9 @@ func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error return } -func (self *Resolver) NameToUrl(name string) (uri string, hash common.Hash, err error) { +func (self *Resolver) KeyToUrl(key common.Hash) (uri string, hash common.Hash, err error) { // look up in urlHint - hash, err = self.NameToContentHash(name) + hash, err = self.KeyToContentHash(key) if err != nil { return } diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go index 5652213f6..17a1c4f94 100644 --- a/common/resolver/resolver_test.go +++ b/common/resolver/resolver_test.go @@ -23,12 +23,12 @@ func NewTestBackend() *testBackend { self := &testBackend{} self.contracts = make(map[string](map[string]string)) - self.contracts[NameRegContractAddress] = make(map[string]string) - key := storageAddress(0, common.Hex2Bytes(codehash)) - self.contracts[NameRegContractAddress][key] = hash + self.contracts[HashRegContractAddress] = make(map[string]string) + key := storageAddress(1, common.Hex2Bytes(codehash)) + self.contracts[HashRegContractAddress][key] = hash self.contracts[URLHintContractAddress] = make(map[string]string) - key = storageAddress(0, common.Hex2Bytes(hash)) + key = storageAddress(1, common.Hex2Bytes(hash)) self.contracts[URLHintContractAddress][key] = url return self @@ -43,10 +43,12 @@ func (self *testBackend) StorageAt(ca, sa string) (res string) { return } -func TestNameToContentHash(t *testing.T) { +func TestKeyToContentHash(t *testing.T) { b := NewTestBackend() - res := New(b, URLHintContractAddress, NameRegContractAddress) - got, err := res.NameToContentHash(codehash) + res := New(b, URLHintContractAddress, HashRegContractAddress) + chash := common.Hash{} + copy(chash[:], common.Hex2BytesFixed(codehash, 32)) + got, err := res.KeyToContentHash(chash) if err != nil { t.Errorf("expected no error, got %v", err) } else { @@ -58,7 +60,7 @@ func TestNameToContentHash(t *testing.T) { func TestContentHashToUrl(t *testing.T) { b := NewTestBackend() - res := New(b, URLHintContractAddress, NameRegContractAddress) + res := New(b, URLHintContractAddress, HashRegContractAddress) chash := common.Hash{} copy(chash[:], common.Hex2Bytes(hash)) got, err := res.ContentHashToUrl(chash) @@ -71,5 +73,5 @@ func TestContentHashToUrl(t *testing.T) { } } -func TestNameToUrl(t *testing.T) { +func TestKeyToUrl(t *testing.T) { } -- cgit v1.2.3 From c4b7d4d3f77160fba1ab3d8366cb2657a90e2282 Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Wed, 8 Apr 2015 13:22:31 +0200 Subject: NatSpec cli option, resolver tests passing --- common/resolver/resolver.go | 1 + common/resolver/resolver_test.go | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index 9c71ac85f..2858a049d 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -81,5 +81,6 @@ func storageAddress(varidx uint32, key []byte) string { data := make([]byte, 64) binary.BigEndian.PutUint32(data[60:64], varidx) copy(data[0:32], key[0:32]) + //fmt.Printf("%x %v\n", key, common.Bytes2Hex(crypto.Sha3(data))) return "0x" + common.Bytes2Hex(crypto.Sha3(data)) } diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go index 17a1c4f94..7d570cbc6 100644 --- a/common/resolver/resolver_test.go +++ b/common/resolver/resolver_test.go @@ -14,7 +14,7 @@ type testBackend struct { var ( text = "test" - codehash = common.RightPadString("1234", 64) + codehash = "1234" //common.RightPadString("1234", 64) hash = common.Bytes2Hex(crypto.Sha3([]byte(text))) url = "bzz://bzzhash/my/path/contr.act" ) @@ -23,13 +23,13 @@ func NewTestBackend() *testBackend { self := &testBackend{} self.contracts = make(map[string](map[string]string)) - self.contracts[HashRegContractAddress] = make(map[string]string) - key := storageAddress(1, common.Hex2Bytes(codehash)) - self.contracts[HashRegContractAddress][key] = hash + self.contracts["0x"+HashRegContractAddress] = make(map[string]string) + key := storageAddress(1, common.Hex2BytesFixed(codehash, 32)) + self.contracts["0x"+HashRegContractAddress][key] = "0x" + hash - self.contracts[URLHintContractAddress] = make(map[string]string) - key = storageAddress(1, common.Hex2Bytes(hash)) - self.contracts[URLHintContractAddress][key] = url + self.contracts["0x"+URLHintContractAddress] = make(map[string]string) + key = storageAddress(1, common.Hex2BytesFixed(hash, 32)) + self.contracts["0x"+URLHintContractAddress][key] = "0x" + common.Bytes2Hex([]byte(url)) return self } @@ -48,6 +48,7 @@ func TestKeyToContentHash(t *testing.T) { res := New(b, URLHintContractAddress, HashRegContractAddress) chash := common.Hash{} copy(chash[:], common.Hex2BytesFixed(codehash, 32)) + got, err := res.KeyToContentHash(chash) if err != nil { t.Errorf("expected no error, got %v", err) @@ -62,7 +63,7 @@ func TestContentHashToUrl(t *testing.T) { b := NewTestBackend() res := New(b, URLHintContractAddress, HashRegContractAddress) chash := common.Hash{} - copy(chash[:], common.Hex2Bytes(hash)) + copy(chash[:], common.Hex2BytesFixed(hash, 32)) got, err := res.ContentHashToUrl(chash) if err != nil { t.Errorf("expected no error, got %v", err) -- cgit v1.2.3 From dba2367157fc4ad7947ee1632dbe76d6a110f49f Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Tue, 14 Apr 2015 15:20:52 +0200 Subject: NatSpec contracts are now not in the genesis block but added by the test --- common/resolver/resolver.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index 2858a049d..45afb2971 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" + xe "github.com/ethereum/go-ethereum/xeth" ) /* @@ -17,10 +17,24 @@ UrlHint : Content Hash -> Url Hint The resolver is meant to be called by the roundtripper transport implementation of a url scheme */ -const ( - URLHintContractAddress = core.ContractAddrURLhint - HashRegContractAddress = core.ContractAddrHashReg -) + +// contract addresses will be hardcoded after they're created +var URLHintContractAddress string = "0000000000000000000000000000000000000000000000000000000000001234" +var HashRegContractAddress string = "0000000000000000000000000000000000000000000000000000000000005678" + +func CreateContracts(xeth *xe.XEth, addr string) { + var err error + URLHintContractAddress, err = xeth.Transact(addr, "", "100000000000", "1000000", "100000", ContractCodeURLhint) + if err != nil { + panic(err) + } + HashRegContractAddress, err = xeth.Transact(addr, "", "100000000000", "1000000", "100000", ContractCodeHashReg) + if err != nil { + panic(err) + } + URLHintContractAddress = URLHintContractAddress[2:] + HashRegContractAddress = HashRegContractAddress[2:] +} type Resolver struct { backend Backend -- cgit v1.2.3 From b6fe9e0c838ced143cbdcc867b53ada2711b39da Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Tue, 14 Apr 2015 16:36:28 +0200 Subject: added missing source file --- common/resolver/contracts.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 common/resolver/contracts.go (limited to 'common/resolver') diff --git a/common/resolver/contracts.go b/common/resolver/contracts.go new file mode 100644 index 000000000..ed7d648d6 --- /dev/null +++ b/common/resolver/contracts.go @@ -0,0 +1,36 @@ +package resolver + +const ( // built-in contracts address and code + ContractCodeURLhint = "0x60b180600c6000396000f30060003560e060020a90048063d66d6c1014601557005b60216004356024356027565b60006000f35b6000600083815260200190815260200160002054600160a060020a0316600014806075575033600160a060020a03166000600084815260200190815260200160002054600160a060020a0316145b607c5760ad565b3360006000848152602001908152602001600020819055508060016000848152602001908152602001600020819055505b505056" + /* + contract URLhint { + function register(uint256 _hash, uint256 _url) { + if (owner[_hash] == 0 || owner[_hash] == msg.sender) { + owner[_hash] = msg.sender; + url[_hash] = _url; + } + } + mapping (uint256 => address) owner; + mapping (uint256 => uint256) url; + } + */ + + ContractCodeHashReg = "0x609880600c6000396000f30060003560e060020a9004806331e12c2014601f578063d66d6c1014602b57005b6025603d565b60006000f35b6037600435602435605d565b60006000f35b600054600160a060020a0316600014605357605b565b336000819055505b565b600054600160a060020a031633600160a060020a031614607b576094565b8060016000848152602001908152602001600020819055505b505056" + /* + contract HashReg { + function setowner() { + if (owner == 0) { + owner = msg.sender; + } + } + function register(uint256 _key, uint256 _content) { + if (msg.sender == owner) { + content[_key] = _content; + } + } + address owner; + mapping (uint256 => uint256) content; + } + */ + +) -- cgit v1.2.3 From 929428d60216f31b2494df1ebf76d9be2a66028c Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Fri, 17 Apr 2015 13:46:38 +0200 Subject: URLhint support for URLs longer than 32 bytes --- common/resolver/contracts.go | 8 +++---- common/resolver/resolver.go | 56 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 17 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/contracts.go b/common/resolver/contracts.go index ed7d648d6..4aad95e43 100644 --- a/common/resolver/contracts.go +++ b/common/resolver/contracts.go @@ -1,17 +1,17 @@ package resolver const ( // built-in contracts address and code - ContractCodeURLhint = "0x60b180600c6000396000f30060003560e060020a90048063d66d6c1014601557005b60216004356024356027565b60006000f35b6000600083815260200190815260200160002054600160a060020a0316600014806075575033600160a060020a03166000600084815260200190815260200160002054600160a060020a0316145b607c5760ad565b3360006000848152602001908152602001600020819055508060016000848152602001908152602001600020819055505b505056" + ContractCodeURLhint = "0x60c180600c6000396000f30060003560e060020a90048063300a3bbf14601557005b6024600435602435604435602a565b60006000f35b6000600084815260200190815260200160002054600160a060020a0316600014806078575033600160a060020a03166000600085815260200190815260200160002054600160a060020a0316145b607f5760bc565b336000600085815260200190815260200160002081905550806001600085815260200190815260200160002083610100811060b657005b01819055505b50505056" /* contract URLhint { - function register(uint256 _hash, uint256 _url) { + function register(uint256 _hash, uint8 idx, uint256 _url) { if (owner[_hash] == 0 || owner[_hash] == msg.sender) { owner[_hash] = msg.sender; - url[_hash] = _url; + url[_hash][idx] = _url; } } mapping (uint256 => address) owner; - mapping (uint256 => uint256) url; + mapping (uint256 => uint256[256]) url; } */ diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index 45afb2971..35f765349 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -52,7 +52,7 @@ func New(eth Backend, uhca, nrca string) *Resolver { func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, err error) { // look up in hashReg - key := storageAddress(1, khash[:]) + key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:])) hash := self.backend.StorageAt("0x"+self.hashRegContractAddress, key) if hash == "0x0" || len(hash) < 3 { @@ -66,16 +66,23 @@ func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, er func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error) { // look up in URL reg - key := storageAddress(1, chash[:]) - hex := self.backend.StorageAt("0x"+self.urlHintContractAddress, key) - uri = string(common.Hex2Bytes(hex[2:])) - l := len(uri) - for (l > 0) && (uri[l-1] == 0) { - l-- + 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("0x"+self.urlHintContractAddress, key) + str = string(common.Hex2Bytes(hex[2:])) + l := len(str) + for (l > 0) && (str[l-1] == 0) { + l-- + } + str = str[:l] + uri = uri + str + idx++ } - uri = uri[:l] - if l == 0 { + if len(uri) == 0 { err = fmt.Errorf("GetURLhint: URL hint not found") } return @@ -91,10 +98,33 @@ func (self *Resolver) KeyToUrl(key common.Hash) (uri string, hash common.Hash, e return } -func storageAddress(varidx uint32, key []byte) string { +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) - binary.BigEndian.PutUint32(data[60:64], varidx) copy(data[0:32], key[0:32]) - //fmt.Printf("%x %v\n", key, common.Bytes2Hex(crypto.Sha3(data))) - return "0x" + common.Bytes2Hex(crypto.Sha3(data)) + copy(data[32:64], addr[0:32]) + return crypto.Sha3(data) +} + +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 "0x" + common.Bytes2Hex(addr) } -- cgit v1.2.3 From e9874cbcc12f5b15ad91a0df396552afe8c71e3e Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Fri, 17 Apr 2015 13:54:23 +0200 Subject: fixed resolver test --- common/resolver/resolver_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go index 7d570cbc6..a67b9ad04 100644 --- a/common/resolver/resolver_test.go +++ b/common/resolver/resolver_test.go @@ -24,12 +24,16 @@ func NewTestBackend() *testBackend { self.contracts = make(map[string](map[string]string)) self.contracts["0x"+HashRegContractAddress] = make(map[string]string) - key := storageAddress(1, common.Hex2BytesFixed(codehash, 32)) + key := storageAddress(storageMapping(storageIdx2Addr(1), common.Hex2BytesFixed(codehash, 32))) self.contracts["0x"+HashRegContractAddress][key] = "0x" + hash self.contracts["0x"+URLHintContractAddress] = make(map[string]string) - key = storageAddress(1, common.Hex2BytesFixed(hash, 32)) + mapaddr := storageMapping(storageIdx2Addr(1), common.Hex2BytesFixed(hash, 32)) + + key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0))) self.contracts["0x"+URLHintContractAddress][key] = "0x" + common.Bytes2Hex([]byte(url)) + key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1))) + self.contracts["0x"+URLHintContractAddress][key] = "0x00" return self } -- cgit v1.2.3 From 093a9106b093310acf4c3911baa61916cff52ab8 Mon Sep 17 00:00:00 2001 From: zelig Date: Sun, 19 Apr 2015 19:24:46 +0100 Subject: contract addresses include hex prefix - simplify resolver and tests - added missing test for KeyToUrl - fix notice error message and its test with !%x(MISSING) - natspec test: insertTx modified - does not prepend 0x to contract address - disable networking in e2e test --- common/resolver/resolver.go | 8 +++----- common/resolver/resolver_test.go | 44 +++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 24 deletions(-) (limited to 'common/resolver') diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go index 35f765349..1e6d03ffb 100644 --- a/common/resolver/resolver.go +++ b/common/resolver/resolver.go @@ -32,8 +32,6 @@ func CreateContracts(xeth *xe.XEth, addr string) { if err != nil { panic(err) } - URLHintContractAddress = URLHintContractAddress[2:] - HashRegContractAddress = HashRegContractAddress[2:] } type Resolver struct { @@ -53,7 +51,7 @@ func New(eth Backend, uhca, nrca string) *Resolver { func (self *Resolver) KeyToContentHash(khash common.Hash) (chash common.Hash, err error) { // look up in hashReg key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:])) - hash := self.backend.StorageAt("0x"+self.hashRegContractAddress, key) + hash := self.backend.StorageAt(self.hashRegContractAddress, key) if hash == "0x0" || len(hash) < 3 { err = fmt.Errorf("GetHashReg: content hash not found") @@ -71,7 +69,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("0x"+self.urlHintContractAddress, key) + hex := self.backend.StorageAt(self.urlHintContractAddress, key) str = string(common.Hex2Bytes(hex[2:])) l := len(str) for (l > 0) && (str[l-1] == 0) { @@ -126,5 +124,5 @@ func storageFixedArray(addr, idx []byte) []byte { } func storageAddress(addr []byte) string { - return "0x" + common.Bytes2Hex(addr) + return common.ToHex(addr) } diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go index a67b9ad04..f5eb51437 100644 --- a/common/resolver/resolver_test.go +++ b/common/resolver/resolver_test.go @@ -14,8 +14,8 @@ type testBackend struct { var ( text = "test" - codehash = "1234" //common.RightPadString("1234", 64) - hash = common.Bytes2Hex(crypto.Sha3([]byte(text))) + codehash = common.StringToHash("1234") + hash = common.BytesToHash(crypto.Sha3([]byte(text))) url = "bzz://bzzhash/my/path/contr.act" ) @@ -23,17 +23,17 @@ func NewTestBackend() *testBackend { self := &testBackend{} self.contracts = make(map[string](map[string]string)) - self.contracts["0x"+HashRegContractAddress] = make(map[string]string) - key := storageAddress(storageMapping(storageIdx2Addr(1), common.Hex2BytesFixed(codehash, 32))) - self.contracts["0x"+HashRegContractAddress][key] = "0x" + hash + self.contracts[HashRegContractAddress] = make(map[string]string) + key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:])) + self.contracts[HashRegContractAddress][key] = hash.Hex() - self.contracts["0x"+URLHintContractAddress] = make(map[string]string) - mapaddr := storageMapping(storageIdx2Addr(1), common.Hex2BytesFixed(hash, 32)) + self.contracts[URLHintContractAddress] = make(map[string]string) + mapaddr := storageMapping(storageIdx2Addr(1), hash[:]) key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0))) - self.contracts["0x"+URLHintContractAddress][key] = "0x" + common.Bytes2Hex([]byte(url)) + self.contracts[URLHintContractAddress][key] = common.ToHex([]byte(url)) key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1))) - self.contracts["0x"+URLHintContractAddress][key] = "0x00" + self.contracts[URLHintContractAddress][key] = "0x00" return self } @@ -50,15 +50,13 @@ func (self *testBackend) StorageAt(ca, sa string) (res string) { func TestKeyToContentHash(t *testing.T) { b := NewTestBackend() res := New(b, URLHintContractAddress, HashRegContractAddress) - chash := common.Hash{} - copy(chash[:], common.Hex2BytesFixed(codehash, 32)) - got, err := res.KeyToContentHash(chash) + got, err := res.KeyToContentHash(codehash) if err != nil { t.Errorf("expected no error, got %v", err) } else { - if common.Bytes2Hex(got[:]) != hash { - t.Errorf("incorrect result, expected %x, got %x: ", hash, common.Bytes2Hex(got[:])) + if got != hash { + t.Errorf("incorrect result, expected %x, got %x: ", hash.Hex(), got.Hex()) } } } @@ -66,17 +64,25 @@ func TestKeyToContentHash(t *testing.T) { func TestContentHashToUrl(t *testing.T) { b := NewTestBackend() res := New(b, URLHintContractAddress, HashRegContractAddress) - chash := common.Hash{} - copy(chash[:], common.Hex2BytesFixed(hash, 32)) - got, err := res.ContentHashToUrl(chash) + got, err := res.ContentHashToUrl(hash) if err != nil { t.Errorf("expected no error, got %v", err) } else { - if string(got[:]) != url { - t.Errorf("incorrect result, expected %v, got %s: ", url, string(got[:])) + if string(got) != url { + t.Errorf("incorrect result, expected %v, got %s: ", url, string(got)) } } } func TestKeyToUrl(t *testing.T) { + b := NewTestBackend() + res := New(b, URLHintContractAddress, HashRegContractAddress) + got, _, err := res.KeyToUrl(codehash) + if err != nil { + t.Errorf("expected no error, got %v", err) + } else { + if string(got) != url { + t.Errorf("incorrect result, expected %v, got %s: ", url, string(got)) + } + } } -- cgit v1.2.3