From 929428d60216f31b2494df1ebf76d9be2a66028c Mon Sep 17 00:00:00 2001
From: zsfelfoldi <zsfelfoldi@gmail.com>
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