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 bef1b60cea7..94b2f723f45 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 @@ -45,7 +45,7 @@ class CoinAddressDerivationTests { ETHEREUM, SMARTCHAIN, POLYGON, OPTIMISM, ZKSYNC, ARBITRUM, ECOCHAIN, AVALANCHECCHAIN, XDAI, FANTOM, CELO, CRONOSCHAIN, SMARTBITCOINCASH, KUCOINCOMMUNITYCHAIN, BOBA, METIS, AURORA, EVMOS, MOONRIVER, MOONBEAM, KAVAEVM, KLAYTN, METER, OKXCHAIN, POLYGONZKEVM, SCROLL, - CONFLUXESPACE, ACALAEVM, OPBNBTESTNET, NEON -> assertEquals("0x8f348F300873Fd5DA36950B2aC75a26584584feE", address) + CONFLUXESPACE, ACALAEVM, OPBNBTESTNET, NEON, BASE -> assertEquals("0x8f348F300873Fd5DA36950B2aC75a26584584feE", address) RONIN -> assertEquals("ronin:8f348F300873Fd5DA36950B2aC75a26584584feE", address) ETHEREUMCLASSIC -> assertEquals("0x078bA3228F3E6C08bEEac9A005de0b7e7089aD1c", address) GOCHAIN -> assertEquals("0x5940ce4A14210d4Ccd0ac206CE92F21828016aC2", address) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aptos/TestAptosSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aptos/TestAptosSigner.kt index 2b9d9b416c1..f16a3be8300 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aptos/TestAptosSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aptos/TestAptosSigner.kt @@ -103,4 +103,47 @@ class TestAptosSigner { "07968dab936c1bad187c60ce4082f307d030d780e91e694ae03aef16aba73f3063000000000000000200000000000000000000000000000000000000000000000000000000000000010d6170746f735f6163636f756e74087472616e7366657200022007968dab936c1bad187c60ce4082f307d030d780e91e694ae03aef16aba73f3008e803000000000000fe4d3200000000006400000000000000c2276ada00000000210020ea526ba1710343d953461ff68641f1b7df5f23b9042ffa2d2a798d3adb3f3d6c405707246db31e2335edc4316a7a656a11691d1d1647f6e864d1ab12f43428aaaf806cf02120d0b608cdd89c5c904af7b137432aacdd60cc53f9fad7bd33578e01" ) } + + @Test + fun AptosTransferTokensCoins() { + // Successfully broadcasted https://explorer.aptoslabs.com/txn/0x197d40ea12e2bfc65a0a913b9f4ca3b0b0208fe0c1514d3d55cef3d5bcf25211?network=mainnet + val key = + "e7f56c77189e03699a75d8ec5c090e41f3d9d4783bc49c33df8a93d915e10de8".toHexBytesInByteString() + + val function = Aptos.StructTag.newBuilder() + .setAccountAddress("0xe9c192ff55cffab3963c695cff6dbf9dad6aff2bb5ac19a6415cad26a81860d9") + .setModule("mee_coin") + .setName("MeeCoin") + .build() + + val transfer = Aptos.TokenTransferCoinsMessage.newBuilder() + .setAmount(10000) + .setTo("0xb7c7d12080209e9dc14498c80200706e760363fb31782247e82cf57d1d6e5d6c") + .setFunction(function) + .build() + val signingInput = Aptos.SigningInput.newBuilder() + .setChainId(1) + .setSender("0x1869b853768f0ba935d67f837a66b172dd39a60ca2315f8d4e0e669bbd35cf25") + .setSequenceNumber(2) + .setGasUnitPrice(100) + .setMaxGasAmount(2000) + .setExpirationTimestampSecs(3664390082) + .setTokenTransferCoins(transfer) + .setPrivateKey(key) + .build() + + val result = AnySigner.sign(signingInput, CoinType.APTOS, Aptos.SigningOutput.parser()) + assertEquals( + Numeric.cleanHexPrefix(Numeric.toHexString(result.rawTxn.toByteArray())), + "1869b853768f0ba935d67f837a66b172dd39a60ca2315f8d4e0e669bbd35cf2502000000000000000200000000000000000000000000000000000000000000000000000000000000010d6170746f735f6163636f756e740e7472616e736665725f636f696e730107e9c192ff55cffab3963c695cff6dbf9dad6aff2bb5ac19a6415cad26a81860d9086d65655f636f696e074d6565436f696e000220b7c7d12080209e9dc14498c80200706e760363fb31782247e82cf57d1d6e5d6c081027000000000000d0070000000000006400000000000000c2276ada0000000001" + ) + assertEquals( + Numeric.cleanHexPrefix(Numeric.toHexString(result.authenticator.signature.toByteArray())), + "30ebd7e95cb464677f411868e2cbfcb22bc01cc63cded36c459dff45e6d2f1354ae4e090e7dfbb509851c0368b343e0e5ecaf6b08e7c1b94c186530b0f7dee0d" + ) + assertEquals( + Numeric.cleanHexPrefix(Numeric.toHexString(result.encoded.toByteArray())), + "1869b853768f0ba935d67f837a66b172dd39a60ca2315f8d4e0e669bbd35cf2502000000000000000200000000000000000000000000000000000000000000000000000000000000010d6170746f735f6163636f756e740e7472616e736665725f636f696e730107e9c192ff55cffab3963c695cff6dbf9dad6aff2bb5ac19a6415cad26a81860d9086d65655f636f696e074d6565436f696e000220b7c7d12080209e9dc14498c80200706e760363fb31782247e82cf57d1d6e5d6c081027000000000000d0070000000000006400000000000000c2276ada0000000001002062e7a6a486553b56a53e89dfae3f780693e537e5b0a7ed33290780e581ca83694030ebd7e95cb464677f411868e2cbfcb22bc01cc63cded36c459dff45e6d2f1354ae4e090e7dfbb509851c0368b343e0e5ecaf6b08e7c1b94c186530b0f7dee0d" + ) + } } diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinFee.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinFee.kt index 5e8a4291060..15d4ee2d593 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinFee.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinFee.kt @@ -14,20 +14,20 @@ class TestBitcoinFee { @Test fun P2pkhCalculateFee() { - val satVb: Long = 10 + val satVb = "10" val tx = Numeric.hexStringToByteArray("02000000017be4e642bb278018ab12277de9427773ad1c5f5b1d164a157e0d99aa48dc1c1e000000006a473044022078eda020d4b86fcb3af78ef919912e6d79b81164dbbb0b0b96da6ac58a2de4b102201a5fd8d48734d5a02371c4b5ee551a69dca3842edbf577d863cf8ae9fdbbd4590121036666dd712e05a487916384bfcd5973eb53e8038eccbbf97f7eed775b87389536ffffffff01c0aff629010000001976a9145eaaa4f458f9158f86afcba08dd7448d27045e3d88ac00000000") - var fee = BitcoinFee.calculateFee(tx, satVb) + var fee = BitcoinFee.calculateFee(tx, satVb).toLong() - assertEquals(fee, 191 * satVb) + assertEquals(fee, 191 * satVb.toLong()) } @Test fun P2wpkhCalculateFee() { - val satVb: Long = 12 + val satVb = "12" val tx = Numeric.hexStringToByteArray("020000000111b9f62923af73e297abb69f749e7a1aa2735fbdfd32ac5f6aa89e5c96841c18000000006b483045022100df9ed0b662b759e68b89a42e7144cddf787782a7129d4df05642dd825930e6e6022051a08f577f11cc7390684bbad2951a6374072253ffcf2468d14035ed0d8cd6490121028d7dce6d72fb8f7af9566616c6436349c67ad379f2404dd66fe7085fe0fba28fffffffff01c0aff629010000001600140d0e1cec6c2babe8badde5e9b3dea667da90036d00000000") - var fee = BitcoinFee.calculateFee(tx, satVb) + var fee = BitcoinFee.calculateFee(tx, satVb).toLong() - assertEquals(fee, 189 * satVb) + assertEquals(fee, 189 * satVb.toLong()) } @Test @@ -38,10 +38,10 @@ class TestBitcoinFee { // Size 235 Bytes // Weight 610 fun Brc20TransferCommitCalculateFee() { - val satVb: Long = 19 + val satVb = "19" val tx = Numeric.hexStringToByteArray("02000000000101089098890d2653567b9e8df2d1fbe5c3c8bf1910ca7184e301db0ad3b495c88e0100000000ffffffff02581b000000000000225120e8b706a97732e705e22ae7710703e7f589ed13c636324461afa443016134cc051040000000000000160014e311b8d6ddff856ce8e9a4e03bc6d4fe5050a83d02483045022100a44aa28446a9a886b378a4a65e32ad9a3108870bd725dc6105160bed4f317097022069e9de36422e4ce2e42b39884aa5f626f8f94194d1013007d5a1ea9220a06dce0121030f209b6ada5edb42c77fd2bc64ad650ae38314c8f451f3e36d80bc8e26f132cb00000000") - var fee = BitcoinFee.calculateFee(tx, satVb) + var fee = BitcoinFee.calculateFee(tx, satVb).toLong() - assertEquals(fee, 153 * satVb) // 153 = ceil(610/4) + assertEquals(fee, 153 * satVb.toLong()) // 153 = ceil(610/4) } } diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt index cb9d745f96e..235cd442b73 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt @@ -34,10 +34,21 @@ class TestBarz { val publicKeyData = Numeric.hexStringToByteArray("04e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b02") val publicKey = PublicKey(publicKeyData, PublicKeyType.NIST256P1EXTENDED) val verificationFacet = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf" - val result = WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet) + val result = WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet, 0) assertEquals(Numeric.toHexString(result), "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000") } + @Test + fun testInitCodeNonZeroSalt() { + val factoryAddress = "0x3fC708630d85A3B5ec217E53100eC2b735d4f800" + val publicKeyData = Numeric.hexStringToByteArray("04e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b02") + val publicKey = PublicKey(publicKeyData, PublicKeyType.NIST256P1EXTENDED) + val verificationFacet = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf" + val salt = 1 + val result = WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet, salt) + assertEquals(Numeric.toHexString(result), "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000") + } + @Test fun testCounterfactualAddress() { val input = Barz.ContractAddressInput.newBuilder() @@ -55,6 +66,24 @@ class TestBarz { assertEquals(result, "0x77F62bb3E43190253D4E198199356CD2b25063cA") } + @Test + fun testCounterfactualAddressNonZeroSalt() { + val input = Barz.ContractAddressInput.newBuilder() + input.apply { + factory = "0x96C489979E39F877BDb8637b75A25C1a5B2DE14C" + accountFacet = "0xF6F5e5fC74905e65e3FF53c6BacEba8535dd14d1" + verificationFacet = "0xaB84813cbf26Fd951CB3d7E33Dccb8995027e490" + entryPoint = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + facetRegistry = "0x9a95d201BB8F559771784D12c01F8084278c65E5" + defaultFallback = "0x522cDc7558b5f798dF5D61AB09B6D95Ebd342EF9" + bytecode = "0x60806040526040516104c83803806104c883398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b6101b3806103156000396000f3fe60806040523661000b57005b600080356001600160e01b03191681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c806100cf576004838101546040516366ffd66360e11b81526000356001600160e01b031916928101929092526001600160a01b03169063cdffacc690602401602060405180830381865afa1580156100a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100cc919061014d565b90505b6001600160a01b0381166101295760405162461bcd60e51b815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e808015610148573d6000f35b3d6000fd5b60006020828403121561015f57600080fd5b81516001600160a01b038116811461017657600080fd5b939250505056fea2646970667358221220d35db061bb6ecdb7688c3674af669ce44d527cae4ded59214d06722d73da62be64736f6c63430008120033" + publicKey = "0xB5547FBdC56DCE45e1B8ef75569916D438e09c46" + salt = 123456 + } + val result = WCBarz.getCounterfactualAddress(input.build().toByteArray()) + assertEquals(result, "0xB91aaa96B138A1B1D94c9df4628187132c5F2bf1") + } + @Test fun testGetFormattedSignature() { val signature = Numeric.hexStringToByteArray("0x3044022012d89e3b41e253dc9e90bd34dc1750d059b76d0b1d16af2059aa26e90b8960bf0220256d8a05572c654906ce422464693e280e243e6d9dbc5f96a681dba846bca276") @@ -126,7 +155,7 @@ class TestBarz { sender = "0x1392Ae041BfBdBAA0cFF9234a0C8F64df97B7218" preVerificationGas = ByteString.copyFrom("0xb708".toHexByteArray()) verificationGasLimit = ByteString.copyFrom("0x2DC6C0".toHexByteArray()) - initCode = ByteString.copyFrom(WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet)) + initCode = ByteString.copyFrom(WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet, 0)) }.build() transaction = Ethereum.Transaction.newBuilder().apply { diff --git a/docs/registry.md b/docs/registry.md index 1ae2fe4c8da..385273ff0ee 100644 --- a/docs/registry.md +++ b/docs/registry.md @@ -86,6 +86,7 @@ This list is generated from [./registry.json](../registry.json) | 3030 | Hedera | HBAR | | | | 5611 | OpBNB testnet | tBNB | | | | 6060 | GoChain | GO | | | +| 8453 | Base | ETH | | | | 8964 | NULS | NULS | | | | 14001 | WAX | WAXP | | | | 18000 | Meter | MTR | | | diff --git a/include/TrustWalletCore/TWBarz.h b/include/TrustWalletCore/TWBarz.h index e68a6527c0e..3bc08ed31b4 100644 --- a/include/TrustWalletCore/TWBarz.h +++ b/include/TrustWalletCore/TWBarz.h @@ -30,7 +30,7 @@ TWString *_Nonnull TWBarzGetCounterfactualAddress(TWData *_Nonnull input); /// \param verificationFacet Verification facet address /// \return The address. TW_EXPORT_STATIC_METHOD -TWData *_Nonnull TWBarzGetInitCode(TWString* _Nonnull factory, struct TWPublicKey* _Nonnull publicKey, TWString* _Nonnull verificationFacet); +TWData *_Nonnull TWBarzGetInitCode(TWString* _Nonnull factory, struct TWPublicKey* _Nonnull publicKey, TWString* _Nonnull verificationFacet, uint32_t salt); /// Converts the original ASN-encoded signature from webauthn to the format accepted by Barz /// diff --git a/include/TrustWalletCore/TWBitcoinFee.h b/include/TrustWalletCore/TWBitcoinFee.h index 2d2da6ec359..33dc9c6c5ea 100644 --- a/include/TrustWalletCore/TWBitcoinFee.h +++ b/include/TrustWalletCore/TWBitcoinFee.h @@ -7,13 +7,19 @@ #pragma once #include "TWData.h" +#include "TWString.h" TW_EXTERN_C_BEGIN TW_EXPORT_CLASS struct TWBitcoinFee; +/// Calculates the fee of any Bitcoin transaction. +/// +/// \param data: the signed transaction in its final form. +/// \param satVb: the satoshis per vbyte amount. The passed on string is interpreted as a unit64_t. +/// \returns the fee denominated in satoshis or nullptr if the transaction failed to be decoded. TW_EXPORT_STATIC_METHOD -uint64_t TWBitcoinFeeCalculateFee(TWData* _Nonnull data, uint64_t satVb); +TWString* _Nullable TWBitcoinFeeCalculateFee(TWData* _Nonnull data, TWString* _Nonnull satVb); TW_EXTERN_C_END diff --git a/include/TrustWalletCore/TWCoinType.h b/include/TrustWalletCore/TWCoinType.h index a762105c596..beef6628af1 100644 --- a/include/TrustWalletCore/TWCoinType.h +++ b/include/TrustWalletCore/TWCoinType.h @@ -170,6 +170,7 @@ enum TWCoinType { TWCoinTypeAcalaEVM = 10000787, TWCoinTypeOpBNBtestnet = 5611, TWCoinTypeNeon = 245022934, + TWCoinTypeBase = 8453, }; /// Returns the blockchain for a coin type. diff --git a/registry.json b/registry.json index 00fd6bd4cbd..e80fa59e5f0 100644 --- a/registry.json +++ b/registry.json @@ -350,6 +350,36 @@ "documentation": "https://docs.syscoin.org" } }, + { + "id": "base", + "name": "Base", + "coinId": 8453, + "symbol": "ETH", + "decimals": 18, + "blockchain": "Ethereum", + "derivation": [ + { + "path": "m/44'/60'/0'/0/0" + } + ], + "curve": "secp256k1", + "publicKeyType": "secp256k1Extended", + "chainId": "8453", + "addressHasher": "keccak256", + "explorer": { + "url": "https://basescan.org", + "txPath": "/tx/", + "accountPath": "/address/", + "sampleTx": "0x4acb15506b7696a2dfac4258f3f86392b4b2b717a3f316a8aa78509b2c3b6ab4", + "sampleAccount": "0xb8ff877ed78ba520ece21b1de7843a8a57ca47cb" + }, + "info": { + "url": "https://base.mirror.xyz/", + "source": "https://github.com/base-org", + "rpc": "https://mainnet.base.org", + "documentation": "https://docs.base.org/" + } + }, { "id": "ethereum", "name": "Ethereum", diff --git a/src/Aptos/Signer.cpp b/src/Aptos/Signer.cpp index 18809c749cc..5c4b676583b 100644 --- a/src/Aptos/Signer.cpp +++ b/src/Aptos/Signer.cpp @@ -162,6 +162,15 @@ TransactionPayload tokenTransferPayload(const Proto::SigningInput& input) { return payload; } +TransactionPayload tokenTransferCoinsPayload(const Proto::SigningInput& input) { + auto&& [args, argsJson] = commonTransferPayload(input.token_transfer_coins()); + auto& function = input.token_transfer_coins().function(); + TypeTag tokenTransferTag = {TypeTag::TypeTagVariant(TStructTag{.st = StructTag(Address(function.account_address()), + function.module(), function.name(), {})})}; + TransactionPayload payload = EntryFunction(gAptosAccountModule, "transfer_coins", {tokenTransferTag}, args, argsJson); + return payload; +} + TransactionPayload registerTokenPayload(const Proto::SigningInput& input) { auto& function = input.register_token().function(); @@ -257,6 +266,9 @@ Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) { case Proto::SigningInput::kLiquidStakingMessage: { return liquidStakingFunctor(input.liquid_staking_message()); } + case Proto::SigningInput::kTokenTransferCoins: { + return tokenTransferCoinsPayload(input); + } case Proto::SigningInput::TRANSACTION_PAYLOAD_NOT_SET: throw std::runtime_error("Transaction payload should be set"); } diff --git a/src/Ethereum/ABI/Array.cpp b/src/Ethereum/ABI/Array.cpp index 472f5a86e1f..9dc78a40d77 100644 --- a/src/Ethereum/ABI/Array.cpp +++ b/src/Ethereum/ABI/Array.cpp @@ -79,7 +79,7 @@ bool ParamArray::decode(const Data& encoded, size_t& offset_inout) { // pad with first type auto first = _params.getParamUnsafe(0); for (size_t i = 0; i < len - n; i++) { - _params.addParam(ParamFactory::make(first->getType())); + _params.addParam(first->clone()); } } @@ -105,7 +105,7 @@ bool ParamArray::setValueJson(const std::string& value) { } // make sure enough elements are in the array while (_params.getCount() < valuesJson.size()) { - addParam(ParamFactory::make(getProtoType())); + addParam(getProtoElem()->clone()); } int cnt = 0; for (const auto& e : valuesJson) { @@ -133,6 +133,13 @@ std::string ParamArray::getExtraTypes(std::vector& ignoreList) cons return (proto != nullptr) ? proto->getExtraTypes(ignoreList) : ""; } +std::shared_ptr ParamArray::clone() const { + auto newArray = std::make_shared(); + newArray->_params = _params.clone(); + newArray->_proto = _proto->clone(); + return newArray; +} + void ParamArrayFix::encode(Data& data) const { this->_params.encode(data); } @@ -156,6 +163,12 @@ bool ParamArrayFix::setValueJson(const std::string& value) { return true; } +std::shared_ptr ParamArrayFix::clone() const { + auto newArray = std::make_shared(); + newArray->_params = _params.clone(); + return newArray; +} + void ParamArrayFix::addParams(const Params& params) { auto addParamFunctor = [this](auto&& param) { if (param == nullptr) { diff --git a/src/Ethereum/ABI/Array.h b/src/Ethereum/ABI/Array.h index 8be902174e6..9a2e38bbd08 100644 --- a/src/Ethereum/ABI/Array.h +++ b/src/Ethereum/ABI/Array.h @@ -15,7 +15,7 @@ namespace TW::Ethereum::ABI { /// Dynamic array of the same types, "[]" /// Normally has at least one element. Empty array can have prototype set so its type is known. /// Empty with no prototype is possible, but should be avoided. -class ParamArray : public ParamCollection { +class ParamArray final : public ParamCollection { private: ParamSet _params; std::shared_ptr _proto; // an optional prototype element, determines the array type, useful in empty array case @@ -36,15 +36,17 @@ class ParamArray : public ParamCollection { void addParams(const std::vector>& params); void setProto(const std::shared_ptr& proto) { _proto = proto; } std::shared_ptr getParam(int paramIndex) { return _params.getParamUnsafe(paramIndex); } - virtual std::string getType() const { return getProtoType() + "[]"; } - virtual size_t getSize() const; - virtual bool isDynamic() const { return true; } - virtual size_t getCount() const { return _params.getCount(); } - virtual void encode(Data& data) const; - virtual bool decode(const Data& encoded, size_t& offset_inout); - virtual bool setValueJson(const std::string& value); - virtual Data hashStruct() const; - virtual std::string getExtraTypes(std::vector& ignoreList) const; + + std::string getType() const override { return getProtoType() + "[]"; } + size_t getSize() const override; + bool isDynamic() const override { return true; } + size_t getCount() const override { return _params.getCount(); } + void encode(Data& data) const override; + bool decode(const Data& encoded, size_t& offset_inout) override; + bool setValueJson(const std::string& value) override; + Data hashStruct() const override; + std::string getExtraTypes(std::vector& ignoreList) const override; + std::shared_ptr clone() const override; }; /// Fixed-size array of the same type e.g, "type[4]" @@ -53,20 +55,23 @@ class ParamArrayFix final : public ParamCollection { //! Public Definitions using Params = std::vector>; - //! Public constructor + //! Public constructors + ParamArrayFix() = default; + explicit ParamArrayFix(const Params& params) noexcept(false) : ParamCollection() { this->addParams(params); } //! Public member methods - [[nodiscard]] std::size_t getCount() const final { return _params.getCount(); } - [[nodiscard]] size_t getSize() const final { return _params.getSize(); } - [[nodiscard]] bool isDynamic() const final { return false; } - [[nodiscard]] std::string getType() const final { return _params.getParamUnsafe(0)->getType() + "[" + std::to_string(_params.getCount()) + "]"; } - void encode(Data& data) const final; - bool decode(const Data& encoded, size_t& offset_inout) final; - bool setValueJson(const std::string& value) final; + [[nodiscard]] std::size_t getCount() const override { return _params.getCount(); } + [[nodiscard]] size_t getSize() const override { return _params.getSize(); } + [[nodiscard]] bool isDynamic() const override { return false; } + [[nodiscard]] std::string getType() const override { return _params.getParamUnsafe(0)->getType() + "[" + std::to_string(_params.getCount()) + "]"; } + void encode(Data& data) const override; + bool decode(const Data& encoded, size_t& offset_inout) override; + bool setValueJson(const std::string& value) override; + std::shared_ptr clone() const override; private: //! Private member functions diff --git a/src/Ethereum/ABI/Bytes.cpp b/src/Ethereum/ABI/Bytes.cpp index cb1277b96f9..5cbee7fc970 100644 --- a/src/Ethereum/ABI/Bytes.cpp +++ b/src/Ethereum/ABI/Bytes.cpp @@ -56,6 +56,10 @@ Data ParamByteArray::hashStruct() const { return Hash::keccak256(_bytes); } +std::shared_ptr ParamByteArray::clone() const { + return std::make_shared(_bytes); +} + void ParamByteArrayFix::setVal(const Data& val) { if (val.size() > _n) { // crop right _bytes = subData(val, 0, _n); @@ -105,6 +109,10 @@ Data ParamByteArrayFix::hashStruct() const { return ParamBase::hashStruct(); } +std::shared_ptr ParamByteArrayFix::clone() const { + return std::make_shared(_n, _bytes); +} + void ParamString::encodeString(const std::string& decoded, Data& data) { auto bytes = Data(decoded.begin(), decoded.end()); ParamByteArray::encodeBytes(bytes, data); @@ -126,4 +134,8 @@ Data ParamString::hashStruct() const { return hash; } +std::shared_ptr ParamString::clone() const { + return std::make_shared(_str); +} + } // namespace TW::Ethereum::ABI diff --git a/src/Ethereum/ABI/Bytes.h b/src/Ethereum/ABI/Bytes.h index a3695a813b5..3fc92f4c78e 100644 --- a/src/Ethereum/ABI/Bytes.h +++ b/src/Ethereum/ABI/Bytes.h @@ -13,7 +13,7 @@ namespace TW::Ethereum::ABI { /// Dynamic array of bytes "bytes" -class ParamByteArray: public ParamCollection +class ParamByteArray final: public ParamCollection { private: Data _bytes; @@ -22,22 +22,23 @@ class ParamByteArray: public ParamCollection ParamByteArray(const Data& val) : ParamCollection() { setVal(val); } void setVal(const Data& val) { _bytes = val; } const Data& getVal() const { return _bytes; } - virtual std::string getType() const { return "bytes"; }; - virtual size_t getSize() const { return 32 + ValueEncoder::paddedTo32(_bytes.size()); } - virtual bool isDynamic() const { return true; } - virtual size_t getCount() const { return _bytes.size(); } + std::string getType() const override { return "bytes"; }; + size_t getSize() const override { return 32 + ValueEncoder::paddedTo32(_bytes.size()); } + bool isDynamic() const override { return true; } + size_t getCount() const override { return _bytes.size(); } static void encodeBytes(const Data& bytes, Data& data); - virtual void encode(Data& data) const { encodeBytes(_bytes, data); } + void encode(Data& data) const override { encodeBytes(_bytes, data); } static bool decodeBytes(const Data& encoded, Data& decoded, size_t& offset_inout); - virtual bool decode(const Data& encoded, size_t& offset_inout) { + bool decode(const Data& encoded, size_t& offset_inout) override { return decodeBytes(encoded, _bytes, offset_inout); } - virtual bool setValueJson(const std::string& value); - virtual Data hashStruct() const; + bool setValueJson(const std::string& value) override; + Data hashStruct() const override; + std::shared_ptr clone() const override; }; /// Fixed-size array of bytes, "bytes" -class ParamByteArrayFix: public ParamCollection +class ParamByteArrayFix final: public ParamCollection { private: size_t _n; @@ -47,41 +48,43 @@ class ParamByteArrayFix: public ParamCollection ParamByteArrayFix(size_t n, const Data& val): ParamCollection(), _n(n), _bytes(Data(_n)) { setVal(val); } void setVal(const Data& val); const std::vector& getVal() const { return _bytes; } - virtual std::string getType() const { return "bytes" + std::to_string(_n); }; - virtual size_t getSize() const { return ValueEncoder::paddedTo32(_bytes.size()); } - virtual bool isDynamic() const { return false; } - virtual size_t getCount() const { return _bytes.size(); } - virtual void encode(Data& data) const; + std::string getType() const override { return "bytes" + std::to_string(_n); }; + size_t getSize() const override { return ValueEncoder::paddedTo32(_bytes.size()); } + bool isDynamic() const override { return false; } + size_t getCount() const override { return _bytes.size(); } + void encode(Data& data) const override; static bool decodeBytesFix(const Data& encoded, size_t n, Data& decoded, size_t& offset_inout); - virtual bool decode(const Data& encoded, size_t& offset_inout) { + bool decode(const Data& encoded, size_t& offset_inout) override { return decodeBytesFix(encoded, _n, _bytes, offset_inout); } - virtual bool setValueJson(const std::string& value); - virtual Data hashStruct() const; + bool setValueJson(const std::string& value) override; + Data hashStruct() const override; + std::shared_ptr clone() const override; }; /// Var-length string parameter -class ParamString: public ParamCollection +class ParamString final: public ParamCollection { private: std::string _str; public: ParamString() = default; - ParamString(std::string val): ParamCollection() { setVal(val); } + ParamString(const std::string& val): ParamCollection() { setVal(val); } void setVal(const std::string& val) { _str = val; } const std::string& getVal() const { return _str; } - virtual std::string getType() const { return "string"; }; - virtual size_t getSize() const { return 32 + ValueEncoder::paddedTo32(_str.size()); } - virtual bool isDynamic() const { return true; } - virtual size_t getCount() const { return _str.size(); } + std::string getType() const override { return "string"; }; + size_t getSize() const override { return 32 + ValueEncoder::paddedTo32(_str.size()); } + bool isDynamic() const override { return true; } + size_t getCount() const override { return _str.size(); } static void encodeString(const std::string& decoded, Data& data); - virtual void encode(Data& data) const { ParamString::encodeString(_str, data); } + void encode(Data& data) const override { ParamString::encodeString(_str, data); } static bool decodeString(const Data& encoded, std::string& decoded, size_t& offset_inout); - virtual bool decode(const Data& encoded, size_t& offset_inout) { + bool decode(const Data& encoded, size_t& offset_inout) override { return decodeString(encoded, _str, offset_inout); } - virtual bool setValueJson(const std::string& value) { _str = value; return true; } - virtual Data hashStruct() const; + bool setValueJson(const std::string& value) override { _str = value; return true; } + Data hashStruct() const override; + std::shared_ptr clone() const override; }; } // namespace TW::Ethereum::ABI diff --git a/src/Ethereum/ABI/ParamAddress.cpp b/src/Ethereum/ABI/ParamAddress.cpp index df29b67763e..1707f9f2084 100644 --- a/src/Ethereum/ABI/ParamAddress.cpp +++ b/src/Ethereum/ABI/ParamAddress.cpp @@ -11,13 +11,17 @@ namespace TW::Ethereum::ABI { Data ParamAddress::getData() const { - Data data = store(getVal(), bytes); + Data data = store(_val.getVal(), bytes); return data; } bool ParamAddress::setValueJson(const std::string& value) { - setVal(load(parse_hex(value))); + _val.setVal(load(parse_hex(value))); return true; } +std::shared_ptr ParamAddress::clone() const { + return std::make_shared(getData()); +} + } // namespace TW::Ethereum::ABI diff --git a/src/Ethereum/ABI/ParamAddress.h b/src/Ethereum/ABI/ParamAddress.h index 38b05bd342c..c9ae0fa9d16 100644 --- a/src/Ethereum/ABI/ParamAddress.h +++ b/src/Ethereum/ABI/ParamAddress.h @@ -12,16 +12,23 @@ namespace TW::Ethereum::ABI { /// 160-bit Address parameter, "address". Padded to the right, treated like ParamUInt160 -class ParamAddress: public ParamUIntN +class ParamAddress final: public ParamBase { +private: + ParamUIntN _val; public: static const size_t bytes = 20; - ParamAddress(): ParamUIntN(bytes * 8) {} - ParamAddress(const Data& val): ParamUIntN(bytes * 8, load(val)) {} - virtual std::string getType() const { return "address"; }; + ParamAddress(): _val(bytes * 8) {} + explicit ParamAddress(const Data& val): _val(bytes * 8, load(val)) {} + std::string getType() const override { return "address"; }; + size_t getSize() const override { return _val.getSize(); } + bool isDynamic() const override { return _val.isDynamic(); } + void encode(Data& data) const override { _val.encode(data); } + bool decode(const Data& encoded, size_t& offset_inout) override { return _val.decode(encoded, offset_inout); } // get the value as (20-byte) byte array (as opposed to uint256_t) Data getData() const; - virtual bool setValueJson(const std::string& value); + bool setValueJson(const std::string& value) override; + std::shared_ptr clone() const override; }; } // namespace TW::Ethereum::ABI diff --git a/src/Ethereum/ABI/ParamBase.h b/src/Ethereum/ABI/ParamBase.h index 673d4c43047..11039de5a75 100644 --- a/src/Ethereum/ABI/ParamBase.h +++ b/src/Ethereum/ABI/ParamBase.h @@ -9,6 +9,7 @@ #include "Data.h" #include +#include namespace TW::Ethereum::ABI { @@ -27,6 +28,9 @@ class ParamBase virtual Data hashStruct() const; // Helper for EIP712 encoding; provide full type of all used types (recursively). Default is empty implementation. virtual std::string getExtraTypes([[maybe_unused]] std::vector& ignoreList) const { return ""; } + // Creates a copy of this element. + // This method **must** be implemented in a `final` class only. + virtual std::shared_ptr clone() const = 0; }; /// Collection of parameters base class diff --git a/src/Ethereum/ABI/ParamNumber.h b/src/Ethereum/ABI/ParamNumber.h index 05e10753b47..a9b9ea6f631 100644 --- a/src/Ethereum/ABI/ParamNumber.h +++ b/src/Ethereum/ABI/ParamNumber.h @@ -31,12 +31,12 @@ inline bool decode(const Data& encoded, uint256_t& decoded, size_t& offset_inout } /// Generic parameter class for numeric types, like bool, uint32, int64, etc. All are stored on 256 bits. -template +template class ParamNumberType : public ParamBase { public: ParamNumberType() = default; - ParamNumberType(T val) { _val = val; } + explicit ParamNumberType(const T& val): _val(val) { } void setVal(T val) { _val = val; } T getVal() const { return _val; } virtual std::string getType() const = 0; @@ -63,108 +63,119 @@ class ParamNumberType : public ParamBase T _val; }; -class ParamUInt256 : public ParamNumberType +class ParamUInt256 final : public ParamNumberType { public: ParamUInt256() : ParamNumberType(uint256_t(0)) {} - ParamUInt256(uint256_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "uint256"; } + explicit ParamUInt256(const uint256_t& val) : ParamNumberType(val) {} + std::string getType() const override { return "uint256"; } uint256_t getVal() const { return ParamNumberType::getVal(); } - virtual bool setValueJson(const std::string& value) { return setUInt256FromValueJson(_val, value); } + bool setValueJson(const std::string& value) override { return setUInt256FromValueJson(_val, value); } static bool setUInt256FromValueJson(uint256_t& dest, const std::string& value); + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamInt256 : public ParamNumberType +class ParamInt256 final : public ParamNumberType { public: ParamInt256() : ParamNumberType(int256_t(0)) {} - ParamInt256(int256_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "int256"; } + explicit ParamInt256(const int256_t& val) : ParamNumberType(val) {} + std::string getType() const override { return "int256"; } int256_t getVal() const { return ParamNumberType::getVal(); } - virtual bool setValueJson(const std::string& value) { return setInt256FromValueJson(_val, value); } + bool setValueJson(const std::string& value) override { return setInt256FromValueJson(_val, value); } static bool setInt256FromValueJson(int256_t& dest, const std::string& value); + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamBool : public ParamNumberType +class ParamBool final : public ParamNumberType { public: ParamBool() : ParamNumberType(false) {} - ParamBool(bool val) : ParamNumberType(val) {} - virtual std::string getType() const { return "bool"; } + explicit ParamBool(bool val) : ParamNumberType(val) {} + std::string getType() const override { return "bool"; } bool getVal() const { return ParamNumberType::getVal(); } - virtual bool setValueJson(const std::string& value); + bool setValueJson(const std::string& value) override; + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamUInt8 : public ParamNumberType +class ParamUInt8 final : public ParamNumberType { public: ParamUInt8() : ParamNumberType(0) {} - ParamUInt8(uint8_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "uint8"; } - virtual bool setValueJson(const std::string& value); + explicit ParamUInt8(uint8_t val) : ParamNumberType(val) {} + std::string getType() const override { return "uint8"; } + bool setValueJson(const std::string& value) override; + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamInt8 : public ParamNumberType +class ParamInt8 final : public ParamNumberType { public: ParamInt8() : ParamNumberType(0) {} - ParamInt8(int8_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "int8"; } - virtual bool setValueJson(const std::string& value); + explicit ParamInt8(int8_t val) : ParamNumberType(val) {} + std::string getType() const override { return "int8"; } + bool setValueJson(const std::string& value) override; + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamUInt16 : public ParamNumberType +class ParamUInt16 final : public ParamNumberType { public: ParamUInt16() : ParamNumberType(0) {} - ParamUInt16(uint16_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "uint16"; } + explicit ParamUInt16(uint16_t val) : ParamNumberType(val) {} + std::string getType() const override { return "uint16"; } + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamInt16 : public ParamNumberType +class ParamInt16 final : public ParamNumberType { public: ParamInt16() : ParamNumberType(0) {} - ParamInt16(int16_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "int16"; } + explicit ParamInt16(int16_t val) : ParamNumberType(val) {} + std::string getType() const override { return "int16"; } + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamUInt32 : public ParamNumberType +class ParamUInt32 final : public ParamNumberType { public: ParamUInt32() : ParamNumberType(0) {} - ParamUInt32(uint32_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "uint32"; } + explicit ParamUInt32(uint32_t val) : ParamNumberType(val) {} + std::string getType() const override { return "uint32"; } + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamInt32 : public ParamNumberType +class ParamInt32 final : public ParamNumberType { public: ParamInt32() : ParamNumberType(0) {} - ParamInt32(int32_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "int32"; } + explicit ParamInt32(int32_t val) : ParamNumberType(val) {} + std::string getType() const override { return "int32"; } + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamUInt64 : public ParamNumberType +class ParamUInt64 final : public ParamNumberType { public: ParamUInt64() : ParamNumberType(0) {} - ParamUInt64(uint64_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "uint64"; } + explicit ParamUInt64(uint64_t val) : ParamNumberType(val) {} + std::string getType() const override { return "uint64"; } + std::shared_ptr clone() const override { return std::make_shared(_val); } }; -class ParamInt64 : public ParamNumberType +class ParamInt64 final : public ParamNumberType { public: ParamInt64() : ParamNumberType(0) {} - ParamInt64(int64_t val) : ParamNumberType(val) {} - virtual std::string getType() const { return "int64"; } + explicit ParamInt64(int64_t val) : ParamNumberType(val) {} + std::string getType() const override { return "int64"; } + std::shared_ptr clone() const override { return std::make_shared(_val); } }; /// Generic parameter class for all other bit sizes, like UInt24, 40, 48, ... 248. /// For predefined sizes (8, 16, 32, 64, 256) use the sepcial types like UInt32. /// Stored on 256 bits. -class ParamUIntN : public ParamBase +class ParamUIntN final : public ParamBase { public: const size_t bits; @@ -172,16 +183,17 @@ class ParamUIntN : public ParamBase ParamUIntN(size_t bits_in, uint256_t val) : bits(bits_in) { init(); setVal(val); } void setVal(uint256_t val); uint256_t getVal() const { return _val; } - virtual std::string getType() const { return "uint" + std::to_string(bits); } - virtual size_t getSize() const { return ValueEncoder::encodedIntSize; } - virtual bool isDynamic() const { return false; } - virtual void encode(Data& data) const { ValueEncoder::encodeUInt256(_val, data); } + std::string getType() const override { return "uint" + std::to_string(bits); } + size_t getSize() const override { return ValueEncoder::encodedIntSize; } + bool isDynamic() const override { return false; } + void encode(Data& data) const override { ValueEncoder::encodeUInt256(_val, data); } static bool decodeNumber(const Data& encoded, uint256_t& decoded, size_t& offset_inout) { return ABI::decode(encoded, decoded, offset_inout); } - virtual bool decode(const Data& encoded, size_t& offset_inout); + bool decode(const Data& encoded, size_t& offset_inout) override; static uint256_t maskForBits(size_t bits); - virtual bool setValueJson(const std::string& value) { return ParamUInt256::setUInt256FromValueJson(_val, value); } + bool setValueJson(const std::string& value) override { return ParamUInt256::setUInt256FromValueJson(_val, value); } + std::shared_ptr clone() const override { return std::make_shared(bits, _val); } private: void init(); @@ -192,7 +204,7 @@ class ParamUIntN : public ParamBase /// Generic parameter class for all other bit sizes, like Int24, 40, 48, ... 248. /// For predefined sizes (8, 16, 32, 64, 256) use the sepcial types like Int32. /// Stored on 256 bits. -class ParamIntN : public ParamBase +class ParamIntN final : public ParamBase { public: const size_t bits; @@ -200,13 +212,14 @@ class ParamIntN : public ParamBase ParamIntN(size_t bits_in, int256_t val) : bits(bits_in) { init(); setVal(val); } void setVal(int256_t val); int256_t getVal() const { return _val; } - virtual std::string getType() const { return "int" + std::to_string(bits); } - virtual size_t getSize() const { return ValueEncoder::encodedIntSize; } - virtual bool isDynamic() const { return false; } - virtual void encode(Data& data) const { ValueEncoder::encodeUInt256((uint256_t)_val, data); } + std::string getType() const override { return "int" + std::to_string(bits); } + size_t getSize() const override { return ValueEncoder::encodedIntSize; } + bool isDynamic() const override { return false; } + void encode(Data& data) const override { ValueEncoder::encodeUInt256((uint256_t)_val, data); } static bool decodeNumber(const Data& encoded, int256_t& decoded, size_t& offset_inout); - virtual bool decode(const Data& encoded, size_t& offset_inout); - virtual bool setValueJson(const std::string& value) { return ParamInt256::setInt256FromValueJson(_val, value); } + bool decode(const Data& encoded, size_t& offset_inout) override; + bool setValueJson(const std::string& value) override { return ParamInt256::setInt256FromValueJson(_val, value); } + std::shared_ptr clone() const override { return std::make_shared(bits, _val); } private: void init(); diff --git a/src/Ethereum/ABI/ParamStruct.cpp b/src/Ethereum/ABI/ParamStruct.cpp index ac4de7b0ccb..680037ceb3d 100644 --- a/src/Ethereum/ABI/ParamStruct.cpp +++ b/src/Ethereum/ABI/ParamStruct.cpp @@ -27,6 +27,10 @@ std::string ParamNamed::getType() const { return _param->getType() + " " + _name; } +std::shared_ptr ParamNamed::cloneNamed() const { + return std::make_shared(_name, _param->clone()); +} + ParamSetNamed::~ParamSetNamed() { _params.clear(); } @@ -104,6 +108,14 @@ std::shared_ptr ParamSetNamed::findParamByName(const std::string& na return nullptr; } +ParamSetNamed ParamSetNamed::clone() const { + ParamSetNamed newSet; + for (const auto& p : _params) { + newSet.addParam(p->cloneNamed()); + } + return newSet; +} + Data ParamStruct::hashType() const { return Hash::keccak256(TW::data(encodeType())); } @@ -138,6 +150,10 @@ std::string ParamStruct::getExtraTypes(std::vector& ignoreList) con return types; } +std::shared_ptr ParamStruct::clone() const { + return std::make_shared(_name, _params.clone()); +} + Data ParamStruct::hashStructJson(const std::string& messageJson) { auto message = json::parse(messageJson, nullptr, false); if (message.is_discarded()) { diff --git a/src/Ethereum/ABI/ParamStruct.h b/src/Ethereum/ABI/ParamStruct.h index c043e588796..64b550d2cfb 100644 --- a/src/Ethereum/ABI/ParamStruct.h +++ b/src/Ethereum/ABI/ParamStruct.h @@ -15,25 +15,27 @@ namespace TW::Ethereum::ABI { /// A named parameter. -class ParamNamed: public ParamBase +class ParamNamed final : public ParamBase { public: std::string _name; std::shared_ptr _param; public: - ParamNamed(const std::string& name, std::shared_ptr param): _name(name), _param(param) {} - - virtual std::string getName() const { return _name; } - virtual std::shared_ptr getParam() const { return _param; } - virtual std::string getType() const; - virtual size_t getSize() const { return _param->getSize(); } - virtual bool isDynamic() const { return _param->isDynamic(); } - virtual void encode(Data& data) const { return _param->encode(data); } - virtual bool decode(const Data& encoded, size_t& offset_inout) { return _param->decode(encoded, offset_inout); } - virtual bool setValueJson(const std::string& value) { return _param->setValueJson(value); } - virtual Data hashStruct() const { return _param->hashStruct(); } - virtual std::string getExtraTypes(std::vector& ignoreList) const { return _param->getExtraTypes(ignoreList); } + explicit ParamNamed(const std::string& name, std::shared_ptr param): _name(name), _param(param) {} + + std::string getName() const { return _name; } + std::shared_ptr getParam() const { return _param; } + std::string getType() const override; + size_t getSize() const override { return _param->getSize(); } + bool isDynamic() const override { return _param->isDynamic(); } + void encode(Data& data) const override { return _param->encode(data); } + bool decode(const Data& encoded, size_t& offset_inout) override { return _param->decode(encoded, offset_inout); } + bool setValueJson(const std::string& value) override { return _param->setValueJson(value); } + Data hashStruct() const override { return _param->hashStruct(); } + std::string getExtraTypes(std::vector& ignoreList) const override { return _param->getExtraTypes(ignoreList); } + std::shared_ptr clone() const override { return cloneNamed(); } + std::shared_ptr cloneNamed() const; }; /// A collection of named parameters. See also: ParamStruct @@ -56,10 +58,11 @@ class ParamSetNamed { Data encodeHashes() const; std::string getExtraTypes(std::vector& ignoreList) const; std::shared_ptr findParamByName(const std::string& name) const; + ParamSetNamed clone() const; }; /// A named structure (set of parameters plus a type name). -class ParamStruct: public ParamCollection +class ParamStruct final : public ParamCollection { private: std::string _name; @@ -68,12 +71,13 @@ class ParamStruct: public ParamCollection public: ParamStruct() = default; ParamStruct(const std::string& name, const std::vector>& params) : ParamCollection(), _name(name), _params(ParamSetNamed(params)) {} + ParamStruct(const std::string& name, ParamSetNamed&& params) : ParamCollection(), _name(name), _params(std::move(params)) {} - std::string getType() const { return _name; } + std::string getType() const override { return _name; } const ParamSetNamed& getParams() const { return _params; } /// Compute the hash of a struct, used for signing, according to EIP712 - virtual Data hashStruct() const; + Data hashStruct() const override; /// Get full type, extended by used sub-types, of the form 'Mail(Person from,Person to,string contents)Person(string name,address wallet)' std::string encodeType() const { std::vector ignoreList; @@ -82,14 +86,15 @@ class ParamStruct: public ParamCollection /// Get the hash of the full type. Data hashType() const; - virtual size_t getSize() const { return _params.getCount(); } - virtual bool isDynamic() const { return true; } - virtual size_t getCount() const { return _params.getCount(); } - virtual void encode([[maybe_unused]] Data& data) const {} - virtual bool decode([[maybe_unused]] const Data& encoded, [[maybe_unused]] size_t& offset_inout) { return true; } - virtual bool setValueJson([[maybe_unused]] const std::string& value) { return false; } // see makeStruct + size_t getSize() const override { return _params.getCount(); } + bool isDynamic() const override { return true; } + size_t getCount() const override { return _params.getCount(); } + void encode([[maybe_unused]] Data& data) const override {} + bool decode([[maybe_unused]] const Data& encoded, [[maybe_unused]] size_t& offset_inout) override { return true; } + bool setValueJson([[maybe_unused]] const std::string& value) override { return false; } // see makeStruct Data encodeHashes() const; - virtual std::string getExtraTypes(std::vector& ignoreList) const; + std::string getExtraTypes(std::vector& ignoreList) const override; + std::shared_ptr clone() const override; std::shared_ptr findParamByName(const std::string& name) const { return _params.findParamByName(name); } /// Compute the hash of a struct, used for signing, according to EIP712 ("v4"). diff --git a/src/Ethereum/ABI/Parameters.cpp b/src/Ethereum/ABI/Parameters.cpp index b3eeb61ca04..973443fa540 100644 --- a/src/Ethereum/ABI/Parameters.cpp +++ b/src/Ethereum/ABI/Parameters.cpp @@ -128,28 +128,37 @@ void ParamSet::encode(Data& data) const { } bool ParamSet::decode(const Data& encoded, size_t& offset_inout) { - // pass 1: small values - for (auto p : _params) { + size_t arrayOffset = offset_inout; + + for (const auto& p : _params) { + // Decode a dynamic element. if (p->isDynamic()) { uint256_t index; if (!ABI::decode(encoded, index, offset_inout)) { return false; } - // index is read but not used - } else { - if (!p->decode(encoded, offset_inout)) { + + // Check if length is in the size_t range. + auto indexSize = static_cast(index); + if (indexSize != index) { return false; } - } - } - // pass2: large values - for (auto p : _params) { - if (p->isDynamic()) { - if (!p->decode(encoded, offset_inout)) { + + // Calculate an offset relative to the beginning of this array. + size_t newOffset = arrayOffset + indexSize; + if (!p->decode(encoded, newOffset)) { return false; } + + continue; + } + + // Otherwise decode a static element, e.g `p->isDynamic() == false`. + if (!p->decode(encoded, offset_inout)) { + return false; } } + return true; } @@ -161,6 +170,15 @@ Data ParamSet::encodeHashes() const { return hashes; } +ParamSet ParamSet::clone() const { + ParamSet newSet; + for (const auto& p : _params) { + newSet.addParam(p->clone()); + } + + return newSet; +} + Data Parameters::hashStruct() const { Data hash(32); Data hashes = _params.encodeHashes(); @@ -170,4 +188,10 @@ Data Parameters::hashStruct() const { return hash; } +std::shared_ptr Parameters::clone() const { + auto newParams = std::make_shared(); + newParams->_params = _params.clone(); + return newParams; +} + } // namespace TW::Ethereum::ABI diff --git a/src/Ethereum/ABI/Parameters.h b/src/Ethereum/ABI/Parameters.h index 30aabf3d340..cc6d0844cd7 100644 --- a/src/Ethereum/ABI/Parameters.h +++ b/src/Ethereum/ABI/Parameters.h @@ -40,13 +40,15 @@ class ParamSet { virtual void encode(Data& data) const; virtual bool decode(const Data& encoded, size_t& offset_inout); Data encodeHashes() const; + /// Creates a copy of this set with exactly the same params. + ParamSet clone() const; private: size_t getHeadSize() const; }; /// Collection of different parameters, dynamic length, "(,,...)". -class Parameters: public ParamCollection +class Parameters final : public ParamCollection { private: ParamSet _params; @@ -57,14 +59,15 @@ class Parameters: public ParamCollection void addParam(const std::shared_ptr& param) { _params.addParam(param); } void addParams(const std::vector>& params) { _params.addParams(params); } std::shared_ptr getParam(size_t paramIndex) const { return _params.getParamUnsafe(paramIndex); } - virtual std::string getType() const { return _params.getType(); } - virtual size_t getSize() const { return _params.getSize(); } - virtual bool isDynamic() const { return true; } - virtual size_t getCount() const { return _params.getCount(); } - virtual void encode(Data& data) const { _params.encode(data); } - virtual bool decode(const Data& encoded, size_t& offset_inout) { return _params.decode(encoded, offset_inout); } - virtual bool setValueJson([[maybe_unused]] const std::string& value) { return false; } - virtual Data hashStruct() const; + std::string getType() const override { return _params.getType(); } + size_t getSize() const override { return _params.getSize(); } + bool isDynamic() const override { return true; } + size_t getCount() const override { return _params.getCount(); } + void encode(Data& data) const override { _params.encode(data); } + bool decode(const Data& encoded, size_t& offset_inout) override { return _params.decode(encoded, offset_inout); } + bool setValueJson([[maybe_unused]] const std::string& value) override { return false; } + Data hashStruct() const override; + std::shared_ptr clone() const override; }; } // namespace TW::Ethereum::ABI diff --git a/src/Ethereum/ABI/Tuple.cpp b/src/Ethereum/ABI/Tuple.cpp index 5f36ac33024..1f661b4aeca 100644 --- a/src/Ethereum/ABI/Tuple.cpp +++ b/src/Ethereum/ABI/Tuple.cpp @@ -14,4 +14,10 @@ int ParamTuple::addParam(std::shared_ptr param) { return _params.addParam(param); } +std::shared_ptr ParamTuple::clone() const { + auto newTuple = std::make_shared(); + newTuple->_params = _params.clone(); + return newTuple; +} + } // namespace TW::Ethereum::ABI \ No newline at end of file diff --git a/src/Ethereum/ABI/Tuple.h b/src/Ethereum/ABI/Tuple.h index 6c8df69a789..2911703987e 100644 --- a/src/Ethereum/ABI/Tuple.h +++ b/src/Ethereum/ABI/Tuple.h @@ -13,13 +13,13 @@ namespace TW::Ethereum::ABI { /// A Tuple is a collection of parameters -class ParamTuple: public ParamCollection +class ParamTuple final : public ParamCollection { public: ParamSet _params; - ParamTuple() {} - ParamTuple(const std::vector>& params) : _params(ParamSet(params)) {} + ParamTuple() = default; + explicit ParamTuple(const std::vector>& params) : _params(ParamSet(params)) {} /// Add a parameter. Returns the index of the parameter. int addParam(std::shared_ptr param); @@ -28,14 +28,15 @@ class ParamTuple: public ParamCollection return _params.getParam(paramIndex, param_out); } /// Return the type signature, of the form "(int32,uint256)" - std::string getType() const { return _params.getType(); } - - virtual size_t getSize() const { return _params.getSize(); } - virtual bool isDynamic() const { return _params.isDynamic(); } - virtual void encode(Data& data) const { return _params.encode(data); } - virtual bool decode(const Data& encoded, size_t& offset_inout) { return _params.decode(encoded, offset_inout); } - virtual bool setValueJson([[maybe_unused]] const std::string& value) { return false; } - virtual size_t getCount() const { return _params.getCount(); } + std::string getType() const override { return _params.getType(); } + + size_t getSize() const override { return _params.getSize(); } + bool isDynamic() const override { return _params.isDynamic(); } + void encode(Data& data) const override { return _params.encode(data); } + bool decode(const Data& encoded, size_t& offset_inout) override { return _params.decode(encoded, offset_inout); } + bool setValueJson([[maybe_unused]] const std::string& value) override { return false; } + size_t getCount() const override { return _params.getCount(); } + std::shared_ptr clone() const override; }; } // namespace TW::Ethereum::ABI diff --git a/src/Ethereum/Barz.cpp b/src/Ethereum/Barz.cpp index 9cfbd0c0d49..e6cc3e92c56 100644 --- a/src/Ethereum/Barz.cpp +++ b/src/Ethereum/Barz.cpp @@ -9,7 +9,6 @@ #include "EIP1014.h" #include "Hash.h" #include "HexCoding.h" -#include #include "../proto/Barz.pb.h" #include "AsnParser.h" #include "Base64.h" @@ -35,15 +34,15 @@ std::string getCounterfactualAddress(const Proto::ContractAddressInput input) { append(initCode, encoded); const Data initCodeHash = Hash::keccak256(initCode); - const Data salt(32, 0); + Data salt = store(input.salt(), 32); return Ethereum::checksumed(Ethereum::Address(hexEncoded(Ethereum::create2Address(input.factory(), salt, initCodeHash)))); } -Data getInitCode(const std::string& factoryAddress, const PublicKey& publicKey, const std::string& verificationFacet) { +Data getInitCode(const std::string& factoryAddress, const PublicKey& publicKey, const std::string& verificationFacet, const uint32_t salt) { auto createAccountFunc = Ethereum::ABI::Function("createAccount", ParamCollection{ std::make_shared(parse_hex(verificationFacet)), std::make_shared(publicKey.bytes), - std::make_shared(0)}); + std::make_shared(salt)}); Data createAccountFuncEncoded; createAccountFunc.encode(createAccountFuncEncoded); diff --git a/src/Ethereum/Barz.h b/src/Ethereum/Barz.h index 7ec5c2cbb6d..cc6fa74998b 100644 --- a/src/Ethereum/Barz.h +++ b/src/Ethereum/Barz.h @@ -14,7 +14,7 @@ namespace TW::Barz { std::string getCounterfactualAddress(const Proto::ContractAddressInput input); -Data getInitCode(const std::string& factoryAddress, const PublicKey& publicKey, const std::string& verificationFacet); +Data getInitCode(const std::string& factoryAddress, const PublicKey& publicKey, const std::string& verificationFacet, const uint32_t salt); Data getFormattedSignature(const Data& signature, const Data challenge, const Data& authenticatorData, const std::string& clientDataJSON); } diff --git a/src/Ethereum/ContractCall.cpp b/src/Ethereum/ContractCall.cpp index 1cd9e76fb85..f2850c21dc4 100644 --- a/src/Ethereum/ContractCall.cpp +++ b/src/Ethereum/ContractCall.cpp @@ -31,15 +31,15 @@ static void fill(ParamSet& paramSet, const string& type) { } } -static vector getArrayValue(ParamSet& paramSet, const string& type, int idx) { +static vector getArrayValue(const ParamSet& paramSet, const string& type, int idx) { shared_ptr param; paramSet.getParam(idx, param); return ParamFactory::getArrayValue(param, type); } -static json buildInputs(ParamSet& paramSet, const json& registry); // forward +static json buildInputs(const ParamSet& paramSet, const json& registry); // forward -static json getTupleValue(ParamSet& paramSet, [[maybe_unused]] const string& type, int idx, const json& typeInfo) { +static json getTupleValue(const ParamSet& paramSet, [[maybe_unused]] const string& type, int idx, const json& typeInfo) { shared_ptr param; paramSet.getParam(idx, param); auto paramTuple = dynamic_pointer_cast(param); @@ -49,13 +49,32 @@ static json getTupleValue(ParamSet& paramSet, [[maybe_unused]] const string& typ return buildInputs(paramTuple->_params, typeInfo["components"]); } -static string getValue(ParamSet& paramSet, const string& type, int idx) { +static vector getArrayValueTuple(const ParamSet& paramSet, int idx, const json& typeInfo) { + shared_ptr param; + paramSet.getParam(idx, param); + + auto array = dynamic_pointer_cast(param); + if (!array) { + return {}; + } + + std::vector values; + for (const auto& tuple : array->getVal()) { + if (auto paramTuple = dynamic_pointer_cast(tuple); paramTuple) { + values.emplace_back(buildInputs(paramTuple->_params, typeInfo["components"])); + } + } + + return values; +} + +static string getValue(const ParamSet& paramSet, const string& type, int idx) { shared_ptr param; paramSet.getParam(idx, param); return ParamFactory::getValue(param, type); } -static json buildInputs(ParamSet& paramSet, const json& registry) { +static json buildInputs(const ParamSet& paramSet, const json& registry) { auto inputs = json::array(); for (auto i = 0ul; i < registry.size(); i++) { auto info = registry[i]; @@ -64,7 +83,9 @@ static json buildInputs(ParamSet& paramSet, const json& registry) { {"name", info["name"]}, {"type", type} }; - if (boost::algorithm::ends_with(type.get(), "[]")) { + if (type == "tuple[]") { + input["components"] = getArrayValueTuple(paramSet, static_cast(i), info); + } else if (boost::algorithm::ends_with(type.get(), "[]")) { input["value"] = json(getArrayValue(paramSet, type, static_cast(i))); } else if (type == "tuple") { input["components"] = getTupleValue(paramSet, type, static_cast(i), info); @@ -80,14 +101,18 @@ static json buildInputs(ParamSet& paramSet, const json& registry) { void fillTuple(ParamSet& paramSet, const json& jsonSet); // forward +void fillTupleArray(ParamSet& paramSet, const json& jsonSet); // forward + void decodeParamSet(ParamSet& paramSet, const json& jsonSet) { for (auto& comp : jsonSet) { if (comp["type"] == "tuple") { fillTuple(paramSet, comp["components"]); - } else { + } else if (comp["type"] == "tuple[]") { + fillTupleArray(paramSet, comp["components"]); + } else { fill(paramSet, comp["type"]); } - } + } } void fillTuple(ParamSet& paramSet, const json& jsonSet) { @@ -96,6 +121,14 @@ void fillTuple(ParamSet& paramSet, const json& jsonSet) { paramSet.addParam(param); } +void fillTupleArray(ParamSet& paramSet, const json& jsonSet) { + std::shared_ptr tuple = make_shared(); + decodeParamSet(tuple->_params, jsonSet); + + auto tupleArray = make_shared(tuple); + paramSet.addParam(tupleArray); +} + optional decodeCall(const Data& call, const json& abi) { // check bytes length if (call.size() <= 4) { diff --git a/src/interface/TWBarz.cpp b/src/interface/TWBarz.cpp index 955dd6103e9..b3261247494 100644 --- a/src/interface/TWBarz.cpp +++ b/src/interface/TWBarz.cpp @@ -21,12 +21,12 @@ TWString *_Nonnull TWBarzGetCounterfactualAddress(TWData *_Nonnull input) { return TWStringCreateWithUTF8Bytes(TW::Barz::getCounterfactualAddress(inputProto).c_str()); } -TWData *_Nonnull TWBarzGetInitCode(TWString* _Nonnull factory, struct TWPublicKey* _Nonnull publicKey, TWString* _Nonnull verificationFacet) { +TWData *_Nonnull TWBarzGetInitCode(TWString* _Nonnull factory, struct TWPublicKey* _Nonnull publicKey, TWString* _Nonnull verificationFacet, uint32_t salt) { const auto& factoryStr = *reinterpret_cast(factory); const auto& publicKeyConverted = *reinterpret_cast(publicKey); const auto& verificationFacetStr = *reinterpret_cast(verificationFacet); - const auto initCode = TW::Barz::getInitCode(factoryStr, publicKeyConverted, verificationFacetStr); + const auto initCode = TW::Barz::getInitCode(factoryStr, publicKeyConverted, verificationFacetStr, salt); return TWDataCreateWithData(&initCode); } diff --git a/src/interface/TWBitcoinFee.cpp b/src/interface/TWBitcoinFee.cpp index 9836100bcf0..6250d46a580 100644 --- a/src/interface/TWBitcoinFee.cpp +++ b/src/interface/TWBitcoinFee.cpp @@ -6,14 +6,15 @@ #include #include "Bitcoin/Transaction.h" -#include "Data.h" -uint64_t TWBitcoinFeeCalculateFee(TWData* _Nonnull data, uint64_t satVb) { +TWString* _Nullable TWBitcoinFeeCalculateFee(TWData* _Nonnull data, TWString* _Nonnull satVb) { auto* encoded = reinterpret_cast(data); - auto fee = TW::Bitcoin::Transaction::calculateFee(*encoded, satVb); + const std::string& satVbStr = *reinterpret_cast(satVb); + uint64_t satVbInt = std::stoull(satVbStr); + auto fee = TW::Bitcoin::Transaction::calculateFee(*encoded, satVbInt); if (!fee) { - return 0; + return nullptr; } - return fee.value(); + return TWStringCreateWithUTF8Bytes(std::to_string(*fee).c_str()); } diff --git a/src/proto/Aptos.proto b/src/proto/Aptos.proto index 9d28e3c58aa..6f124b47423 100644 --- a/src/proto/Aptos.proto +++ b/src/proto/Aptos.proto @@ -27,7 +27,7 @@ message StructTag { string name = 3; } -// Necessary fields to process a TokenTransferMessage +// Necessary fields to process a `0x1::coin::transfer` function. message TokenTransferMessage { // Destination Account address (string) string to = 1; @@ -37,6 +37,17 @@ message TokenTransferMessage { StructTag function = 3; } +// Necessary fields to process a `0x1::aptos_account::transfer_coins` function. +// Can be used to transfer tokens with registering the recipient account if needed. +message TokenTransferCoinsMessage { + // Destination Account address (string) + string to = 1; + // Amount to be transferred (uint64) + uint64 amount = 2; + // token function to call, e.g BTC: 0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC + StructTag function = 3; +} + // Necessary fields to process a ManagedTokensRegisterMessage message ManagedTokensRegisterMessage { // token function to register, e.g BTC: 0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9::coins::BTC @@ -153,6 +164,7 @@ message SigningInput { NftMessage nft_message = 12; ManagedTokensRegisterMessage register_token = 13; LiquidStaking liquid_staking_message = 14; + TokenTransferCoinsMessage token_transfer_coins = 15; } } diff --git a/src/proto/Barz.proto b/src/proto/Barz.proto index 0165295481b..20853f04ad4 100644 --- a/src/proto/Barz.proto +++ b/src/proto/Barz.proto @@ -26,4 +26,7 @@ message ContractAddressInput { string bytecode = 7; // PublicKey of the wallet string public_key = 8; + + // Salt is used to derive multiple account from the same public key + uint32 salt = 9; } diff --git a/swift/Tests/BarzTests.swift b/swift/Tests/BarzTests.swift index b2f81dbab60..d86ae0b1aba 100644 --- a/swift/Tests/BarzTests.swift +++ b/swift/Tests/BarzTests.swift @@ -15,10 +15,19 @@ class BarzTests: XCTestCase { let publicKeyData = Data(hexString: "0x04e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b02")! let publicKey = PublicKey(data: publicKeyData, type: .nist256p1Extended)! let verificationFacet = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf" - let result = Barz.getInitCode(factory: factoryAddress, publicKey: publicKey, verificationFacet: verificationFacet) + let result = Barz.getInitCode(factory: factoryAddress, publicKey: publicKey, verificationFacet: verificationFacet, salt: 0) XCTAssertEqual(result.hexString, "3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000") } + func testInitCodeNoneZeroSalt() { + let factoryAddress = "0x3fC708630d85A3B5ec217E53100eC2b735d4f800" + let publicKeyData = Data(hexString: "0x04e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b02")! + let publicKey = PublicKey(data: publicKeyData, type: .nist256p1Extended)! + let verificationFacet = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf" + let result = Barz.getInitCode(factory: factoryAddress, publicKey: publicKey, verificationFacet: verificationFacet, salt: 1) + XCTAssertEqual(result.hexString, "3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000") + } + func testCounterfactualAddress() { let input = BarzContractAddressInput.with { $0.factory = "0x2c97f4a366Dd5D91178ec9E36c5C1fcA393A538C" @@ -29,11 +38,28 @@ class BarzTests: XCTestCase { $0.defaultFallback = "0x22eB0720d9Fc4bC90BB812B309e939880B71c20d" $0.bytecode = bytecode $0.publicKey = "0xB5547FBdC56DCE45e1B8ef75569916D438e09c46" + $0.salt = 0 } XCTAssertEqual(Barz.getCounterfactualAddress(input: try! input.serializedData()), "0x77F62bb3E43190253D4E198199356CD2b25063cA"); } + func testCounterfactualAddressNonZeroSalt() { + let input = BarzContractAddressInput.with { + $0.factory = "0x96C489979E39F877BDb8637b75A25C1a5B2DE14C" + $0.accountFacet = "0xF6F5e5fC74905e65e3FF53c6BacEba8535dd14d1" + $0.verificationFacet = "0xaB84813cbf26Fd951CB3d7E33Dccb8995027e490" + $0.entryPoint = entryPoint + $0.facetRegistry = "0x9a95d201BB8F559771784D12c01F8084278c65E5" + $0.defaultFallback = "0x522cDc7558b5f798dF5D61AB09B6D95Ebd342EF9" + $0.bytecode = "0x60806040526040516104c83803806104c883398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b6101b3806103156000396000f3fe60806040523661000b57005b600080356001600160e01b03191681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c806100cf576004838101546040516366ffd66360e11b81526000356001600160e01b031916928101929092526001600160a01b03169063cdffacc690602401602060405180830381865afa1580156100a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100cc919061014d565b90505b6001600160a01b0381166101295760405162461bcd60e51b815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e808015610148573d6000f35b3d6000fd5b60006020828403121561015f57600080fd5b81516001600160a01b038116811461017657600080fd5b939250505056fea2646970667358221220d35db061bb6ecdb7688c3674af669ce44d527cae4ded59214d06722d73da62be64736f6c63430008120033" + $0.publicKey = "0xB5547FBdC56DCE45e1B8ef75569916D438e09c46" + $0.salt = 123456 + } + + XCTAssertEqual(Barz.getCounterfactualAddress(input: try! input.serializedData()), "0xB91aaa96B138A1B1D94c9df4628187132c5F2bf1"); + } + func testFormatSignature() { let signature = Data(hexString: "0x3044022012d89e3b41e253dc9e90bd34dc1750d059b76d0b1d16af2059aa26e90b8960bf0220256d8a05572c654906ce422464693e280e243e6d9dbc5f96a681dba846bca276")! let challenge = Data(hexString: "0xcf267a78c5adaf96f341a696eb576824284c572f3e61be619694d539db1925f9")! @@ -96,7 +122,8 @@ class BarzTests: XCTestCase { $0.initCode = Barz.getInitCode( factory: factory, publicKey: publicKey, - verificationFacet: "0x5034534Efe9902779eD6eA6983F435c00f3bc510" + verificationFacet: "0x5034534Efe9902779eD6eA6983F435c00f3bc510", + salt: 0 ) } diff --git a/swift/Tests/Blockchains/BitcoinTests.swift b/swift/Tests/Blockchains/BitcoinTests.swift index 2155db798b2..95dc60c4fcd 100644 --- a/swift/Tests/Blockchains/BitcoinTests.swift +++ b/swift/Tests/Blockchains/BitcoinTests.swift @@ -473,17 +473,19 @@ class BitcoinTransactionSignerTests: XCTestCase { } func testBitcoinP2pkhCalculateFee() throws { - let satVb: UInt64 = 10 + let satVb = "10" let tx = Data(hexString: "02000000017be4e642bb278018ab12277de9427773ad1c5f5b1d164a157e0d99aa48dc1c1e000000006a473044022078eda020d4b86fcb3af78ef919912e6d79b81164dbbb0b0b96da6ac58a2de4b102201a5fd8d48734d5a02371c4b5ee551a69dca3842edbf577d863cf8ae9fdbbd4590121036666dd712e05a487916384bfcd5973eb53e8038eccbbf97f7eed775b87389536ffffffff01c0aff629010000001976a9145eaaa4f458f9158f86afcba08dd7448d27045e3d88ac00000000")! - let fee = BitcoinFee.calculateFee(data: tx, satVb: satVb) - XCTAssertEqual(fee, 191 * satVb) + let fee = BitcoinFee.calculateFee(data: tx, satVb: satVb)! + let feeInt = UInt64(fee)! + XCTAssertEqual(feeInt, 191 * 10) } func testBitcoinP2wpkhCalculateFee() throws { - let satVb: UInt64 = 12 + let satVb = "12" let tx = Data(hexString: "020000000111b9f62923af73e297abb69f749e7a1aa2735fbdfd32ac5f6aa89e5c96841c18000000006b483045022100df9ed0b662b759e68b89a42e7144cddf787782a7129d4df05642dd825930e6e6022051a08f577f11cc7390684bbad2951a6374072253ffcf2468d14035ed0d8cd6490121028d7dce6d72fb8f7af9566616c6436349c67ad379f2404dd66fe7085fe0fba28fffffffff01c0aff629010000001600140d0e1cec6c2babe8badde5e9b3dea667da90036d00000000")! - let fee = BitcoinFee.calculateFee(data: tx, satVb: satVb) - XCTAssertEqual(fee, 189 * satVb) + let fee = BitcoinFee.calculateFee(data: tx, satVb: satVb)! + let feeInt = UInt64(fee)! + XCTAssertEqual(feeInt, 189 * 12) } // Metadata can be observed live on: @@ -493,10 +495,11 @@ class BitcoinTransactionSignerTests: XCTestCase { // Size 235 Bytes // Weight 610 func testBitcoinBrc20TransferCommitCalculateFee() throws { - let satVb: UInt64 = 19 + let satVb = "19" let tx = Data(hexString: "02000000000101089098890d2653567b9e8df2d1fbe5c3c8bf1910ca7184e301db0ad3b495c88e0100000000ffffffff02581b000000000000225120e8b706a97732e705e22ae7710703e7f589ed13c636324461afa443016134cc051040000000000000160014e311b8d6ddff856ce8e9a4e03bc6d4fe5050a83d02483045022100a44aa28446a9a886b378a4a65e32ad9a3108870bd725dc6105160bed4f317097022069e9de36422e4ce2e42b39884aa5f626f8f94194d1013007d5a1ea9220a06dce0121030f209b6ada5edb42c77fd2bc64ad650ae38314c8f451f3e36d80bc8e26f132cb00000000")! - let fee = BitcoinFee.calculateFee(data: tx, satVb: satVb) - XCTAssertEqual(fee, 153 * satVb) // 153 = ceil(610/4) + let fee = BitcoinFee.calculateFee(data: tx, satVb: satVb)! + let feeInt = UInt64(fee); + XCTAssertEqual(feeInt, 153 * 19) // 153 = ceil(610/4) } } diff --git a/swift/Tests/CoinAddressDerivationTests.swift b/swift/Tests/CoinAddressDerivationTests.swift index c5f39c9d51f..ed6254e2a8f 100644 --- a/swift/Tests/CoinAddressDerivationTests.swift +++ b/swift/Tests/CoinAddressDerivationTests.swift @@ -108,7 +108,8 @@ class CoinAddressDerivationTests: XCTestCase { .confluxeSpace, .opBNBtestnet, .acalaEVM, - .neon: + .neon, + .base: let expectedResult = "0x8f348F300873Fd5DA36950B2aC75a26584584feE" assertCoinDerivation(coin, expectedResult, derivedAddress, address) case .ronin: diff --git a/tests/chains/Aptos/SignerTests.cpp b/tests/chains/Aptos/SignerTests.cpp index b12e6de891f..65c0bc87089 100644 --- a/tests/chains/Aptos/SignerTests.cpp +++ b/tests/chains/Aptos/SignerTests.cpp @@ -681,4 +681,50 @@ TEST(AptosSigner, TokenTxSign) { assertJSONEqual(expectedJson, parsedJson); } +TEST(AptosSigner, TokenTransferCoins) { + // Successfully broadcasted https://explorer.aptoslabs.com/txn/0x197d40ea12e2bfc65a0a913b9f4ca3b0b0208fe0c1514d3d55cef3d5bcf25211?network=mainnet + Proto::SigningInput input; + input.set_sender("0x1869b853768f0ba935d67f837a66b172dd39a60ca2315f8d4e0e669bbd35cf25"); + input.set_sequence_number(2); + auto& tf = *input.mutable_token_transfer_coins(); + tf.set_to("0xb7c7d12080209e9dc14498c80200706e760363fb31782247e82cf57d1d6e5d6c"); + tf.set_amount(10000); + tf.mutable_function()->set_account_address("0xe9c192ff55cffab3963c695cff6dbf9dad6aff2bb5ac19a6415cad26a81860d9"); + tf.mutable_function()->set_module("mee_coin"); + tf.mutable_function()->set_name("MeeCoin"); + input.set_max_gas_amount(2000); + input.set_gas_unit_price(100); + input.set_expiration_timestamp_secs(3664390082); + input.set_chain_id(1); + auto privateKey = PrivateKey(parse_hex("e7f56c77189e03699a75d8ec5c090e41f3d9d4783bc49c33df8a93d915e10de8")); + input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); + auto result = Signer::sign(input); + + ASSERT_EQ(hex(result.raw_txn()), "1869b853768f0ba935d67f837a66b172dd39a60ca2315f8d4e0e669bbd35cf2502000000000000000200000000000000000000000000000000000000000000000000000000000000010d6170746f735f6163636f756e740e7472616e736665725f636f696e730107e9c192ff55cffab3963c695cff6dbf9dad6aff2bb5ac19a6415cad26a81860d9086d65655f636f696e074d6565436f696e000220b7c7d12080209e9dc14498c80200706e760363fb31782247e82cf57d1d6e5d6c081027000000000000d0070000000000006400000000000000c2276ada0000000001"); + ASSERT_EQ(hex(result.authenticator().signature()), "30ebd7e95cb464677f411868e2cbfcb22bc01cc63cded36c459dff45e6d2f1354ae4e090e7dfbb509851c0368b343e0e5ecaf6b08e7c1b94c186530b0f7dee0d"); + ASSERT_EQ(hex(result.encoded()), "1869b853768f0ba935d67f837a66b172dd39a60ca2315f8d4e0e669bbd35cf2502000000000000000200000000000000000000000000000000000000000000000000000000000000010d6170746f735f6163636f756e740e7472616e736665725f636f696e730107e9c192ff55cffab3963c695cff6dbf9dad6aff2bb5ac19a6415cad26a81860d9086d65655f636f696e074d6565436f696e000220b7c7d12080209e9dc14498c80200706e760363fb31782247e82cf57d1d6e5d6c081027000000000000d0070000000000006400000000000000c2276ada0000000001002062e7a6a486553b56a53e89dfae3f780693e537e5b0a7ed33290780e581ca83694030ebd7e95cb464677f411868e2cbfcb22bc01cc63cded36c459dff45e6d2f1354ae4e090e7dfbb509851c0368b343e0e5ecaf6b08e7c1b94c186530b0f7dee0d"); + nlohmann::json expectedJson = R"( + { + "expiration_timestamp_secs": "3664390082", + "gas_unit_price": "100", + "max_gas_amount": "2000", + "payload": { + "arguments": ["0xb7c7d12080209e9dc14498c80200706e760363fb31782247e82cf57d1d6e5d6c","10000"], + "function": "0x1::aptos_account::transfer_coins", + "type": "entry_function_payload", + "type_arguments": ["0xe9c192ff55cffab3963c695cff6dbf9dad6aff2bb5ac19a6415cad26a81860d9::mee_coin::MeeCoin"] + }, + "sender": "0x1869b853768f0ba935d67f837a66b172dd39a60ca2315f8d4e0e669bbd35cf25", + "sequence_number": "2", + "signature": { + "public_key": "0x62e7a6a486553b56a53e89dfae3f780693e537e5b0a7ed33290780e581ca8369", + "signature": "0x30ebd7e95cb464677f411868e2cbfcb22bc01cc63cded36c459dff45e6d2f1354ae4e090e7dfbb509851c0368b343e0e5ecaf6b08e7c1b94c186530b0f7dee0d", + "type": "ed25519_signature" + } + } + )"_json; + nlohmann::json parsedJson = nlohmann::json::parse(result.json()); + assertJSONEqual(expectedJson, parsedJson); +} + } // namespace TW::Aptos::tests diff --git a/tests/chains/Base/TWCoinTypeTests.cpp b/tests/chains/Base/TWCoinTypeTests.cpp new file mode 100644 index 00000000000..a07285626d2 --- /dev/null +++ b/tests/chains/Base/TWCoinTypeTests.cpp @@ -0,0 +1,37 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// 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. +// +// This is a GENERATED FILE, changes made here MAY BE LOST. +// Generated one-time (codegen/bin/cointests) +// + +#include "TestUtilities.h" +#include +#include + + +TEST(TWBaseCoinType, TWCoinType) { + const auto coin = TWCoinTypeBase; + const auto symbol = WRAPS(TWCoinTypeConfigurationGetSymbol(coin)); + const auto id = WRAPS(TWCoinTypeConfigurationGetID(coin)); + const auto name = WRAPS(TWCoinTypeConfigurationGetName(coin)); + const auto chainId = WRAPS(TWCoinTypeChainId(coin)); + const auto txId = WRAPS(TWStringCreateWithUTF8Bytes("0x4acb15506b7696a2dfac4258f3f86392b4b2b717a3f316a8aa78509b2c3b6ab4")); + const auto txUrl = WRAPS(TWCoinTypeConfigurationGetTransactionURL(coin, txId.get())); + const auto accId = WRAPS(TWStringCreateWithUTF8Bytes("0xb8ff877ed78ba520ece21b1de7843a8a57ca47cb")); + const auto accUrl = WRAPS(TWCoinTypeConfigurationGetAccountURL(coin, accId.get())); + + assertStringsEqual(id, "base"); + assertStringsEqual(name, "Base"); + assertStringsEqual(symbol, "ETH"); + ASSERT_EQ(TWCoinTypeConfigurationGetDecimals(coin), 18); + ASSERT_EQ(TWCoinTypeBlockchain(coin), TWBlockchainEthereum); + ASSERT_EQ(TWCoinTypeP2shPrefix(coin), 0x0); + ASSERT_EQ(TWCoinTypeStaticPrefix(coin), 0x0); + assertStringsEqual(chainId, "8453"); + assertStringsEqual(txUrl, "https://basescan.org/tx/0x4acb15506b7696a2dfac4258f3f86392b4b2b717a3f316a8aa78509b2c3b6ab4"); + assertStringsEqual(accUrl, "https://basescan.org/address/0xb8ff877ed78ba520ece21b1de7843a8a57ca47cb"); +} diff --git a/tests/chains/Bitcoin/TWBitcoinFeeTests.cpp b/tests/chains/Bitcoin/TWBitcoinFeeTests.cpp index 0692760478f..87fa9b584ac 100644 --- a/tests/chains/Bitcoin/TWBitcoinFeeTests.cpp +++ b/tests/chains/Bitcoin/TWBitcoinFeeTests.cpp @@ -11,17 +11,17 @@ namespace TW::Bitcoin { TEST(TWBitcoinFee, P2pkhFee) { - auto satVb = 10; + const auto satVb = STRING("10"); auto data = DATA("02000000017be4e642bb278018ab12277de9427773ad1c5f5b1d164a157e0d99aa48dc1c1e000000006a473044022078eda020d4b86fcb3af78ef919912e6d79b81164dbbb0b0b96da6ac58a2de4b102201a5fd8d48734d5a02371c4b5ee551a69dca3842edbf577d863cf8ae9fdbbd4590121036666dd712e05a487916384bfcd5973eb53e8038eccbbf97f7eed775b87389536ffffffff01c0aff629010000001976a9145eaaa4f458f9158f86afcba08dd7448d27045e3d88ac00000000"); - auto fee = TWBitcoinFeeCalculateFee(data.get(), satVb); - ASSERT_EQ(fee, 191 * satVb); + const auto fee = WRAPS(TWBitcoinFeeCalculateFee(data.get(), satVb.get())); + assertStringsEqual(fee, std::to_string(191UL * 10).c_str()); } TEST(TWBitcoinFee, P2wpkhFee) { - auto satVb = 12; + const auto satVb = STRING("12"); auto data = DATA("020000000111b9f62923af73e297abb69f749e7a1aa2735fbdfd32ac5f6aa89e5c96841c18000000006b483045022100df9ed0b662b759e68b89a42e7144cddf787782a7129d4df05642dd825930e6e6022051a08f577f11cc7390684bbad2951a6374072253ffcf2468d14035ed0d8cd6490121028d7dce6d72fb8f7af9566616c6436349c67ad379f2404dd66fe7085fe0fba28fffffffff01c0aff629010000001600140d0e1cec6c2babe8badde5e9b3dea667da90036d00000000"); - auto fee = TWBitcoinFeeCalculateFee(data.get(), satVb); - ASSERT_EQ(fee, 189 * satVb); + const auto fee = WRAPS(TWBitcoinFeeCalculateFee(data.get(), satVb.get())); + assertStringsEqual(fee, std::to_string(189UL * 12).c_str()); } // Metadata can be observed live on: @@ -31,10 +31,10 @@ TEST(TWBitcoinFee, P2wpkhFee) { // Size 235 Bytes // Weight 610 TEST(TWBitcoinFee, BRC20TransferCommitFee) { - auto satVb = 19; + const auto satVb = STRING("19"); auto data = DATA("02000000000101089098890d2653567b9e8df2d1fbe5c3c8bf1910ca7184e301db0ad3b495c88e0100000000ffffffff02581b000000000000225120e8b706a97732e705e22ae7710703e7f589ed13c636324461afa443016134cc051040000000000000160014e311b8d6ddff856ce8e9a4e03bc6d4fe5050a83d02483045022100a44aa28446a9a886b378a4a65e32ad9a3108870bd725dc6105160bed4f317097022069e9de36422e4ce2e42b39884aa5f626f8f94194d1013007d5a1ea9220a06dce0121030f209b6ada5edb42c77fd2bc64ad650ae38314c8f451f3e36d80bc8e26f132cb00000000"); - auto fee = TWBitcoinFeeCalculateFee(data.get(), satVb); - ASSERT_EQ(fee, 153 * satVb); // 153 = ceil(610/4) + const auto fee = WRAPS(TWBitcoinFeeCalculateFee(data.get(), satVb.get())); + assertStringsEqual(fee, std::to_string(153UL * 19).c_str()); // 153 = ceil(610/4) } } // namespace TW::Bitcoin diff --git a/tests/chains/Ethereum/AbiTests.cpp b/tests/chains/Ethereum/AbiTests.cpp index c1eceb2acf3..14e9e971fdb 100644 --- a/tests/chains/Ethereum/AbiTests.cpp +++ b/tests/chains/Ethereum/AbiTests.cpp @@ -856,7 +856,8 @@ TEST(EthereumAbi, DecodeArrayOfByteArray) { bool res = param.decode(encoded, offset); EXPECT_TRUE(res); EXPECT_EQ(2ul, param.getCount()); - EXPECT_EQ(7 * 32ul, offset); + // `size_of(array.len())` + `size_of(byte_array[0].len())` + `size_of(byte_array[1].len()) + EXPECT_EQ(3 * 32ul, offset); EXPECT_EQ(2ul, param.getVal().size()); } @@ -986,7 +987,8 @@ TEST(EthereumAbi, DecodeParamsMixed) { EXPECT_EQ(3, (std::dynamic_pointer_cast((std::dynamic_pointer_cast(p.getParam(1)))->getParam(2)))->getVal()); EXPECT_EQ(true, (std::dynamic_pointer_cast(p.getParam(2)))->getVal()); EXPECT_EQ("Hello", (std::dynamic_pointer_cast(p.getParam(3)))->getVal()); - EXPECT_EQ(13 * 32ul, offset); + // Offset of `ParamUInt256`, `ParamBool` static elements and sizes of `ParamArray`, `ParamBool`, `ParamByteArray`. + EXPECT_EQ(5 * 32ul, offset); } ///// Function encode & decode @@ -1113,7 +1115,8 @@ TEST(EthereumAbi, DecodeFunctionOutputCase2) { size_t offset = 0; bool res = func.decodeOutput(encoded, offset); EXPECT_TRUE(res); - EXPECT_EQ(128ul, offset); + // The offset should only be shifted by the size of the array. + EXPECT_EQ(32ul, offset); // new output values std::shared_ptr param; @@ -1185,7 +1188,8 @@ TEST(EthereumAbi, DecodeFunctionInputWithDynamicArgumentsCase1) { EXPECT_EQ(3ul, (std::dynamic_pointer_cast(param))->getCount()); EXPECT_EQ(uint256_t(1), (std::dynamic_pointer_cast((std::dynamic_pointer_cast(param))->getVal()[0]))->getVal()); EXPECT_EQ(uint256_t(3), (std::dynamic_pointer_cast((std::dynamic_pointer_cast(param))->getVal()[2]))->getVal()); - EXPECT_EQ(4 + 9 * 32ul, offset); + // Offset of `ParamBool` static element and sizes of `ParamByteArray`, `ParamArray` arrays. + EXPECT_EQ(4 + 3 * 32ul, offset); } TEST(EthereumAbi, DecodeFunctionInputWithDynamicArgumentsCase2) { @@ -1228,7 +1232,8 @@ TEST(EthereumAbi, DecodeFunctionInputWithDynamicArgumentsCase2) { EXPECT_EQ("31323334353637383930", hex((std::dynamic_pointer_cast(param))->getVal())); EXPECT_TRUE(func.getInParam(3, param)); EXPECT_EQ(std::string("Hello, world!"), (std::dynamic_pointer_cast(param))->getVal()); - EXPECT_EQ(4 + 9 * 32ul, offset); + // Offset of `ParamUInt256` static element and sizes of `ParamArray`, `ParamByteArrayFix`, `ParamString` dynamic arrays. + EXPECT_EQ(4 + 4 * 32ul, offset); } TEST(EthereumAbi, DecodeFunctionContractMulticall) { @@ -1271,7 +1276,8 @@ TEST(EthereumAbi, DecodeFunctionContractMulticall) { size_t offset = 0; bool res = func.decodeInput(encoded, offset); EXPECT_TRUE(res); - EXPECT_EQ(4 + 29 * 32ul, offset); + // The offset should only be shifted by the size of the array. + EXPECT_EQ(4 + 32ul, offset); } TEST(EthereumAbi, ParamFactoryMake) { diff --git a/tests/chains/Ethereum/BarzTests.cpp b/tests/chains/Ethereum/BarzTests.cpp index 7c6a5763d4d..842da520541 100644 --- a/tests/chains/Ethereum/BarzTests.cpp +++ b/tests/chains/Ethereum/BarzTests.cpp @@ -20,26 +20,47 @@ namespace TW::Barz::tests { // https://testnet.bscscan.com/tx/0x6c6e1fe81c722c0abce1856b9b4e078ab2cad06d51f2d1b04945e5ba2286d1b4 TEST(Barz, GetInitCode) { - // C++ const PublicKey& publicKey = PublicKey(parse_hex("0x04e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b02"), TWPublicKeyTypeNIST256p1Extended); + // C++ { const std::string& factoryAddress = "0x3fC708630d85A3B5ec217E53100eC2b735d4f800"; const std::string& verificationFacetAddress = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf"; + const auto salt = 0; - const auto& initCode = Barz::getInitCode(factoryAddress, publicKey, verificationFacetAddress); + const auto& initCode = Barz::getInitCode(factoryAddress, publicKey, verificationFacetAddress, salt); ASSERT_EQ(hexEncoded(initCode), "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000"); } + { + const std::string& factoryAddress = "0x3fC708630d85A3B5ec217E53100eC2b735d4f800"; + const std::string& verificationFacetAddress = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf"; + const auto salt = 1; + + const auto& initCode = Barz::getInitCode(factoryAddress, publicKey, verificationFacetAddress, salt); + ASSERT_EQ(hexEncoded(initCode), "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000"); + } + // C { const auto factoryAddress = STRING("0x3fC708630d85A3B5ec217E53100eC2b735d4f800"); const auto verificationFacetAddress = STRING("0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf"); + const auto salt = 0; - const auto& initCodeData = TWBarzGetInitCode(factoryAddress.get(), WRAP(TWPublicKey, new TWPublicKey{ TW::PublicKey(publicKey) }).get(), verificationFacetAddress.get()); + const auto& initCodeData = TWBarzGetInitCode(factoryAddress.get(), WRAP(TWPublicKey, new TWPublicKey{ TW::PublicKey(publicKey) }).get(), verificationFacetAddress.get(), salt); const auto& initCode = hexEncoded(*reinterpret_cast(WRAPD(initCodeData).get())); EXPECT_EQ(initCode, "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000"); } + + { + const auto factoryAddress = STRING("0x3fC708630d85A3B5ec217E53100eC2b735d4f800"); + const auto verificationFacetAddress = STRING("0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf"); + const auto salt = 1; + + const auto& initCodeData = TWBarzGetInitCode(factoryAddress.get(), WRAP(TWPublicKey, new TWPublicKey{ TW::PublicKey(publicKey) }).get(), verificationFacetAddress.get(), salt); + const auto& initCode = hexEncoded(*reinterpret_cast(WRAPD(initCodeData).get())); + EXPECT_EQ(initCode, "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000"); + } } TEST(Barz, GetCounterfactualAddress) { @@ -52,6 +73,7 @@ TEST(Barz, GetCounterfactualAddress) { input.set_default_fallback("0x22eB0720d9Fc4bC90BB812B309e939880B71c20d"); input.set_bytecode("0x608060405260405162003cc638038062003cc68339818101604052810190620000299190620019ad565b60008673ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b81526004016020604051808303816000875af115801562000079573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009f919062001aec565b9050600060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603620000fe576040517f5a5b4d3900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600267ffffffffffffffff8111156200011e576200011d6200196b565b5b6040519080825280602002602001820160405280156200015b57816020015b62000147620018ff565b8152602001906001900390816200013d5790505b5090506000600167ffffffffffffffff8111156200017e576200017d6200196b565b5b604051908082528060200260200182016040528015620001ad5781602001602082028036833780820191505090505b5090506000600167ffffffffffffffff811115620001d057620001cf6200196b565b5b604051908082528060200260200182016040528015620001ff5781602001602082028036833780820191505090505b509050631f931c1c60e01b8260008151811062000221576200022062001b21565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060405180606001604052808d73ffffffffffffffffffffffffffffffffffffffff16815260200160006002811115620002ab57620002aa62001b37565b5b81526020018381525083600081518110620002cb57620002ca62001b21565b5b60200260200101819052508381600081518110620002ee57620002ed62001b21565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060405180606001604052808b73ffffffffffffffffffffffffffffffffffffffff1681526020016000600281111562000378576200037762001b37565b5b8152602001828152508360018151811062000398576200039762001b21565b5b6020026020010181905250620003b9846200047e60201b620001671760201c565b6200046c838c8b8e8e8d8d8d8d604051602401620003de979695949392919062001b8c565b6040516020818303038152906040527f95a21aec000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050620004b060201b620001911760201c565b5050505050505050505050506200211f565b806200048f6200073460201b60201c565b60010160016101000a81548163ffffffff021916908360e01c021790555050565b60005b8351811015620006df576000848281518110620004d557620004d462001b21565b5b602002602001015160200151905060006002811115620004fa57620004f962001b37565b5b81600281111562000510576200050f62001b37565b5b0362000570576200056a85838151811062000530576200052f62001b21565b5b60200260200101516000015186848151811062000552576200055162001b21565b5b6020026020010151604001516200073960201b60201c565b620006c8565b6001600281111562000587576200058662001b37565b5b8160028111156200059d576200059c62001b37565b5b03620005fd57620005f7858381518110620005bd57620005bc62001b21565b5b602002602001015160000151868481518110620005df57620005de62001b21565b5b602002602001015160400151620009db60201b60201c565b620006c7565b60028081111562000613576200061262001b37565b5b81600281111562000629576200062862001b37565b5b0362000689576200068385838151811062000649576200064862001b21565b5b6020026020010151600001518684815181106200066b576200066a62001b21565b5b60200260200101516040015162000c8f60201b60201c565b620006c6565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006bd9062001be7565b60405180910390fd5b5b5b508080620006d69062001c61565b915050620004b3565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051620007159392919062001c82565b60405180910390a16200072f828262000e3760201b60201c565b505050565b600090565b600081511162000780576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007779062001d97565b60405180910390fd5b60006200079262000f6b60201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000806576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007fd9062001dfb565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036200087c576200087b828562000f9860201b60201c565b5b60005b8351811015620009d4576000848281518110620008a157620008a062001b21565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161462000998576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200098f9062001e5f565b60405180910390fd5b620009ac8583868a6200107c60201b60201c565b8380620009b99062001ec3565b94505050508080620009cb9062001c61565b9150506200087f565b5050505050565b600081511162000a22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a199062001d97565b60405180910390fd5b600062000a3462000f6b60201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000aa8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a9f9062001dfb565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff160362000b1e5762000b1d828562000f9860201b60201c565b5b60005b835181101562000c8857600084828151811062000b435762000b4262001b21565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000c39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000c309062001eef565b60405180910390fd5b62000c4c8582846200122960201b60201c565b62000c608583868a6200107c60201b60201c565b838062000c6d9062001ec3565b9450505050808062000c7f9062001c61565b91505062000b21565b5050505050565b600081511162000cd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000ccd9062001d97565b60405180910390fd5b600062000ce862000f6b60201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161462000d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d539062001f53565b60405180910390fd5b60005b825181101562000e3157600083828151811062000d815762000d8062001b21565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905062000e198482846200122960201b60201c565b5050808062000e289062001c61565b91505062000d5f565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16031562000f675762000e988260405180606001604052806028815260200162003c7a60289139620018aa60201b60201c565b6000808373ffffffffffffffffffffffffffffffffffffffff168360405162000ec2919062001fb7565b600060405180830381855af49150503d806000811462000eff576040519150601f19603f3d011682016040523d82523d6000602084013e62000f04565b606091505b50915091508162000f645760008151111562000f235780518082602001fd5b83836040517f192105d700000000000000000000000000000000000000000000000000000000815260040162000f5b92919062001fd7565b60405180910390fd5b50505b5050565b6000807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90508091505090565b62000fc38160405180606001604052806024815260200162003ca260249139620018aa60201b60201c565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036200129b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620012929062002003565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036200130c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013039062002067565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180549050620013e59190620020cb565b9050808214620015805760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106200144a576200144962001b21565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110620014c957620014c862001b21565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805480620015d757620015d6620020ec565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff0219169055505060008103620018a357600060018660020180549050620016c49190620020cb565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490508181146200180c57600087600201838154811062001732576200173162001b21565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508088600201838154811062001779576200177862001b21565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b86600201805480620018235762001822620020ec565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b9050600081118290620018f9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620018f0919062002102565b60405180910390fd5b50505050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600060028111156200193e576200193d62001b37565b5b8152602001606081525090565b60008151905060018060a01b03811681146200196657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620019a157808201518184015260208101905062001984565b50600083830152505050565b600080600080600080600080610100898b031215620019cb57600080fd5b620019d6896200194b565b9750620019e660208a016200194b565b9650620019f660408a016200194b565b955062001a0660608a016200194b565b945062001a1660808a016200194b565b935062001a2660a08a016200194b565b925062001a3660c08a016200194b565b915060e089015160018060401b038082111562001a5257600080fd5b818b0191508b601f83011262001a6757600080fd5b81518181111562001a7d5762001a7c6200196b565b5b601f1960405181603f83601f860116011681019150808210848311171562001aaa5762001aa96200196b565b5b816040528281528e602084870101111562001ac457600080fd5b62001ad783602083016020880162001981565b80955050505050509295985092959890939650565b60006020828403121562001aff57600080fd5b815163ffffffff60e01b8116811462001b1757600080fd5b8091505092915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60018060a01b03811682525050565b6000815180845262001b7681602086016020860162001981565b6020601f19601f83011685010191505092915050565b600060018060a01b03808a168352808916602084015280881660408401528087166060840152808616608084015280851660a08401525060e060c083015262001bd960e083018462001b5c565b905098975050505050505050565b60208152602760208201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560408201527f74416374696f6e0000000000000000000000000000000000000000000000000060608201526000608082019050919050565b634e487b7160e01b600052601160045260246000fd5b60008019820362001c775762001c7662001c4b565b5b600182019050919050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562001d6357607f198a8503018652815188850160018060a01b038251168652848201516003811062001cf157634e487b7160e01b600052602160045260246000fd5b80868801525060408083015192508a81880152508082518083528a880191508684019350600092505b8083101562001d465763ffffffff60e01b84511682528682019150868401935060018301925062001d1a565b508096505050508282019150828601955060018101905062001cab565b505062001d738189018b62001b4d565b50868103604088015262001d88818962001b5c565b95505050505050949350505050565b60208152602b60208201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660408201527f6163657420746f2063757400000000000000000000000000000000000000000060608201526000608082019050919050565b60208152602c60208201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260408201527f652061646472657373283029000000000000000000000000000000000000000060608201526000608082019050919050565b60208152603560208201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60408201527f6e207468617420616c726561647920657869737473000000000000000000000060608201526000608082019050919050565b600060018060601b0380831681810362001ee25762001ee162001c4b565b5b6001810192505050919050565b60208152603860208201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60408201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060608201526000608082019050919050565b60208152603660208201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260408201527f657373206d75737420626520616464726573732830290000000000000000000060608201526000608082019050919050565b6000825162001fcb81846020870162001981565b80830191505092915050565b60018060a01b038316815260406020820152600062001ffa604083018462001b5c565b90509392505050565b60208152603760208201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360408201527f74696f6e207468617420646f65736e277420657869737400000000000000000060608201526000608082019050919050565b60208152602e60208201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560408201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060608201526000608082019050919050565b6000828203905081811115620020e657620020e562001c4b565b5b92915050565b634e487b7160e01b600052603160045260246000fd5b60208152600062002117602083018462001b5c565b905092915050565b611b4b806200212f6000396000f3fe60806040523661000b57005b6000807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9050809150600082600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610141576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610138906114d3565b60405180910390fd5b3660008037600080366000845af43d6000803e8060008114610162573d6000f35b3d6000fd5b806101706103c0565b60010160016101000a81548163ffffffff021916908360e01c021790555050565b60005b83518110156103755760008482815181106101b2576101b1611510565b5b6020026020010151602001519050600060028111156101d4576101d3611526565b5b8160028111156101e7576101e6611526565b5b036102375761023285838151811061020257610201611510565b5b60200260200101516000015186848151811061022157610220611510565b5b6020026020010151604001516103c5565b610361565b6001600281111561024b5761024a611526565b5b81600281111561025e5761025d611526565b5b036102ae576102a985838151811061027957610278611510565b5b60200260200101516000015186848151811061029857610297611510565b5b60200260200101516040015161063c565b610360565b6002808111156102c1576102c0611526565b5b8160028111156102d4576102d3611526565b5b036103245761031f8583815181106102ef576102ee611510565b5b60200260200101516000015186848151811061030e5761030d611510565b5b6020026020010151604001516108bd565b61035f565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103569061153c565b60405180910390fd5b5b5b50808061036d906115b6565b915050610194565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738383836040516103a99392919061163b565b60405180910390a16103bb8282610a48565b505050565b600090565b6000815111610409576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040090611747565b60405180910390fd5b6000610413610b6a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610484576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047b906117ab565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16036104f1576104f08285610b97565b5b60005b835181101561063557600084828151811061051257610511611510565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610606576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105fd9061180f565b60405180910390fd5b6106128583868a610c72565b838061061d90611873565b9450505050808061062d906115b6565b9150506104f4565b5050505050565b6000815111610680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161067790611747565b60405180910390fd5b600061068a610b6a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036106fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106f2906117ab565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff1603610768576107678285610b97565b5b60005b83518110156108b657600084828151811061078957610788611510565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361087c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610873906118a2565b60405180910390fd5b610887858284610e1f565b6108938583868a610c72565b838061089e90611873565b945050505080806108ae906115b6565b91505061076b565b5050505050565b6000815111610901576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f890611747565b60405180910390fd5b600061090b610b6a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461097c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097390611906565b60405180910390fd5b60005b8251811015610a4257600083828151811061099d5761099c611510565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610a2d848284610e1f565b50508080610a3a906115b6565b91505061097f565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160315610b6657610a9f82604051806060016040528060288152602001611aca60289139611481565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610ac7919061196a565b600060405180830381855af49150503d8060008114610b02576040519150601f19603f3d011682016040523d82523d6000602084013e610b07565b606091505b509150915081610b6357600081511115610b245780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610b5a929190611988565b60405180910390fd5b50505b5050565b6000807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90508091505090565b610bb981604051806060016040528060248152602001611af260249139611481565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e85906119b2565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610efc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef390611a16565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000180549050610fd39190611a7a565b90508082146111675760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001828154811061103457611033611510565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000184815481106110b0576110af611510565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054806111bb576111ba611a98565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff021916905550506000810361147a576000600186600201805490506112a59190611a7a565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490508181146113e657600087600201838154811061130f5761130e611510565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508088600201838154811061135357611352611510565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b866002018054806113fa576113f9611a98565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b90506000811182906114cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c49190611aae565b60405180910390fd5b50505050565b602081526020808201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f7420657869737460408201526000606082019050919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60208152602760208201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560408201527f74416374696f6e0000000000000000000000000000000000000000000000000060608201526000608082019050919050565b634e487b7160e01b600052601160045260246000fd5b6000801982036115c9576115c86115a0565b5b600182019050919050565b60018060a01b03811682525050565b60005b838110156116015780820151818401526020810190506115e6565b50600083830152505050565b600081518084526116258160208601602086016115e3565b6020601f19601f83011685010191505092915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101561171757607f198a8503018652815188850160018060a01b03825116865284820151600381106116a857634e487b7160e01b600052602160045260246000fd5b80868801525060408083015192508a81880152508082518083528a880191508684019350600092505b808310156116fb5763ffffffff60e01b8451168252868201915086840193506001830192506116d1565b5080965050505082820191508286019550600181019050611664565b50506117258189018b6115d4565b508681036040880152611738818961160d565b95505050505050949350505050565b60208152602b60208201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660408201527f6163657420746f2063757400000000000000000000000000000000000000000060608201526000608082019050919050565b60208152602c60208201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260408201527f652061646472657373283029000000000000000000000000000000000000000060608201526000608082019050919050565b60208152603560208201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60408201527f6e207468617420616c726561647920657869737473000000000000000000000060608201526000608082019050919050565b60006bffffffffffffffffffffffff808316818103611895576118946115a0565b5b6001810192505050919050565b60208152603860208201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60408201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060608201526000608082019050919050565b60208152603660208201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260408201527f657373206d75737420626520616464726573732830290000000000000000000060608201526000608082019050919050565b6000825161197c8184602087016115e3565b80830191505092915050565b60018060a01b03831681526040602082015260006119a9604083018461160d565b90509392505050565b60208152603760208201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360408201527f74696f6e207468617420646f65736e277420657869737400000000000000000060608201526000608082019050919050565b60208152602e60208201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560408201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060608201526000608082019050919050565b6000828203905081811115611a9257611a916115a0565b5b92915050565b634e487b7160e01b600052603160045260246000fd5b602081526000611ac1602083018461160d565b90509291505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122045b771fb2128a1a34c5b052e9a86464933844b34929cf0d65bbea6a4e76e3b2764736f6c634300081200334c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465"); input.set_public_key("0xB5547FBdC56DCE45e1B8ef75569916D438e09c46"); + input.set_salt(0); // C++ { @@ -68,6 +90,33 @@ TEST(Barz, GetCounterfactualAddress) { } } +TEST(Barz, GetCounterfactualAddressNonZeroSalt) { + TW::Barz::Proto::ContractAddressInput input; + input.set_factory("0x96C489979E39F877BDb8637b75A25C1a5B2DE14C"); + input.set_account_facet("0xF6F5e5fC74905e65e3FF53c6BacEba8535dd14d1"); + input.set_verification_facet("0xaB84813cbf26Fd951CB3d7E33Dccb8995027e490"); + input.set_entry_point("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"); + input.set_facet_registry("0x9a95d201BB8F559771784D12c01F8084278c65E5"); + input.set_default_fallback("0x522cDc7558b5f798dF5D61AB09B6D95Ebd342EF9"); + input.set_bytecode("0x60806040526040516104c83803806104c883398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b6101b3806103156000396000f3fe60806040523661000b57005b600080356001600160e01b03191681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c806100cf576004838101546040516366ffd66360e11b81526000356001600160e01b031916928101929092526001600160a01b03169063cdffacc690602401602060405180830381865afa1580156100a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100cc919061014d565b90505b6001600160a01b0381166101295760405162461bcd60e51b815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e808015610148573d6000f35b3d6000fd5b60006020828403121561015f57600080fd5b81516001600160a01b038116811461017657600080fd5b939250505056fea2646970667358221220d35db061bb6ecdb7688c3674af669ce44d527cae4ded59214d06722d73da62be64736f6c63430008120033"); + input.set_public_key("0xB5547FBdC56DCE45e1B8ef75569916D438e09c46"); + input.set_salt(123456); + + // C++ + { + const std::string& address = getCounterfactualAddress(input); + ASSERT_EQ(address, "0xB91aaa96B138A1B1D94c9df4628187132c5F2bf1"); + } + + // C + { + const auto inputData = input.SerializeAsString(); + const auto inputTWData = WRAPD(TWDataCreateWithBytes((const uint8_t *)inputData.data(), inputData.size())); + const auto& result = WRAPS(TWBarzGetCounterfactualAddress(inputTWData.get())); + assertStringsEqual(result, "0xB91aaa96B138A1B1D94c9df4628187132c5F2bf1"); + } +} + TEST(Barz, GetFormattedSignature) { // C++ { @@ -157,7 +206,8 @@ TEST(Barz, SignR1TransferAccountNotDeployed) { auto factory = "0x3fC708630d85A3B5ec217E53100eC2b735d4f800"; auto verificationFacet = "0x5034534Efe9902779eD6eA6983F435c00f3bc510"; auto publicKey = PublicKey(parse_hex("0x04b173a6a812025c40c38bac46343646bd0a8137c807aae6e04aac238cc24d2ad2116ca14d23d357588ff2aabd7db29d5976f4ecc8037775db86f67e873a306b1f"), TWPublicKeyTypeNIST256p1Extended); - auto initCode = Barz::getInitCode(factory, publicKey, verificationFacet); + auto salt = 0; + auto initCode = Barz::getInitCode(factory, publicKey, verificationFacet, salt); auto key = parse_hex("0x3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483"); diff --git a/tests/chains/Ethereum/ContractCallTests.cpp b/tests/chains/Ethereum/ContractCallTests.cpp index ca3108d4a05..19af2d14dbf 100644 --- a/tests/chains/Ethereum/ContractCallTests.cpp +++ b/tests/chains/Ethereum/ContractCallTests.cpp @@ -217,4 +217,18 @@ TEST(ContractCall, TupleNested) { EXPECT_EQ(decoded.value(), expected); } +TEST(ContractCall, TupleArray) { + auto abiPath = TESTS_ROOT + "/chains/Ethereum/Data/swap_v2.json"; + auto decodedPath = TESTS_ROOT + "/chains/Ethereum/Data/swap_v2_decoded.json"; + auto abi = load_json(abiPath); + auto expectedJson = load_json(decodedPath); + + auto call = parse_hex("846a1bc6000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000740000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000820000000000000000000000000a140f413c63fbda84e9008607e678258fffbc76b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000044095ea7b300000000000000000000000099a58482bd75cbab83b27ec03ca68ff489b5788f00000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099a58482bd75cbab83b27ec03ca68ff489b5788f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000003840651cb35000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000bebc44782c7db0a1a60cb6fe97d0b483032ff1c7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000298ce42936ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d66600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000762696e616e636500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a307863653136463639333735353230616230313337376365374238386635424138433438463844363636000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a140f413c63fbda84e9008607e678258fffbc76b000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf300000000000000000000000000000000000000000000000000000000000000010000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000044095ea7b30000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf3000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000104414bf3890000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf300000000000000000000000055d398326f99059ff775485246999027b319795500000000000000000000000000000000000000000000000000000000000000640000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd300000000000000000000000000000000000000000000000000000189c04a7044000000000000000000000000000000000000000000000000000029a23529cf68000000000000000000000000000000000000000000005af4f3f913bd553d03b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf30000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000100000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000044095ea7b30000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000104414bf38900000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00000000000000000000000000000000000000000000000000000000000001f40000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd300000000000000000000000000000000000000000000000000000189c04a7045000000000000000000000000000000000000000000005b527785e694f805bdd300000000000000000000000000000000000000000000005f935a1fa5c4a6ec61000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000055d398326f99059ff775485246999027b319795500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000242e1a7d4d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a140f413c63fbda84e9008607e678258fffbc76b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + auto decoded = decodeCall(call, abi); + ASSERT_TRUE(decoded.has_value()); + + nlohmann::json parsedJson = nlohmann::json::parse(decoded.value()); + EXPECT_EQ(parsedJson, expectedJson); +} + } // namespace TW::Ethereum::ABI::tests diff --git a/tests/chains/Ethereum/Data/swap_v2.json b/tests/chains/Ethereum/Data/swap_v2.json new file mode 100644 index 00000000000..3651cd7b1ac --- /dev/null +++ b/tests/chains/Ethereum/Data/swap_v2.json @@ -0,0 +1,70 @@ +{ + "846a1bc6":{ + "inputs":[ + { + "name":"token", + "type":"address" + }, + { + "name":"amount", + "type":"uint256" + }, + { + "components":[ + { + "name":"callType", + "type":"uint8" + }, + { + "name":"target", + "type":"address" + }, + { + "name":"value", + "type":"uint256" + }, + { + "name":"callData", + "type":"bytes" + }, + { + "name":"payload", + "type":"bytes" + } + ], + "name":"calls", + "type":"tuple[]" + }, + { + "name":"bridgedTokenSymbol", + "type":"string" + }, + { + "name":"destinationChain", + "type":"string" + }, + { + "name":"destinationAddress", + "type":"string" + }, + { + "name":"payload", + "type":"bytes" + }, + { + "name":"gasRefundRecipient", + "type":"address" + }, + { + "name":"enableExpress", + "type":"bool" + } + ], + "name":"callBridgeCall", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + } +} \ No newline at end of file diff --git a/tests/chains/Ethereum/Data/swap_v2_decoded.json b/tests/chains/Ethereum/Data/swap_v2_decoded.json new file mode 100644 index 00000000000..49a95d7806e --- /dev/null +++ b/tests/chains/Ethereum/Data/swap_v2_decoded.json @@ -0,0 +1,105 @@ +{ + "function": "callBridgeCall(address,uint256,(uint8,address,uint256,bytes,bytes)[],string,string,string,bytes,address,bool)", + "inputs": [ + { + "name": "token", + "type": "address", + "value": "0xdac17f958d2ee523a2206206994597c13d831ec7" + }, + { + "name": "amount", + "type": "uint256", + "value": "20000000000000000" + }, + { + "components": [ + [ + { + "name": "callType", + "type": "uint8", + "value": "0" + }, + { + "name": "target", + "type": "address", + "value": "0xdac17f958d2ee523a2206206994597c13d831ec7" + }, + { + "name": "value", + "type": "uint256", + "value": "0" + }, + { + "name": "callData", + "type": "bytes", + "value": "0x095ea7b300000000000000000000000099a58482bd75cbab83b27ec03ca68ff489b5788f00000000000000000000000000000000000000000000000000470de4df820000" + }, + { + "name": "payload", + "type": "bytes", + "value": "0x" + } + ], + [ + { + "name": "callType", + "type": "uint8", + "value": "0" + }, + { + "name": "target", + "type": "address", + "value": "0x99a58482bd75cbab83b27ec03ca68ff489b5788f" + }, + { + "name": "value", + "type": "uint256", + "value": "0" + }, + { + "name": "callData", + "type": "bytes", + "value": "0x0651cb35000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000bebc44782c7db0a1a60cb6fe97d0b483032ff1c7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000298ce42936ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666" + }, + { + "name": "payload", + "type": "bytes", + "value": "0x" + } + ] + ], + "name": "calls", + "type": "tuple[]" + }, + { + "name": "bridgedTokenSymbol", + "type": "string", + "value": "USDC" + }, + { + "name": "destinationChain", + "type": "string", + "value": "binance" + }, + { + "name": "destinationAddress", + "type": "string", + "value": "0xce16F69375520ab01377ce7B88f5BA8C48F8D666" + }, + { + "name": "payload", + "type": "bytes", + "value": "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a140f413c63fbda84e9008607e678258fffbc76b000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000ac000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf300000000000000000000000000000000000000000000000000000000000000010000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000044095ea7b30000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb1400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf3000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000104414bf3890000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf300000000000000000000000055d398326f99059ff775485246999027b319795500000000000000000000000000000000000000000000000000000000000000640000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd300000000000000000000000000000000000000000000000000000189c04a7044000000000000000000000000000000000000000000000000000029a23529cf68000000000000000000000000000000000000000000005af4f3f913bd553d03b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf30000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000100000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000044095ea7b30000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb14000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000104414bf38900000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00000000000000000000000000000000000000000000000000000000000001f40000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd300000000000000000000000000000000000000000000000000000189c04a7045000000000000000000000000000000000000000000005b527785e694f805bdd300000000000000000000000000000000000000000000005f935a1fa5c4a6ec61000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000055d398326f99059ff775485246999027b319795500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000242e1a7d4d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a140f413c63fbda84e9008607e678258fffbc76b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "name": "gasRefundRecipient", + "type": "address", + "value": "0xa140f413c63fbda84e9008607e678258fffbc76b" + }, + { + "name": "enableExpress", + "type": "bool", + "value": true + } + ] +} \ No newline at end of file diff --git a/tests/common/CoinAddressDerivationTests.cpp b/tests/common/CoinAddressDerivationTests.cpp index ac948f7aa11..0a242324f7c 100644 --- a/tests/common/CoinAddressDerivationTests.cpp +++ b/tests/common/CoinAddressDerivationTests.cpp @@ -78,6 +78,7 @@ TEST(Coin, DeriveAddress) { case TWCoinTypeScroll: case TWCoinTypeOpBNBtestnet: case TWCoinTypeNeon: + case TWCoinTypeBase: EXPECT_EQ(address, "0x9d8A62f656a8d1615C1294fd71e9CFb3E4855A4F"); break; diff --git a/wasm/tests/Blockchain/Bitcoin.test.ts b/wasm/tests/Blockchain/Bitcoin.test.ts index d516512bb54..270f774d86f 100644 --- a/wasm/tests/Blockchain/Bitcoin.test.ts +++ b/wasm/tests/Blockchain/Bitcoin.test.ts @@ -202,4 +202,14 @@ describe("Bitcoin", () => { assert.isTrue(outputHex.endsWith("5b0063036f7264010118746578742f706c61696e3b636861727365743d7574662d3800377b2270223a226272632d3230222c226f70223a227472616e73666572222c227469636b223a226f616466222c22616d74223a223230227d6821c00f209b6ada5edb42c77fd2bc64ad650ae38314c8f451f3e36d80bc8e26f132cb00000000")) assert.equal(output.transactionId, "7046dc2689a27e143ea2ad1039710885147e9485ab6453fa7e87464aa7dd3eca"); }); + + it("test Bitcoin calculate BRC20 Commit fee", () => { + const { BitcoinFee, HexCoding } = globalThis.core; + + const rawTx = HexCoding.decode("02000000000101089098890d2653567b9e8df2d1fbe5c3c8bf1910ca7184e301db0ad3b495c88e0100000000ffffffff02581b000000000000225120e8b706a97732e705e22ae7710703e7f589ed13c636324461afa443016134cc051040000000000000160014e311b8d6ddff856ce8e9a4e03bc6d4fe5050a83d02483045022100a44aa28446a9a886b378a4a65e32ad9a3108870bd725dc6105160bed4f317097022069e9de36422e4ce2e42b39884aa5f626f8f94194d1013007d5a1ea9220a06dce0121030f209b6ada5edb42c77fd2bc64ad650ae38314c8f451f3e36d80bc8e26f132cb00000000"); + const satVb = "19"; + + const fee = BitcoinFee.calculateFee(rawTx, satVb); + assert.equal(fee, "2907") // 19*153 + }); });