forked from onflow/flow-go-sdk
-
Notifications
You must be signed in to change notification settings - Fork 1
/
flow.go
181 lines (146 loc) · 4.66 KB
/
flow.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
* Flow Go SDK
*
* Copyright 2019 Dapper Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package flow
import (
"encoding/hex"
"sync"
"github.com/ethereum/go-ethereum/rlp"
"github.com/onflow/flow-go-sdk/crypto"
)
// An Identifier is a 32-byte unique identifier for an entity.
type Identifier [32]byte
// EmptyID is the empty identifier.
var EmptyID = Identifier{}
// Bytes returns the bytes representation of this identifier.
func (i Identifier) Bytes() []byte {
return i[:]
}
// Hex returns the hexadecimal string representation of this identifier.
func (i Identifier) Hex() string {
return hex.EncodeToString(i[:])
}
// String returns the string representation of this identifier.
func (i Identifier) String() string {
return i.Hex()
}
// BytesToID constructs an identifier from a byte slice.
func BytesToID(b []byte) Identifier {
var id Identifier
copy(id[:], b)
return id
}
// HexToID constructs an identifier from a hexadecimal string.
func HexToID(h string) Identifier {
b, _ := hex.DecodeString(h)
return BytesToID(b)
}
// HashToID constructs an identifier from a 32-byte hash.
func HashToID(hash []byte) Identifier {
return BytesToID(hash)
}
// BytesToHash constructs a crypto hash from byte slice.
func BytesToHash(hash []byte) crypto.Hash {
h := make(crypto.Hash, len(hash))
copy(h, hash)
return h
}
type StateCommitment Identifier
// BytesToStateCommitment constructs a state commitment from a byte slice.
func BytesToStateCommitment(b []byte) StateCommitment {
return StateCommitment(BytesToID(b))
}
// HexToStateCommitment constructs a state commitment from a hexadecimal string.
func HexToStateCommitment(h string) StateCommitment {
return StateCommitment(HexToID(h))
}
// HashToStateCommitment constructs a state commitment from a 32-byte hash.
func HashToStateCommitment(hash []byte) StateCommitment {
return StateCommitment(HashToID(hash))
}
// A ChainID is a unique identifier for a specific Flow network instance.
//
// Chain IDs are used used to prevent replay attacks and to support network-specific address generation.
type ChainID string
const (
// Mainnet is the chain ID for the mainnet chain.
Mainnet ChainID = "flow-mainnet"
// Long-lived test networks
// Testnet is the chain ID for the testnet chain.
Testnet ChainID = "flow-testnet"
// Sandboxnet is the chain ID for sandboxnet chain.
Sandboxnet ChainID = "flow-sandboxnet"
// Transient test networks
// Benchnet is the chain ID for the transient benchmarking chain.
Benchnet ChainID = "flow-benchnet"
// Localnet is the chain ID for the local development chain.
Localnet ChainID = "flow-localnet"
// Emulator is the chain ID for the emulated chain.
Emulator ChainID = "flow-emulator"
// BftTestnet is the chain ID for testing attack vector scenarios.
BftTestnet ChainID = "flow-bft-test-net"
// MonotonicEmulator is the chain ID for the emulated node chain with monotonic address generation.
MonotonicEmulator ChainID = "flow-emulator-monotonic"
)
func (id ChainID) String() string {
return string(id)
}
// entityHasher is a thread-safe hasher used to hash Flow entities.
type entityHasher struct {
mut sync.Mutex
hasher crypto.Hasher
}
func (h *entityHasher) ComputeHash(b []byte) crypto.Hash {
h.mut.Lock()
defer h.mut.Unlock()
return h.hasher.ComputeHash(b)
}
// defaultEntityHasher is the default hasher used to compute Flow identifiers.
var defaultEntityHasher *entityHasher
func init() {
defaultEntityHasher = &entityHasher{
hasher: crypto.NewSHA3_256(),
}
}
func rlpEncode(v interface{}) ([]byte, error) {
return rlp.EncodeToBytes(v)
}
func rlpDecode(b []byte, v interface{}) error {
return rlp.DecodeBytes(b, v)
}
func mustRLPEncode(v interface{}) []byte {
// Note(sideninja): This is a temporary workaround until cadence defines canonical format addressing the issue https://github.com/onflow/flow-go-sdk/issues/286
if tx, ok := v.(payloadCanonicalForm); ok {
for _, arg := range tx.Arguments {
if arg[len(arg)-1] == byte(10) {
arg = arg[:len(tx.Arguments)-1]
}
}
}
b, err := rlpEncode(v)
if err != nil {
panic(err)
}
return b
}
func mustRLPDecode(b []byte, v interface{}) {
err := rlpDecode(b, v)
if err != nil {
panic(err)
}
return
}