-
Notifications
You must be signed in to change notification settings - Fork 172
Expand file tree
/
Copy pathutil.py
More file actions
107 lines (80 loc) · 2.5 KB
/
util.py
File metadata and controls
107 lines (80 loc) · 2.5 KB
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
from web3 import Web3
from web3.auto import w3
from dydx3 import constants
PREPEND_DEC = '\x19Ethereum Signed Message:\n32'
PREPEND_HEX = '\x19Ethereum Signed Message:\n\x20'
def is_valid_sig_type(
sig_type,
):
return sig_type in [
constants.SIGNATURE_TYPE_DECIMAL,
constants.SIGNATURE_TYPE_HEXADECIMAL,
constants.SIGNATURE_TYPE_NO_PREPEND,
]
def ec_recover_typed_signature(
hashVal,
typed_signature,
):
if len(strip_hex_prefix(typed_signature)) != 66 * 2:
raise Exception('Unable to ecrecover signature: ' + typed_signature)
sig_type = int(typed_signature[-2:], 16)
prepended_hash = ''
if sig_type == constants.SIGNATURE_TYPE_NO_PREPEND:
prepended_hash = hashVal
elif sig_type == constants.SIGNATURE_TYPE_DECIMAL:
prepended_hash = Web3.solidity_keccak(
['string', 'bytes32'],
[PREPEND_DEC, hashVal],
)
elif sig_type == constants.SIGNATURE_TYPE_HEXADECIMAL:
prepended_hash = Web3.solidity_keccak(
['string', 'bytes32'],
[PREPEND_HEX, hashVal],
)
else:
raise Exception('Invalid signature type: ' + str(sig_type))
if not prepended_hash:
raise Exception('Invalid hash: ' + hashVal)
signature = typed_signature[:-2]
address = w3.eth.account._recover_hash(prepended_hash, signature=signature)
return address
def create_typed_signature(
signature,
sig_type,
):
if not is_valid_sig_type(sig_type):
raise Exception('Invalid signature type: ' + sig_type)
return fix_raw_signature(signature) + '0' + str(sig_type)
def fix_raw_signature(
signature,
):
stripped = strip_hex_prefix(signature)
if len(stripped) != 130:
raise Exception('Invalid raw signature: ' + signature)
rs = stripped[:128]
v = stripped[128: 130]
if v == '00':
return '0x' + rs + '1b'
if v == '01':
return '0x' + rs + '1c'
if v in ['1b', '1c']:
return '0x' + stripped
raise Exception('Invalid v value: ' + v)
# ============ Byte Helpers ============
def strip_hex_prefix(input):
if input.startswith('0x'):
return input[2:]
return input
def addresses_are_equal(
address_one,
address_two,
):
if not address_one or not address_two:
return False
return (
strip_hex_prefix(
address_one
).lower() == strip_hex_prefix(address_two).lower()
)
def hash_string(input):
return Web3.solidity_keccak(['string'], [input])