Fix bytes/str conflict in Python 3, add network selection for address derivation from the seed
This commit is contained in:
parent
c02009128d
commit
10c6ee1a67
|
@ -30,6 +30,7 @@
|
||||||
# https://github.com/bigreddmachine/MoneroPy/blob/master/moneropy/mnemonic.py ch: 80cc16c39b16c55a8d052fbf7fae68644f7a5f02
|
# https://github.com/bigreddmachine/MoneroPy/blob/master/moneropy/mnemonic.py ch: 80cc16c39b16c55a8d052fbf7fae68644f7a5f02
|
||||||
# https://github.com/spesmilo/electrum/blob/master/lib/old_mnemonic.py ch:9a0aa9b4783ea03ea13c6d668e080e0cdf261c5b
|
# https://github.com/spesmilo/electrum/blob/master/lib/old_mnemonic.py ch:9a0aa9b4783ea03ea13c6d668e080e0cdf261c5b
|
||||||
|
|
||||||
|
from monero import address
|
||||||
from monero import wordlists
|
from monero import wordlists
|
||||||
from monero import ed25519
|
from monero import ed25519
|
||||||
from monero import base58
|
from monero import base58
|
||||||
|
@ -146,7 +147,7 @@ class Seed(object):
|
||||||
def sc_reduce(self, input):
|
def sc_reduce(self, input):
|
||||||
integer = ed25519.decodeint(unhexlify(input))
|
integer = ed25519.decodeint(unhexlify(input))
|
||||||
modulo = integer % ed25519.l
|
modulo = integer % ed25519.l
|
||||||
return hexlify(ed25519.encodeint(modulo))
|
return hexlify(ed25519.encodeint(modulo)).decode()
|
||||||
|
|
||||||
def hex_seed(self):
|
def hex_seed(self):
|
||||||
return self.hex
|
return self.hex
|
||||||
|
@ -162,18 +163,28 @@ class Seed(object):
|
||||||
def public_spend_key(self):
|
def public_spend_key(self):
|
||||||
keyInt = ed25519.decodeint(unhexlify(self.secret_spend_key()))
|
keyInt = ed25519.decodeint(unhexlify(self.secret_spend_key()))
|
||||||
aG = ed25519.scalarmultbase(keyInt)
|
aG = ed25519.scalarmultbase(keyInt)
|
||||||
return hexlify(ed25519.encodepoint(aG))
|
return hexlify(ed25519.encodepoint(aG)).decode()
|
||||||
|
|
||||||
def public_view_key(self):
|
def public_view_key(self):
|
||||||
keyInt = ed25519.decodeint(unhexlify(self.secret_view_key()))
|
keyInt = ed25519.decodeint(unhexlify(self.secret_view_key()))
|
||||||
aG = ed25519.scalarmultbase(keyInt)
|
aG = ed25519.scalarmultbase(keyInt)
|
||||||
return hexlify(ed25519.encodepoint(aG))
|
return hexlify(ed25519.encodepoint(aG)).decode()
|
||||||
|
|
||||||
def public_address(self):
|
def public_address(self, net='mainnet'):
|
||||||
data = str.encode("12") + self.public_spend_key() + self.public_view_key()
|
"""Returns the master :class:`Address <monero.address.Address>` represented by the seed.
|
||||||
|
|
||||||
|
:param net: the network, one of 'mainnet', 'testnet', 'stagenet'. Default is 'mainnet'.
|
||||||
|
|
||||||
|
:rtype: :class:`Address <monero.address.Address>`
|
||||||
|
"""
|
||||||
|
if net not in ('mainnet', 'testnet', 'stagenet'):
|
||||||
|
raise ValueError(
|
||||||
|
"Invalid net argument. Must be one of ('mainnet', 'testnet', 'stagenet').")
|
||||||
|
netbyte = 18 if net == 'mainnet' else 53 if net == 'testnet' else 24
|
||||||
|
data = "{:x}{:s}{:s}".format(netbyte, self.public_spend_key(), self.public_view_key())
|
||||||
h = keccak_256()
|
h = keccak_256()
|
||||||
h.update(unhexlify(data))
|
h.update(unhexlify(data))
|
||||||
checksum = str.encode(h.hexdigest())
|
checksum = h.hexdigest()
|
||||||
return base58.encode(data + checksum[0:8])
|
return base58.encode(data + checksum[0:8])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,5 +61,31 @@ class SeedTestCase(unittest.TestCase):
|
||||||
Seed("\\x008")
|
Seed("\\x008")
|
||||||
self.assertEqual(ts.expected, ValueError)
|
self.assertEqual(ts.expected, ValueError)
|
||||||
|
|
||||||
|
|
||||||
|
def test_keys(self):
|
||||||
|
seed = Seed("adjust mugged vaults atlas nasty mews damp toenail suddenly toxic possible "\
|
||||||
|
"framed succeed fuzzy return demonstrate nucleus album noises peculiar virtual "\
|
||||||
|
"rowboat inorganic jester fuzzy")
|
||||||
|
self.assertTrue(seed.validate_checksum())
|
||||||
|
self.assertEqual(
|
||||||
|
seed.secret_spend_key(),
|
||||||
|
'482700617ba810f94035d7f4d7ccc1a29878e165b4867872b705204c85406906')
|
||||||
|
self.assertEqual(
|
||||||
|
seed.secret_view_key(),
|
||||||
|
'09ed72c713d3e9e19bef2f5204cf85f6cb25de7842aa0722abeb12697f171903')
|
||||||
|
self.assertEqual(
|
||||||
|
seed.public_spend_key(),
|
||||||
|
'4ee576f52b9c6a824a3d5c2832d117177d2bb9992507c2c78788bb8dbaf4b640')
|
||||||
|
self.assertEqual(
|
||||||
|
seed.public_view_key(),
|
||||||
|
'e1ef99d66312ec0b16b17c66c591ab59594e21621588b63b62fa69fe615a768e')
|
||||||
|
self.assertEqual(
|
||||||
|
seed.public_address(),
|
||||||
|
'44cWztNFdAqNnycvZbUoj44vsbAEmKnx9aNgkjHdjtMsBrSeKiY8J4s2raH7EMawA2Fwo9utaRTV7Aw8EcTMNMxhH4YtKdH')
|
||||||
|
self.assertEqual(
|
||||||
|
seed.public_address(net='stagenet'),
|
||||||
|
'54pZ5jHDGmwNnycvZbUoj44vsbAEmKnx9aNgkjHdjtMsBrSeKiY8J4s2raH7EMawA2Fwo9utaRTV7Aw8EcTMNMxhH6cuARW')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue