From 47f38ceb06c92607dc820a5c51b0046f6dcc7136 Mon Sep 17 00:00:00 2001 From: hewigovens <360470+hewigovens@users.noreply.github.com> Date: Mon, 20 May 2019 22:12:16 +0800 Subject: [PATCH 1/6] implement zilliqa bech32 address --- .../blockchains/CoinAddressDerivationTests.kt | 2 +- include/TrustWalletCore/TWHRP.h | 2 + include/TrustWalletCore/TWZilliqaAddress.h | 4 ++ js/tests/utils/CoinAddressDerivation.test.ts | 2 +- src/Coin.cpp | 2 +- src/Zilliqa/Address.cpp | 47 +++---------------- src/Zilliqa/Address.h | 44 +++++++---------- src/Zilliqa/AddressChecksum.cpp | 6 +-- src/Zilliqa/AddressChecksum.h | 6 +-- src/Zilliqa/Signer.cpp | 8 +++- src/interface/TWHRP.cpp | 3 ++ src/interface/TWZilliqaAddress.cpp | 12 +++-- swift/Tests/Blockchains/ZilliqaTests.swift | 11 ++++- swift/Tests/CoinAddressDerivationTests.swift | 2 +- swift/Tests/HDWalletTests.swift | 2 +- tests/CoinTests.cpp | 3 +- tests/Zilliqa/AddressTests.cpp | 43 ++++++++--------- tests/Zilliqa/SignerTests.cpp | 6 ++- tests/interface/TWCoinTypeConfigTests.cpp | 1 + tests/interface/TWZilliqaTests.cpp | 12 +++-- 20 files changed, 102 insertions(+), 116 deletions(-) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt index 5d17220fab1..cbffb51ab90 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt @@ -71,7 +71,7 @@ class CoinAddressDerivationTests { STEEM -> assertEquals("STM6WSusVTidc1e7TbLjhqQPYctbsndTRwXHpi82gMuJyKEkJVLvg", address) EOS -> assertEquals("EOS6hs8sRvGSzuQtq223zwJipMzqTJpXUVjyvHPvPwBSZWWrJTJkg", address) IOTEX -> assertEquals("io1qw9cccecw09q7p5kzyqtuhfhvah2mhfrc84jfk", address) - ZILLIQA -> assertEquals("0xDdb41006F7B6FA8e5FBF06A71c01F789FeBC66e8", address) + ZILLIQA -> assertEquals("zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6", address) SEMUX -> assertEquals("0xfe604170382452f77bc922bc19eb4b53504b09c2", address) DEXON -> assertEquals("0x6F3E6a6dDf2C2B4B32B8Bb452eA3F36B2BB489BF", address) ZELCASH -> assertEquals("t1UKbRPzL4WN8Rs8aZ8RNiWoD2ftCMHKGUf", address) diff --git a/include/TrustWalletCore/TWHRP.h b/include/TrustWalletCore/TWHRP.h index 66e3eca9d83..545493c5b2a 100644 --- a/include/TrustWalletCore/TWHRP.h +++ b/include/TrustWalletCore/TWHRP.h @@ -23,6 +23,7 @@ enum TWHRP { TWHRPCosmos /* "cosmos" */, TWHRPGroestlcoin /* "grs" */, TWHRPQtum /* "qtum" */, + TWHRPZilliqa /* "zilliqa" */, }; static const char *_Nonnull HRP_BINANCE = "bnb"; @@ -33,6 +34,7 @@ static const char *_Nonnull HRP_COSMOS = "cosmos"; static const char *_Nonnull HRP_GROESTLCOIN = "grs"; static const char *_Nonnull HRP_VIACOIN = "via"; static const char *_Nonnull HRP_QTUM = "qc"; +static const char *_Nonnull HRP_ZILLIQA = "zil"; const char *_Nullable stringForHRP(enum TWHRP hrp); enum TWHRP hrpForString(const char *_Nonnull string); diff --git a/include/TrustWalletCore/TWZilliqaAddress.h b/include/TrustWalletCore/TWZilliqaAddress.h index a7a87048d9c..05a8287608b 100644 --- a/include/TrustWalletCore/TWZilliqaAddress.h +++ b/include/TrustWalletCore/TWZilliqaAddress.h @@ -41,4 +41,8 @@ void TWZilliqaAddressDelete(struct TWZilliqaAddress *_Nonnull address); TW_EXPORT_PROPERTY TWString *_Nonnull TWZilliqaAddressDescription(struct TWZilliqaAddress *_Nonnull address); +/// Returns the key hash. +TW_EXPORT_PROPERTY +TWData *_Nonnull TWZilliqaAddressKeyHash(struct TWZilliqaAddress *_Nonnull address); + TW_EXTERN_C_END diff --git a/js/tests/utils/CoinAddressDerivation.test.ts b/js/tests/utils/CoinAddressDerivation.test.ts index a5b0119bb65..4526a51740f 100644 --- a/js/tests/utils/CoinAddressDerivation.test.ts +++ b/js/tests/utils/CoinAddressDerivation.test.ts @@ -62,7 +62,7 @@ describe('CoinAddressDerivation', () => { case CoinType.LUX: expect('LYL6SZG8S6dyXRFT8Bw4FHUoVef3cWCoPi').to.equal(address); break; case CoinType.QTUM: expect('QhceuaTdeCZtcxmVc6yyEDEJ7Riu5gWFoF').to.equal(address); break; case CoinType.NULS: expect('NsdtNvsfmPerWk4BhcapHTB3LptF8Sbe').to.equal(address); break; - case CoinType.ZILLIQA: expect('0xDdb41006F7B6FA8e5FBF06A71c01F789FeBC66e8').to.equal(address); break; + case CoinType.ZILLIQA: expect('zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6').to.equal(address); break; case CoinType.SEMUX: expect('0xfe604170382452f77bc922bc19eb4b53504b09c2').to.equal(address); break; } }; diff --git a/src/Coin.cpp b/src/Coin.cpp index 76cba8a4974..3c9ec02f969 100644 --- a/src/Coin.cpp +++ b/src/Coin.cpp @@ -146,7 +146,7 @@ bool TW::validateAddress(TWCoinType coin, const std::string& string) { return Zcash::TAddress::isValid(string, {{Zcash::TAddress::staticPrefix, TWP2PKHPrefixZcashT}, {Zcash::TAddress::staticPrefix, TWP2SHPrefixZcashT}}); case TWCoinTypeZilliqa: - return Zilliqa::Address::isValid(string); + return Zilliqa::isValidAddress(string); case TWCoinTypeNano: return Nano::Address::isValid(string); diff --git a/src/Zilliqa/Address.cpp b/src/Zilliqa/Address.cpp index 9312269e75f..5258803c8be 100644 --- a/src/Zilliqa/Address.cpp +++ b/src/Zilliqa/Address.cpp @@ -1,42 +1,7 @@ -#include "Address.h" -#include "AddressChecksum.h" -#include "stdint.h" -#include "../HexCoding.h" - -using namespace TW::Zilliqa; - -bool Address::isValid(const std::string& string) { - if (string.size() != 42 || string[0] != '0' || string[1] != 'x') { - return false; - } - const auto data = parse_hex(string); - return Address::isValid(data); -} - -Address::Address(const std::string& string) { - if (!isValid(string)) { - throw std::invalid_argument("Invalid address data"); - } - const auto data = parse_hex(string); - std::copy(data.begin(), data.end(), bytes.begin()); -} +// Copyright © 2017-2019 Trust. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. -Address::Address(const PublicKey& publicKey) { - if (publicKey.type != TWPublicKeyTypeSECP256k1) { - throw std::invalid_argument("Ziliqa::Address needs SECP256k1 public key"); - } - const auto data = - publicKey.hash({}, static_cast(Hash::sha256), false); - std::copy(data.end() - Address::size, data.end(), bytes.begin()); -} - -Address::Address(const Data& data) { - if (!isValid(data)) { - throw std::invalid_argument("Invalid address data"); - } - std::copy(data.begin(), data.end(), bytes.begin()); -} - -std::string Address::string() const { - return checksumed(*this); -} +#include "Address.h" diff --git a/src/Zilliqa/Address.h b/src/Zilliqa/Address.h index 3e8bf5f73a7..029728e19f2 100644 --- a/src/Zilliqa/Address.h +++ b/src/Zilliqa/Address.h @@ -7,45 +7,33 @@ #pragma once #include "../PublicKey.h" +#include "../Cosmos/Address.h" + +#include #include namespace TW::Zilliqa { -class Address { - public: - /// Number of bytes in an address. - static const size_t size = 20; - - /// Address data followed by the public key - std::array bytes; - - /// Determines whether a collection of bytes makes a valid address. - static bool isValid(const Data& data) { return data.size() == size; } - - /// Determines whether a string makes a valid address. - static bool isValid(const std::string& string); + static bool isValidAddress(const std::string& address) { + return Cosmos::Address::isValid(address, HRP_ZILLIQA); + } - /// Initializes an address from a string representation. - explicit Address(const std::string& string); + static Cosmos::Address Address(const PublicKey& publicKey) { + const auto hashed = Hash::sha256(publicKey.bytes); + auto keyHash = Data(20); + std::copy(hashed.end() - 20, hashed.end(), keyHash.begin()); - /// Initializes an address with a collection of bytes. - explicit Address(const Data& data); - - /// Initializes an address from a public key. - explicit Address(const PublicKey& publicKey); - - /// Returns a string representation of the address. 20-bytes hex-encoded - std::string string() const; -}; + return Cosmos::Address(HRP_ZILLIQA, keyHash); + } -inline bool operator==(const Address& lhs, const Address& rhs) { - return lhs.bytes == rhs.bytes; -} + static Cosmos::Address Address(const Data& keyHash) { + return Cosmos::Address(HRP_ZILLIQA, keyHash); + } } // namespace TW::Zilliqa /// Wrapper for C interface. struct TWZilliqaAddress { - TW::Zilliqa::Address impl; + TW::Cosmos::Address impl; }; diff --git a/src/Zilliqa/AddressChecksum.cpp b/src/Zilliqa/AddressChecksum.cpp index 2988d457690..4bad7cfc4bc 100644 --- a/src/Zilliqa/AddressChecksum.cpp +++ b/src/Zilliqa/AddressChecksum.cpp @@ -15,9 +15,9 @@ using namespace TW; using namespace TW::Zilliqa; /// see https://github.com/Zilliqa/Zilliqa/blob/1c53b792c7ae44f7b77366536a7e2f73a3eade6a/src/libServer/AddressChecksum.h -std::string Zilliqa::checksumed(const Address& address) { - const auto addressString = hex(address.bytes); - const auto hash = hex(Hash::sha256(address.bytes)); +std::string Zilliqa::checksumed(const Data& bytes) { + const auto addressString = hex(bytes); + const auto hash = hex(Hash::sha256(bytes)); uint256_t temp_1 = 1; uint256_t v("0x" + hash); diff --git a/src/Zilliqa/AddressChecksum.h b/src/Zilliqa/AddressChecksum.h index 3c48758e491..750705d1920 100644 --- a/src/Zilliqa/AddressChecksum.h +++ b/src/Zilliqa/AddressChecksum.h @@ -6,11 +6,11 @@ #pragma once -#include "Address.h" +#include "../Data.h" #include namespace TW::Zilliqa { -std::string checksumed(const Address& address); +std::string checksumed(const Data& address); -} // namespace TW::Ethereum +} // namespace TW::Zilliqa diff --git a/src/Zilliqa/Signer.cpp b/src/Zilliqa/Signer.cpp index 1856e777967..1e8167c8fb4 100644 --- a/src/Zilliqa/Signer.cpp +++ b/src/Zilliqa/Signer.cpp @@ -30,13 +30,17 @@ Data Signer::getPreImage(const Proto::SigningInput& input) noexcept { auto internal = ZilliqaMessage::ProtoTransactionCoreInfo(); const auto key = PrivateKey(Data(input.private_key().begin(), input.private_key().end())); - const auto address = Address(input.to_address()); + const auto address = Cosmos::Address::decode(input.to_address()); + + if (!address.second) { + return {}; + } const auto pubKey = key.getPublicKey(TWPublicKeyTypeSECP256k1); internal.set_version(input.version()); internal.set_nonce(input.nonce()); - internal.set_toaddr(address.bytes.data(), address.bytes.size()); + internal.set_toaddr(address.first.keyHash.data(), address.first.keyHash.size()); auto sender = new ZilliqaMessage::ByteArray(); sender->set_data(pubKey.bytes.data(), pubKey.bytes.size()); diff --git a/src/interface/TWHRP.cpp b/src/interface/TWHRP.cpp index acbc3e97c1a..928bc6ba6cb 100644 --- a/src/interface/TWHRP.cpp +++ b/src/interface/TWHRP.cpp @@ -18,6 +18,7 @@ const char* stringForHRP(enum TWHRP hrp) { case TWHRPCosmos: return HRP_COSMOS; case TWHRPGroestlcoin: return HRP_GROESTLCOIN; case TWHRPQtum: return HRP_QTUM; + case TWHRPZilliqa: return HRP_ZILLIQA; default: return nullptr; } } @@ -39,6 +40,8 @@ enum TWHRP hrpForString(const char *_Nonnull string) { return TWHRPGroestlcoin; } else if (std::strcmp(string, HRP_QTUM) == 0) { return TWHRPQtum; + } else if (std::strcmp(string, HRP_ZILLIQA) == 0) { + return TWHRPZilliqa; } else { return TWHRPUnknown; } diff --git a/src/interface/TWZilliqaAddress.cpp b/src/interface/TWZilliqaAddress.cpp index d31c26c7fff..33d09cbe40d 100644 --- a/src/interface/TWZilliqaAddress.cpp +++ b/src/interface/TWZilliqaAddress.cpp @@ -24,15 +24,17 @@ bool TWZilliqaAddressEqual(struct TWZilliqaAddress *_Nonnull lhs, struct TWZilli bool TWZilliqaAddressIsValidString(TWString *_Nonnull string) { auto s = reinterpret_cast(string); - return Address::isValid(*s); + return Zilliqa::isValidAddress(*s); } struct TWZilliqaAddress *_Nullable TWZilliqaAddressCreateWithString(TWString *_Nonnull string) { auto s = reinterpret_cast(string); - if (!Address::isValid(*s)) { + auto dec = Cosmos::Address::decode(*s); + if (!dec.second || dec.first.hrp != HRP_ZILLIQA) { return nullptr; } - return new TWZilliqaAddress{ Address(*s) }; + + return new TWZilliqaAddress{ Address(dec.first.keyHash) }; } struct TWZilliqaAddress *_Nonnull TWZilliqaAddressCreateWithPublicKey(struct TWPublicKey *_Nonnull publicKey) { @@ -47,3 +49,7 @@ TWString *_Nonnull TWZilliqaAddressDescription(struct TWZilliqaAddress *_Nonnull const auto string = address->impl.string(); return TWStringCreateWithUTF8Bytes(string.c_str()); } + +TWData *_Nonnull TWZilliqaAddressKeyHash(struct TWZilliqaAddress *_Nonnull address) { + return TWDataCreateWithBytes(address->impl.keyHash.data(), address->impl.keyHash.size()); + } diff --git a/swift/Tests/Blockchains/ZilliqaTests.swift b/swift/Tests/Blockchains/ZilliqaTests.swift index 9c2020cc62a..f25cd97a8c5 100644 --- a/swift/Tests/Blockchains/ZilliqaTests.swift +++ b/swift/Tests/Blockchains/ZilliqaTests.swift @@ -7,6 +7,15 @@ import XCTest import TrustWalletCore class ZilliqaTests: XCTestCase { + + func testAddress() { + let pubKey = PublicKey(data: Data(hexString: "029d25b68a18442590e113132a34bb524695c4291d2c49abf2e4cdd7d98db862c3")!, type: .secp256k1)! + let address = ZilliqaAddress(publicKey: pubKey) + + XCTAssertEqual(address.keyHash.hexString, "7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C".lowercased()) + XCTAssertEqual(address.description, ZilliqaAddress(string: "zil10lx2eurx5hexaca0lshdr75czr025cevqu83uz")!.description) + } + func testSigner() { let privateKey = PrivateKey(data: Data(hexString: "0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748")!)! @@ -15,7 +24,7 @@ class ZilliqaTests: XCTestCase { let input = ZilliqaSigningInput.with { $0.version = TWZilliqaTxVersion $0.nonce = 2 - $0.toAddress = "0x7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C" + $0.toAddress = "zil10lx2eurx5hexaca0lshdr75czr025cevqu83uz" $0.amount = Data(hexString: "e8d4a51000")! $0.gasPrice = Data(hexString: "3b9aca00")! $0.gasLimit = 1 diff --git a/swift/Tests/CoinAddressDerivationTests.swift b/swift/Tests/CoinAddressDerivationTests.swift index 904ee5a6f95..b2892badc62 100644 --- a/swift/Tests/CoinAddressDerivationTests.swift +++ b/swift/Tests/CoinAddressDerivationTests.swift @@ -155,7 +155,7 @@ class CoinAddressDerivationTests: XCTestCase { let expectedResult = "io1qw9cccecw09q7p5kzyqtuhfhvah2mhfrc84jfk" AssetCoinDerivation(coin, expectedResult, derivedAddress, address) case .zilliqa: - let expectedResult = "0xDdb41006F7B6FA8e5FBF06A71c01F789FeBC66e8" + let expectedResult = "zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6" AssetCoinDerivation(coin, expectedResult, derivedAddress, address) case .semux: let expectedResult = "0xfe604170382452f77bc922bc19eb4b53504b09c2" diff --git a/swift/Tests/HDWalletTests.swift b/swift/Tests/HDWalletTests.swift index 35326a209e8..8b817a4ee36 100644 --- a/swift/Tests/HDWalletTests.swift +++ b/swift/Tests/HDWalletTests.swift @@ -243,7 +243,7 @@ class HDWalletTests: XCTestCase { let address = zil.deriveAddress(privateKey: key) XCTAssertEqual(key.data.hexString, "b49a9fb16cd2b46ee538be807f712073009ea528e407a25a4bf91a63c3e49f99") - XCTAssertEqual(address.description, "0x65E1a9341E08d10E6f3C00930CE879c5bF980319") + XCTAssertEqual(address.description, "zil1vhs6jdq7prgsumeuqzfse6recklesqcesfe685") } func testSignHash() { diff --git a/tests/CoinTests.cpp b/tests/CoinTests.cpp index fea7abbdbfa..060e49536ff 100644 --- a/tests/CoinTests.cpp +++ b/tests/CoinTests.cpp @@ -12,7 +12,8 @@ namespace TW { TEST(Coin, ValidateAddressZilliqa) { - EXPECT_TRUE(validateAddress(TWCoinTypeZilliqa, "0x91cddcebe846ce4d47712287eee53cf17c2cfb77")); + EXPECT_TRUE(validateAddress(TWCoinTypeZilliqa, "zil1j8xae6lggm8y63m3y2r7aefu797ze7mhzulnqg")); + EXPECT_FALSE(validateAddress(TWCoinTypeZilliqa, "0x91cddcebe846ce4d47712287eee53cf17c2cfb77")); EXPECT_FALSE(validateAddress(TWCoinTypeZilliqa, "91cddcebe846ce4d47712287eee53cf17c2cfb77")); EXPECT_FALSE(validateAddress(TWCoinTypeZilliqa, "0x")); EXPECT_FALSE(validateAddress(TWCoinTypeZilliqa, "")); diff --git a/tests/Zilliqa/AddressTests.cpp b/tests/Zilliqa/AddressTests.cpp index 211741b0c8e..a6ecd8da1f0 100644 --- a/tests/Zilliqa/AddressTests.cpp +++ b/tests/Zilliqa/AddressTests.cpp @@ -7,6 +7,9 @@ #include "HexCoding.h" #include "PrivateKey.h" #include "Zilliqa/Address.h" +#include "Zilliqa/AddressChecksum.h" + +#include #include @@ -18,53 +21,45 @@ TEST(ZilliqaAddress, FromPrivateKey) { PrivateKey(parse_hex("3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6")); const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1)); const auto address = Address(publicKey); - auto expectedAddress = "0x91cdDcEBE846ce4d47712287EEe53cF17c2cfB77"; + auto expectedAddress = "zil1j8xae6lggm8y63m3y2r7aefu797ze7mhzulnqg"; ASSERT_EQ(address.string(), expectedAddress); } -TEST(ZilliqaAddress, fromBadString) { - EXPECT_ANY_THROW(Address("0x3")); -} -TEST(ZilliqaAddress, fromBadPubKey) { - const auto privateKey = - PrivateKey(parse_hex("3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6")); - PublicKey publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeED25519)); - EXPECT_ANY_THROW((Address(publicKey))); +TEST(ZilliqaAddress, FromKeyhash) { + const auto hash = "0x91cdDcEBE846ce4d47712287EEe53cF17c2cfB77"; + const auto address = Address(parse_hex(hash)); + ASSERT_EQ(address.string(), "zil1j8xae6lggm8y63m3y2r7aefu797ze7mhzulnqg"); } -TEST(ZilliqaAddress, fromString) { - const auto expected = "0x91cdDcEBE846ce4d47712287EEe53cF17c2cfB77"; - ASSERT_EQ(Address(expected).string(), expected); -} +TEST(ZilliqaAddress, Validation) { + ASSERT_FALSE(Zilliqa::isValidAddress("0x91cddcebe846ce4d47712287eee53cf17c2cfb7")); + ASSERT_FALSE(Zilliqa::isValidAddress("")); + ASSERT_FALSE(Zilliqa::isValidAddress("0x")); + ASSERT_FALSE(Zilliqa::isValidAddress("91cddcebe846ce4d47712287eee53cf17c2cfb7")); -TEST(ZilliqaAddress, IsValid) { - ASSERT_FALSE(Address::isValid("0x91cddcebe846ce4d47712287eee53cf17c2cfb7")); - ASSERT_FALSE(Address::isValid("")); - ASSERT_FALSE(Address::isValid("0x")); - ASSERT_FALSE(Address::isValid("91cddcebe846ce4d47712287eee53cf17c2cfb7")); - ASSERT_TRUE(Address::isValid("0x91cddcebe846ce4d47712287eee53cf17c2cfb77")); + ASSERT_TRUE(Zilliqa::isValidAddress("zil1fwh4ltdguhde9s7nysnp33d5wye6uqpugufkz7")); } TEST(ZilliqaAddress, Checksum) { ASSERT_EQ( - Address(parse_hex("4BAF5FADA8E5DB92C3D3242618C5B47133AE003C")).string(), + checksumed(parse_hex("4BAF5FADA8E5DB92C3D3242618C5B47133AE003C")), "0x4BAF5faDA8e5Db92C3d3242618c5B47133AE003C" ); ASSERT_EQ( - Address(parse_hex("448261915A80CDE9BDE7C7A791685200D3A0BF4E")).string(), + checksumed(parse_hex("448261915A80CDE9BDE7C7A791685200D3A0BF4E")), "0x448261915a80cdE9BDE7C7a791685200D3A0bf4E" ); ASSERT_EQ( - Address(parse_hex("0xDED02FD979FC2E55C0243BD2F52DF022C40ADA1E")).string(), + checksumed(parse_hex("0xDED02FD979FC2E55C0243BD2F52DF022C40ADA1E")), "0xDed02fD979fC2e55c0243bd2F52df022c40ADa1E" ); ASSERT_EQ( - Address(parse_hex("0x13F06E60297BEA6A3C402F6F64C416A6B31E586E")).string(), + checksumed(parse_hex("0x13F06E60297BEA6A3C402F6F64C416A6B31E586E")), "0x13F06E60297bea6A3c402F6f64c416A6b31e586e" ); ASSERT_EQ( - Address(parse_hex("0x1A90C25307C3CC71958A83FA213A2362D859CF33")).string(), + checksumed(parse_hex("0x1A90C25307C3CC71958A83FA213A2362D859CF33")), "0x1a90C25307C3Cc71958A83fa213A2362D859CF33" ); } diff --git a/tests/Zilliqa/SignerTests.cpp b/tests/Zilliqa/SignerTests.cpp index dbe6743f742..f68e7ded50d 100644 --- a/tests/Zilliqa/SignerTests.cpp +++ b/tests/Zilliqa/SignerTests.cpp @@ -25,11 +25,12 @@ TEST(ZilliqaSigner, PreImage) { auto gasPrice = uint256_t(1000000000); auto amountData = store(amount); auto gasData = store(gasPrice); + auto toAddress = Address(parse_hex("0x9Ca91EB535Fb92Fda5094110FDaEB752eDb9B039")); auto input = Proto::SigningInput(); input.set_version(65537); input.set_nonce(4); - input.set_to_address("0x9Ca91EB535Fb92Fda5094110FDaEB752eDb9B039"); + input.set_to_address(toAddress.string()); input.set_amount(amountData.data(), amountData.size()); input.set_gas_price(gasData.data(), gasData.size()); input.set_gas_limit(uint64_t(1)); @@ -52,11 +53,12 @@ TEST(ZilliqaSigner, Signing) { auto gasPrice = uint256_t(1000000000); auto amountData = store(amount); auto gasData = store(gasPrice); + auto toAddress = Address(parse_hex("0x7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C")); auto input = Proto::SigningInput(); input.set_version(65537); input.set_nonce(2); - input.set_to_address("0x7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C"); + input.set_to_address(toAddress.string()); input.set_amount(amountData.data(), amountData.size()); input.set_gas_price(gasData.data(), gasData.size()); input.set_gas_limit(uint64_t(1)); diff --git a/tests/interface/TWCoinTypeConfigTests.cpp b/tests/interface/TWCoinTypeConfigTests.cpp index 73a632509ce..162f22cc4d4 100644 --- a/tests/interface/TWCoinTypeConfigTests.cpp +++ b/tests/interface/TWCoinTypeConfigTests.cpp @@ -565,4 +565,5 @@ TEST(TWCoinTypeConfiguration, TWCoinTypeBlockchain) { ASSERT_EQ(TWBlockchainEOS, TWCoinTypeBlockchain(TWCoinTypeBravoCoin)); ASSERT_EQ(TWBlockchainNano, TWCoinTypeBlockchain(TWCoinTypeNano)); ASSERT_EQ(TWBlockchainSemux, TWCoinTypeBlockchain(TWCoinTypeSemux)); + ASSERT_EQ(TWBlockchainZilliqa, TWCoinTypeBlockchain(TWCoinTypeZilliqa)); } diff --git a/tests/interface/TWZilliqaTests.cpp b/tests/interface/TWZilliqaTests.cpp index adb68d45d5b..ee7b71093df 100644 --- a/tests/interface/TWZilliqaTests.cpp +++ b/tests/interface/TWZilliqaTests.cpp @@ -10,19 +10,25 @@ #include "PublicKey.h" #include "HexCoding.h" +#include "Zilliqa/Address.h" + #include #include #include #include #include +#include #include -TEST(ZilliqaTests, Config) { - ASSERT_EQ(TWBlockchainZilliqa, TWCoinTypeBlockchain(TWCoinTypeZilliqa)); +TEST(Zilliqa, Address) { + EXPECT_TRUE(TWZilliqaAddressIsValidString(STRING("zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6").get())); + + EXPECT_FALSE(TWZilliqaAddressIsValidString(STRING("0x7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C").get())); + EXPECT_FALSE(TWZilliqaAddressIsValidString(STRING("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4").get())); } -TEST(ZilliqaTests, Sign) { +TEST(Zilliqa, Signing) { uint8_t bytes[] = {0xaf, 0xee, 0xfc, 0xa7, 0x4d, 0x9a, 0x32, 0x5c, 0xf1, 0xd6, 0xb6, 0x91, 0x1d, 0x61, 0xa6, 0x5c, 0x32, 0xaf, 0xa8, 0xe0, 0x2b, 0xd5, 0xe7, 0x8e, 0x2e, 0x4a, 0xc2, 0x91, 0x0b, 0xab, 0x45, 0xf5}; auto keyData = WRAPD(TWDataCreateWithBytes(bytes, 32)); From eba532e73c9a5b9434fd4746a1325c27fe6087ab Mon Sep 17 00:00:00 2001 From: hewigovens <360470+hewigovens@users.noreply.github.com> Date: Mon, 20 May 2019 22:56:51 +0800 Subject: [PATCH 2/6] improve code coverage --- .codacy.yaml | 4 ++++ README.md | 2 +- src/Zilliqa/Signer.cpp | 5 ----- tests/Zilliqa/AddressTests.cpp | 2 ++ tests/interface/TWHRPTests.cpp | 2 ++ tests/interface/TWZilliqaTests.cpp | 4 ++++ 6 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 .codacy.yaml diff --git a/.codacy.yaml b/.codacy.yaml new file mode 100644 index 00000000000..cf5ccb0428e --- /dev/null +++ b/.codacy.yaml @@ -0,0 +1,4 @@ +exclude_paths: + - 'codegen/**' + - 'tools/**' + - 'trezor-crypto/**' \ No newline at end of file diff --git a/README.md b/README.md index dfb9bfdc253..78824d953e3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Trust Wallet Core is a cross-platform library that implements low-level cryptogr [![Linux status](https://dev.azure.com/TrustWallet/Trust%20Wallet%20Core/_apis/build/status/Wallet%20Core%20Linux)](https://dev.azure.com/TrustWallet/Trust%20Wallet%20Core/_build/latest?definitionId=24) [![JavaScript status](https://dev.azure.com/TrustWallet/Trust%20Wallet%20Core/_apis/build/status/Wallet%20Core%20JavaScript)](https://dev.azure.com/TrustWallet/Trust%20Wallet%20Core/_build?definitionId=29) - +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/82e76f6ea4ba4f0d9029e8846c04c093)](https://www.codacy.com/app/hewigovens/wallet-core?utm_source=github.com&utm_medium=referral&utm_content=TrustWallet/wallet-core&utm_campaign=Badge_Grade) ![Codecov](https://codecov.io/gh/TrustWallet/wallet-core/branch/master/graph/badge.svg) ![GitHub](https://img.shields.io/github/license/TrustWallet/wallet-core.svg) ![Maven Central](https://img.shields.io/maven-central/v/com.trustwallet.walletcore/walletcore.svg) diff --git a/src/Zilliqa/Signer.cpp b/src/Zilliqa/Signer.cpp index 1e8167c8fb4..f7171cc2606 100644 --- a/src/Zilliqa/Signer.cpp +++ b/src/Zilliqa/Signer.cpp @@ -31,11 +31,6 @@ Data Signer::getPreImage(const Proto::SigningInput& input) noexcept { const auto key = PrivateKey(Data(input.private_key().begin(), input.private_key().end())); const auto address = Cosmos::Address::decode(input.to_address()); - - if (!address.second) { - return {}; - } - const auto pubKey = key.getPublicKey(TWPublicKeyTypeSECP256k1); internal.set_version(input.version()); diff --git a/tests/Zilliqa/AddressTests.cpp b/tests/Zilliqa/AddressTests.cpp index a6ecd8da1f0..d0c7e6c8a5d 100644 --- a/tests/Zilliqa/AddressTests.cpp +++ b/tests/Zilliqa/AddressTests.cpp @@ -22,6 +22,8 @@ TEST(ZilliqaAddress, FromPrivateKey) { const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1)); const auto address = Address(publicKey); auto expectedAddress = "zil1j8xae6lggm8y63m3y2r7aefu797ze7mhzulnqg"; + + ASSERT_EQ(address.hrp, hrpForString(TWHRPZilliqa)); ASSERT_EQ(address.string(), expectedAddress); } diff --git a/tests/interface/TWHRPTests.cpp b/tests/interface/TWHRPTests.cpp index 50421199891..a53b4b3a9cc 100644 --- a/tests/interface/TWHRPTests.cpp +++ b/tests/interface/TWHRPTests.cpp @@ -19,6 +19,7 @@ TEST(TWHRP, StringForHRP) { ASSERT_STREQ(stringForHRP(TWHRPCosmos), "cosmos"); ASSERT_STREQ(stringForHRP(TWHRPGroestlcoin), "grs"); ASSERT_STREQ(stringForHRP(TWHRPQtum), "qc"); + ASSERT_STREQ(stringForHRP(TWHRPZilliqa), "zil"); } TEST(TWHRP, HRPForString) { @@ -30,4 +31,5 @@ TEST(TWHRP, HRPForString) { ASSERT_EQ(hrpForString("cosmos"), TWHRPCosmos); ASSERT_EQ(hrpForString("grs"), TWHRPGroestlcoin); ASSERT_EQ(hrpForString("qc"), TWHRPQtum); + ASSERT_EQ(hrpForString("zil"), TWHRPZilliqa); } diff --git a/tests/interface/TWZilliqaTests.cpp b/tests/interface/TWZilliqaTests.cpp index ee7b71093df..487d89a1189 100644 --- a/tests/interface/TWZilliqaTests.cpp +++ b/tests/interface/TWZilliqaTests.cpp @@ -26,6 +26,10 @@ TEST(Zilliqa, Address) { EXPECT_FALSE(TWZilliqaAddressIsValidString(STRING("0x7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C").get())); EXPECT_FALSE(TWZilliqaAddressIsValidString(STRING("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4").get())); + + auto address = TWZilliqaAddressCreateWithString(STRING("zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6").get()); + auto desc = WRAPS(TWZilliqaAddressDescription(address)); + assertStringsEqual(desc, "zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6"); } TEST(Zilliqa, Signing) { From 358ff35203bd177c72e7a950b2e62776a16bd2b5 Mon Sep 17 00:00:00 2001 From: hewigovens <360470+hewigovens@users.noreply.github.com> Date: Mon, 20 May 2019 23:04:14 +0800 Subject: [PATCH 3/6] make cocodacy happy --- swift/Tests/Blockchains/ZilliqaTests.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/swift/Tests/Blockchains/ZilliqaTests.swift b/swift/Tests/Blockchains/ZilliqaTests.swift index f25cd97a8c5..316f4633929 100644 --- a/swift/Tests/Blockchains/ZilliqaTests.swift +++ b/swift/Tests/Blockchains/ZilliqaTests.swift @@ -9,11 +9,13 @@ import TrustWalletCore class ZilliqaTests: XCTestCase { func testAddress() { - let pubKey = PublicKey(data: Data(hexString: "029d25b68a18442590e113132a34bb524695c4291d2c49abf2e4cdd7d98db862c3")!, type: .secp256k1)! + let data = Data(hexString: "029d25b68a18442590e113132a34bb524695c4291d2c49abf2e4cdd7d98db862c3")! + let pubKey = PublicKey(data: data, type: .secp256k1)! let address = ZilliqaAddress(publicKey: pubKey) + let address2 = ZilliqaAddress(string: "zil10lx2eurx5hexaca0lshdr75czr025cevqu83uz")! XCTAssertEqual(address.keyHash.hexString, "7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C".lowercased()) - XCTAssertEqual(address.description, ZilliqaAddress(string: "zil10lx2eurx5hexaca0lshdr75czr025cevqu83uz")!.description) + XCTAssertEqual(address.description, address2.description) } func testSigner() { From 8f77ae613be046140b354ebe753732cd4ad4866f Mon Sep 17 00:00:00 2001 From: hewigovens <360470+hewigovens@users.noreply.github.com> Date: Tue, 21 May 2019 08:00:23 +0800 Subject: [PATCH 4/6] Fix tests --- src/Zilliqa/Address.h | 5 +++++ tests/Zilliqa/AddressTests.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Zilliqa/Address.h b/src/Zilliqa/Address.h index 029728e19f2..0d92dc80353 100644 --- a/src/Zilliqa/Address.h +++ b/src/Zilliqa/Address.h @@ -13,6 +13,9 @@ #include +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" + namespace TW::Zilliqa { static bool isValidAddress(const std::string& address) { @@ -33,6 +36,8 @@ namespace TW::Zilliqa { } // namespace TW::Zilliqa +#pragma clang diagnostic pop + /// Wrapper for C interface. struct TWZilliqaAddress { TW::Cosmos::Address impl; diff --git a/tests/Zilliqa/AddressTests.cpp b/tests/Zilliqa/AddressTests.cpp index d0c7e6c8a5d..526b013874b 100644 --- a/tests/Zilliqa/AddressTests.cpp +++ b/tests/Zilliqa/AddressTests.cpp @@ -23,7 +23,7 @@ TEST(ZilliqaAddress, FromPrivateKey) { const auto address = Address(publicKey); auto expectedAddress = "zil1j8xae6lggm8y63m3y2r7aefu797ze7mhzulnqg"; - ASSERT_EQ(address.hrp, hrpForString(TWHRPZilliqa)); + ASSERT_EQ(address.hrp, stringForHRP(TWHRPZilliqa)); ASSERT_EQ(address.string(), expectedAddress); } From d06f31236be12594712ef52f81baa79fa77767b3 Mon Sep 17 00:00:00 2001 From: hewigovens <360470+hewigovens@users.noreply.github.com> Date: Tue, 21 May 2019 10:13:33 +0800 Subject: [PATCH 5/6] test keyhash --- tests/interface/TWZilliqaTests.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/interface/TWZilliqaTests.cpp b/tests/interface/TWZilliqaTests.cpp index 487d89a1189..84d11fae9b5 100644 --- a/tests/interface/TWZilliqaTests.cpp +++ b/tests/interface/TWZilliqaTests.cpp @@ -22,14 +22,20 @@ #include TEST(Zilliqa, Address) { - EXPECT_TRUE(TWZilliqaAddressIsValidString(STRING("zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6").get())); + + auto string = STRING("zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6"); + EXPECT_TRUE(TWZilliqaAddressIsValidString(string.get())); EXPECT_FALSE(TWZilliqaAddressIsValidString(STRING("0x7FCcaCf066a5F26Ee3AFfc2ED1FA9810Deaa632C").get())); EXPECT_FALSE(TWZilliqaAddressIsValidString(STRING("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4").get())); + EXPECT_FALSE(TWZilliqaAddressCreateWithString(STRING("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4").get()) != NULL); + + auto address = WRAP(TWZilliqaAddress, TWZilliqaAddressCreateWithString(string.get())); + auto desc = WRAPS(TWZilliqaAddressDescription(address.get())); + auto keyHash = WRAPD(TWZilliqaAddressKeyHash(address.get())); - auto address = TWZilliqaAddressCreateWithString(STRING("zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6").get()); - auto desc = WRAPS(TWZilliqaAddressDescription(address)); assertStringsEqual(desc, "zil1mk6pqphhkmaguhalq6n3cq0h38ltcehg0rfmv6"); + assertHexEqual(keyHash, "ddb41006f7b6fa8e5fbf06a71c01f789febc66e8"); } TEST(Zilliqa, Signing) { From a6d92d646e514b623a7d72d4ad0cd21ef71394a8 Mon Sep 17 00:00:00 2001 From: hewigovens <360470+hewigovens@users.noreply.github.com> Date: Tue, 21 May 2019 11:12:51 +0800 Subject: [PATCH 6/6] Add a test case from zil js lib --- tests/Zilliqa/AddressTests.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/Zilliqa/AddressTests.cpp b/tests/Zilliqa/AddressTests.cpp index 526b013874b..f4d7504796b 100644 --- a/tests/Zilliqa/AddressTests.cpp +++ b/tests/Zilliqa/AddressTests.cpp @@ -29,9 +29,11 @@ TEST(ZilliqaAddress, FromPrivateKey) { TEST(ZilliqaAddress, FromKeyhash) { - const auto hash = "0x91cdDcEBE846ce4d47712287EEe53cF17c2cfB77"; - const auto address = Address(parse_hex(hash)); + const auto address = Address(parse_hex("0x91cdDcEBE846ce4d47712287EEe53cF17c2cfB77")); + const auto address2 = Address(parse_hex("1d19918a737306218b5cbb3241fcdcbd998c3a72")); + ASSERT_EQ(address.string(), "zil1j8xae6lggm8y63m3y2r7aefu797ze7mhzulnqg"); + ASSERT_EQ(address2.string(), "zil1r5verznnwvrzrz6uhveyrlxuhkvccwnju4aehf"); } TEST(ZilliqaAddress, Validation) {