Skip to content

Commit e9b7218

Browse files
authored
Merge pull request #50 from ainblockchain/release/v1.3.0
Release/v1.3.0
2 parents 4116ea3 + 381a525 commit e9b7218

File tree

7 files changed

+48
-22
lines changed

7 files changed

+48
-22
lines changed

ain/account.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@ def __init__(self, privateKey: Union[bytes, str] = None):
3434
self.address = privateToAddress(privateKeyBytes)
3535

3636
@classmethod
37-
def fromMnemonic(cls, mnemonic: str, index: int = 0):
37+
def fromMnemonic(cls, mnemonic: str, index: int = 0, chain: str = "AIN"):
3838
"""Inits an `Account` with the given mnemonic.
3939
4040
Args:
4141
mnemonic (str): The mnemonic of account.
4242
index (int): The index of account. Defaults to 0.
43+
chain (str): The chain to use the derivation path of. Defaults to "AIN".
4344
"""
44-
return cls(mnemonicToPrivatekey(mnemonic, index))
45+
return cls(mnemonicToPrivatekey(mnemonic, index, chain))
4546

4647
@classmethod
4748
def create(cls, entropy: str = None):

ain/utils/__init__.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,11 @@ def encodeVarInt(number: int) -> bytes:
4646
SIGNED_MESSAGE_PREFIX = "AINetwork Signed Message:\n"
4747
SIGNED_MESSAGE_PREFIX_BYTES = bytes(SIGNED_MESSAGE_PREFIX, "utf-8")
4848
SIGNED_MESSAGE_PREFIX_LENGTH = encodeVarInt(len(SIGNED_MESSAGE_PREFIX))
49-
# TODO(platfowner): Migrate to Ethereum HD derivation path 'm/44'/60'/0'/0/'.
50-
AIN_HD_DERIVATION_PATH = "m/44'/412'/0'/0/" # The hardware wallet derivation path of AIN
49+
# NOTE(platfowner): In AI Network, we decided to use both Ethereum Network's
50+
# derivation path ("m/44'/60'/0'/0/") and
51+
# its own ("m/44'/412'/0'/0/").
52+
AIN_HD_DERIVATION_PATH = "m/44'/412'/0'/0/"
53+
ETH_HD_DERIVATION_PATH = "m/44'/60'/0'/0/"
5154

5255
def getTimestamp() -> int:
5356
"""Gets the current unix timestamp.
@@ -530,12 +533,13 @@ def generateMnemonic() -> str:
530533
"""
531534
return Mnemonic("english").generate()
532535

533-
def mnemonicToPrivatekey(mnemonic: str, index: int = 0) -> bytes:
536+
def mnemonicToPrivatekey(mnemonic: str, index: int = 0, chain: str = "AIN") -> bytes:
534537
"""Returns an private key with the given mnemonic.
535538
536539
Args:
537540
mnemonic (str): The mnemonic of account.
538541
index (int): The index of account. Defaults to 0.
542+
chain (str): The chain to use the derivation path of. Defaults to "AIN".
539543
540544
Returns:
541545
bytes: The private key with the given mnemonic.
@@ -548,7 +552,8 @@ def mnemonicToPrivatekey(mnemonic: str, index: int = 0) -> bytes:
548552

549553
seed = Mnemonic.to_seed(mnemonic)
550554
bip32 = BIP32.from_seed(seed)
551-
path = AIN_HD_DERIVATION_PATH + f"{index}"
555+
prefix = AIN_HD_DERIVATION_PATH if chain == "AIN" else ETH_HD_DERIVATION_PATH
556+
path = prefix + f"{index}"
552557
return bip32.get_privkey_from_path(path)
553558

554559
# NOTE(kriii): Referenced https://github.com/bitchan/eccrypto/blob/master/index.js#L195-L258

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@
4444
test_suite="tests",
4545
tests_require=test_requirements,
4646
url="https://github.com/ainblockchain/ain-py",
47-
version="1.2.1",
47+
version="1.3.0",
4848
zip_safe=False,
4949
)

tests/data.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@
77
pk = bytes.fromhex("cf0ba8241cd1452c282c4dfa33d48e43ca34e60f5da9a2422293aa34ac14b018991d0cbc42089e4dcf3b3cc2907d51f06baed00cad7f855182572c77cbfad2b3")
88
sk = bytes.fromhex("cef602325bc0882591e5768e94cd94a326947e8ee5d3b02fb29d1b89a9334d99")
99
mnemonic = "lab diesel rule gas student bulb menu option play habit ski result"
10-
mnemonicPrivateKey = bytes.fromhex("1fa9d5e22aa39d264c7c939f99b47696cf534bead88e4ca81da767b1ed122fa8")
11-
mnemonicPublicKey = bytes.fromhex("6ab3e3c1d727fe72e06a6243a05ee6b1607c162a1696629ac9f19b0c1661d586554cadb17ea9d1ae246f60735f9d0e399c61139d7afef72de28809edb695990e")
12-
mnemonicAddress = "0xe402A6296233F2DfefE35cbC3203802965B4E4d7"
10+
# NOTE(platfowner): In AI Network, we decided to use both Ethereum Network's
11+
# derivation path ("m/44'/60'/0'/0/") and
12+
# its own ("m/44'/412'/0'/0/").
13+
mnemonicPrivateKeyAin = bytes.fromhex("1fa9d5e22aa39d264c7c939f99b47696cf534bead88e4ca81da767b1ed122fa8")
14+
mnemonicPublicKeyAin = bytes.fromhex("6ab3e3c1d727fe72e06a6243a05ee6b1607c162a1696629ac9f19b0c1661d586554cadb17ea9d1ae246f60735f9d0e399c61139d7afef72de28809edb695990e")
15+
mnemonicAddressAin = "0xe402A6296233F2DfefE35cbC3203802965B4E4d7"
16+
mnemonicPrivateKeyEth = bytes.fromhex("6819573717d78a332c67460c9f6d4ed8cc72457620646ba365673177a7aa34dd")
17+
mnemonicPublicKeyEth = bytes.fromhex("98cea6be654001ec6c47cd13dd7e193fc82b69954a2726949cbcc724088081657b51b12b2bfbd6055c060a86d4b6e189faa44a0e43157503f78e929f01cd7742")
18+
mnemonicAddressEth = "0xCb6D24618842a9dE0a1f73Ab55DEB301D811ad13"
1319
checksumAddresses = [
1420
"0x21fE266480080535b0CCe687669e5DBe13f42559",
1521
"0x32F9c01ab1247C9366C8A22B6929eB0A905dBBd1",

tests/snapshots/snap_test_ain.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@
254254
}
255255
}
256256

257-
snapshots['TestDatabase::test03GetProofHash 1'] = '0x88496dfee3566db91f487aa4cbf69a0c42a3e2a5d0a65bfd4897d699e8734785'
257+
snapshots['TestDatabase::test03GetProofHash 1'] = '0x596d0fd28fd56eea0e286985a17e8b1374b7a7557539fd137dcdea0187da6956'
258258

259259
snapshots['TestDatabase::test03GetStateInfo 1'] = {
260260
'#num_children': 1,

tests/test_ain_account.py

+16-7
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,26 @@
33
from ain.utils import *
44
from .data import (
55
mnemonic,
6-
mnemonicPrivateKey,
7-
mnemonicPublicKey,
8-
mnemonicAddress,
6+
mnemonicPrivateKeyAin,
7+
mnemonicPublicKeyAin,
8+
mnemonicAddressAin,
9+
mnemonicPrivateKeyEth,
10+
mnemonicPublicKeyEth,
11+
mnemonicAddressEth,
912
)
1013

1114
class TestAccount(TestCase):
12-
def testAccountFromMnemonic(self):
15+
def testAccountFromMnemonicAin(self):
1316
account = Account.fromMnemonic(mnemonic)
14-
self.assertEqual(account.private_key, mnemonicPrivateKey.hex())
15-
self.assertEqual(account.public_key, mnemonicPublicKey.hex())
16-
self.assertEqual(account.address, mnemonicAddress)
17+
self.assertEqual(account.private_key, mnemonicPrivateKeyAin.hex())
18+
self.assertEqual(account.public_key, mnemonicPublicKeyAin.hex())
19+
self.assertEqual(account.address, mnemonicAddressAin)
20+
21+
def testAccountFromMnemonicEth(self):
22+
account = Account.fromMnemonic(mnemonic, 0, "ETH")
23+
self.assertEqual(account.private_key, mnemonicPrivateKeyEth.hex())
24+
self.assertEqual(account.public_key, mnemonicPublicKeyEth.hex())
25+
self.assertEqual(account.address, mnemonicAddressEth)
1726

1827
def testAccountCreateFromEntropyNone(self):
1928
account = Account.create()

tests/test_ain_utils.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
pk,
88
sk,
99
mnemonic,
10-
mnemonicPrivateKey,
10+
mnemonicPrivateKeyAin,
11+
mnemonicPrivateKeyEth,
1112
checksumAddresses,
1213
message,
1314
correctSignature,
@@ -477,9 +478,13 @@ def testEcVerifySigIncorrectAddress(self):
477478
def testEcVerifySigDifferentMessage(self):
478479
self.assertFalse(ecVerifySig("Hello World", correctSignature, address))
479480

480-
class TestMnemonicToPrivatekey(TestCase):
481-
def testMnemonicToPrivatekey(self):
482-
self.assertEqual(mnemonicToPrivatekey(mnemonic), mnemonicPrivateKey)
481+
class TestMnemonicToPrivatekeyAin(TestCase):
482+
def testMnemonicToPrivatekeyAin(self):
483+
self.assertEqual(mnemonicToPrivatekey(mnemonic), mnemonicPrivateKeyAin)
484+
485+
class TestMnemonicToPrivatekeyEth(TestCase):
486+
def testMnemonicToPrivatekeyEth(self):
487+
self.assertEqual(mnemonicToPrivatekey(mnemonic, 0, "ETH"), mnemonicPrivateKeyEth)
483488

484489
class TestEncryption(TestCase):
485490
def testEncryptToDecrypt(self):

0 commit comments

Comments
 (0)