-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathaddress.go
87 lines (68 loc) · 2.57 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
package core
import (
"bytes"
)
// SystemAccountAddress is the hard-coded address in which we save global settings on all shards
var SystemAccountAddress = bytes.Repeat([]byte{255}, 32)
// NumInitCharactersForScAddress numbers of characters for smart contract address identifier
const NumInitCharactersForScAddress = 10
// VMTypeLen number of characters with VMType identifier in an address, these are the last 2 characters from the
// initial identifier
const VMTypeLen = 2
// ShardIdentiferLen number of characters for shard identifier in an address
const ShardIdentiferLen = 2
const metaChainShardIdentifier uint8 = 255
const numInitCharactersForOnMetachainSC = 15
const numInitCharactersForSystemAccountAddress = 30
// IsSystemAccountAddress returns true if given address is system account address
func IsSystemAccountAddress(address []byte) bool {
if len(address) < numInitCharactersForSystemAccountAddress {
return false
}
return bytes.Equal(address[:numInitCharactersForSystemAccountAddress], SystemAccountAddress[:numInitCharactersForSystemAccountAddress])
}
// IsSmartContractAddress verifies if a set address is of type smart contract
func IsSmartContractAddress(rcvAddress []byte) bool {
if len(rcvAddress) <= NumInitCharactersForScAddress {
return false
}
if IsEmptyAddress(rcvAddress) {
return true
}
numOfZeros := NumInitCharactersForScAddress - VMTypeLen
isSCAddress := bytes.Equal(rcvAddress[:numOfZeros], make([]byte, numOfZeros))
return isSCAddress
}
// IsEmptyAddress returns whether an address is empty
func IsEmptyAddress(address []byte) bool {
isEmptyAddress := bytes.Equal(address, make([]byte, len(address)))
return isEmptyAddress
}
// IsMetachainIdentifier verifies if the identifier is of type metachain
func IsMetachainIdentifier(identifier []byte) bool {
if len(identifier) == 0 {
return false
}
for i := 0; i < len(identifier); i++ {
if identifier[i] != metaChainShardIdentifier {
return false
}
}
return true
}
// IsSmartContractOnMetachain verifies if an address is smart contract on metachain
func IsSmartContractOnMetachain(identifier []byte, rcvAddress []byte) bool {
if len(rcvAddress) <= NumInitCharactersForScAddress+numInitCharactersForOnMetachainSC {
return false
}
if !IsMetachainIdentifier(identifier) {
return false
}
if !IsSmartContractAddress(rcvAddress) {
return false
}
leftSide := rcvAddress[NumInitCharactersForScAddress:(NumInitCharactersForScAddress + numInitCharactersForOnMetachainSC)]
isOnMetaChainSCAddress := bytes.Equal(leftSide,
make([]byte, numInitCharactersForOnMetachainSC))
return isOnMetaChainSCAddress
}