/
address.go
141 lines (120 loc) · 3.88 KB
/
address.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package evm
import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/renproject/multichain/api/address"
"github.com/renproject/pack"
"github.com/renproject/surge"
)
// AddressEncodeDecoder implements the address.EncodeDecoder interface
type AddressEncodeDecoder struct {
AddressEncoder
AddressDecoder
}
// AddressEncoder implements the address.Encoder interface.
type AddressEncoder interface {
EncodeAddress(address.RawAddress) (address.Address, error)
}
type addressEncoder struct{}
// NewAddressEncodeDecoder constructs a new AddressEncodeDecoder.
func NewAddressEncodeDecoder() address.EncodeDecoder {
return AddressEncodeDecoder{
AddressEncoder: NewAddressEncoder(),
AddressDecoder: NewAddressDecoder(),
}
}
// AddressDecoder implements the address.Decoder interface.
type AddressDecoder interface {
DecodeAddress(address.Address) (address.RawAddress, error)
}
type addressDecoder struct{}
// NewAddressDecoder constructs a new AddressDecoder.
func NewAddressDecoder() AddressDecoder {
return addressDecoder{}
}
// NewAddressEncoder constructs a new AddressEncoder.
func NewAddressEncoder() AddressEncoder {
return addressEncoder{}
}
func (addressDecoder) DecodeAddress(encoded address.Address) (address.RawAddress, error) {
ethaddr, err := NewAddressFromHex(string(pack.String(encoded)))
if err != nil {
return nil, err
}
return address.RawAddress(pack.Bytes(ethaddr[:])), nil
}
func (addressEncoder) EncodeAddress(rawAddr address.RawAddress) (address.Address, error) {
addr := common.BytesToAddress([]byte(rawAddr))
return address.Address(addr.Hex()), nil
}
// An Address represents a public address on the Ethereum blockchain. It can be
// the address of an external account, or the address of a smart contract.
type Address common.Address
// NewAddressFromHex returns an Address decoded from a hex
// string.
func NewAddressFromHex(str string) (Address, error) {
if strings.HasPrefix(str, "0x") {
str = str[2:]
}
if len(str) != 40 {
return Address{}, fmt.Errorf("invalid ethaddress %v", str)
}
ethaddrData, err := hex.DecodeString(str)
if err != nil {
return Address{}, fmt.Errorf("invalid ethaddress %v: %v", str, err)
}
ethaddr := common.Address{}
copy(ethaddr[:], ethaddrData)
return Address(ethaddr), nil
}
// SizeHint returns the number of bytes needed to represent this address in
// binary.
func (Address) SizeHint() int {
return common.AddressLength
}
// Marshal the address to binary.
func (addr Address) Marshal(buf []byte, rem int) ([]byte, int, error) {
if len(buf) < common.AddressLength || rem < common.AddressLength {
return buf, rem, surge.ErrUnexpectedEndOfBuffer
}
copy(buf, addr[:])
return buf[common.AddressLength:], rem - common.AddressLength, nil
}
// Unmarshal the address from binary.
func (addr *Address) Unmarshal(buf []byte, rem int) ([]byte, int, error) {
if len(buf) < common.AddressLength || rem < common.AddressLength {
return buf, rem, surge.ErrUnexpectedEndOfBuffer
}
copy(addr[:], buf[:common.AddressLength])
return buf[common.AddressLength:], rem - common.AddressLength, nil
}
// MarshalJSON implements JSON marshaling by encoding the address as a hex
// string.
func (addr Address) MarshalJSON() ([]byte, error) {
return json.Marshal(common.Address(addr).Hex())
}
// UnmarshalJSON implements JSON unmarshaling by expected the data be a hex
// encoded string representation of an address.
func (addr *Address) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err != nil {
return err
}
ethaddr, err := NewAddressFromHex(str)
if err != nil {
return err
}
*addr = ethaddr
return nil
}
// String returns the address as a human-readable hex string.
func (addr Address) String() string {
return hex.EncodeToString(addr[:])
}
// Bytes returns the address as a slice of 20 bytes.
func (addr Address) Bytes() pack.Bytes {
return pack.Bytes(addr[:])
}