aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/big.go16
-rw-r--r--common/big_test.go16
-rw-r--r--common/bytes.go17
-rw-r--r--common/bytes_test.go16
-rw-r--r--common/compiler/solidity.go24
-rw-r--r--common/compiler/solidity_test.go24
-rw-r--r--common/config.go16
-rw-r--r--common/db.go16
-rw-r--r--common/debug.go16
-rw-r--r--common/docserver/docserver.go83
-rw-r--r--common/docserver/docserver_test.go36
-rw-r--r--common/list.go16
-rw-r--r--common/main_test.go16
-rw-r--r--common/math/dist.go16
-rw-r--r--common/math/dist_test.go16
-rw-r--r--common/natspec/natspec.go42
-rw-r--r--common/natspec/natspec_e2e_test.go182
-rw-r--r--common/natspec/natspec_e2e_test.go.orig253
-rw-r--r--common/natspec/natspec_js.go16
-rw-r--r--common/natspec/natspec_test.go16
-rw-r--r--common/number/int.go16
-rw-r--r--common/number/uint_test.go16
-rw-r--r--common/package.go16
-rw-r--r--common/path.go16
-rw-r--r--common/path_test.go16
-rw-r--r--common/registrar/contracts.go163
-rw-r--r--common/registrar/ethreg/ethreg.go48
-rw-r--r--common/registrar/registrar.go408
-rw-r--r--common/registrar/registrar_test.go112
-rw-r--r--common/resolver/contracts.go36
-rw-r--r--common/resolver/resolver.go232
-rw-r--r--common/resolver/resolver_test.go93
-rw-r--r--common/rlp.go16
-rw-r--r--common/rlp_test.go16
-rw-r--r--common/size.go16
-rw-r--r--common/size_test.go16
-rw-r--r--common/test_utils.go16
-rw-r--r--common/types.go16
-rw-r--r--common/types_template.go16
-rw-r--r--common/types_test.go16
-rw-r--r--common/value.go16
-rw-r--r--common/value_test.go16
42 files changed, 1736 insertions, 449 deletions
diff --git a/common/big.go b/common/big.go
index 05d56daba..ec936b5bc 100644
--- a/common/big.go
+++ b/common/big.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import "math/big"
diff --git a/common/big_test.go b/common/big_test.go
index cedbaf144..df8dfd980 100644
--- a/common/big_test.go
+++ b/common/big_test.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/bytes.go b/common/bytes.go
index d279156b4..a65c0122b 100644
--- a/common/bytes.go
+++ b/common/bytes.go
@@ -1,3 +1,20 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+// Package common contains various helper functions.
package common
import (
diff --git a/common/bytes_test.go b/common/bytes_test.go
index 069af984c..4e7c63941 100644
--- a/common/bytes_test.go
+++ b/common/bytes_test.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go
index caf86974e..e1869cc3b 100644
--- a/common/compiler/solidity.go
+++ b/common/compiler/solidity.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package compiler
import (
@@ -185,12 +201,12 @@ func (sol *Solidity) Compile(source string) (contracts map[string]*Contract, err
return
}
-func ExtractInfo(contract *Contract, filename string) (contenthash common.Hash, err error) {
- contractInfo, err := json.Marshal(contract.Info)
+func SaveInfo(info *ContractInfo, filename string) (contenthash common.Hash, err error) {
+ infojson, err := json.Marshal(info)
if err != nil {
return
}
- contenthash = common.BytesToHash(crypto.Sha3(contractInfo))
- err = ioutil.WriteFile(filename, contractInfo, 0600)
+ contenthash = common.BytesToHash(crypto.Sha3(infojson))
+ err = ioutil.WriteFile(filename, infojson, 0600)
return
}
diff --git a/common/compiler/solidity_test.go b/common/compiler/solidity_test.go
index 59b6b6cd6..49772cd2e 100644
--- a/common/compiler/solidity_test.go
+++ b/common/compiler/solidity_test.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package compiler
import (
@@ -72,19 +88,15 @@ func TestNoCompiler(t *testing.T) {
}
}
-func TestExtractInfo(t *testing.T) {
+func TestSaveInfo(t *testing.T) {
var cinfo ContractInfo
err := json.Unmarshal([]byte(info), &cinfo)
if err != nil {
t.Errorf("%v", err)
}
- contract := &Contract{
- Code: "",
- Info: cinfo,
- }
filename := "/tmp/solctest.info.json"
os.Remove(filename)
- cinfohash, err := ExtractInfo(contract, filename)
+ cinfohash, err := SaveInfo(&cinfo, filename)
if err != nil {
t.Errorf("error extracting info: %v", err)
}
diff --git a/common/config.go b/common/config.go
index 23a902bc1..f5507d3e9 100644
--- a/common/config.go
+++ b/common/config.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/db.go b/common/db.go
index 7f3becd5a..2d484482e 100644
--- a/common/db.go
+++ b/common/db.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
// Database interface
diff --git a/common/debug.go b/common/debug.go
index 69675cc6c..be4e3d36c 100644
--- a/common/debug.go
+++ b/common/debug.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/docserver/docserver.go b/common/docserver/docserver.go
index 5e076aa7e..3a3343909 100644
--- a/common/docserver/docserver.go
+++ b/common/docserver/docserver.go
@@ -1,37 +1,45 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package docserver
import (
"fmt"
"io/ioutil"
"net/http"
+ "path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
-// http://golang.org/pkg/net/http/#RoundTripper
-var (
- schemes = map[string]func(*DocServer) http.RoundTripper{
- // Simple File server from local disk file:///etc/passwd :)
- "file": fileServerOnDocRoot,
- }
-)
-
-func fileServerOnDocRoot(ds *DocServer) http.RoundTripper {
- return http.NewFileTransport(http.Dir(ds.DocRoot))
-}
-
type DocServer struct {
*http.Transport
DocRoot string
+ schemes []string
}
-func New(docRoot string) (self *DocServer, err error) {
+func New(docRoot string) (self *DocServer) {
self = &DocServer{
Transport: &http.Transport{},
DocRoot: docRoot,
+ schemes: []string{"file"},
}
- err = self.RegisterProtocols(schemes)
+ self.DocRoot = "/tmp/"
+ self.RegisterProtocol("file", http.NewFileTransport(http.Dir(self.DocRoot)))
return
}
@@ -45,16 +53,44 @@ func (self *DocServer) Client() *http.Client {
}
}
-func (self *DocServer) RegisterProtocols(schemes map[string]func(*DocServer) http.RoundTripper) (err error) {
- for scheme, rtf := range schemes {
- self.RegisterProtocol(scheme, rtf(self))
+func (self *DocServer) RegisterScheme(scheme string, rt http.RoundTripper) {
+ self.schemes = append(self.schemes, scheme)
+ self.RegisterProtocol(scheme, rt)
+}
+
+func (self *DocServer) HasScheme(scheme string) bool {
+ for _, s := range self.schemes {
+ if s == scheme {
+ return true
+ }
}
- return
+ return false
}
func (self *DocServer) GetAuthContent(uri string, hash common.Hash) (content []byte, err error) {
// retrieve content
+ content, err = self.Get(uri, "")
+ if err != nil {
+ return
+ }
+
+ // check hash to authenticate content
+ chash := crypto.Sha3Hash(content)
+ if chash != hash {
+ content = nil
+ err = fmt.Errorf("content hash mismatch %x != %x (exp)", hash[:], chash[:])
+ }
+
+ return
+
+}
+
+// Get(uri, path) downloads the document at uri, if path is non-empty it
+// is interpreted as a filepath to which the contents are saved
+func (self *DocServer) Get(uri, path string) (content []byte, err error) {
+ // retrieve content
resp, err := self.Client().Get(uri)
+
defer func() {
if resp != nil {
resp.Body.Close()
@@ -68,13 +104,10 @@ func (self *DocServer) GetAuthContent(uri string, hash common.Hash) (content []b
return
}
- // check hash to authenticate content
- hashbytes := crypto.Sha3(content)
- var chash common.Hash
- copy(chash[:], hashbytes)
- if chash != hash {
- content = nil
- err = fmt.Errorf("content hash mismatch")
+ if path != "" {
+ var abspath string
+ abspath, err = filepath.Abs(path)
+ ioutil.WriteFile(abspath, content, 0700)
}
return
diff --git a/common/docserver/docserver_test.go b/common/docserver/docserver_test.go
index 400d7447a..136ec9ccc 100644
--- a/common/docserver/docserver_test.go
+++ b/common/docserver/docserver_test.go
@@ -1,7 +1,24 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package docserver
import (
"io/ioutil"
+ "net/http"
"os"
"testing"
@@ -15,7 +32,7 @@ func TestGetAuthContent(t *testing.T) {
copy(hash[:], crypto.Sha3([]byte(text)))
ioutil.WriteFile("/tmp/test.content", []byte(text), os.ModePerm)
- ds, err := New("/tmp/")
+ ds := New("/tmp/")
content, err := ds.GetAuthContent("file:///test.content", hash)
if err != nil {
t.Errorf("no error expected, got %v", err)
@@ -26,7 +43,7 @@ func TestGetAuthContent(t *testing.T) {
hash = common.Hash{}
content, err = ds.GetAuthContent("file:///test.content", hash)
- expected := "content hash mismatch"
+ expected := "content hash mismatch 0000000000000000000000000000000000000000000000000000000000000000 != 9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658 (exp)"
if err == nil {
t.Errorf("expected error, got nothing")
} else {
@@ -36,3 +53,18 @@ func TestGetAuthContent(t *testing.T) {
}
}
+
+type rt struct{}
+
+func (rt) RoundTrip(req *http.Request) (resp *http.Response, err error) { return }
+
+func TestRegisterScheme(t *testing.T) {
+ ds := New("/tmp/")
+ if ds.HasScheme("scheme") {
+ t.Errorf("expected scheme not to be registered")
+ }
+ ds.RegisterScheme("scheme", rt{})
+ if !ds.HasScheme("scheme") {
+ t.Errorf("expected scheme to be registered")
+ }
+}
diff --git a/common/list.go b/common/list.go
index 594a8a24b..4370d69fe 100644
--- a/common/list.go
+++ b/common/list.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/main_test.go b/common/main_test.go
index 2bed278e6..c1efb848b 100644
--- a/common/main_test.go
+++ b/common/main_test.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/math/dist.go b/common/math/dist.go
index 0a0731971..93b1635e4 100644
--- a/common/math/dist.go
+++ b/common/math/dist.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package math
import (
diff --git a/common/math/dist_test.go b/common/math/dist_test.go
index 90e302f44..d2e3650b4 100644
--- a/common/math/dist_test.go
+++ b/common/math/dist_test.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package math
import (
diff --git a/common/natspec/natspec.go b/common/natspec/natspec.go
index 7e5f053c7..ed16d62a0 100644
--- a/common/natspec/natspec.go
+++ b/common/natspec/natspec.go
@@ -1,17 +1,33 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package natspec
import (
"bytes"
"encoding/json"
"fmt"
- "github.com/robertkrimen/otto"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
- "github.com/ethereum/go-ethereum/common/resolver"
+ "github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/xeth"
+ "github.com/robertkrimen/otto"
)
type abi2method map[[8]byte]*method
@@ -88,7 +104,7 @@ func New(xeth *xeth.XEth, jsontx string, http *docserver.DocServer) (self *NatSp
}
// also called by admin.contractInfo.get
-func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, http *docserver.DocServer) (content []byte, err error) {
+func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, ds *docserver.DocServer) (content []byte, err error) {
// retrieve contract hash from state
codehex := xeth.CodeAt(contractAddress)
codeb := xeth.CodeAtBytes(contractAddress)
@@ -99,20 +115,32 @@ func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, http *docserv
}
codehash := common.BytesToHash(crypto.Sha3(codeb))
// set up nameresolver with natspecreg + urlhint contract addresses
- res := resolver.New(xeth)
+ reg := registrar.New(xeth)
// resolve host via HashReg/UrlHint Resolver
- uri, hash, err := res.KeyToUrl(codehash)
+ hash, err := reg.HashToHash(codehash)
if err != nil {
return
}
+ if ds.HasScheme("bzz") {
+ content, err = ds.Get("bzz://"+hash.Hex()[2:], "")
+ if err == nil { // non-fatal
+ return
+ }
+ err = nil
+ //falling back to urlhint
+ }
- // get content via http client and authenticate content using hash
- content, err = http.GetAuthContent(uri, hash)
+ uri, err := reg.HashToUrl(hash)
if err != nil {
return
}
+ // get content via http client and authenticate content using hash
+ content, err = ds.GetAuthContent(uri, hash)
+ if err != nil {
+ return
+ }
return
}
diff --git a/common/natspec/natspec_e2e_test.go b/common/natspec/natspec_e2e_test.go
index 7e9172649..0cbe040c0 100644
--- a/common/natspec/natspec_e2e_test.go
+++ b/common/natspec/natspec_e2e_test.go
@@ -1,18 +1,36 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package natspec
import (
"fmt"
"io/ioutil"
+ "math/big"
"os"
+ "runtime"
"strings"
"testing"
+ "time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
- "github.com/ethereum/go-ethereum/common/resolver"
+ "github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
xe "github.com/ethereum/go-ethereum/xeth"
@@ -73,13 +91,10 @@ const (
)
type testFrontend struct {
- t *testing.T
- // resolver *resolver.Resolver
+ t *testing.T
ethereum *eth.Ethereum
xeth *xe.XEth
- coinbase common.Address
- stateDb *state.StateDB
- txc uint64
+ wait chan *big.Int
lastConfirm string
wantNatSpec bool
}
@@ -91,10 +106,7 @@ func (self *testFrontend) UnlockAccount(acc []byte) bool {
func (self *testFrontend) ConfirmTransaction(tx string) bool {
if self.wantNatSpec {
- ds, err := docserver.New("/tmp/")
- if err != nil {
- self.t.Errorf("Error creating DocServer: %v", err)
- }
+ ds := docserver.New("/tmp/")
self.lastConfirm = GetNotice(self.xeth, tx, ds)
}
return true
@@ -128,6 +140,8 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
DataDir: "/tmp/eth-natspec",
AccountManager: am,
MaxPeers: 0,
+ PowTest: true,
+ Etherbase: common.HexToAddress(testAddress),
})
if err != nil {
@@ -153,30 +167,41 @@ func testInit(t *testing.T) (self *testFrontend) {
// mock frontend
self = &testFrontend{t: t, ethereum: ethereum}
self.xeth = xe.New(ethereum, self)
-
- addr, _ := ethereum.Etherbase()
- self.coinbase = addr
- self.stateDb = self.ethereum.ChainManager().State().Copy()
+ self.wait = self.xeth.UpdateState()
+ addr, _ := self.ethereum.Etherbase()
// initialise the registry contracts
- // self.resolver.CreateContracts(addr)
- resolver.New(self.xeth).CreateContracts(addr)
- self.applyTxs()
- // t.Logf("HashReg contract registered at %v", resolver.HashRegContractAddress)
- // t.Logf("URLHint contract registered at %v", resolver.UrlHintContractAddress)
+ reg := registrar.New(self.xeth)
+ var registrarTxhash, hashRegTxhash, urlHintTxhash string
+ registrarTxhash, err = reg.SetGlobalRegistrar("", addr)
+ if err != nil {
+ t.Errorf("error creating GlobalRegistrar: %v", err)
+ }
- return
+ hashRegTxhash, err = reg.SetHashReg("", addr)
+ if err != nil {
+ t.Errorf("error creating HashReg: %v", err)
+ }
+ urlHintTxhash, err = reg.SetUrlHint("", addr)
+ if err != nil {
+ t.Errorf("error creating UrlHint: %v", err)
+ }
+ if !processTxs(self, t, 3) {
+ t.Errorf("error mining txs")
+ }
+ _ = registrarTxhash
+ _ = hashRegTxhash
+ _ = urlHintTxhash
-}
+ /* TODO:
+ * lookup receipt and contract addresses by tx hash
+ * name registration for HashReg and UrlHint addresses
+ * mine those transactions
+ * then set once more SetHashReg SetUrlHint
+ */
-// this is needed for transaction to be applied to the state in testing
-// the heavy lifing is done in XEth.ApplyTestTxs
-// this is fragile,
-// and does process leaking since xeth loops cannot quit safely
-// should be replaced by proper mining with testDAG for easy full integration tests
-func (self *testFrontend) applyTxs() {
- self.txc, self.xeth = self.xeth.ApplyTestTxs(self.stateDb, self.coinbase, self.txc)
return
+
}
// end to end test
@@ -185,54 +210,63 @@ func TestNatspecE2E(t *testing.T) {
tf := testInit(t)
defer tf.ethereum.Stop()
+ addr, _ := tf.ethereum.Etherbase()
// create a contractInfo file (mock cloud-deployed contract metadocs)
// incidentally this is the info for the registry contract itself
ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm)
- dochash := common.BytesToHash(crypto.Sha3([]byte(testContractInfo)))
+ dochash := crypto.Sha3Hash([]byte(testContractInfo))
// take the codehash for the contract we wanna test
- // codehex := tf.xeth.CodeAt(resolver.HashRegContractAddress)
- codeb := tf.xeth.CodeAtBytes(resolver.HashRegContractAddress)
- codehash := common.BytesToHash(crypto.Sha3(codeb))
+ codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr)
+ codehash := crypto.Sha3Hash(codeb)
// use resolver to register codehash->dochash->url
- registry := resolver.New(tf.xeth)
- _, err := registry.Register(tf.coinbase, codehash, dochash, "file:///"+testFileName)
+ // test if globalregistry works
+ // registrar.HashRefAddr = "0x0"
+ // registrar.UrlHintAddr = "0x0"
+ reg := registrar.New(tf.xeth)
+ _, err := reg.SetHashToHash(addr, codehash, dochash)
if err != nil {
t.Errorf("error registering: %v", err)
}
- // apply txs to the state
- tf.applyTxs()
+ _, err = reg.SetUrlToHash(addr, dochash, "file:///"+testFileName)
+ if err != nil {
+ t.Errorf("error registering: %v", err)
+ }
+ if !processTxs(tf, t, 5) {
+ return
+ }
// NatSpec info for register method of HashReg contract installed
// now using the same transactions to check confirm messages
tf.wantNatSpec = true // this is set so now the backend uses natspec confirmation
- _, err = registry.RegisterContentHash(tf.coinbase, codehash, dochash)
+ _, err = reg.SetHashToHash(addr, codehash, dochash)
if err != nil {
t.Errorf("error calling contract registry: %v", err)
}
+ fmt.Printf("GlobalRegistrar: %v, HashReg: %v, UrlHint: %v\n", registrar.GlobalRegistrarAddr, registrar.HashRegAddr, registrar.UrlHintAddr)
if tf.lastConfirm != testExpNotice {
- t.Errorf("Wrong confirm message. expected '%v', got '%v'", testExpNotice, tf.lastConfirm)
+ t.Errorf("Wrong confirm message. expected\n'%v', got\n'%v'", testExpNotice, tf.lastConfirm)
}
// test unknown method
- exp := fmt.Sprintf(testExpNotice2, resolver.HashRegContractAddress)
- _, err = registry.SetOwner(tf.coinbase)
+ exp := fmt.Sprintf(testExpNotice2, registrar.HashRegAddr)
+ _, err = reg.SetOwner(addr)
if err != nil {
t.Errorf("error setting owner: %v", err)
}
if tf.lastConfirm != exp {
- t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
+ t.Errorf("Wrong confirm message, expected\n'%v', got\n'%v'", exp, tf.lastConfirm)
}
// test unknown contract
- exp = fmt.Sprintf(testExpNotice3, resolver.UrlHintContractAddress)
+ exp = fmt.Sprintf(testExpNotice3, registrar.UrlHintAddr)
- _, err = registry.RegisterUrl(tf.coinbase, dochash, "file:///test.content")
+ _, err = reg.SetUrlToHash(addr, dochash, "file:///test.content")
if err != nil {
t.Errorf("error registering: %v", err)
}
@@ -242,3 +276,63 @@ func TestNatspecE2E(t *testing.T) {
}
}
+
+func pendingTransactions(repl *testFrontend, t *testing.T) (txc int64, err error) {
+ txs := repl.ethereum.TxPool().GetTransactions()
+ return int64(len(txs)), nil
+}
+
+func processTxs(repl *testFrontend, t *testing.T, expTxc int) bool {
+ var txc int64
+ var err error
+ for i := 0; i < 50; i++ {
+ txc, err = pendingTransactions(repl, t)
+ if err != nil {
+ t.Errorf("unexpected error checking pending transactions: %v", err)
+ return false
+ }
+ if expTxc < int(txc) {
+ t.Errorf("too many pending transactions: expected %v, got %v", expTxc, txc)
+ return false
+ } else if expTxc == int(txc) {
+ break
+ }
+ time.Sleep(100 * time.Millisecond)
+ }
+ if int(txc) != expTxc {
+ t.Errorf("incorrect number of pending transactions, expected %v, got %v", expTxc, txc)
+ return false
+ }
+
+ err = repl.ethereum.StartMining(runtime.NumCPU())
+ if err != nil {
+ t.Errorf("unexpected error mining: %v", err)
+ return false
+ }
+ defer repl.ethereum.StopMining()
+
+ timer := time.NewTimer(100 * time.Second)
+ height := new(big.Int).Add(repl.xeth.CurrentBlock().Number(), big.NewInt(1))
+ repl.wait <- height
+ select {
+ case <-timer.C:
+ // if times out make sure the xeth loop does not block
+ go func() {
+ select {
+ case repl.wait <- nil:
+ case <-repl.wait:
+ }
+ }()
+ case <-repl.wait:
+ }
+ txc, err = pendingTransactions(repl, t)
+ if err != nil {
+ t.Errorf("unexpected error checking pending transactions: %v", err)
+ return false
+ }
+ if txc != 0 {
+ t.Errorf("%d trasactions were not mined", txc)
+ return false
+ }
+ return true
+}
diff --git a/common/natspec/natspec_e2e_test.go.orig b/common/natspec/natspec_e2e_test.go.orig
new file mode 100644
index 000000000..ae8e17ad9
--- /dev/null
+++ b/common/natspec/natspec_e2e_test.go.orig
@@ -0,0 +1,253 @@
+package natspec
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/accounts"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/docserver"
+ "github.com/ethereum/go-ethereum/common/registrar"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/eth"
+ xe "github.com/ethereum/go-ethereum/xeth"
+)
+
+const (
+ testBalance = "10000000000000000000"
+
+ testFileName = "long_file_name_for_testing_registration_of_URLs_longer_than_32_bytes.content"
+
+ testNotice = "Register key `utils.toHex(_key)` <- content `utils.toHex(_content)`"
+
+ testExpNotice = "Register key 0xadd1a7d961cff0242089674ec2ef6fca671ab15e1fe80e38859fc815b98d88ab <- content 0xb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7"
+
+ testExpNotice2 = `About to submit transaction (NatSpec notice error: abi key does not match any method): {"params":[{"to":"%s","data": "0x31e12c20"}]}`
+
+ testExpNotice3 = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x1392c62d05b2d149e22a339c531157ae06b44d39a674cce500064b12b9aeb019'): {"params":[{"to":"%s","data": "0x300a3bbfb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066696c653a2f2f2f746573742e636f6e74656e74"}]}`
+)
+
+const (
+ testUserDoc = `
+{
+ "methods": {
+ "register(uint256,uint256)": {
+ "notice": "` + testNotice + `"
+ }
+ },
+ "invariants": [
+ { "notice": "" }
+ ],
+ "construction": [
+ { "notice": "" }
+ ]
+}
+`
+ testAbiDefinition = `
+[{
+ "name": "register",
+ "constant": false,
+ "type": "function",
+ "inputs": [{
+ "name": "_key",
+ "type": "uint256"
+ }, {
+ "name": "_content",
+ "type": "uint256"
+ }],
+ "outputs": []
+}]
+`
+
+ testContractInfo = `
+{
+ "userDoc": ` + testUserDoc + `,
+ "abiDefinition": ` + testAbiDefinition + `
+}
+`
+)
+
+type testFrontend struct {
+ t *testing.T
+ ethereum *eth.Ethereum
+ xeth *xe.XEth
+ coinbase common.Address
+ stateDb *state.StateDB
+ txc uint64
+ lastConfirm string
+ wantNatSpec bool
+}
+
+func (self *testFrontend) UnlockAccount(acc []byte) bool {
+ self.ethereum.AccountManager().Unlock(common.BytesToAddress(acc), "password")
+ return true
+}
+
+func (self *testFrontend) ConfirmTransaction(tx string) bool {
+ if self.wantNatSpec {
+ ds := docserver.New("/tmp/")
+ self.lastConfirm = GetNotice(self.xeth, tx, ds)
+ }
+ return true
+}
+
+func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
+
+ os.RemoveAll("/tmp/eth-natspec/")
+
+ err = os.MkdirAll("/tmp/eth-natspec/keystore", os.ModePerm)
+ if err != nil {
+ panic(err)
+ }
+
+ // create a testAddress
+ ks := crypto.NewKeyStorePassphrase("/tmp/eth-natspec/keystore")
+ am := accounts.NewManager(ks)
+ testAccount, err := am.NewAccount("password")
+ if err != nil {
+ panic(err)
+ }
+ testAddress := strings.TrimPrefix(testAccount.Address.Hex(), "0x")
+
+ // set up mock genesis with balance on the testAddress
+ core.GenesisAccounts = []byte(`{
+ "` + testAddress + `": {"balance": "` + testBalance + `"}
+ }`)
+
+ // only use minimalistic stack with no networking
+ ethereum, err = eth.New(&eth.Config{
+ DataDir: "/tmp/eth-natspec",
+ AccountManager: am,
+ MaxPeers: 0,
+ })
+
+ if err != nil {
+ panic(err)
+ }
+
+ return
+}
+
+func testInit(t *testing.T) (self *testFrontend) {
+ // initialise and start minimal ethereum stack
+ ethereum, err := testEth(t)
+ if err != nil {
+ t.Errorf("error creating ethereum: %v", err)
+ return
+ }
+ err = ethereum.Start()
+ if err != nil {
+ t.Errorf("error starting ethereum: %v", err)
+ return
+ }
+
+ // mock frontend
+ self = &testFrontend{t: t, ethereum: ethereum}
+ self.xeth = xe.New(ethereum, self)
+
+ addr, _ := ethereum.Etherbase()
+ self.coinbase = addr
+ self.stateDb = self.ethereum.ChainManager().State().Copy()
+
+ // initialise the registry contracts
+ reg := registrar.New(self.xeth)
+ err = reg.SetHashReg("", addr)
+ if err != nil {
+ t.Errorf("error creating HashReg: %v", err)
+ }
+ err = reg.SetUrlHint("", addr)
+ if err != nil {
+ t.Errorf("error creating UrlHint: %v", err)
+ }
+ self.applyTxs()
+
+ return
+
+}
+
+// this is needed for transaction to be applied to the state in testing
+// the heavy lifing is done in XEth.ApplyTestTxs
+// this is fragile,
+// and does process leaking since xeth loops cannot quit safely
+// should be replaced by proper mining with testDAG for easy full integration tests
+func (self *testFrontend) applyTxs() {
+ self.txc, self.xeth = self.xeth.ApplyTestTxs(self.stateDb, self.coinbase, self.txc)
+ return
+}
+
+// end to end test
+func TestNatspecE2E(t *testing.T) {
+ t.Skip()
+
+ tf := testInit(t)
+ defer tf.ethereum.Stop()
+
+ // create a contractInfo file (mock cloud-deployed contract metadocs)
+ // incidentally this is the info for the registry contract itself
+ ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm)
+ dochash := common.BytesToHash(crypto.Sha3([]byte(testContractInfo)))
+
+ // take the codehash for the contract we wanna test
+ // codehex := tf.xeth.CodeAt(registar.HashRegAddr)
+ codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr)
+ codehash := common.BytesToHash(crypto.Sha3(codeb))
+
+ // use resolver to register codehash->dochash->url
+ // test if globalregistry works
+ // registrar.HashRefAddr = "0x0"
+ // registrar.UrlHintAddr = "0x0"
+ reg := registrar.New(tf.xeth)
+ _, err := reg.SetHashToHash(tf.coinbase, codehash, dochash)
+ if err != nil {
+ t.Errorf("error registering: %v", err)
+ }
+ _, err = reg.SetUrlToHash(tf.coinbase, dochash, "file:///"+testFileName)
+ if err != nil {
+ t.Errorf("error registering: %v", err)
+ }
+ // apply txs to the state
+ tf.applyTxs()
+
+ // NatSpec info for register method of HashReg contract installed
+ // now using the same transactions to check confirm messages
+
+ tf.wantNatSpec = true // this is set so now the backend uses natspec confirmation
+ _, err = reg.SetHashToHash(tf.coinbase, codehash, dochash)
+ if err != nil {
+ t.Errorf("error calling contract registry: %v", err)
+ }
+
+ fmt.Printf("GlobalRegistrar: %v, HashReg: %v, UrlHint: %v\n", registrar.GlobalRegistrarAddr, registrar.HashRegAddr, registrar.UrlHintAddr)
+ if tf.lastConfirm != testExpNotice {
+ t.Errorf("Wrong confirm message. expected '%v', got '%v'", testExpNotice, tf.lastConfirm)
+ }
+
+ // test unknown method
+ exp := fmt.Sprintf(testExpNotice2, registrar.HashRegAddr)
+ _, err = reg.SetOwner(tf.coinbase)
+ if err != nil {
+ t.Errorf("error setting owner: %v", err)
+ }
+
+ if tf.lastConfirm != exp {
+ t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
+ }
+
+ // test unknown contract
+ exp = fmt.Sprintf(testExpNotice3, registrar.UrlHintAddr)
+
+ _, err = reg.SetUrlToHash(tf.coinbase, dochash, "file:///test.content")
+ if err != nil {
+ t.Errorf("error registering: %v", err)
+ }
+
+ if tf.lastConfirm != exp {
+ t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
+ }
+
+}
diff --git a/common/natspec/natspec_js.go b/common/natspec/natspec_js.go
index 571044bde..ce41e72c4 100644
--- a/common/natspec/natspec_js.go
+++ b/common/natspec/natspec_js.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package natspec
const natspecJS = //`require=function t(e,n,r){function i(f,u){if(!n[f]){if(!e[f]){var s="function"==typeof require&&require;if(!u&&s)return s(f,!0);if(o)return o(f,!0);var c=new Error("Cannot find module '"+f+"'");throw c.code="MODULE_NOT_FOUND",c}var a=n[f]={exports:{}};e[f][0].call(a.exports,function(t){var n=e[f][1][t];return i(n?n:t)},a,a.exports,t,e,n,r)}return n[f].exports}for(var o="function"==typeof require&&require,f=0;f<r.length;f++)i(r[f]);return i}({1:[function(){},{}],2:[function(t,e){function n(){if(!f){f=!0;for(var t,e=o.length;e;){t=o,o=[];for(var n=-1;++n<e;)t[n]();e=o.length}f=!1}}function r(){}var i=e.exports={},o=[],f=!1;i.nextTick=function(t){o.push(t),f||setTimeout(n,0)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.on=r,i.addListener=r,i.once=r,i.off=r,i.removeListener=r,i.removeAllListeners=r,i.emit=r,i.binding=function(){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},{}],3:[function(t,e){var n=t("./utils"),r=t("./types"),i=t("./const"),o=t("./formatters"),f=function(t){console.error("parser does not support type: "+t)},u=function(t){return"[]"===t.slice(-2)},s=function(t,e){return u(t)||"string"===t?o.formatInputInt(e.length):""},c=r.inputTypes(),a=function(t,e){var n="",r="",i="";return t.forEach(function(t,r){n+=s(t.type,e[r])}),t.forEach(function(n,o){for(var s=!1,a=0;a<c.length&&!s;a++)s=c[a].type(t[o].type,e[o]);s||f(t[o].type);var l=c[a-1].format;u(t[o].type)?i+=e[o].reduce(function(t,e){return t+l(e)},""):"string"===t[o].type?i+=l(e[o]):r+=l(e[o])}),n+=r+i},l=function(t){return u(t)||"string"===t?2*i.ETH_PADDING:0},p=r.outputTypes(),h=function(t,e){e=e.slice(2);var n=[],s=2*i.ETH_PADDING,c=t.reduce(function(t,e){return t+l(e.type)},0),a=e.slice(0,c);return e=e.slice(c),t.forEach(function(i,c){for(var l=!1,h=0;h<p.length&&!l;h++)l=p[h].type(t[c].type);l||f(t[c].type);var g=p[h-1].format;if(u(t[c].type)){var m=o.formatOutputUInt(a.slice(0,s));a=a.slice(s);for(var d=[],v=0;m>v;v++)d.push(g(e.slice(0,s))),e=e.slice(s);n.push(d)}else r.prefixedType("string")(t[c].type)?(a=a.slice(s),n.push(g(e.slice(0,s))),e=e.slice(s)):(n.push(g(e.slice(0,s))),e=e.slice(s))}),n},g=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),i=n.extractTypeName(t.name),o=function(){var e=Array.prototype.slice.call(arguments);return a(t.inputs,e)};void 0===e[r]&&(e[r]=o),e[r][i]=o}),e},m=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),i=n.extractTypeName(t.name),o=function(e){return h(t.outputs,e)};void 0===e[r]&&(e[r]=o),e[r][i]=o}),e};e.exports={inputParser:g,outputParser:m,formatInput:a,formatOutput:h}},{"./const":4,"./formatters":5,"./types":6,"./utils":7}],4:[function(t,e){(function(n){if("build"!==n.env.NODE_ENV)var r=t("bignumber.js");var i=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:i,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3}}).call(this,t("_process"))},{_process:2,"bignumber.js":8}],5:[function(t,e){(function(n){if("build"!==n.env.NODE_ENV)var r=t("bignumber.js");var i=t("./utils"),o=t("./const"),f=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},u=function(t){var e=2*o.ETH_PADDING;return t instanceof r||"number"==typeof t?("number"==typeof t&&(t=new r(t)),r.config(o.ETH_BIGNUMBER_ROUNDING_MODE),t=t.round(),t.lessThan(0)&&(t=new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16).plus(t).plus(1)),t=t.toString(16)):t=0===t.indexOf("0x")?t.substr(2):"string"==typeof t?u(new r(t)):(+t).toString(16),f(t,e)},s=function(t){return i.fromAscii(t,o.ETH_PADDING).substr(2)},c=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},a=function(t){return u(new r(t).times(new r(2).pow(128)))},l=function(t){return"1"===new r(t.substr(0,1),16).toString(2).substr(0,1)},p=function(t){return t=t||"0",l(t)?new r(t,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(t,16)},h=function(t){return t=t||"0",new r(t,16)},g=function(t){return p(t).dividedBy(new r(2).pow(128))},m=function(t){return h(t).dividedBy(new r(2).pow(128))},d=function(t){return"0x"+t},v=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},w=function(t){return i.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:u,formatInputString:s,formatInputBool:c,formatInputReal:a,formatOutputInt:p,formatOutputUInt:h,formatOutputReal:g,formatOutputUReal:m,formatOutputHash:d,formatOutputBool:v,formatOutputString:w,formatOutputAddress:y}}).call(this,t("_process"))},{"./const":4,"./utils":7,_process:2,"bignumber.js":8}],6:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},i=function(t){return function(e){return t===e}},o=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("hash"),format:n.formatInputInt},{type:r("string"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:i("address"),format:n.formatInputInt},{type:i("bool"),format:n.formatInputBool}]},f=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("hash"),format:n.formatOutputHash},{type:r("string"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:i("address"),format:n.formatOutputAddress},{type:i("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:i,inputTypes:o,outputTypes:f}},{"./formatters":5}],7:[function(t,e){var n=t("./const"),r=function(t,e){for(var n=!1,r=0;r<t.length&&!n;r++)n=e(t[r]);return n?r-1:-1},i=function(t){var e="",n=0,r=t.length;for("0x"===t.substring(0,2)&&(n=2);r>n;n+=2){var i=parseInt(t.substr(n,2),16);if(0===i)break;e+=String.fromCharCode(i)}return e},o=function(t){for(var e="",n=0;n<t.length;n++){var r=t.charCodeAt(n).toString(16);e+=r.length<2?"0"+r:r}return e},f=function(t,e){e=void 0===e?0:e;for(var n=o(t);n.length<2*e;)n+="00";return"0x"+n},u=function(t){var e=t.indexOf("(");return-1!==e?t.substr(0,e):t},s=function(t){var e=t.indexOf("(");return-1!==e?t.substr(e+1,t.length-1-(e+1)).replace(" ",""):""},c=function(t){return t.filter(function(t){return"function"===t.type})},a=function(t){return t.filter(function(t){return"event"===t.type})},l=function(t){for(var e="string"==typeof t?0===t.indexOf("0x")?parseInt(t.substr(2),16):parseInt(t):t,r=0,i=n.ETH_UNITS;e>3e3&&r<i.length-1;)e/=1e3,r++;for(var o=e.toString().length<e.toFixed(2).length?e.toString():e.toFixed(2),f=function(t,e,n){return e+","+n};;){var u=o;if(o=o.replace(/(\d)(\d\d\d[\.\,])/,f),u===o)break}return o+" "+i[r]};e.exports={findIndex:r,toAscii:i,fromAscii:f,extractDisplayName:u,extractTypeName:s,filterFunctions:c,filterEvents:a,toEth:l}},{"./const":4}],8:[function(t,e){!function(n){"use strict";function r(t){function e(t,r){var i,o,f,u,s,c,a=this;if(!(a instanceof e))return $&&U(26,"constructor call without new",t),new e(t,r);if(null!=r&&z(r,2,64,L,"base")){if(r=0|r,c=t+"",10==r)return a=new e(t instanceof e?t:c),F(a,B+a.e+1,H);if((u="number"==typeof t)&&0*t!=0||!new RegExp("^-?"+(i="["+N.slice(0,r)+"]+")+"(?:\\."+i+")?$",37>r?"i":"").test(c))return m(a,c,u,r);u?(a.s=0>1/t?(c=c.slice(1),-1):1,$&&c.replace(/^0\.0*|\./,"").length>15&&U(L,O,t),u=!1):a.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1,c=n(c,10,r,a.s)}else{if(t instanceof e)return a.s=t.s,a.e=t.e,a.c=(t=t.c)?t.slice():t,void(L=0);if((u="number"==typeof t)&&0*t==0){if(a.s=0>1/t?(t=-t,-1):1,t===~~t){for(o=0,f=t;f>=10;f/=10,o++);return a.e=o,a.c=[t],void(L=0)}c=t+""}else{if(!d.test(c=t+""))return m(a,c,u);a.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1}}for((o=c.indexOf("."))>-1&&(c=c.replace(".","")),(f=c.search(/e/i))>0?(0>o&&(o=f),o+=+c.slice(f+1),c=c.substring(0,f)):0>o&&(o=c.length),f=0;48===c.charCodeAt(f);f++);for(s=c.length;48===c.charCodeAt(--s););if(c=c.slice(f,s+1))if(s=c.length,u&&$&&s>15&&U(L,O,a.s*t),o=o-f-1,o>q)a.c=a.e=null;else if(k>o)a.c=[a.e=0];else{if(a.e=o,a.c=[],f=(o+1)%I,0>o&&(f+=I),s>f){for(f&&a.c.push(+c.slice(0,f)),s-=I;s>f;)a.c.push(+c.slice(f,f+=I));c=c.slice(f),f=I-c.length}else f-=s;for(;f--;c+="0");a.c.push(+c)}else a.c=[a.e=0];L=0}function n(t,n,r,i){var f,u,s,a,p,h,g,m=t.indexOf("."),d=B,v=H;for(37>r&&(t=t.toLowerCase()),m>=0&&(s=Y,Y=0,t=t.replace(".",""),g=new e(r),p=g.pow(t.length-m),Y=s,g.c=c(l(o(p.c),p.e),10,n),g.e=g.c.length),h=c(t,r,n),u=s=h.length;0==h[--s];h.pop());if(!h[0])return"0";if(0>m?--u:(p.c=h,p.e=u,p.s=i,p=G(p,g,d,v,n),h=p.c,a=p.r,u=p.e),f=u+d+1,m=h[f],s=n/2,a=a||0>f||null!=h[f+1],a=4>v?(null!=m||a)&&(0==v||v==(p.s<0?3:2)):m>s||m==s&&(4==v||a||6==v&&1&h[f-1]||v==(p.s<0?8:7)),1>f||!h[0])t=a?l("1",-d):"0";else{if(h.length=f,a)for(--n;++h[--f]>n;)h[f]=0,f||(++u,h.unshift(1));for(s=h.length;!h[--s];);for(m=0,t="";s>=m;t+=N.charAt(h[m++]));t=l(t,u)}return t}function h(t,n,r,i){var f,u,s,c,p;if(r=null!=r&&z(r,0,8,i,b)?0|r:H,!t.c)return t.toString();if(f=t.c[0],s=t.e,null==n)p=o(t.c),p=19==i||24==i&&C>=s?a(p,s):l(p,s);else if(t=F(new e(t),n,r),u=t.e,p=o(t.c),c=p.length,19==i||24==i&&(u>=n||C>=u)){for(;n>c;p+="0",c++);p=a(p,u)}else if(n-=s,p=l(p,u),u+1>c){if(--n>0)for(p+=".";n--;p+="0");}else if(n+=u-c,n>0)for(u+1==c&&(p+=".");n--;p+="0");return t.s<0&&f?"-"+p:p}function S(t,n){var r,i,o=0;for(s(t[0])&&(t=t[0]),r=new e(t[0]);++o<t.length;){if(i=new e(t[o]),!i.s){r=i;break}n.call(r,i)&&(r=i)}return r}function A(t,e,n,r,i){return(e>t||t>n||t!=p(t))&&U(r,(i||"decimal places")+(e>t||t>n?" out of range":" not an integer"),t),!0}function R(t,e,n){for(var r=1,i=e.length;!e[--i];e.pop());for(i=e[0];i>=10;i/=10,r++);return(n=r+n*I-1)>q?t.c=t.e=null:k>n?t.c=[t.e=0]:(t.e=n,t.c=e),t}function U(t,e,n){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][t]+"() "+e+": "+n);throw r.name="BigNumber Error",L=0,r}function F(t,e,n,r){var i,o,f,u,s,c,a,l=t.c,p=_;if(l){t:{for(i=1,u=l[0];u>=10;u/=10,i++);if(o=e-i,0>o)o+=I,f=e,s=l[c=0],a=s/p[i-f-1]%10|0;else if(c=v((o+1)/I),c>=l.length){if(!r)break t;for(;l.length<=c;l.push(0));s=a=0,i=1,o%=I,f=o-I+1}else{for(s=u=l[c],i=1;u>=10;u/=10,i++);o%=I,f=o-I+i,a=0>f?0:s/p[i-f-1]%10|0}if(r=r||0>e||null!=l[c+1]||(0>f?s:s%p[i-f-1]),r=4>n?(a||r)&&(0==n||n==(t.s<0?3:2)):a>5||5==a&&(4==n||r||6==n&&(o>0?f>0?s/p[i-f]:0:l[c-1])%10&1||n==(t.s<0?8:7)),1>e||!l[0])return l.length=0,r?(e-=t.e+1,l[0]=p[e%I],t.e=-e||0):l[0]=t.e=0,t;if(0==o?(l.length=c,u=1,c--):(l.length=c+1,u=p[I-o],l[c]=f>0?w(s/p[i-f]%p[f])*u:0),r)for(;;){if(0==c){for(o=1,f=l[0];f>=10;f/=10,o++);for(f=l[0]+=u,u=1;f>=10;f/=10,u++);o!=u&&(t.e++,l[0]==E&&(l[0]=1));break}if(l[c]+=u,l[c]!=E)break;l[c--]=0,u=1}for(o=l.length;0===l[--o];l.pop());}t.e>q?t.c=t.e=null:t.e<k&&(t.c=[t.e=0])}return t}var G,L=0,M=e.prototype,P=new e(1),B=20,H=4,C=-7,j=21,k=-1e7,q=1e7,$=!0,z=A,V=!1,W=1,Y=100,Z={decimalSeparator:".",groupSeparator:",",groupSize:3,secondaryGroupSize:0,fractionGroupSeparator:" ",fractionGroupSize:0};return e.another=r,e.ROUND_UP=0,e.ROUND_DOWN=1,e.ROUND_CEIL=2,e.ROUND_FLOOR=3,e.ROUND_HALF_UP=4,e.ROUND_HALF_DOWN=5,e.ROUND_HALF_EVEN=6,e.ROUND_HALF_CEIL=7,e.ROUND_HALF_FLOOR=8,e.EUCLID=9,e.config=function(){var t,e,n=0,r={},i=arguments,o=i[0],f=o&&"object"==typeof o?function(){return o.hasOwnProperty(e)?null!=(t=o[e]):void 0}:function(){return i.length>n?null!=(t=i[n++]):void 0};return f(e="DECIMAL_PLACES")&&z(t,0,D,2,e)&&(B=0|t),r[e]=B,f(e="ROUNDING_MODE")&&z(t,0,8,2,e)&&(H=0|t),r[e]=H,f(e="EXPONENTIAL_AT")&&(s(t)?z(t[0],-D,0,2,e)&&z(t[1],0,D,2,e)&&(C=0|t[0],j=0|t[1]):z(t,-D,D,2,e)&&(C=-(j=0|(0>t?-t:t)))),r[e]=[C,j],f(e="RANGE")&&(s(t)?z(t[0],-D,-1,2,e)&&z(t[1],1,D,2,e)&&(k=0|t[0],q=0|t[1]):z(t,-D,D,2,e)&&(0|t?k=-(q=0|(0>t?-t:t)):$&&U(2,e+" cannot be zero",t))),r[e]=[k,q],f(e="ERRORS")&&(t===!!t||1===t||0===t?(L=0,z=($=!!t)?A:u):$&&U(2,e+y,t)),r[e]=$,f(e="CRYPTO")&&(t===!!t||1===t||0===t?(V=!(!t||!g||"object"!=typeof g),t&&!V&&$&&U(2,"crypto unavailable",g)):$&&U(2,e+y,t)),r[e]=V,f(e="MODULO_MODE")&&z(t,0,9,2,e)&&(W=0|t),r[e]=W,f(e="POW_PRECISION")&&z(t,0,D,2,e)&&(Y=0|t),r[e]=Y,f(e="FORMAT")&&("object"==typeof t?Z=t:$&&U(2,e+" not an object",t)),r[e]=Z,r},e.max=function(){return S(arguments,M.lt)},e.min=function(){return S(arguments,M.gt)},e.random=function(){var t=9007199254740992,n=Math.random()*t&2097151?function(){return w(Math.random()*t)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(t){var r,i,o,f,u,s=0,c=[],a=new e(P);if(t=null!=t&&z(t,0,D,14)?0|t:B,f=v(t/I),V)if(g&&g.getRandomValues){for(r=g.getRandomValues(new Uint32Array(f*=2));f>s;)u=131072*r[s]+(r[s+1]>>>11),u>=9e15?(i=g.getRandomValues(new Uint32Array(2)),r[s]=i[0],r[s+1]=i[1]):(c.push(u%1e14),s+=2);s=f/2}else if(g&&g.randomBytes){for(r=g.randomBytes(f*=7);f>s;)u=281474976710656*(31&r[s])+1099511627776*r[s+1]+4294967296*r[s+2]+16777216*r[s+3]+(r[s+4]<<16)+(r[s+5]<<8)+r[s+6],u>=9e15?g.randomBytes(7).copy(r,s):(c.push(u%1e14),s+=7);s=f/7}else $&&U(14,"crypto unavailable",g);if(!s)for(;f>s;)u=n(),9e15>u&&(c[s++]=u%1e14);for(f=c[--s],t%=I,f&&t&&(u=_[I-t],c[s]=w(f/u)*u);0===c[s];c.pop(),s--);if(0>s)c=[o=0];else{for(o=-1;0===c[0];c.shift(),o-=I);for(s=1,u=c[0];u>=10;u/=10,s++);I>s&&(o-=I-s)}return a.e=o,a.c=c,a}}(),G=function(){function t(t,e,n){var r,i,o,f,u=0,s=t.length,c=e%T,a=e/T|0;for(t=t.slice();s--;)o=t[s]%T,f=t[s]/T|0,r=a*o+f*c,i=c*o+r%T*T+u,u=(i/n|0)+(r/T|0)+a*f,t[s]=i%n;return u&&t.unshift(u),t}function n(t,e,n,r){var i,o;if(n!=r)o=n>r?1:-1;else for(i=o=0;n>i;i++)if(t[i]!=e[i]){o=t[i]>e[i]?1:-1;break}return o}function r(t,e,n,r){for(var i=0;n--;)t[n]-=i,i=t[n]<e[n]?1:0,t[n]=i*r+t[n]-e[n];for(;!t[0]&&t.length>1;t.shift());}return function(o,f,u,s,c){var a,l,p,h,g,m,d,v,y,b,O,N,x,_,T,D,S,A=o.s==f.s?1:-1,R=o.c,U=f.c;if(!(R&&R[0]&&U&&U[0]))return new e(o.s&&f.s&&(R?!U||R[0]!=U[0]:U)?R&&0==R[0]||!U?0*A:A/0:0/0);for(v=new e(A),y=v.c=[],l=o.e-f.e,A=u+l+1,c||(c=E,l=i(o.e/I)-i(f.e/I),A=A/I|0),p=0;U[p]==(R[p]||0);p++);if(U[p]>(R[p]||0)&&l--,0>A)y.push(1),h=!0;else{for(_=R.length,D=U.length,p=0,A+=2,g=w(c/(U[0]+1)),g>1&&(U=t(U,g,c),R=t(R,g,c),D=U.length,_=R.length),x=D,b=R.slice(0,D),O=b.length;D>O;b[O++]=0);S=U.slice(),S.unshift(0),T=U[0],U[1]>=c/2&&T++;do g=0,a=n(U,b,D,O),0>a?(N=b[0],D!=O&&(N=N*c+(b[1]||0)),g=w(N/T),g>1?(g>=c&&(g=c-1),m=t(U,g,c),d=m.length,O=b.length,a=n(m,b,d,O),1==a&&(g--,r(m,d>D?S:U,d,c))):(0==g&&(a=g=1),m=U.slice()),d=m.length,O>d&&m.unshift(0),r(b,m,O,c),-1==a&&(O=b.length,a=n(U,b,D,O),1>a&&(g++,r(b,O>D?S:U,O,c))),O=b.length):0===a&&(g++,b=[0]),y[p++]=g,a&&b[0]?b[O++]=R[x]||0:(b=[R[x]],O=1);while((x++<_||null!=b[0])&&A--);h=null!=b[0],y[0]||y.shift()}if(c==E){for(p=1,A=y[0];A>=10;A/=10,p++);F(v,u+(v.e=p+l*I-1)+1,s,h)}else v.e=l,v.r=+h;return v}}(),m==function(){var t=/^(-?)0([xbo])(\w[\w.]*$)/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,i=/^-?(Infinity|NaN)$/,o=/^\s*\+([\w.])|^\s+|\s+$/g;return function(f,u,s,c){var a,l=s?u:u.replace(o,"$1");if(i.test(l))f.s=isNaN(l)?null:0>l?-1:1;else{if(!s&&(l=l.replace(t,function(t,e,n){return a="x"==(n=n.toLowerCase())?16:"b"==n?2:8,c&&c!=a?t:e}),c&&(a=c,l=l.replace(n,"$1").replace(r,"0.$1")),u!=l))return new e(l,a);$&&U(L,"not a"+(c?" base "+c:"")+" number",u),f.s=null}f.c=f.e=null,L=0}}(),M.absoluteValue=M.abs=function(){var t=new e(this);return t.s<0&&(t.s=1),t},M.ceil=function(){return F(new e(this),this.e+1,2)},M.comparedTo=M.cmp=function(t,n){return L=1,f(this,new e(t,n))},M.decimalPlaces=M.dp=function(){var t,e,n=this.c;if(!n)return null;if(t=((e=n.length-1)-i(this.e/I))*I,e=n[e])for(;e%10==0;e/=10,t--);return 0>t&&(t=0),t},M.dividedBy=M.div=function(t,n){return L=3,G(this,new e(t,n),B,H)},M.dividedToIntegerBy=M.divToInt=function(t,n){return L=4,G(this,new e(t,n),0,1)},M.equals=M.eq=function(t,n){return L=5,0===f(this,new e(t,n))},M.floor=function(){return F(new e(this),this.e+1,3)},M.greaterThan=M.gt=function(t,n){return L=6,f(this,new e(t,n))>0},M.greaterThanOrEqualTo=M.gte=function(t,n){return L=7,1===(n=f(this,new e(t,n)))||0===n},M.isFinite=function(){return!!this.c},M.isInteger=M.isInt=function(){return!!this.c&&i(this.e/I)>this.c.length-2},M.isNaN=function(){return!this.s},M.isNegative=M.isNeg=function(){return this.s<0},M.isZero=function(){return!!this.c&&0==this.c[0]},M.lessThan=M.lt=function(t,n){return L=8,f(this,new e(t,n))<0},M.lessThanOrEqualTo=M.lte=function(t,n){return L=9,-1===(n=f(this,new e(t,n)))||0===n},M.minus=M.sub=function(t,n){var r,o,f,u,s=this,c=s.s;if(L=10,t=new e(t,n),n=t.s,!c||!n)return new e(0/0);if(c!=n)return t.s=-n,s.plus(t);var a=s.e/I,l=t.e/I,p=s.c,h=t.c;if(!a||!l){if(!p||!h)return p?(t.s=-n,t):new e(h?s:0/0);if(!p[0]||!h[0])return h[0]?(t.s=-n,t):new e(p[0]?s:3==H?-0:0)}if(a=i(a),l=i(l),p=p.slice(),c=a-l){for((u=0>c)?(c=-c,f=p):(l=a,f=h),f.reverse(),n=c;n--;f.push(0));f.reverse()}else for(o=(u=(c=p.length)<(n=h.length))?c:n,c=n=0;o>n;n++)if(p[n]!=h[n]){u=p[n]<h[n];break}if(u&&(f=p,p=h,h=f,t.s=-t.s),n=(o=h.length)-(r=p.length),n>0)for(;n--;p[r++]=0);for(n=E-1;o>c;){if(p[--o]<h[o]){for(r=o;r&&!p[--r];p[r]=n);--p[r],p[o]+=E}p[o]-=h[o]}for(;0==p[0];p.shift(),--l);return p[0]?R(t,p,l):(t.s=3==H?-1:1,t.c=[t.e=0],t)},M.modulo=M.mod=function(t,n){var r,i,o=this;return L=11,t=new e(t,n),!o.c||!t.s||t.c&&!t.c[0]?new e(0/0):!t.c||o.c&&!o.c[0]?new e(o):(9==W?(i=t.s,t.s=1,r=G(o,t,0,3),t.s=i,r.s*=i):r=G(o,t,0,W),o.minus(r.times(t)))},M.negated=M.neg=function(){var t=new e(this);return t.s=-t.s||null,t},M.plus=M.add=function(t,n){var r,o=this,f=o.s;if(L=12,t=new e(t,n),n=t.s,!f||!n)return new e(0/0);if(f!=n)return t.s=-n,o.minus(t);var u=o.e/I,s=t.e/I,c=o.c,a=t.c;if(!u||!s){if(!c||!a)return new e(f/0);if(!c[0]||!a[0])return a[0]?t:new e(c[0]?o:0*f)}if(u=i(u),s=i(s),c=c.slice(),f=u-s){for(f>0?(s=u,r=a):(f=-f,r=c),r.reverse();f--;r.push(0));r.reverse()}for(f=c.length,n=a.length,0>f-n&&(r=a,a=c,c=r,n=f),f=0;n;)f=(c[--n]=c[n]+a[n]+f)/E|0,c[n]%=E;return f&&(c.unshift(f),++s),R(t,c,s)},M.precision=M.sd=function(t){var e,n,r=this,i=r.c;if(null!=t&&t!==!!t&&1!==t&&0!==t&&($&&U(13,"argument"+y,t),t!=!!t&&(t=null)),!i)return null;if(n=i.length-1,e=n*I+1,n=i[n]){for(;n%10==0;n/=10,e--);for(n=i[0];n>=10;n/=10,e++);}return t&&r.e+1>e&&(e=r.e+1),e},M.round=function(t,n){var r=new e(this);return(null==t||z(t,0,D,15))&&F(r,~~t+this.e+1,null!=n&&z(n,0,8,15,b)?0|n:H),r},M.shift=function(t){var n=this;return z(t,-x,x,16,"argument")?n.times("1e"+p(t)):new e(n.c&&n.c[0]&&(-x>t||t>x)?n.s*(0>t?0:1/0):n)},M.squareRoot=M.sqrt=function(){var t,n,r,f,u,s=this,c=s.c,a=s.s,l=s.e,p=B+4,h=new e("0.5");if(1!==a||!c||!c[0])return new e(!a||0>a&&(!c||c[0])?0/0:c?s:1/0);if(a=Math.sqrt(+s),0==a||a==1/0?(n=o(c),(n.length+l)%2==0&&(n+="0"),a=Math.sqrt(n),l=i((l+1)/2)-(0>l||l%2),a==1/0?n="1e"+l:(n=a.toExponential(),n=n.slice(0,n.indexOf("e")+1)+l),r=new e(n)):r=new e(a+""),r.c[0])for(l=r.e,a=l+p,3>a&&(a=0);;)if(u=r,r=h.times(u.plus(G(s,u,p,1))),o(u.c).slice(0,a)===(n=o(r.c)).slice(0,a)){if(r.e<l&&--a,n=n.slice(a-3,a+1),"9999"!=n&&(f||"4999"!=n)){(!+n||!+n.slice(1)&&"5"==n.charAt(0))&&(F(r,r.e+B+2,1),t=!r.times(r).eq(s));break}if(!f&&(F(u,u.e+B+2,0),u.times(u).eq(s))){r=u;break}p+=4,a+=4,f=1}return F(r,r.e+B+1,H,t)},M.times=M.mul=function(t,n){var r,o,f,u,s,c,a,l,p,h,g,m,d,v,w,y=this,b=y.c,O=(L=17,t=new e(t,n)).c;if(!(b&&O&&b[0]&&O[0]))return!y.s||!t.s||b&&!b[0]&&!O||O&&!O[0]&&!b?t.c=t.e=t.s=null:(t.s*=y.s,b&&O?(t.c=[0],t.e=0):t.c=t.e=null),t;for(o=i(y.e/I)+i(t.e/I),t.s*=y.s,a=b.length,h=O.length,h>a&&(d=b,b=O,O=d,f=a,a=h,h=f),f=a+h,d=[];f--;d.push(0));for(v=E,w=T,f=h;--f>=0;){for(r=0,g=O[f]%w,m=O[f]/w|0,s=a,u=f+s;u>f;)l=b[--s]%w,p=b[s]/w|0,c=m*l+p*g,l=g*l+c%w*w+d[u]+r,r=(l/v|0)+(c/w|0)+m*p,d[u--]=l%v;d[u]=r}return r?++o:d.shift(),R(t,d,o)},M.toDigits=function(t,n){var r=new e(this);return t=null!=t&&z(t,1,D,18,"precision")?0|t:null,n=null!=n&&z(n,0,8,18,b)?0|n:H,t?F(r,t,n):r},M.toExponential=function(t,e){return h(this,null!=t&&z(t,0,D,19)?~~t+1:null,e,19)},M.toFixed=function(t,e){return h(this,null!=t&&z(t,0,D,20)?~~t+this.e+1:null,e,20)},M.toFormat=function(t,e){var n=h(this,null!=t&&z(t,0,D,21)?~~t+this.e+1:null,e,21);if(this.c){var r,i=n.split("."),o=+Z.groupSize,f=+Z.secondaryGroupSize,u=Z.groupSeparator,s=i[0],c=i[1],a=this.s<0,l=a?s.slice(1):s,p=l.length;if(f&&(r=o,o=f,f=r,p-=r),o>0&&p>0){for(r=p%o||o,s=l.substr(0,r);p>r;r+=o)s+=u+l.substr(r,o);f>0&&(s+=u+l.slice(r)),a&&(s="-"+s)}n=c?s+Z.decimalSeparator+((f=+Z.fractionGroupSize)?c.replace(new RegExp("\\d{"+f+"}\\B","g"),"$&"+Z.fractionGroupSeparator):c):s}return n},M.toFraction=function(t){var n,r,i,f,u,s,c,a,l,p=$,h=this,g=h.c,m=new e(P),d=r=new e(P),v=c=new e(P);if(null!=t&&($=!1,s=new e(t),$=p,(!(p=s.isInt())||s.lt(P))&&($&&U(22,"max denominator "+(p?"out of range":"not an integer"),t),t=!p&&s.c&&F(s,s.e+1,1).gte(P)?s:null)),!g)return h.toString();for(l=o(g),f=m.e=l.length-h.e-1,m.c[0]=_[(u=f%I)<0?I+u:u],t=!t||s.cmp(m)>0?f>0?m:d:s,u=q,q=1/0,s=new e(l),c.c[0]=0;a=G(s,m,0,1),i=r.plus(a.times(v)),1!=i.cmp(t);)r=v,v=i,d=c.plus(a.times(i=d)),c=i,m=s.minus(a.times(i=m)),s=i;return i=G(t.minus(r),v,0,1),c=c.plus(i.times(d)),r=r.plus(i.times(v)),c.s=d.s=h.s,f*=2,n=G(d,v,f,H).minus(h).abs().cmp(G(c,r,f,H).minus(h).abs())<1?[d.toString(),v.toString()]:[c.toString(),r.toString()],q=u,n},M.toNumber=function(){var t=this;return+t||(t.s?0*t.s:0/0)},M.toPower=M.pow=function(t){var n,r,i=w(0>t?-t:+t),o=this;if(!z(t,-x,x,23,"exponent")&&(!isFinite(t)||i>x&&(t/=0)||parseFloat(t)!=t&&!(t=0/0)))return new e(Math.pow(+o,t));for(n=Y?v(Y/I+2):0,r=new e(P);;){if(i%2){if(r=r.times(o),!r.c)break;n&&r.c.length>n&&(r.c.length=n)}if(i=w(i/2),!i)break;o=o.times(o),n&&o.c&&o.c.length>n&&(o.c.length=n)}return 0>t&&(r=P.div(r)),n?F(r,Y,H):r},M.toPrecision=function(t,e){return h(this,null!=t&&z(t,1,D,24,"precision")?0|t:null,e,24)},M.toString=function(t){var e,r=this,i=r.s,f=r.e;return null===f?i?(e="Infinity",0>i&&(e="-"+e)):e="NaN":(e=o(r.c),e=null!=t&&z(t,2,64,25,"base")?n(l(e,f),0|t,10,i):C>=f||f>=j?a(e,f):l(e,f),0>i&&r.c[0]&&(e="-"+e)),e},M.truncated=M.trunc=function(){return F(new e(this),this.e+1,1)},M.valueOf=M.toJSON=function(){return this.toString()},null!=t&&e.config(t),e}function i(t){var e=0|t;return t>0||t===e?e:e-1}function o(t){for(var e,n,r=1,i=t.length,o=t[0]+"";i>r;){for(e=t[r++]+"",n=I-e.length;n--;e="0"+e);o+=e}for(i=o.length;48===o.charCodeAt(--i););return o.slice(0,i+1||1)}function f(t,e){var n,r,i=t.c,o=e.c,f=t.s,u=e.s,s=t.e,c=e.e;if(!f||!u)return null;if(n=i&&!i[0],r=o&&!o[0],n||r)return n?r?0:-u:f;if(f!=u)return f;if(n=0>f,r=s==c,!i||!o)return r?0:!i^n?1:-1;if(!r)return s>c^n?1:-1;for(u=(s=i.length)<(c=o.length)?s:c,f=0;u>f;f++)if(i[f]!=o[f])return i[f]>o[f]^n?1:-1;return s==c?0:s>c^n?1:-1}function u(t,e,n){return(t=p(t))>=e&&n>=t}function s(t){return"[object Array]"==Object.prototype.toString.call(t)}function c(t,e,n){for(var r,i,o=[0],f=0,u=t.length;u>f;){for(i=o.length;i--;o[i]*=e);for(o[r=0]+=N.indexOf(t.charAt(f++));r<o.length;r++)o[r]>n-1&&(null==o[r+1]&&(o[r+1]=0),o[r+1]+=o[r]/n|0,o[r]%=n)}return o.reverse()}function a(t,e){return(t.length>1?t.charAt(0)+"."+t.slice(1):t)+(0>e?"e":"e+")+e}function l(t,e){var n,r;if(0>e){for(r="0.";++e;r+="0");t=r+t}else if(n=t.length,++e>n){for(r="0",e-=n;--e;r+="0");t+=r}else n>e&&(t=t.slice(0,e)+"."+t.slice(e));return t}function p(t){return t=parseFloat(t),0>t?v(t):w(t)}var h,g,m,d=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,v=Math.ceil,w=Math.floor,y=" not a boolean or binary digit",b="rounding mode",O="number type has more than 15 significant digits",N="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",E=1e14,I=14,x=9007199254740991,_=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],T=1e7,D=1e9;if(h=r(),"function"==typeof define&&define.amd)define(function(){return h});else if("undefined"!=typeof e&&e.exports){if(e.exports=h,!g)try{g=t("crypto")}catch(S){}}else n.BigNumber=h}(this)},{crypto:1}],natspec:[function(t,e){var n=t("./node_modules/ethereum.js/lib/abi.js"),r=function(){var t=function(t,e){Object.keys(t).forEach(function(n){e[n]=t[n]})},e=function(t){return Object.keys(t).reduce(function(t,e){return t+"var "+e+" = context['"+e+"'];\n"},"")},r=function(t,e){return t.filter(function(t){return t.name===e})[0]},i=function(t,e){var r=n.formatOutput(t.inputs,"0x"+e.params[0].data.slice(10));return t.inputs.reduce(function(t,e,n){return t[e.name]=r[n],t},{})},o=function(t,e){var n,r="",i=/\` + "`" + `(?:\\.|[^` + "`" + `\\])*\` + "`" + `/gim,o=0;try{for(;null!==(n=i.exec(t));){var f=i.lastIndex-n[0].length,u=n[0].slice(1,n[0].length-1);r+=t.slice(o,f);var s=e(u);r+=s,o=i.lastIndex}r+=t.slice(o)}catch(c){throw new Error("Natspec evaluation failed, wrong input params")}return r},f=function(n,f){var u={};if(f)try{var s=r(f.abi,f.method),c=i(s,f.transaction);t(c,u)}catch(a){throw new Error("Natspec evaluation failed, method does not exist")}var l=e(u),p=o(n,function(t){var e=new Function("context",l+"return "+t+";");return e(u).toString()});return p},u=function(t,e){try{return f(t,e)}catch(n){return n.message}};return{evaluateExpression:f,evaluateExpressionSafe:u}}();e.exports=r},{"./node_modules/ethereum.js/lib/abi.js":3}]},{},[]);
diff --git a/common/natspec/natspec_test.go b/common/natspec/natspec_test.go
index 05df9e750..654e3a62d 100644
--- a/common/natspec/natspec_test.go
+++ b/common/natspec/natspec_test.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package natspec
import (
diff --git a/common/number/int.go b/common/number/int.go
index 6cc5e68b4..aa54227d7 100644
--- a/common/number/int.go
+++ b/common/number/int.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package number
import (
diff --git a/common/number/uint_test.go b/common/number/uint_test.go
index 262d584ed..ea1d5ce1f 100644
--- a/common/number/uint_test.go
+++ b/common/number/uint_test.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package number
import (
diff --git a/common/package.go b/common/package.go
index 7f38d8e4d..bb2d41c1e 100644
--- a/common/package.go
+++ b/common/package.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/path.go b/common/path.go
index 6e3259656..def2c76f4 100644
--- a/common/path.go
+++ b/common/path.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/path_test.go b/common/path_test.go
index 4b90c543b..410937c53 100644
--- a/common/path_test.go
+++ b/common/path_test.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/registrar/contracts.go b/common/registrar/contracts.go
new file mode 100644
index 000000000..ab8fc543c
--- /dev/null
+++ b/common/registrar/contracts.go
@@ -0,0 +1,163 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package registrar
+
+const ( // built-in contracts address source code and evm code
+ UrlHintCode = "0x60c180600c6000396000f30060003560e060020a90048063300a3bbf14601557005b6024600435602435604435602a565b60006000f35b6000600084815260200190815260200160002054600160a060020a0316600014806078575033600160a060020a03166000600085815260200190815260200160002054600160a060020a0316145b607f5760bc565b336000600085815260200190815260200160002081905550806001600085815260200190815260200160002083610100811060b657005b01819055505b50505056"
+
+ UrlHintSrc = `
+contract URLhint {
+ function register(uint256 _hash, uint8 idx, uint256 _url) {
+ if (owner[_hash] == 0 || owner[_hash] == msg.sender) {
+ owner[_hash] = msg.sender;
+ url[_hash][idx] = _url;
+ }
+ }
+ mapping (uint256 => address) owner;
+ (uint256 => uint256[256]) url;
+}
+ `
+
+ HashRegCode = "0x609880600c6000396000f30060003560e060020a9004806331e12c2014601f578063d66d6c1014602b57005b6025603d565b60006000f35b6037600435602435605d565b60006000f35b600054600160a060020a0316600014605357605b565b336000819055505b565b600054600160a060020a031633600160a060020a031614607b576094565b8060016000848152602001908152602001600020819055505b505056"
+
+ HashRegSrc = `
+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;
+}
+`
+
+ GlobalRegistrarSrc = `
+//sol
+
+import "owned";
+
+contract NameRegister {
+ function addr(bytes32 _name) constant returns (address o_owner) {}
+ function name(address _owner) constant returns (bytes32 o_name) {}
+}
+
+contract Registrar is NameRegister {
+ event Changed(bytes32 indexed name);
+ event PrimaryChanged(bytes32 indexed name, address indexed addr);
+
+ function owner(bytes32 _name) constant returns (address o_owner) {}
+ function addr(bytes32 _name) constant returns (address o_address) {}
+ function subRegistrar(bytes32 _name) constant returns (address o_subRegistrar) {}
+ function content(bytes32 _name) constant returns (bytes32 o_content) {}
+
+ function name(address _owner) constant returns (bytes32 o_name) {}
+}
+
+contract GlobalRegistrar is Registrar {
+ struct Record {
+ address owner;
+ address primary;
+ address subRegistrar;
+ bytes32 content;
+ uint value;
+ uint renewalDate;
+ }
+
+ function Registrar() {
+ // TODO: Populate with hall-of-fame.
+ }
+
+ function reserve(bytes32 _name) {
+ // Don't allow the same name to be overwritten.
+ // TODO: bidding mechanism
+ if (m_toRecord[_name].owner == 0) {
+ m_toRecord[_name].owner = msg.sender;
+ Changed(_name);
+ }
+ }
+
+ /*
+ TODO
+ > 12 chars: free
+ <= 12 chars: auction:
+ 1. new names are auctioned
+ - 7 day period to collect all bid bytes32es + deposits
+ - 1 day period to collect all bids to be considered (validity requires associated deposit to be >10% of bid)
+ - all valid bids are burnt except highest - difference between that and second highest is returned to winner
+ 2. remember when last auctioned/renewed
+ 3. anyone can force renewal process:
+ - 7 day period to collect all bid bytes32es + deposits
+ - 1 day period to collect all bids & full amounts - bids only uncovered if sufficiently high.
+ - 1% of winner burnt; original owner paid rest.
+ */
+
+ modifier onlyrecordowner(bytes32 _name) { if (m_toRecord[_name].owner == msg.sender) _ }
+
+ function transfer(bytes32 _name, address _newOwner) onlyrecordowner(_name) {
+ m_toRecord[_name].owner = _newOwner;
+ Changed(_name);
+ }
+
+ function disown(bytes32 _name) onlyrecordowner(_name) {
+ if (m_toName[m_toRecord[_name].primary] == _name)
+ {
+ PrimaryChanged(_name, m_toRecord[_name].primary);
+ m_toName[m_toRecord[_name].primary] = "";
+ }
+ delete m_toRecord[_name];
+ Changed(_name);
+ }
+
+ function setAddress(bytes32 _name, address _a, bool _primary) onlyrecordowner(_name) {
+ m_toRecord[_name].primary = _a;
+ if (_primary)
+ {
+ PrimaryChanged(_name, _a);
+ m_toName[_a] = _name;
+ }
+ Changed(_name);
+ }
+ function setSubRegistrar(bytes32 _name, address _registrar) onlyrecordowner(_name) {
+ m_toRecord[_name].subRegistrar = _registrar;
+ Changed(_name);
+ }
+ function setContent(bytes32 _name, bytes32 _content) onlyrecordowner(_name) {
+ m_toRecord[_name].content = _content;
+ Changed(_name);
+ }
+
+ function owner(bytes32 _name) constant returns (address) { return m_toRecord[_name].owner; }
+ function addr(bytes32 _name) constant returns (address) { return m_toRecord[_name].primary; }
+// function subRegistrar(bytes32 _name) constant returns (address) { return m_toRecord[_name].subRegistrar; } // TODO: bring in on next iteration.
+ function register(bytes32 _name) constant returns (address) { return m_toRecord[_name].subRegistrar; } // only possible for now
+ function content(bytes32 _name) constant returns (bytes32) { return m_toRecord[_name].content; }
+ function name(address _owner) constant returns (bytes32 o_name) { return m_toName[_owner]; }
+
+ mapping (address => bytes32) m_toName;
+ mapping (bytes32 => Record) m_toRecord;
+}
+`
+ GlobalRegistrarAbi = `[{"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"}]`
+
+ GlobalRegistrarCode = `0x610b408061000e6000396000f3006000357c01000000000000000000000000000000000000000000000000000000009004806301984892146100b357806302571be3146100ce5780632dff6941146100ff5780633b3b57de1461011a578063432ced041461014b5780635a3a05bd1461016257806379ce9fac1461019357806389a69c0e146101b0578063b9f37c86146101cd578063be99a980146101de578063c3d014d614610201578063d93e75731461021e578063e1fa8e841461023557005b6100c4600480359060200150610b02565b8060005260206000f35b6100df6004803590602001506109f3565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b610110600480359060200150610ad4565b8060005260206000f35b61012b600480359060200150610a3e565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b61015c600480359060200150610271565b60006000f35b610173600480359060200150610266565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101aa600480359060200180359060200150610341565b60006000f35b6101c7600480359060200180359060200150610844565b60006000f35b6101d860045061026e565b60006000f35b6101fb6004803590602001803590602001803590602001506106de565b60006000f35b61021860048035906020018035906020015061092c565b60006000f35b61022f600480359060200150610429565b60006000f35b610246600480359060200150610a89565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b60005b919050565b5b565b60006001600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561033d57336001600050600083815260200190815260200160002060005060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550807fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc6040604090036040a25b5b50565b813373ffffffffffffffffffffffffffffffffffffffff166001600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561042357816001600050600085815260200190815260200160002060005060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc6040604090036040a25b505b5050565b803373ffffffffffffffffffffffffffffffffffffffff166001600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156106d95781600060005060006001600050600086815260200190815260200160002060005060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505414156105fd576001600050600083815260200190815260200160002060005060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85456040604090036040a36000600060005060006001600050600086815260200190815260200160002060005060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b6001600050600083815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160005060009055600482016000506000905560058201600050600090555050817fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc6040604090036040a25b505b50565b823373ffffffffffffffffffffffffffffffffffffffff166001600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561083d57826001600050600086815260200190815260200160002060005060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055508115610811578273ffffffffffffffffffffffffffffffffffffffff16847ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85456040604090036040a383600060005060008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b837fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc6040604090036040a25b505b505050565b813373ffffffffffffffffffffffffffffffffffffffff166001600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561092657816001600050600085815260200190815260200160002060005060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc6040604090036040a25b505b5050565b813373ffffffffffffffffffffffffffffffffffffffff166001600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156109ed57816001600050600085815260200190815260200160002060005060030160005081905550827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc6040604090036040a25b505b5050565b60006001600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610a39565b919050565b60006001600050600083815260200190815260200160002060005060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610a84565b919050565b60006001600050600083815260200190815260200160002060005060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610acf565b919050565b600060016000506000838152602001908152602001600020600050600301600050549050610afd565b919050565b6000600060005060008373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549050610b3b565b91905056`
+)
diff --git a/common/registrar/ethreg/ethreg.go b/common/registrar/ethreg/ethreg.go
new file mode 100644
index 000000000..e7df1e7f6
--- /dev/null
+++ b/common/registrar/ethreg/ethreg.go
@@ -0,0 +1,48 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package ethreg
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common/registrar"
+ "github.com/ethereum/go-ethereum/xeth"
+)
+
+// implements a versioned Registrar on an archiving full node
+type EthReg struct {
+ backend *xeth.XEth
+ registry *registrar.Registrar
+}
+
+func New(xe *xeth.XEth) (self *EthReg) {
+ self = &EthReg{backend: xe}
+ self.registry = registrar.New(xe)
+ return
+}
+
+func (self *EthReg) Registry() *registrar.Registrar {
+ return self.registry
+}
+
+func (self *EthReg) Resolver(n *big.Int) *registrar.Registrar {
+ xe := self.backend
+ if n != nil {
+ xe = self.backend.AtStateNum(n.Int64())
+ }
+ return registrar.New(xe)
+}
diff --git a/common/registrar/registrar.go b/common/registrar/registrar.go
new file mode 100644
index 000000000..64fa97f6e
--- /dev/null
+++ b/common/registrar/registrar.go
@@ -0,0 +1,408 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. 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 (HashReg and UrlHint retrieved from the global
+registrar the first time any Registrar method is called in a client session
+
+So the caller needs to make sure the relevant environment initialised the desired
+contracts
+*/
+var (
+ UrlHintAddr = "0x0"
+ HashRegAddr = "0x0"
+ GlobalRegistrarAddr = "0x0"
+ // GlobalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
+
+ zero = regexp.MustCompile("^(0x)?0*$")
+)
+
+const (
+ trueHex = "0000000000000000000000000000000000000000000000000000000000000001"
+ falseHex = "0000000000000000000000000000000000000000000000000000000000000000"
+)
+
+func abiSignature(s string) string {
+ return common.ToHex(crypto.Sha3([]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 GlobalRegistrarAddr == "0x0" || GlobalRegistrarAddr == "0x" {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ _, 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) {
+ 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) {
+ // 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("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) {
+ // 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("GetURLhint: 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.Sha3(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):], ""
+}
diff --git a/common/registrar/registrar_test.go b/common/registrar/registrar_test.go
new file mode 100644
index 000000000..4b9a77a68
--- /dev/null
+++ b/common/registrar/registrar_test.go
@@ -0,0 +1,112 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package registrar
+
+import (
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+type testBackend struct {
+ // contracts mock
+ contracts map[string](map[string]string)
+}
+
+var (
+ text = "test"
+ codehash = common.StringToHash("1234")
+ hash = common.BytesToHash(crypto.Sha3([]byte(text)))
+ url = "bzz://bzzhash/my/path/contr.act"
+)
+
+func NewTestBackend() *testBackend {
+ HashRegAddr = common.BigToAddress(common.Big0).Hex() //[2:]
+ UrlHintAddr = common.BigToAddress(common.Big1).Hex() //[2:]
+ self := &testBackend{}
+ self.contracts = make(map[string](map[string]string))
+
+ self.contracts[HashRegAddr[2:]] = make(map[string]string)
+ key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:]))
+ self.contracts[HashRegAddr[2:]][key] = hash.Hex()
+
+ self.contracts[UrlHintAddr[2:]] = make(map[string]string)
+ mapaddr := storageMapping(storageIdx2Addr(1), hash[:])
+
+ key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0)))
+ self.contracts[UrlHintAddr[2:]][key] = common.ToHex([]byte(url))
+ key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1)))
+ self.contracts[UrlHintAddr[2:]][key] = "0x0"
+ return self
+}
+
+func (self *testBackend) StorageAt(ca, sa string) (res string) {
+ c := self.contracts[ca]
+ if c == nil {
+ return
+ }
+ res = c[sa]
+ return
+}
+
+func (self *testBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
+ return "", nil
+}
+
+func (self *testBackend) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, string, error) {
+ return "", "", nil
+}
+
+func TestSetGlobalRegistrar(t *testing.T) {
+ b := NewTestBackend()
+ res := New(b)
+ _, err := res.SetGlobalRegistrar("addresshex", common.BigToAddress(common.Big1))
+ if err != nil {
+ t.Errorf("unexpected error: %v'", err)
+ }
+}
+
+func TestHashToHash(t *testing.T) {
+ b := NewTestBackend()
+ res := New(b)
+ // res.SetHashReg()
+
+ got, err := res.HashToHash(codehash)
+ if err != nil {
+ t.Errorf("expected no error, got %v", err)
+ } else {
+ if got != hash {
+ t.Errorf("incorrect result, expected '%v', got '%v'", hash.Hex(), got.Hex())
+ }
+ }
+}
+
+func TestHashToUrl(t *testing.T) {
+ b := NewTestBackend()
+ res := New(b)
+ // res.SetUrlHint()
+
+ got, err := res.HashToUrl(hash)
+ if err != nil {
+ t.Errorf("expected error, got %v", err)
+ } else {
+ if got != url {
+ t.Errorf("incorrect result, expected '%v', got '%s'", url, got)
+ }
+ }
+}
diff --git a/common/resolver/contracts.go b/common/resolver/contracts.go
deleted file mode 100644
index 4aad95e43..000000000
--- a/common/resolver/contracts.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package resolver
-
-const ( // built-in contracts address and code
- ContractCodeURLhint = "0x60c180600c6000396000f30060003560e060020a90048063300a3bbf14601557005b6024600435602435604435602a565b60006000f35b6000600084815260200190815260200160002054600160a060020a0316600014806078575033600160a060020a03166000600085815260200190815260200160002054600160a060020a0316145b607f5760bc565b336000600085815260200190815260200160002081905550806001600085815260200190815260200160002083610100811060b657005b01819055505b50505056"
- /*
- contract URLhint {
- function register(uint256 _hash, uint8 idx, uint256 _url) {
- if (owner[_hash] == 0 || owner[_hash] == msg.sender) {
- owner[_hash] = msg.sender;
- url[_hash][idx] = _url;
- }
- }
- mapping (uint256 => address) owner;
- mapping (uint256 => uint256[256]) 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;
- }
- */
-
-)
diff --git a/common/resolver/resolver.go b/common/resolver/resolver.go
deleted file mode 100644
index 9016547e1..000000000
--- a/common/resolver/resolver.go
+++ /dev/null
@@ -1,232 +0,0 @@
-package resolver
-
-import (
- "encoding/binary"
- "fmt"
-
- "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"
-)
-
-/*
-Resolver implements the Ethereum DNS mapping
-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
-of a url scheme
-*/
-
-// // contract addresses will be hardcoded after they're created
-var UrlHintContractAddress, HashRegContractAddress string
-
-const (
- txValue = "0"
- txGas = "100000"
- txGasPrice = "1000000000000"
-)
-
-func abi(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()")
-)
-
-type Backend interface {
- StorageAt(string, string) string
- Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error)
-}
-
-type Resolver struct {
- backend Backend
-}
-
-func New(eth Backend) *Resolver {
- return &Resolver{eth}
-}
-
-// 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)
- if err != nil {
- return
- }
- UrlHintContractAddress, err = self.backend.Transact(addr.Hex(), "", "", txValue, txGas, txGasPrice, ContractCodeURLhint)
- glog.V(logger.Detail).Infof("HashReg @ %v\nUrlHint @ %v\n", HashRegContractAddress, UrlHintContractAddress)
- return
-}
-
-// called as first step in the registration process on HashReg
-func (self *Resolver) SetOwner(address common.Address) (txh string, err error) {
- return self.backend.Transact(
- address.Hex(),
- HashRegContractAddress,
- "", txValue, txGas, txGasPrice,
- 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
-// kept
-func (self *Resolver) RegisterContentHash(address common.Address, codehash, dochash common.Hash) (txh string, err error) {
- _, err = self.SetOwner(address)
- if err != nil {
- return
- }
- codehex := common.Bytes2Hex(codehash[:])
- dochex := common.Bytes2Hex(dochash[:])
-
- data := registerContentHashAbi + codehex + dochex
- return self.backend.Transact(
- address.Hex(),
- HashRegContractAddress,
- "", txValue, txGas, txGasPrice,
- data,
- )
-}
-
-// 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
-// it could be purely
-func (self *Resolver) RegisterUrl(address common.Address, hash common.Hash, url string) (txh string, err error) {
- 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(),
- UrlHintContractAddress,
- "", txValue, txGas, txGasPrice,
- data,
- )
- if err != nil {
- return
- }
- cnt++
- }
- return
-}
-
-func (self *Resolver) Register(address common.Address, codehash, dochash common.Hash, url string) (txh string, err error) {
-
- _, err = self.RegisterContentHash(address, codehash, dochash)
- if err != nil {
- return
- }
- return self.RegisterUrl(address, dochash, url)
-}
-
-// resolution is costless non-transactional
-// 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))
- key := storageAddress(storageMapping(storageIdx2Addr(1), khash[:]))
- hash := self.backend.StorageAt(at, key)
-
- if hash == "0x0" || len(hash) < 3 {
- err = fmt.Errorf("content hash not found for '%v'", khash.Hex())
- return
- }
- copy(chash[:], common.Hex2BytesFixed(hash[2:], 32))
- return
-}
-
-// retrieves the url-hint for the content hash -
-// if we use content addressed storage, this step is no longer necessary
-func (self *Resolver) ContentHashToUrl(chash common.Hash) (uri string, err error) {
- // 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(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++
- }
-
- if len(uri) == 0 {
- err = fmt.Errorf("GetURLhint: URL hint not found for '%v'", chash.Hex())
- }
- return
-}
-
-func (self *Resolver) KeyToUrl(key common.Hash) (uri string, hash common.Hash, err error) {
- // look up in urlHint
- hash, err = self.KeyToContentHash(key)
- if err != nil {
- return
- }
- uri, err = self.ContentHashToUrl(hash)
- 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.Sha3(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)
-}
diff --git a/common/resolver/resolver_test.go b/common/resolver/resolver_test.go
deleted file mode 100644
index 02d12592e..000000000
--- a/common/resolver/resolver_test.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package resolver
-
-import (
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-type testBackend struct {
- // contracts mock
- contracts map[string](map[string]string)
-}
-
-var (
- text = "test"
- codehash = common.StringToHash("1234")
- hash = common.BytesToHash(crypto.Sha3([]byte(text)))
- url = "bzz://bzzhash/my/path/contr.act"
-)
-
-func NewTestBackend() *testBackend {
- 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)
- key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:]))
- self.contracts[HashRegContractAddress][key] = hash.Hex()
-
- self.contracts[UrlHintContractAddress] = make(map[string]string)
- mapaddr := storageMapping(storageIdx2Addr(1), hash[:])
-
- key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0)))
- self.contracts[UrlHintContractAddress][key] = common.ToHex([]byte(url))
- key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1)))
- self.contracts[UrlHintContractAddress][key] = "0x00"
- return self
-}
-
-func (self *testBackend) StorageAt(ca, sa string) (res string) {
- c := self.contracts[ca]
- if c == nil {
- return
- }
- res = c[sa]
- return
-}
-
-func (self *testBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
- return "", nil
-}
-
-func TestKeyToContentHash(t *testing.T) {
- b := NewTestBackend()
- res := New(b)
-
- got, err := res.KeyToContentHash(codehash)
- if err != nil {
- t.Errorf("expected no error, got %v", err)
- } else {
- if got != hash {
- t.Errorf("incorrect result, expected '%v', got '%v'", hash.Hex(), got.Hex())
- }
- }
-}
-
-func TestContentHashToUrl(t *testing.T) {
- b := NewTestBackend()
- res := New(b)
- got, err := res.ContentHashToUrl(hash)
- if err != nil {
- t.Errorf("expected no error, got %v", err)
- } else {
- if got != url {
- t.Errorf("incorrect result, expected '%v', got '%s'", url, got)
- }
- }
-}
-
-func TestKeyToUrl(t *testing.T) {
- b := NewTestBackend()
- res := New(b)
- got, _, err := res.KeyToUrl(codehash)
- if err != nil {
- t.Errorf("expected no error, got %v", err)
- } else {
- if got != url {
- t.Errorf("incorrect result, expected \n'%s', got \n'%s'", url, got)
- }
- }
-}
diff --git a/common/rlp.go b/common/rlp.go
index 06ac410e9..670d5b6e3 100644
--- a/common/rlp.go
+++ b/common/rlp.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/rlp_test.go b/common/rlp_test.go
index 2a55da928..75949c40d 100644
--- a/common/rlp_test.go
+++ b/common/rlp_test.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/size.go b/common/size.go
index 4ea7f7b11..2fc2dfd7b 100644
--- a/common/size.go
+++ b/common/size.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/size_test.go b/common/size_test.go
index cfe7efe31..48cf3cab3 100644
--- a/common/size_test.go
+++ b/common/size_test.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/test_utils.go b/common/test_utils.go
index 8346c147a..96ed31cad 100644
--- a/common/test_utils.go
+++ b/common/test_utils.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/types.go b/common/types.go
index e41112a77..69d16ad4b 100644
--- a/common/types.go
+++ b/common/types.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/types_template.go b/common/types_template.go
index 1c82a36dc..64ca6f73d 100644
--- a/common/types_template.go
+++ b/common/types_template.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
// +build none
//sed -e 's/_N_/Hash/g' -e 's/_S_/32/g' -e '1d' types_template.go | gofmt -w hash.go
diff --git a/common/types_test.go b/common/types_test.go
index 9f303152c..21ae5706c 100644
--- a/common/types_test.go
+++ b/common/types_test.go
@@ -1,3 +1,19 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import "testing"
diff --git a/common/value.go b/common/value.go
index c3893d565..5409a2c68 100644
--- a/common/value.go
+++ b/common/value.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (
diff --git a/common/value_test.go b/common/value_test.go
index 38a0e9843..139a7f999 100644
--- a/common/value_test.go
+++ b/common/value_test.go
@@ -1,3 +1,19 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum 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.
+//
+// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
package common
import (