hive-nectar 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of hive-nectar might be problematic. Click here for more details.

Files changed (86) hide show
  1. hive_nectar-0.0.2.dist-info/METADATA +182 -0
  2. hive_nectar-0.0.2.dist-info/RECORD +86 -0
  3. hive_nectar-0.0.2.dist-info/WHEEL +4 -0
  4. hive_nectar-0.0.2.dist-info/entry_points.txt +2 -0
  5. hive_nectar-0.0.2.dist-info/licenses/LICENSE.txt +23 -0
  6. nectar/__init__.py +32 -0
  7. nectar/account.py +4371 -0
  8. nectar/amount.py +475 -0
  9. nectar/asciichart.py +270 -0
  10. nectar/asset.py +82 -0
  11. nectar/block.py +446 -0
  12. nectar/blockchain.py +1178 -0
  13. nectar/blockchaininstance.py +2284 -0
  14. nectar/blockchainobject.py +221 -0
  15. nectar/blurt.py +563 -0
  16. nectar/cli.py +6285 -0
  17. nectar/comment.py +1217 -0
  18. nectar/community.py +513 -0
  19. nectar/constants.py +111 -0
  20. nectar/conveyor.py +309 -0
  21. nectar/discussions.py +1709 -0
  22. nectar/exceptions.py +149 -0
  23. nectar/hive.py +546 -0
  24. nectar/hivesigner.py +420 -0
  25. nectar/imageuploader.py +72 -0
  26. nectar/instance.py +129 -0
  27. nectar/market.py +1013 -0
  28. nectar/memo.py +449 -0
  29. nectar/message.py +357 -0
  30. nectar/nodelist.py +444 -0
  31. nectar/price.py +557 -0
  32. nectar/profile.py +65 -0
  33. nectar/rc.py +308 -0
  34. nectar/snapshot.py +726 -0
  35. nectar/steem.py +582 -0
  36. nectar/storage.py +53 -0
  37. nectar/transactionbuilder.py +622 -0
  38. nectar/utils.py +545 -0
  39. nectar/version.py +2 -0
  40. nectar/vote.py +557 -0
  41. nectar/wallet.py +472 -0
  42. nectar/witness.py +617 -0
  43. nectarapi/__init__.py +11 -0
  44. nectarapi/exceptions.py +123 -0
  45. nectarapi/graphenerpc.py +589 -0
  46. nectarapi/node.py +178 -0
  47. nectarapi/noderpc.py +229 -0
  48. nectarapi/rpcutils.py +97 -0
  49. nectarapi/version.py +2 -0
  50. nectarbase/__init__.py +14 -0
  51. nectarbase/ledgertransactions.py +75 -0
  52. nectarbase/memo.py +243 -0
  53. nectarbase/objects.py +429 -0
  54. nectarbase/objecttypes.py +22 -0
  55. nectarbase/operationids.py +102 -0
  56. nectarbase/operations.py +1297 -0
  57. nectarbase/signedtransactions.py +48 -0
  58. nectarbase/transactions.py +11 -0
  59. nectarbase/version.py +2 -0
  60. nectargrapheneapi/__init__.py +6 -0
  61. nectargraphenebase/__init__.py +27 -0
  62. nectargraphenebase/account.py +846 -0
  63. nectargraphenebase/aes.py +52 -0
  64. nectargraphenebase/base58.py +192 -0
  65. nectargraphenebase/bip32.py +494 -0
  66. nectargraphenebase/bip38.py +134 -0
  67. nectargraphenebase/chains.py +149 -0
  68. nectargraphenebase/dictionary.py +3 -0
  69. nectargraphenebase/ecdsasig.py +326 -0
  70. nectargraphenebase/objects.py +123 -0
  71. nectargraphenebase/objecttypes.py +6 -0
  72. nectargraphenebase/operationids.py +3 -0
  73. nectargraphenebase/operations.py +23 -0
  74. nectargraphenebase/prefix.py +11 -0
  75. nectargraphenebase/py23.py +38 -0
  76. nectargraphenebase/signedtransactions.py +201 -0
  77. nectargraphenebase/types.py +419 -0
  78. nectargraphenebase/unsignedtransactions.py +283 -0
  79. nectargraphenebase/version.py +2 -0
  80. nectarstorage/__init__.py +38 -0
  81. nectarstorage/base.py +306 -0
  82. nectarstorage/exceptions.py +16 -0
  83. nectarstorage/interfaces.py +237 -0
  84. nectarstorage/masterpassword.py +239 -0
  85. nectarstorage/ram.py +30 -0
  86. nectarstorage/sqlite.py +334 -0
@@ -0,0 +1,326 @@
1
+ # -*- coding: utf-8 -*-
2
+ import hashlib
3
+ import logging
4
+ import struct
5
+ import time
6
+ from binascii import hexlify
7
+
8
+ import ecdsa
9
+
10
+ from .account import PrivateKey, PublicKey
11
+ from .py23 import bytes_types, py23_bytes
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+ SECP256K1_MODULE = None
16
+ SECP256K1_AVAILABLE = False
17
+ CRYPTOGRAPHY_AVAILABLE = False
18
+ GMPY2_MODULE = False
19
+ if not SECP256K1_MODULE:
20
+ try:
21
+ import secp256k1prp as secp256k1
22
+
23
+ SECP256K1_MODULE = "secp256k1"
24
+ SECP256K1_AVAILABLE = True
25
+ except:
26
+ try:
27
+ import secp256k1
28
+
29
+ SECP256K1_MODULE = "secp256k1"
30
+ SECP256K1_AVAILABLE = True
31
+ except ImportError:
32
+ try:
33
+ import cryptography
34
+
35
+ SECP256K1_MODULE = "cryptography"
36
+ CRYPTOGRAPHY_AVAILABLE = True
37
+ except ImportError:
38
+ SECP256K1_MODULE = "ecdsa"
39
+
40
+ try:
41
+ from cryptography.exceptions import InvalidSignature
42
+ from cryptography.hazmat.backends import default_backend
43
+ from cryptography.hazmat.primitives import hashes
44
+ from cryptography.hazmat.primitives.asymmetric import ec
45
+ from cryptography.hazmat.primitives.asymmetric.utils import (
46
+ decode_dss_signature,
47
+ encode_dss_signature,
48
+ )
49
+
50
+ CRYPTOGRAPHY_AVAILABLE = True
51
+ except ImportError:
52
+ CRYPTOGRAPHY_AVAILABLE = False
53
+ log.debug("Cryptography not available")
54
+
55
+ log.debug("Using SECP256K1 module: %s" % SECP256K1_MODULE)
56
+
57
+
58
+ def _is_canonical(sig):
59
+ sig = bytearray(sig)
60
+ return (
61
+ not (int(sig[0]) & 0x80)
62
+ and not (sig[0] == 0 and not (int(sig[1]) & 0x80))
63
+ and not (int(sig[32]) & 0x80)
64
+ and not (sig[32] == 0 and not (int(sig[33]) & 0x80))
65
+ )
66
+
67
+
68
+ def compressedPubkey(pk):
69
+ if SECP256K1_MODULE == "cryptography" and not isinstance(pk, ecdsa.keys.VerifyingKey):
70
+ order = ecdsa.SECP256k1.order
71
+ x = pk.public_numbers().x
72
+ y = pk.public_numbers().y
73
+ else:
74
+ order = pk.curve.generator.order()
75
+ p = pk.pubkey.point
76
+ x = p.x()
77
+ y = p.y()
78
+ x_str = ecdsa.util.number_to_string(x, order)
79
+ return py23_bytes(chr(2 + (y & 1)), "ascii") + x_str
80
+
81
+
82
+ def recover_public_key(digest, signature, i, message=None):
83
+ """Recover the public key from the the signature"""
84
+
85
+ # See http: //www.secg.org/download/aid-780/sec1-v2.pdf section 4.1.6 primarily
86
+ curve = ecdsa.SECP256k1.curve
87
+ G = ecdsa.SECP256k1.generator
88
+ order = ecdsa.SECP256k1.order
89
+ yp = i % 2
90
+ r, s = ecdsa.util.sigdecode_string(signature, order)
91
+ # 1.1
92
+ x = r + (i // 2) * order
93
+ # 1.3. This actually calculates for either effectively 02||X or 03||X depending on 'k' instead of always for 02||X as specified.
94
+ # This substitutes for the lack of reversing R later on. -R actually is defined to be just flipping the y-coordinate in the elliptic curve.
95
+ alpha = ((x * x * x) + (curve.a() * x) + curve.b()) % curve.p()
96
+ beta = ecdsa.numbertheory.square_root_mod_prime(alpha, curve.p())
97
+ y = beta if (beta - yp) % 2 == 0 else curve.p() - beta
98
+ # 1.4 Constructor of Point is supposed to check if nR is at infinity.
99
+ R = ecdsa.ellipticcurve.Point(curve, x, y, order)
100
+ # 1.5 Compute e
101
+ e = ecdsa.util.string_to_number(digest)
102
+ # 1.6 Compute Q = r^-1(sR - eG)
103
+ Q = ecdsa.numbertheory.inverse_mod(r, order) * (s * R + (-e % order) * G)
104
+
105
+ if SECP256K1_MODULE == "cryptography" and message is not None:
106
+ if not isinstance(message, bytes_types):
107
+ message = py23_bytes(message, "utf-8")
108
+ sigder = encode_dss_signature(r, s)
109
+ try:
110
+ Q_point = Q.to_affine()
111
+ public_key = ec.EllipticCurvePublicNumbers(
112
+ Q_point.x(), Q_point.y(), ec.SECP256K1()
113
+ ).public_key(default_backend())
114
+ except:
115
+ try:
116
+ public_key = ec.EllipticCurvePublicNumbers(
117
+ Q._Point__x, Q._Point__y, ec.SECP256K1()
118
+ ).public_key(default_backend())
119
+ except:
120
+ Q_point = Q.to_affine()
121
+ public_key = ec.EllipticCurvePublicNumbers(
122
+ int(Q_point.x()), int(Q_point.y()), ec.SECP256K1()
123
+ ).public_key(default_backend())
124
+ public_key.verify(sigder, message, ec.ECDSA(hashes.SHA256()))
125
+ return public_key
126
+ else:
127
+ # Not strictly necessary, but let's verify the message for paranoia's sake.
128
+ if not ecdsa.VerifyingKey.from_public_point(Q, curve=ecdsa.SECP256k1).verify_digest(
129
+ signature, digest, sigdecode=ecdsa.util.sigdecode_string
130
+ ):
131
+ return None
132
+ return ecdsa.VerifyingKey.from_public_point(Q, curve=ecdsa.SECP256k1)
133
+
134
+
135
+ def recoverPubkeyParameter(message, digest, signature, pubkey):
136
+ """Use to derive a number that allows to easily recover the
137
+ public key from the signature
138
+ """
139
+ if not isinstance(message, bytes_types):
140
+ message = py23_bytes(message, "utf-8")
141
+ for i in range(0, 4):
142
+ if SECP256K1_MODULE == "secp256k1":
143
+ sig = pubkey.ecdsa_recoverable_deserialize(signature, i)
144
+ p = secp256k1.PublicKey(pubkey.ecdsa_recover(message, sig))
145
+ if p.serialize() == pubkey.serialize():
146
+ return i
147
+ elif SECP256K1_MODULE == "cryptography" and not isinstance(pubkey, PublicKey):
148
+ p = recover_public_key(digest, signature, i, message)
149
+ p_comp = hexlify(compressedPubkey(p))
150
+ pubkey_comp = hexlify(compressedPubkey(pubkey))
151
+ if p_comp == pubkey_comp:
152
+ return i
153
+ else: # pragma: no cover
154
+ p = recover_public_key(digest, signature, i)
155
+ p_comp = hexlify(compressedPubkey(p))
156
+ p_string = hexlify(p.to_string())
157
+ if isinstance(pubkey, PublicKey):
158
+ pubkey_string = py23_bytes(repr(pubkey), "latin")
159
+ else: # pragma: no cover
160
+ pubkey_string = hexlify(pubkey.to_string())
161
+ if p_string == pubkey_string or p_comp == pubkey_string:
162
+ return i
163
+ return None
164
+
165
+
166
+ def sign_message(message, wif, hashfn=hashlib.sha256):
167
+ """Sign a digest with a wif key
168
+
169
+ :param str wif: Private key in
170
+ """
171
+
172
+ if not isinstance(message, bytes_types):
173
+ message = py23_bytes(message, "utf-8")
174
+
175
+ digest = hashfn(message).digest()
176
+ priv_key = PrivateKey(wif)
177
+ if SECP256K1_MODULE == "secp256k1":
178
+ p = py23_bytes(priv_key)
179
+ ndata = secp256k1.ffi.new("const int *ndata")
180
+ ndata[0] = 0
181
+ while True:
182
+ ndata[0] += 1
183
+ privkey = secp256k1.PrivateKey(p, raw=True)
184
+ sig = secp256k1.ffi.new("secp256k1_ecdsa_recoverable_signature *")
185
+ signed = secp256k1.lib.secp256k1_ecdsa_sign_recoverable(
186
+ privkey.ctx, sig, digest, privkey.private_key, secp256k1.ffi.NULL, ndata
187
+ )
188
+ if not signed == 1:
189
+ raise AssertionError()
190
+ signature, i = privkey.ecdsa_recoverable_serialize(sig)
191
+ if _is_canonical(signature):
192
+ i += 4 # compressed
193
+ i += 27 # compact
194
+ break
195
+ elif SECP256K1_MODULE == "cryptography":
196
+ cnt = 0
197
+ private_key = ec.derive_private_key(
198
+ int(repr(priv_key), 16), ec.SECP256K1(), default_backend()
199
+ )
200
+ public_key = private_key.public_key()
201
+ while True:
202
+ cnt += 1
203
+ if not cnt % 20:
204
+ log.info("Still searching for a canonical signature. Tried %d times already!" % cnt)
205
+ order = ecdsa.SECP256k1.order
206
+ sigder = private_key.sign(message, ec.ECDSA(hashes.SHA256()))
207
+ r, s = decode_dss_signature(sigder)
208
+ signature = ecdsa.util.sigencode_string(r, s, order)
209
+ # Make sure signature is canonical!
210
+ #
211
+ sigder = bytearray(sigder)
212
+ lenR = sigder[3]
213
+ lenS = sigder[5 + lenR]
214
+ if lenR == 32 and lenS == 32:
215
+ # Derive the recovery parameter
216
+ #
217
+ i = recoverPubkeyParameter(message, digest, signature, public_key)
218
+ i += 4 # compressed
219
+ i += 27 # compact
220
+ break
221
+ else: # pragma: no branch # pragma: no cover
222
+ cnt = 0
223
+ p = py23_bytes(priv_key)
224
+ sk = ecdsa.SigningKey.from_string(p, curve=ecdsa.SECP256k1)
225
+ while 1:
226
+ cnt += 1
227
+ if not cnt % 20:
228
+ log.info("Still searching for a canonical signature. Tried %d times already!" % cnt)
229
+
230
+ # Deterministic k
231
+ #
232
+ k = ecdsa.rfc6979.generate_k(
233
+ sk.curve.generator.order(),
234
+ sk.privkey.secret_multiplier,
235
+ hashlib.sha256,
236
+ hashlib.sha256(
237
+ digest
238
+ + struct.pack("d", time.time()) # use the local time to randomize the signature
239
+ ).digest(),
240
+ )
241
+
242
+ # Sign message
243
+ #
244
+ sigder = sk.sign_digest(digest, sigencode=ecdsa.util.sigencode_der, k=k)
245
+
246
+ # Reformating of signature
247
+ #
248
+ r, s = ecdsa.util.sigdecode_der(sigder, sk.curve.generator.order())
249
+ signature = ecdsa.util.sigencode_string(r, s, sk.curve.generator.order())
250
+
251
+ # Make sure signature is canonical!
252
+ #
253
+ sigder = bytearray(sigder)
254
+ lenR = sigder[3]
255
+ lenS = sigder[5 + lenR]
256
+ if lenR == 32 and lenS == 32:
257
+ # Derive the recovery parameter
258
+ #
259
+ i = recoverPubkeyParameter(message, digest, signature, sk.get_verifying_key())
260
+ i += 4 # compressed
261
+ i += 27 # compact
262
+ break
263
+
264
+ # pack signature
265
+ #
266
+ sigstr = struct.pack("<B", i)
267
+ sigstr += signature
268
+
269
+ return sigstr
270
+
271
+
272
+ def verify_message(message, signature, hashfn=hashlib.sha256, recover_parameter=None):
273
+ if not isinstance(message, bytes_types):
274
+ message = py23_bytes(message, "utf-8")
275
+ if not isinstance(signature, bytes_types):
276
+ signature = py23_bytes(signature, "utf-8")
277
+ if not isinstance(message, bytes_types):
278
+ raise AssertionError()
279
+ if not isinstance(signature, bytes_types):
280
+ raise AssertionError()
281
+ digest = hashfn(message).digest()
282
+ sig = signature[1:]
283
+ if recover_parameter is None:
284
+ recover_parameter = bytearray(signature)[0] - 4 - 27 # recover parameter only
285
+ if recover_parameter < 0:
286
+ log.info("Could not recover parameter")
287
+ return None
288
+
289
+ if SECP256K1_MODULE == "secp256k1":
290
+ ALL_FLAGS = secp256k1.lib.SECP256K1_CONTEXT_VERIFY | secp256k1.lib.SECP256K1_CONTEXT_SIGN
291
+ # Placeholder
292
+ pub = secp256k1.PublicKey(flags=ALL_FLAGS)
293
+ # Recover raw signature
294
+ sig = pub.ecdsa_recoverable_deserialize(sig, recover_parameter)
295
+ # Recover PublicKey
296
+ verifyPub = secp256k1.PublicKey(pub.ecdsa_recover(message, sig))
297
+ # Convert recoverable sig to normal sig
298
+ normalSig = verifyPub.ecdsa_recoverable_convert(sig)
299
+ # Verify
300
+ verifyPub.ecdsa_verify(message, normalSig)
301
+ phex = verifyPub.serialize(compressed=True)
302
+ elif SECP256K1_MODULE == "cryptography":
303
+ p = recover_public_key(digest, sig, recover_parameter, message)
304
+ order = ecdsa.SECP256k1.order
305
+ r, s = ecdsa.util.sigdecode_string(sig, order)
306
+ sigder = encode_dss_signature(r, s)
307
+ p.verify(sigder, message, ec.ECDSA(hashes.SHA256()))
308
+ phex = compressedPubkey(p)
309
+ else: # pragma: no branch # pragma: no cover
310
+ p = recover_public_key(digest, sig, recover_parameter)
311
+ # Will throw an exception of not valid
312
+ p.verify_digest(sig, digest, sigdecode=ecdsa.util.sigdecode_string)
313
+ phex = compressedPubkey(p)
314
+
315
+ return phex
316
+
317
+
318
+ def tweakaddPubkey(pk, digest256, SECP256K1_MODULE=SECP256K1_MODULE):
319
+ if SECP256K1_MODULE == "secp256k1":
320
+ tmp_key = secp256k1.PublicKey(pubkey=bytes(pk), raw=True)
321
+ new_key = tmp_key.tweak_add(digest256) # <-- add
322
+ raw_key = hexlify(new_key.serialize()).decode("ascii")
323
+ else:
324
+ raise Exception("Must have secp256k1 for `tweak_add`")
325
+ # raw_key = ecmult(pk, 1, digest256, SECP256K1_MODULE)
326
+ return PublicKey(raw_key, prefix=pk.prefix)
@@ -0,0 +1,123 @@
1
+ # -*- coding: utf-8 -*-
2
+ import json
3
+
4
+ from nectargraphenebase.types import Id, JsonObj, Optional, String
5
+
6
+ from .operationids import operations
7
+ from .py23 import integer_types, py23_bytes, string_types
8
+
9
+
10
+ class Operation(object):
11
+ def __init__(self, op):
12
+ if isinstance(op, list) and len(op) == 2:
13
+ if isinstance(op[0], integer_types):
14
+ self.opId = op[0]
15
+ name = self.getOperationNameForId(self.opId)
16
+ else:
17
+ self.opId = self.operations().get(op[0], None)
18
+ name = op[0]
19
+ if self.opId is None:
20
+ raise ValueError("Unknown operation")
21
+ self.name = name[0].upper() + name[1:] # klassname
22
+ try:
23
+ klass = self._getklass(self.name)
24
+ except Exception:
25
+ raise NotImplementedError("Unimplemented Operation %s" % self.name)
26
+ self.op = klass(op[1])
27
+ self.appbase = False
28
+ elif isinstance(op, dict):
29
+ if len(op["type"]) > 10 and op["type"][-9:] == "operation":
30
+ name = op["type"][:-10]
31
+ else:
32
+ name = op["type"]
33
+ self.opId = self.operations().get(name, None)
34
+ if self.opId is None:
35
+ raise ValueError("Unknown operation")
36
+ self.name = name[0].upper() + name[1:] # klassname
37
+ try:
38
+ klass = self._getklass(self.name)
39
+ except Exception:
40
+ raise NotImplementedError("Unimplemented Operation %s" % self.name)
41
+ self.op = klass(op["value"])
42
+ self.appbase = True
43
+ else:
44
+ self.op = op
45
+ self.name = type(self.op).__name__.lower() # also store name
46
+ self.opId = self.operations()[self.name]
47
+
48
+ def operations(self):
49
+ return operations
50
+
51
+ def getOperationNameForId(self, i):
52
+ """Convert an operation id into the corresponding string"""
53
+ for key in self.operations():
54
+ if int(self.operations()[key]) is int(i):
55
+ return key
56
+ return "Unknown Operation ID %d" % i
57
+
58
+ def _getklass(self, name):
59
+ module = __import__("graphenebase.operations", fromlist=["operations"])
60
+ class_ = getattr(module, name)
61
+ return class_
62
+
63
+ def __bytes__(self):
64
+ return py23_bytes(Id(self.opId)) + py23_bytes(self.op)
65
+
66
+ def __str__(self):
67
+ return json.dumps([self.opId, self.op.toJson()])
68
+
69
+
70
+ class GrapheneObject(object):
71
+ """Core abstraction class
72
+
73
+ This class is used for any JSON reflected object in Graphene.
74
+
75
+ * ``instance.__json__()``: encodes data into json format
76
+ * ``bytes(instance)``: encodes data into wire format
77
+ * ``str(instances)``: dumps json object as string
78
+
79
+ """
80
+
81
+ def __init__(self, data=None):
82
+ self.data = data
83
+
84
+ def __bytes__(self):
85
+ if self.data is None:
86
+ return py23_bytes()
87
+ b = b""
88
+ for name, value in list(self.data.items()):
89
+ if isinstance(value, string_types):
90
+ b += py23_bytes(value, "utf-8")
91
+ else:
92
+ b += py23_bytes(value)
93
+ return b
94
+
95
+ def __json__(self):
96
+ if self.data is None:
97
+ return {}
98
+ d = {} # JSON output is *not* ordered
99
+ for name, value in list(self.data.items()):
100
+ if isinstance(value, Optional) and value.isempty():
101
+ continue
102
+
103
+ if isinstance(value, String):
104
+ d.update({name: str(value)})
105
+ else:
106
+ try:
107
+ d.update({name: JsonObj(value)})
108
+ except Exception:
109
+ d.update({name: value.__str__()})
110
+ return d
111
+
112
+ def __str__(self):
113
+ return json.dumps(self.__json__())
114
+
115
+ def toJson(self):
116
+ return self.__json__()
117
+
118
+ def json(self):
119
+ return self.__json__()
120
+
121
+
122
+ def isArgsThisClass(self, args):
123
+ return len(args) == 1 and type(args[0]).__name__ == type(self).__name__
@@ -0,0 +1,6 @@
1
+ #: Object types for object ids
2
+ object_type = {}
3
+ object_type["null"] = 0
4
+ object_type["base"] = 1
5
+ object_type["account"] = 2
6
+ object_type["OBJECT_TYPE_COUNT"] = 3
@@ -0,0 +1,3 @@
1
+ #: Operation ids
2
+ operations = {}
3
+ operations["demooepration"] = 0
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+ from .objects import GrapheneObject, isArgsThisClass
3
+ from .types import (
4
+ Set,
5
+ String,
6
+ )
7
+
8
+
9
+ class Demooepration(GrapheneObject):
10
+ def __init__(self, *args, **kwargs):
11
+ if isArgsThisClass(self, args):
12
+ self.data = args[0].data
13
+ else:
14
+ if len(args) == 1 and len(kwargs) == 0:
15
+ kwargs = args[0]
16
+ super(Demooepration, self).__init__(
17
+ OrderedDict(
18
+ [
19
+ ("string", String(kwargs["string"], "account")),
20
+ ("extensions", Set([])),
21
+ ]
22
+ )
23
+ )
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+ class Prefix:
3
+ """This class is meant to allow changing the prefix.
4
+ The prefix is used to link a public key to a specific blockchain.
5
+ """
6
+
7
+ prefix = "STM"
8
+
9
+ def set_prefix(self, prefix):
10
+ if prefix:
11
+ self.prefix = prefix
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ import sys
3
+
4
+ PY2 = sys.version_info[0] == 2
5
+ PY3 = sys.version_info[0] == 3
6
+
7
+
8
+ if PY3:
9
+ bytes_types = (bytes,)
10
+ string_types = (str,)
11
+ integer_types = (int,)
12
+ text_type = str
13
+ binary_type = bytes
14
+ else:
15
+ bytes_types = (bytes,)
16
+ string_types = (basestring,) # noqa: F821
17
+ integer_types = (int, long) # noqa: F821
18
+ text_type = unicode # noqa: F821
19
+ binary_type = str
20
+
21
+
22
+ def py23_bytes(item=None, encoding=None):
23
+ if item is None:
24
+ return b""
25
+ if hasattr(item, "__bytes__"):
26
+ return item.__bytes__()
27
+ else:
28
+ if encoding:
29
+ return bytes(item, encoding)
30
+ else:
31
+ return bytes(item)
32
+
33
+
34
+ def py23_chr(item):
35
+ if PY2:
36
+ return chr(item)
37
+ else:
38
+ return bytes([item])