From 4f4b9ca981c32c36c5bf0bad0e2d07dac096d79d Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 19 Aug 2020 22:33:41 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../main/java/com/tangem/data/Blockchain.java | 1 + app/src/main/java/com/tangem/data/PayId.kt | 1 + .../com/tangem/wallet/CoinEngineFactory.kt | 4 + .../wallet/cardano/CardanoShelleyEngine.java | 76 ++++--------------- 4 files changed, 19 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/tangem/data/Blockchain.java b/app/src/main/java/com/tangem/data/Blockchain.java index 75b9b28495..fc729c6dba 100644 --- a/app/src/main/java/com/tangem/data/Blockchain.java +++ b/app/src/main/java/com/tangem/data/Blockchain.java @@ -20,6 +20,7 @@ public enum Blockchain { Rootstock("RSK", "RBTC", 1.0, R.drawable.tangem2, "RSK"), RootstockToken("RskToken", "RBTC", 1.0, R.drawable.tangem2, "RSK"), Cardano("CARDANO", "ADA", 1000000.0, R.drawable.tangem2, "Cardano"), + CardanoShelley("CARDANO-S", "ADA", 1000000.0, R.drawable.tangem2, "Cardano"), Ripple("XRP", "XRP", 1000000.0, R.drawable.ic_logo_xrp, "XRP Ledger"), Binance("BINANCE", "BNB", 100000000.0, R.drawable.ic_logo_binance, "Binance"), BinanceTestNet("BINANCE/test", "BNB", 100000000.0, R.drawable.ic_logo_binance, "Binance Testnet"), diff --git a/app/src/main/java/com/tangem/data/PayId.kt b/app/src/main/java/com/tangem/data/PayId.kt index 3c882fbdd7..34fab51687 100644 --- a/app/src/main/java/com/tangem/data/PayId.kt +++ b/app/src/main/java/com/tangem/data/PayId.kt @@ -11,6 +11,7 @@ private val payIdSupported = EnumSet.of( Blockchain.Stellar, Blockchain.StellarAsset, Blockchain.Cardano, + Blockchain.CardanoShelley, Blockchain.Ducatus, Blockchain.BitcoinCash, Blockchain.Binance, diff --git a/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt b/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt index 0cf887e769..c1829aa910 100644 --- a/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt +++ b/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt @@ -9,6 +9,7 @@ import com.tangem.wallet.btc.BtcEngine import com.tangem.wallet.btcmultisig.BtcMultisigEngine import com.tangem.wallet.cardano.CardanoData import com.tangem.wallet.cardano.CardanoEngine +import com.tangem.wallet.cardano.CardanoShelleyEngine import com.tangem.wallet.ducatus.DucatusEngine import com.tangem.wallet.eos.EosEngine import com.tangem.wallet.eth.EthEngine @@ -51,6 +52,7 @@ object CoinEngineFactory { Blockchain.Rootstock -> RskEngine() Blockchain.RootstockToken -> RskTokenEngine() Blockchain.Cardano -> CardanoEngine() + Blockchain.CardanoShelley -> CardanoShelleyEngine() Blockchain.Ripple -> XrpEngine() Blockchain.Binance, Blockchain.BinanceTestNet -> BinanceEngine() Blockchain.BinanceAsset -> BinanceAssetEngine() @@ -91,6 +93,8 @@ object CoinEngineFactory { RskTokenEngine(context) else if (Blockchain.Cardano == context.blockchain) CardanoEngine(context) + else if (Blockchain.CardanoShelley == context.blockchain) + CardanoShelleyEngine(context) else if (Blockchain.Ripple == context.blockchain) XrpEngine(context) else if (Blockchain.Binance == context.blockchain || Blockchain.BinanceTestNet == context.blockchain) diff --git a/app/src/main/java/com/tangem/wallet/cardano/CardanoShelleyEngine.java b/app/src/main/java/com/tangem/wallet/cardano/CardanoShelleyEngine.java index 2e9e7aba81..bb83d306f0 100644 --- a/app/src/main/java/com/tangem/wallet/cardano/CardanoShelleyEngine.java +++ b/app/src/main/java/com/tangem/wallet/cardano/CardanoShelleyEngine.java @@ -5,6 +5,7 @@ import android.text.InputFilter; import android.util.Base64; import android.util.Log; +import com.google.android.gms.common.util.ArrayUtils; import com.tangem.App; import com.tangem.Constant; import com.tangem.data.local.PendingTransactionsStorage; @@ -64,9 +65,8 @@ public class CardanoShelleyEngine extends CoinEngine { private static final String TAG = CardanoShelleyEngine.class.getSimpleName(); - private static final long protocolMagic = 764824073; - private static final String BECH32_HRP = "addr1"; + private static final byte ADDRESS_HEADER_BYTE = 97; public CardanoData coinData = null; @@ -316,64 +316,13 @@ public class CardanoShelleyEngine extends CoinEngine { @Override public String calculateAddress(byte[] pkUncompressed) throws CborException, IOException { + Blake2b blake2b = Blake2b.Digest.newInstance(28); + byte[] publicKeyHash = blake2b.digest(pkUncompressed); - ByteArrayOutputStream exBaos = new ByteArrayOutputStream(); - exBaos.write(pkUncompressed); - exBaos.write(BTCUtils.fromHex("0000000000000000000000000000000000000000000000000000000000000000")); - byte[] pkExtended = exBaos.toByteArray(); + byte[] addressBytes = ArrayUtils.concatByteArrays(new byte[] {ADDRESS_HEADER_BYTE}, publicKeyHash); + byte[] convertedAddressBytes = Crypto.convertBits(addressBytes, 0, addressBytes.length, 8, 5, true); - exBaos.reset(); - new CborEncoder(exBaos).encode(new CborBuilder() - .addArray() - .add(0) - .addArray() - .add(0) - .add(pkExtended) - .end() - .addMap() - .end() - .end() - .build()); - byte[] forSha3 = exBaos.toByteArray(); - - Digest sha3 = DigestFactory.createSHA3_256(); - sha3.update(forSha3, 0, forSha3.length); - byte[] forBlake = new byte[32]; - sha3.doFinal(forBlake, 0); - - final Blake2b blake2b = Blake2b.Digest.newInstance(28); - byte[] pkHash = blake2b.digest(forBlake); - - //pkHash + attributes - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - new CborEncoder(baos).encode(new CborBuilder() - .addArray() - .add(pkHash) - .addMap()//additional attributes - .end() - .add(0)//address type - .end() - .build()); - byte[] addr = baos.toByteArray(); - - final CRC32 crc32 = new CRC32(); - crc32.update(addr); - long checksum = crc32.getValue(); - - DataItem addrItem = new CborBuilder().add(addr).build().get(0); - addrItem.setTag(24); - - //addr + checksum - baos.reset(); - new CborEncoder(baos).encode(new CborBuilder() - .addArray() - .add(addrItem) - .add(checksum) - .end() - .build()); - - byte[] hexAddress = baos.toByteArray(); - return encodeBase58(hexAddress); + return Bech32.encode("addr", convertedAddressBytes); } @Override @@ -440,7 +389,10 @@ public class CardanoShelleyEngine extends CoinEngine { destinationBytes = decodeBase58(destination); } - String myAddress = ctx.getCoinData().getWallet(); + String changeAddress = ctx.getCoinData().getWallet(); + byte[] changeAddressDecoded = Bech32.decode(changeAddress).getData(); + byte[] changeAddressBytes = Crypto.convertBits(changeAddressDecoded, 0, changeAddressDecoded.length, 5, 8, false); + byte[] pbKey = ctx.getCard().getWalletPublicKey(); List utxoList = coinData.getUnspentOutputs(); long fullAmount = coinData.getBalance(); @@ -497,7 +449,7 @@ public class CardanoShelleyEngine extends CoinEngine { if (changeFinal > 0) { outputsArray .addArray() - .add(decodeBase58(myAddress)) + .add(changeAddressBytes) .add(changeFinal) .end(); } @@ -574,11 +526,9 @@ public class CardanoShelleyEngine extends CoinEngine { DataItem witnessDataItem = new CborBuilder().addArray().addArray() .add(pbKey) .add(signFromCard) - .add(BTCUtils.fromHex("0000000000000000000000000000000000000000000000000000000000000000")) - .add(BTCUtils.fromHex("A0")) .end().end().build().get(0); - DataItem witnessKey = new CborBuilder().add(2).build().get(0); + DataItem witnessKey = new CborBuilder().add(0).build().get(0); witnessMap.put(witnessKey, witnessDataItem); baos.reset();