mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
common: delete dead code
This commit is contained in:
parent
8a8102e7ab
commit
5369616e16
9 changed files with 0 additions and 810 deletions
|
|
@ -23,7 +23,6 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
|
|
@ -82,19 +81,6 @@ func StartNode(stack *node.Node) {
|
|||
}()
|
||||
}
|
||||
|
||||
func FormatTransactionData(data string) []byte {
|
||||
d := common.StringToByteFunc(data, func(s string) (ret []byte) {
|
||||
slice := regexp.MustCompile(`\n|\s`).Split(s, 1000000000)
|
||||
for _, dataItem := range slice {
|
||||
d := common.FormatData(dataItem)
|
||||
ret = append(ret, d...)
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
func ImportChain(chain *core.BlockChain, fn string) error {
|
||||
// Watch for Ctrl-C while the import is running.
|
||||
// If a signal is received, the import will stop at the next batch.
|
||||
|
|
|
|||
12
common/.gitignore
vendored
12
common/.gitignore
vendored
|
|
@ -1,12 +0,0 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
#
|
||||
# If you find yourself ignoring temporary files generated by your text editor
|
||||
# or operating system, you probably want to add a global ignore instead:
|
||||
# git config --global core.excludesfile ~/.gitignore_global
|
||||
|
||||
/tmp
|
||||
*/**/*un~
|
||||
*un~
|
||||
.DS_Store
|
||||
*/**/.DS_Store
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.2
|
||||
140
common/README.md
140
common/README.md
|
|
@ -1,140 +0,0 @@
|
|||
# common
|
||||
|
||||
[](https://travis-ci.org/ethereum/go-ethereum)
|
||||
|
||||
The common package contains the ethereum utility library.
|
||||
|
||||
# Installation
|
||||
|
||||
As a subdirectory the main go-ethereum repository, you get it with
|
||||
`go get github.com/ethereum/go-ethereum`.
|
||||
|
||||
# Usage
|
||||
|
||||
## RLP (Recursive Linear Prefix) Encoding
|
||||
|
||||
RLP Encoding is an encoding scheme used by the Ethereum project. It
|
||||
encodes any native value or list to a string.
|
||||
|
||||
More in depth information about the encoding scheme see the
|
||||
[Wiki](http://wiki.ethereum.org/index.php/RLP) article.
|
||||
|
||||
```go
|
||||
rlp := common.Encode("doge")
|
||||
fmt.Printf("%q\n", rlp) // => "\0x83dog"
|
||||
|
||||
rlp = common.Encode([]interface{}{"dog", "cat"})
|
||||
fmt.Printf("%q\n", rlp) // => "\0xc8\0x83dog\0x83cat"
|
||||
decoded := common.Decode(rlp)
|
||||
fmt.Println(decoded) // => ["dog" "cat"]
|
||||
```
|
||||
|
||||
## Patricia Trie
|
||||
|
||||
Patricie Tree is a merkle trie used by the Ethereum project.
|
||||
|
||||
More in depth information about the (modified) Patricia Trie can be
|
||||
found on the [Wiki](http://wiki.ethereum.org/index.php/Patricia_Tree).
|
||||
|
||||
The patricia trie uses a db as backend and could be anything as long as
|
||||
it satisfies the Database interface found in `common/db.go`.
|
||||
|
||||
```go
|
||||
db := NewDatabase()
|
||||
|
||||
// db, root
|
||||
trie := common.NewTrie(db, "")
|
||||
|
||||
trie.Put("puppy", "dog")
|
||||
trie.Put("horse", "stallion")
|
||||
trie.Put("do", "verb")
|
||||
trie.Put("doge", "coin")
|
||||
|
||||
// Look up the key "do" in the trie
|
||||
out := trie.Get("do")
|
||||
fmt.Println(out) // => verb
|
||||
|
||||
trie.Delete("puppy")
|
||||
```
|
||||
|
||||
The patricia trie, in combination with RLP, provides a robust,
|
||||
cryptographically authenticated data structure that can be used to store
|
||||
all (key, value) bindings.
|
||||
|
||||
```go
|
||||
// ... Create db/trie
|
||||
|
||||
// Note that RLP uses interface slices as list
|
||||
value := common.Encode([]interface{}{"one", 2, "three", []interface{}{42}})
|
||||
// Store the RLP encoded value of the list
|
||||
trie.Put("mykey", value)
|
||||
```
|
||||
|
||||
## Value
|
||||
|
||||
Value is a Generic Value which is used in combination with RLP data or
|
||||
`([])interface{}` structures. It may serve as a bridge between RLP data
|
||||
and actual real values and takes care of all the type checking and
|
||||
casting. Unlike Go's `reflect.Value` it does not panic if it's unable to
|
||||
cast to the requested value. It simple returns the base value of that
|
||||
type (e.g. `Slice()` returns []interface{}, `Uint()` return 0, etc).
|
||||
|
||||
### Creating a new Value
|
||||
|
||||
`NewEmptyValue()` returns a new \*Value with it's initial value set to a
|
||||
`[]interface{}`
|
||||
|
||||
`AppendList()` appends a list to the current value.
|
||||
|
||||
`Append(v)` appends the value (v) to the current value/list.
|
||||
|
||||
```go
|
||||
val := common.NewEmptyValue().Append(1).Append("2")
|
||||
val.AppendList().Append(3)
|
||||
```
|
||||
|
||||
### Retrieving values
|
||||
|
||||
`Get(i)` returns the `i` item in the list.
|
||||
|
||||
`Uint()` returns the value as an unsigned int64.
|
||||
|
||||
`Slice()` returns the value as a interface slice.
|
||||
|
||||
`Str()` returns the value as a string.
|
||||
|
||||
`Bytes()` returns the value as a byte slice.
|
||||
|
||||
`Len()` assumes current to be a slice and returns its length.
|
||||
|
||||
`Byte()` returns the value as a single byte.
|
||||
|
||||
```go
|
||||
val := common.NewValue([]interface{}{1,"2",[]interface{}{3}})
|
||||
val.Get(0).Uint() // => 1
|
||||
val.Get(1).Str() // => "2"
|
||||
s := val.Get(2) // => Value([]interface{}{3})
|
||||
s.Get(0).Uint() // => 3
|
||||
```
|
||||
|
||||
## Decoding
|
||||
|
||||
Decoding streams of RLP data is simplified
|
||||
|
||||
```go
|
||||
val := common.NewValueFromBytes(rlpData)
|
||||
val.Get(0).Uint()
|
||||
```
|
||||
|
||||
## Encoding
|
||||
|
||||
Encoding from Value to RLP is done with the `Encode` method. The
|
||||
underlying value can be anything RLP can encode (int, str, lists, bytes)
|
||||
|
||||
```go
|
||||
val := common.NewValue([]interface{}{1,"2",[]interface{}{3}})
|
||||
rlp := val.Encode()
|
||||
// Store the rlp data
|
||||
Store(rlp)
|
||||
```
|
||||
155
common/bytes.go
155
common/bytes.go
|
|
@ -18,12 +18,7 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ToHex(b []byte) string {
|
||||
|
|
@ -48,65 +43,6 @@ func FromHex(s string) []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Number to bytes
|
||||
//
|
||||
// Returns the number in bytes with the specified base
|
||||
func NumberToBytes(num interface{}, bits int) []byte {
|
||||
buf := new(bytes.Buffer)
|
||||
err := binary.Write(buf, binary.BigEndian, num)
|
||||
if err != nil {
|
||||
fmt.Println("NumberToBytes failed:", err)
|
||||
}
|
||||
|
||||
return buf.Bytes()[buf.Len()-(bits/8):]
|
||||
}
|
||||
|
||||
// Bytes to number
|
||||
//
|
||||
// Attempts to cast a byte slice to a unsigned integer
|
||||
func BytesToNumber(b []byte) uint64 {
|
||||
var number uint64
|
||||
|
||||
// Make sure the buffer is 64bits
|
||||
data := make([]byte, 8)
|
||||
data = append(data[:len(b)], b...)
|
||||
|
||||
buf := bytes.NewReader(data)
|
||||
err := binary.Read(buf, binary.BigEndian, &number)
|
||||
if err != nil {
|
||||
fmt.Println("BytesToNumber failed:", err)
|
||||
}
|
||||
|
||||
return number
|
||||
}
|
||||
|
||||
// Read variable int
|
||||
//
|
||||
// Read a variable length number in big endian byte order
|
||||
func ReadVarInt(buff []byte) (ret uint64) {
|
||||
switch l := len(buff); {
|
||||
case l > 4:
|
||||
d := LeftPadBytes(buff, 8)
|
||||
binary.Read(bytes.NewReader(d), binary.BigEndian, &ret)
|
||||
case l > 2:
|
||||
var num uint32
|
||||
d := LeftPadBytes(buff, 4)
|
||||
binary.Read(bytes.NewReader(d), binary.BigEndian, &num)
|
||||
ret = uint64(num)
|
||||
case l > 1:
|
||||
var num uint16
|
||||
d := LeftPadBytes(buff, 2)
|
||||
binary.Read(bytes.NewReader(d), binary.BigEndian, &num)
|
||||
ret = uint64(num)
|
||||
default:
|
||||
var num uint8
|
||||
binary.Read(bytes.NewReader(buff), binary.BigEndian, &num)
|
||||
ret = uint64(num)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Copy bytes
|
||||
//
|
||||
// Returns an exact copy of the provided bytes
|
||||
|
|
@ -152,53 +88,6 @@ func Hex2BytesFixed(str string, flen int) []byte {
|
|||
}
|
||||
}
|
||||
|
||||
func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) {
|
||||
if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") {
|
||||
ret = Hex2Bytes(str[2:])
|
||||
} else {
|
||||
ret = cb(str)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func FormatData(data string) []byte {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
// Simple stupid
|
||||
d := new(big.Int)
|
||||
if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
|
||||
return RightPadBytes([]byte(data[1:len(data)-1]), 32)
|
||||
} else if len(data) > 1 && data[:2] == "0x" {
|
||||
d.SetBytes(Hex2Bytes(data[2:]))
|
||||
} else {
|
||||
d.SetString(data, 0)
|
||||
}
|
||||
|
||||
return BigToBytes(d, 256)
|
||||
}
|
||||
|
||||
func ParseData(data ...interface{}) (ret []byte) {
|
||||
for _, item := range data {
|
||||
switch t := item.(type) {
|
||||
case string:
|
||||
var str []byte
|
||||
if IsHex(t) {
|
||||
str = Hex2Bytes(t[2:])
|
||||
} else {
|
||||
str = []byte(t)
|
||||
}
|
||||
|
||||
ret = append(ret, RightPadBytes(str, 32)...)
|
||||
case []byte:
|
||||
ret = append(ret, LeftPadBytes(t, 32)...)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func RightPadBytes(slice []byte, l int) []byte {
|
||||
if l < len(slice) {
|
||||
return slice
|
||||
|
|
@ -220,47 +109,3 @@ func LeftPadBytes(slice []byte, l int) []byte {
|
|||
|
||||
return padded
|
||||
}
|
||||
|
||||
func LeftPadString(str string, l int) string {
|
||||
if l < len(str) {
|
||||
return str
|
||||
}
|
||||
|
||||
zeros := Bytes2Hex(make([]byte, (l-len(str))/2))
|
||||
|
||||
return zeros + str
|
||||
|
||||
}
|
||||
|
||||
func RightPadString(str string, l int) string {
|
||||
if l < len(str) {
|
||||
return str
|
||||
}
|
||||
|
||||
zeros := Bytes2Hex(make([]byte, (l-len(str))/2))
|
||||
|
||||
return str + zeros
|
||||
|
||||
}
|
||||
|
||||
func ToAddress(slice []byte) (addr []byte) {
|
||||
if len(slice) < 20 {
|
||||
addr = LeftPadBytes(slice, 20)
|
||||
} else if len(slice) > 20 {
|
||||
addr = slice[len(slice)-20:]
|
||||
} else {
|
||||
addr = slice
|
||||
}
|
||||
|
||||
addr = CopyBytes(addr)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ByteSliceToInterface(slice [][]byte) (ret []interface{}) {
|
||||
for _, i := range slice {
|
||||
ret = append(ret, i)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,54 +27,6 @@ type BytesSuite struct{}
|
|||
|
||||
var _ = checker.Suite(&BytesSuite{})
|
||||
|
||||
func (s *BytesSuite) TestNumberToBytes(c *checker.C) {
|
||||
// data1 := int(1)
|
||||
// res1 := NumberToBytes(data1, 16)
|
||||
// c.Check(res1, checker.Panics)
|
||||
|
||||
var data2 float64 = 3.141592653
|
||||
exp2 := []byte{0xe9, 0x38}
|
||||
res2 := NumberToBytes(data2, 16)
|
||||
c.Assert(res2, checker.DeepEquals, exp2)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestBytesToNumber(c *checker.C) {
|
||||
datasmall := []byte{0xe9, 0x38, 0xe9, 0x38}
|
||||
datalarge := []byte{0xe9, 0x38, 0xe9, 0x38, 0xe9, 0x38, 0xe9, 0x38}
|
||||
|
||||
var expsmall uint64 = 0xe938e938
|
||||
var explarge uint64 = 0x0
|
||||
|
||||
ressmall := BytesToNumber(datasmall)
|
||||
reslarge := BytesToNumber(datalarge)
|
||||
|
||||
c.Assert(ressmall, checker.Equals, expsmall)
|
||||
c.Assert(reslarge, checker.Equals, explarge)
|
||||
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestReadVarInt(c *checker.C) {
|
||||
data8 := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
data4 := []byte{1, 2, 3, 4}
|
||||
data2 := []byte{1, 2}
|
||||
data1 := []byte{1}
|
||||
|
||||
exp8 := uint64(72623859790382856)
|
||||
exp4 := uint64(16909060)
|
||||
exp2 := uint64(258)
|
||||
exp1 := uint64(1)
|
||||
|
||||
res8 := ReadVarInt(data8)
|
||||
res4 := ReadVarInt(data4)
|
||||
res2 := ReadVarInt(data2)
|
||||
res1 := ReadVarInt(data1)
|
||||
|
||||
c.Assert(res8, checker.Equals, exp8)
|
||||
c.Assert(res4, checker.Equals, exp4)
|
||||
c.Assert(res2, checker.Equals, exp2)
|
||||
c.Assert(res1, checker.Equals, exp1)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestCopyBytes(c *checker.C) {
|
||||
data1 := []byte{1, 2, 3, 4}
|
||||
exp1 := []byte{1, 2, 3, 4}
|
||||
|
|
@ -95,22 +47,6 @@ func (s *BytesSuite) TestIsHex(c *checker.C) {
|
|||
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestParseDataString(c *checker.C) {
|
||||
res1 := ParseData("hello", "world", "0x0106")
|
||||
data := "68656c6c6f000000000000000000000000000000000000000000000000000000776f726c640000000000000000000000000000000000000000000000000000000106000000000000000000000000000000000000000000000000000000000000"
|
||||
exp1 := Hex2Bytes(data)
|
||||
c.Assert(res1, checker.DeepEquals, exp1)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestParseDataBytes(c *checker.C) {
|
||||
data1 := []byte{232, 212, 165, 16, 0}
|
||||
exp1 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 212, 165, 16, 0}
|
||||
|
||||
res1 := ParseData(data1)
|
||||
c.Assert(res1, checker.DeepEquals, exp1)
|
||||
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestLeftPadBytes(c *checker.C) {
|
||||
val1 := []byte{1, 2, 3, 4}
|
||||
exp1 := []byte{0, 0, 0, 0, 1, 2, 3, 4}
|
||||
|
|
@ -122,28 +58,6 @@ func (s *BytesSuite) TestLeftPadBytes(c *checker.C) {
|
|||
c.Assert(res2, checker.DeepEquals, val1)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestFormatData(c *checker.C) {
|
||||
data1 := ""
|
||||
data2 := "0xa9e67e00"
|
||||
data3 := "a9e67e"
|
||||
data4 := "\"a9e67e00\""
|
||||
|
||||
// exp1 := []byte{}
|
||||
exp2 := []byte{00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0xa9, 0xe6, 0x7e, 00}
|
||||
exp3 := []byte{00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}
|
||||
exp4 := []byte{0x61, 0x39, 0x65, 0x36, 0x37, 0x65, 0x30, 0x30, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}
|
||||
|
||||
res1 := FormatData(data1)
|
||||
res2 := FormatData(data2)
|
||||
res3 := FormatData(data3)
|
||||
res4 := FormatData(data4)
|
||||
|
||||
c.Assert(res1, checker.IsNil)
|
||||
c.Assert(res2, checker.DeepEquals, exp2)
|
||||
c.Assert(res3, checker.DeepEquals, exp3)
|
||||
c.Assert(res4, checker.DeepEquals, exp4)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestRightPadBytes(c *checker.C) {
|
||||
val := []byte{1, 2, 3, 4}
|
||||
exp := []byte{1, 2, 3, 4, 0, 0, 0, 0}
|
||||
|
|
@ -155,28 +69,6 @@ func (s *BytesSuite) TestRightPadBytes(c *checker.C) {
|
|||
c.Assert(resshrt, checker.DeepEquals, val)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestLeftPadString(c *checker.C) {
|
||||
val := "test"
|
||||
exp := "\x30\x30\x30\x30" + val
|
||||
|
||||
resstd := LeftPadString(val, 8)
|
||||
resshrt := LeftPadString(val, 2)
|
||||
|
||||
c.Assert(resstd, checker.Equals, exp)
|
||||
c.Assert(resshrt, checker.Equals, val)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestRightPadString(c *checker.C) {
|
||||
val := "test"
|
||||
exp := val + "\x30\x30\x30\x30"
|
||||
|
||||
resstd := RightPadString(val, 8)
|
||||
resshrt := RightPadString(val, 2)
|
||||
|
||||
c.Assert(resstd, checker.Equals, exp)
|
||||
c.Assert(resshrt, checker.Equals, val)
|
||||
}
|
||||
|
||||
func TestFromHex(t *testing.T) {
|
||||
input := "0x01"
|
||||
expected := []byte{1}
|
||||
|
|
|
|||
190
common/icap.go
190
common/icap.go
|
|
@ -1,190 +0,0 @@
|
|||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library 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.
|
||||
//
|
||||
// The go-ethereum library 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 the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Spec at https://github.com/ethereum/wiki/wiki/ICAP:-Inter-exchange-Client-Address-Protocol
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
Base36Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
ICAPLengthError = errors.New("Invalid ICAP length")
|
||||
ICAPEncodingError = errors.New("Invalid ICAP encoding")
|
||||
ICAPChecksumError = errors.New("Invalid ICAP checksum")
|
||||
ICAPCountryCodeError = errors.New("Invalid ICAP country code")
|
||||
ICAPAssetIdentError = errors.New("Invalid ICAP asset identifier")
|
||||
ICAPInstCodeError = errors.New("Invalid ICAP institution code")
|
||||
ICAPClientIdentError = errors.New("Invalid ICAP client identifier")
|
||||
)
|
||||
|
||||
func ICAPToAddress(s string) (Address, error) {
|
||||
switch len(s) {
|
||||
case 35: // "XE" + 2 digit checksum + 31 base-36 chars of address
|
||||
return parseICAP(s)
|
||||
case 34: // "XE" + 2 digit checksum + 30 base-36 chars of address
|
||||
return parseICAP(s)
|
||||
case 20: // "XE" + 2 digit checksum + 3-char asset identifier +
|
||||
// 4-char institution identifier + 9-char institution client identifier
|
||||
return parseIndirectICAP(s)
|
||||
default:
|
||||
return Address{}, ICAPLengthError
|
||||
}
|
||||
}
|
||||
|
||||
func parseICAP(s string) (Address, error) {
|
||||
if !strings.HasPrefix(s, "XE") {
|
||||
return Address{}, ICAPCountryCodeError
|
||||
}
|
||||
if err := validCheckSum(s); err != nil {
|
||||
return Address{}, err
|
||||
}
|
||||
// checksum is ISO13616, Ethereum address is base-36
|
||||
bigAddr, _ := new(big.Int).SetString(s[4:], 36)
|
||||
return BigToAddress(bigAddr), nil
|
||||
}
|
||||
|
||||
func parseIndirectICAP(s string) (Address, error) {
|
||||
if !strings.HasPrefix(s, "XE") {
|
||||
return Address{}, ICAPCountryCodeError
|
||||
}
|
||||
if s[4:7] != "ETH" {
|
||||
return Address{}, ICAPAssetIdentError
|
||||
}
|
||||
if err := validCheckSum(s); err != nil {
|
||||
return Address{}, err
|
||||
}
|
||||
// TODO: integrate with ICAP namereg
|
||||
return Address{}, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func AddressToICAP(a Address) (string, error) {
|
||||
enc := base36Encode(a.Big())
|
||||
// zero padd encoded address to Direct ICAP length if needed
|
||||
if len(enc) < 30 {
|
||||
enc = join(strings.Repeat("0", 30-len(enc)), enc)
|
||||
}
|
||||
icap := join("XE", checkDigits(enc), enc)
|
||||
return icap, nil
|
||||
}
|
||||
|
||||
// TODO: integrate with ICAP namereg when it's available
|
||||
func AddressToIndirectICAP(a Address, instCode string) (string, error) {
|
||||
// return addressToIndirectICAP(a, instCode)
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
||||
func addressToIndirectICAP(a Address, instCode string) (string, error) {
|
||||
// TODO: add addressToClientIdent which grabs client ident from ICAP namereg
|
||||
//clientIdent := addressToClientIdent(a)
|
||||
clientIdent := "todo"
|
||||
return clientIdentToIndirectICAP(instCode, clientIdent)
|
||||
}
|
||||
|
||||
func clientIdentToIndirectICAP(instCode, clientIdent string) (string, error) {
|
||||
if len(instCode) != 4 || !validBase36(instCode) {
|
||||
return "", ICAPInstCodeError
|
||||
}
|
||||
if len(clientIdent) != 9 || !validBase36(instCode) {
|
||||
return "", ICAPClientIdentError
|
||||
}
|
||||
|
||||
// currently ETH is only valid asset identifier
|
||||
s := join("ETH", instCode, clientIdent)
|
||||
return join("XE", checkDigits(s), s), nil
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN
|
||||
func validCheckSum(s string) error {
|
||||
s = join(s[4:], s[:4])
|
||||
expanded, err := iso13616Expand(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
checkSumNum, _ := new(big.Int).SetString(expanded, 10)
|
||||
if checkSumNum.Mod(checkSumNum, Big97).Cmp(Big1) != 0 {
|
||||
return ICAPChecksumError
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkDigits(s string) string {
|
||||
expanded, _ := iso13616Expand(strings.Join([]string{s, "XE00"}, ""))
|
||||
num, _ := new(big.Int).SetString(expanded, 10)
|
||||
num.Sub(Big98, num.Mod(num, Big97))
|
||||
|
||||
checkDigits := num.String()
|
||||
// zero padd checksum
|
||||
if len(checkDigits) == 1 {
|
||||
checkDigits = join("0", checkDigits)
|
||||
}
|
||||
return checkDigits
|
||||
}
|
||||
|
||||
// not base-36, but expansion to decimal literal: A = 10, B = 11, ... Z = 35
|
||||
func iso13616Expand(s string) (string, error) {
|
||||
var parts []string
|
||||
if !validBase36(s) {
|
||||
return "", ICAPEncodingError
|
||||
}
|
||||
for _, c := range s {
|
||||
i := uint64(c)
|
||||
if i >= 65 {
|
||||
parts = append(parts, strconv.FormatUint(uint64(c)-55, 10))
|
||||
} else {
|
||||
parts = append(parts, string(c))
|
||||
}
|
||||
}
|
||||
return join(parts...), nil
|
||||
}
|
||||
|
||||
func base36Encode(i *big.Int) string {
|
||||
var chars []rune
|
||||
x := new(big.Int)
|
||||
for {
|
||||
x.Mod(i, Big36)
|
||||
chars = append(chars, rune(Base36Chars[x.Uint64()]))
|
||||
i.Div(i, Big36)
|
||||
if i.Cmp(Big0) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
// reverse slice
|
||||
for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
|
||||
chars[i], chars[j] = chars[j], chars[i]
|
||||
}
|
||||
return string(chars)
|
||||
}
|
||||
|
||||
func validBase36(s string) bool {
|
||||
for _, c := range s {
|
||||
i := uint64(c)
|
||||
// 0-9 or A-Z
|
||||
if i < 48 || (i > 57 && i < 65) || i > 90 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func join(s ...string) string {
|
||||
return strings.Join(s, "")
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library 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.
|
||||
//
|
||||
// The go-ethereum library 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 the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package common
|
||||
|
||||
import "testing"
|
||||
|
||||
/* More test vectors:
|
||||
https://github.com/ethereum/web3.js/blob/master/test/iban.fromAddress.js
|
||||
https://github.com/ethereum/web3.js/blob/master/test/iban.toAddress.js
|
||||
https://github.com/ethereum/web3.js/blob/master/test/iban.isValid.js
|
||||
https://github.com/ethereum/libethereum/blob/develop/test/libethcore/icap.cpp
|
||||
*/
|
||||
|
||||
type icapTest struct {
|
||||
name string
|
||||
addr string
|
||||
icap string
|
||||
}
|
||||
|
||||
var icapOKTests = []icapTest{
|
||||
{"Direct1", "0x52dc504a422f0e2a9e7632a34a50f1a82f8224c7", "XE499OG1EH8ZZI0KXC6N83EKGT1BM97P2O7"},
|
||||
{"Direct2", "0x11c5496aee77c1ba1f0854206a26dda82a81d6d8", "XE1222Q908LN1QBBU6XUQSO1OHWJIOS46OO"},
|
||||
{"DirectZeroPrefix", "0x00c5496aee77c1ba1f0854206a26dda82a81d6d8", "XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS"},
|
||||
{"DirectDoubleZeroPrefix", "0x0000a5327eab78357cbf2ae8f3d49fd9d90c7d22", "XE0600DQK33XDTYUCRI0KYM5ELAKXDWWF6"},
|
||||
}
|
||||
|
||||
var icapInvalidTests = []icapTest{
|
||||
{"DirectInvalidCheckSum", "", "XE7438O073KYGTWWZN0F2WZ0R8PX5ZPPZS"},
|
||||
{"DirectInvalidCountryCode", "", "XD7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS"},
|
||||
{"DirectInvalidLength36", "", "XE499OG1EH8ZZI0KXC6N83EKGT1BM97P2O77"},
|
||||
{"DirectInvalidLength33", "", "XE499OG1EH8ZZI0KXC6N83EKGT1BM97P2"},
|
||||
|
||||
{"IndirectInvalidCheckSum", "", "XE35ETHXREGGOPHERSSS"},
|
||||
{"IndirectInvalidAssetIdentifier", "", "XE34ETHXREGGOPHERSSS"},
|
||||
{"IndirectInvalidLength19", "", "XE34ETHXREGGOPHERSS"},
|
||||
{"IndirectInvalidLength21", "", "XE34ETHXREGGOPHERSSSS"},
|
||||
}
|
||||
|
||||
func TestICAPOK(t *testing.T) {
|
||||
for _, test := range icapOKTests {
|
||||
decodeEncodeTest(HexToAddress(test.addr), test.icap, t)
|
||||
}
|
||||
}
|
||||
|
||||
func TestICAPInvalid(t *testing.T) {
|
||||
for _, test := range icapInvalidTests {
|
||||
failedDecodingTest(test.icap, t)
|
||||
}
|
||||
}
|
||||
|
||||
func decodeEncodeTest(addr0 Address, icap0 string, t *testing.T) {
|
||||
icap1, err := AddressToICAP(addr0)
|
||||
if err != nil {
|
||||
t.Errorf("ICAP encoding failed: %s", err)
|
||||
}
|
||||
if icap1 != icap0 {
|
||||
t.Errorf("ICAP mismatch: have: %s want: %s", icap1, icap0)
|
||||
}
|
||||
|
||||
addr1, err := ICAPToAddress(icap0)
|
||||
if err != nil {
|
||||
t.Errorf("ICAP decoding failed: %s", err)
|
||||
}
|
||||
if addr1 != addr0 {
|
||||
t.Errorf("Address mismatch: have: %x want: %x", addr1, addr0)
|
||||
}
|
||||
}
|
||||
|
||||
func failedDecodingTest(icap string, t *testing.T) {
|
||||
addr, err := ICAPToAddress(icap)
|
||||
if err == nil {
|
||||
t.Errorf("Expected ICAP decoding to fail.")
|
||||
}
|
||||
if addr != (Address{}) {
|
||||
t.Errorf("Expected empty Address on failed ICAP decoding.")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright 2014 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library 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.
|
||||
//
|
||||
// The go-ethereum library 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 the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// The list type is an anonymous slice handler which can be used
|
||||
// for containing any slice type to use in an environment which
|
||||
// does not support slice types (e.g., JavaScript, QML)
|
||||
type List struct {
|
||||
mut sync.Mutex
|
||||
val interface{}
|
||||
list reflect.Value
|
||||
Length int
|
||||
}
|
||||
|
||||
// Initialise a new list. Panics if non-slice type is given.
|
||||
func NewList(t interface{}) *List {
|
||||
list := reflect.ValueOf(t)
|
||||
if list.Kind() != reflect.Slice {
|
||||
panic("list container initialized with a non-slice type")
|
||||
}
|
||||
|
||||
return &List{sync.Mutex{}, t, list, list.Len()}
|
||||
}
|
||||
|
||||
func EmptyList() *List {
|
||||
return NewList([]interface{}{})
|
||||
}
|
||||
|
||||
// Get N element from the embedded slice. Returns nil if OOB.
|
||||
func (self *List) Get(i int) interface{} {
|
||||
if self.list.Len() > i {
|
||||
self.mut.Lock()
|
||||
defer self.mut.Unlock()
|
||||
|
||||
i := self.list.Index(i).Interface()
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *List) GetAsJson(i int) interface{} {
|
||||
e := self.Get(i)
|
||||
|
||||
r, _ := json.Marshal(e)
|
||||
|
||||
return string(r)
|
||||
}
|
||||
|
||||
// Appends value at the end of the slice. Panics when incompatible value
|
||||
// is given.
|
||||
func (self *List) Append(v interface{}) {
|
||||
self.mut.Lock()
|
||||
defer self.mut.Unlock()
|
||||
|
||||
self.list = reflect.Append(self.list, reflect.ValueOf(v))
|
||||
self.Length = self.list.Len()
|
||||
}
|
||||
|
||||
// Returns the underlying slice as interface.
|
||||
func (self *List) Interface() interface{} {
|
||||
return self.list.Interface()
|
||||
}
|
||||
|
||||
// For JavaScript <3
|
||||
func (self *List) ToJSON() string {
|
||||
// make(T, 0) != nil
|
||||
list := make([]interface{}, 0)
|
||||
for i := 0; i < self.Length; i++ {
|
||||
list = append(list, self.Get(i))
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(list)
|
||||
|
||||
return string(data)
|
||||
}
|
||||
Loading…
Reference in a new issue