Skip to content

Commit d88a263

Browse files
authored
Support calculating the TX hash of a transaction (#4008)
* Support calculating the TX hash of a transaction * Implement the calc_tx_hash for TON/Aptos/Sui * Adjust the code according to the comments * Refactor the calcTxHash for Solana * Format rust code using `cargo fmt` * Change UtxoTransactionUtil to BitcoinTransactionUtil * Add some comments * Adjust the code according to the comments * Add more test cases * Fix issue found by `cargo clippy`
1 parent 136506f commit d88a263

File tree

58 files changed

+658
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+658
-2
lines changed

codegen-v2/src/codegen/rust/templates/blockchain_crate/entry.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use tw_coin_entry::modules::json_signer::NoJsonSigner;
1414
use tw_coin_entry::modules::message_signer::NoMessageSigner;
1515
use tw_coin_entry::modules::plan_builder::NoPlanBuilder;
1616
use tw_coin_entry::modules::transaction_decoder::NoTransactionDecoder;
17+
use tw_coin_entry::modules::transaction_util::NoTransactionUtil;
1718
use tw_coin_entry::modules::wallet_connector::NoWalletConnector;
1819
use tw_coin_entry::prefix::NoPrefix;
1920
use tw_keypair::tw::PublicKey;
@@ -35,6 +36,7 @@ impl CoinEntry for {BLOCKCHAIN}Entry {
3536
type MessageSigner = NoMessageSigner;
3637
type WalletConnector = NoWalletConnector;
3738
type TransactionDecoder = NoTransactionDecoder;
39+
type TransactionUtil = NoTransactionUtil;
3840

3941
#[inline]
4042
fn parse_address(
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// Copyright © 2017 Trust Wallet.
4+
5+
#pragma once
6+
7+
#include "TWBase.h"
8+
#include "TWCoinType.h"
9+
#include "TWData.h"
10+
11+
TW_EXTERN_C_BEGIN
12+
13+
TW_EXPORT_STRUCT
14+
struct TWTransactionUtil;
15+
16+
/// Calculate the TX hash of a transaction.
17+
///
18+
/// \param coin coin type.
19+
/// \param encodedTx encoded transaction data.
20+
/// \return The TX hash of a transaction, If the input is invalid or the chain is unsupported, null is returned.
21+
TW_EXPORT_STATIC_METHOD
22+
TWString* _Nullable TWTransactionUtilCalcTxHash(enum TWCoinType coinType, TWString* _Nonnull encodedTx);
23+
24+
TW_EXTERN_C_END

rust/chains/tw_aptos/src/entry.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use crate::address::Address;
66
use crate::compiler::Compiler;
7+
use crate::modules::transaction_util::AptosTransactionUtil;
78
use crate::signer::Signer;
89
use std::str::FromStr;
910
use tw_coin_entry::coin_context::CoinContext;
@@ -35,6 +36,7 @@ impl CoinEntry for AptosEntry {
3536
type MessageSigner = NoMessageSigner;
3637
type WalletConnector = NoWalletConnector;
3738
type TransactionDecoder = NoTransactionDecoder;
39+
type TransactionUtil = AptosTransactionUtil;
3840

3941
#[inline]
4042
fn parse_address(
@@ -102,4 +104,9 @@ impl CoinEntry for AptosEntry {
102104
fn message_signer(&self) -> Option<Self::MessageSigner> {
103105
None
104106
}
107+
108+
#[inline]
109+
fn transaction_util(&self) -> Option<Self::TransactionUtil> {
110+
Some(AptosTransactionUtil)
111+
}
105112
}

rust/chains/tw_aptos/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub mod nft;
1212

1313
pub mod compiler;
1414
pub mod liquid_staking;
15+
pub mod modules;
1516
pub mod signer;
1617
pub mod transaction;
1718
pub mod transaction_builder;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// Copyright © 2017 Trust Wallet.
4+
5+
pub mod transaction_util;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// Copyright © 2017 Trust Wallet.
4+
5+
use tw_coin_entry::coin_context::CoinContext;
6+
use tw_coin_entry::error::prelude::*;
7+
use tw_coin_entry::modules::transaction_util::TransactionUtil;
8+
use tw_encoding::hex;
9+
use tw_hash::sha3::sha3_256;
10+
11+
pub struct AptosTransactionUtil;
12+
13+
impl TransactionUtil for AptosTransactionUtil {
14+
fn calc_tx_hash(&self, coin: &dyn CoinContext, encoded_tx: &str) -> SigningResult<String> {
15+
Self::calc_tx_hash_impl(coin, encoded_tx)
16+
}
17+
}
18+
19+
impl AptosTransactionUtil {
20+
fn calc_tx_hash_impl(_coin: &dyn CoinContext, encoded_tx: &str) -> SigningResult<String> {
21+
let txn_bytes = hex::decode(encoded_tx).map_err(|_| SigningErrorType::Error_input_parse)?;
22+
23+
// See: https://github.com/aptos-labs/aptos-ts-sdk/blob/f54cac824a41e41dea09c7a6916858a8604dc901/src/api/transaction.ts#L118
24+
let prefix = sha3_256("APTOS::Transaction".as_bytes());
25+
26+
let mut hash_message = Vec::new();
27+
hash_message.extend_from_slice(&prefix);
28+
// 0 is the index of the enum `Transaction`, see: https://github.com/aptos-labs/aptos-core/blob/6a130c1cca274a5cfdb4a65b441cd5fe61b6c15b/types/src/transaction/mod.rs#L1939
29+
hash_message.push(0);
30+
hash_message.extend_from_slice(&txn_bytes);
31+
32+
let tx_hash = sha3_256(&hash_message);
33+
Ok(hex::encode(tx_hash, true))
34+
}
35+
}

rust/chains/tw_binance/src/entry.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use tw_coin_entry::modules::json_signer::NoJsonSigner;
1616
use tw_coin_entry::modules::message_signer::NoMessageSigner;
1717
use tw_coin_entry::modules::plan_builder::NoPlanBuilder;
1818
use tw_coin_entry::modules::transaction_decoder::NoTransactionDecoder;
19+
use tw_coin_entry::modules::transaction_util::NoTransactionUtil;
1920
use tw_keypair::tw::PublicKey;
2021
use tw_proto::Binance::Proto;
2122
use tw_proto::TxCompiler::Proto as CompilerProto;
@@ -35,6 +36,7 @@ impl CoinEntry for BinanceEntry {
3536
type MessageSigner = NoMessageSigner;
3637
type WalletConnector = BinanceWalletConnector;
3738
type TransactionDecoder = NoTransactionDecoder;
39+
type TransactionUtil = NoTransactionUtil;
3840

3941
#[inline]
4042
fn parse_address(

rust/chains/tw_cosmos/src/entry.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use tw_cosmos_sdk::address::{Address, Bech32Prefix};
1616
use tw_cosmos_sdk::context::StandardCosmosContext;
1717
use tw_cosmos_sdk::modules::compiler::tw_compiler::TWTransactionCompiler;
1818
use tw_cosmos_sdk::modules::signer::tw_signer::TWSigner;
19+
use tw_cosmos_sdk::modules::transaction_util::CosmosTransactionUtil;
1920
use tw_keypair::tw;
2021
use tw_proto::Cosmos::Proto;
2122
use tw_proto::TxCompiler::Proto as CompilerProto;
@@ -35,6 +36,7 @@ impl CoinEntry for CosmosEntry {
3536
type MessageSigner = NoMessageSigner;
3637
type WalletConnector = NoWalletConnector;
3738
type TransactionDecoder = NoTransactionDecoder;
39+
type TransactionUtil = CosmosTransactionUtil<StandardCosmosContext>;
3840

3941
#[inline]
4042
fn parse_address(
@@ -95,4 +97,9 @@ impl CoinEntry for CosmosEntry {
9597
public_keys,
9698
)
9799
}
100+
101+
#[inline]
102+
fn transaction_util(&self) -> Option<Self::TransactionUtil> {
103+
Some(CosmosTransactionUtil::<StandardCosmosContext>::default())
104+
}
98105
}

rust/chains/tw_ethereum/src/entry.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use tw_evm::evm_entry::EvmEntry;
1818
use tw_evm::modules::compiler::Compiler;
1919
use tw_evm::modules::message_signer::EthMessageSigner;
2020
use tw_evm::modules::signer::Signer;
21+
use tw_evm::modules::transaction_util::EvmTransactionUtil;
2122
use tw_keypair::tw::PublicKey;
2223
use tw_proto::Ethereum::Proto;
2324
use tw_proto::TxCompiler::Proto as CompilerProto;
@@ -37,6 +38,7 @@ impl CoinEntry for EthereumEntry {
3738
type MessageSigner = EthMessageSigner;
3839
type WalletConnector = NoWalletConnector;
3940
type TransactionDecoder = NoTransactionDecoder;
41+
type TransactionUtil = EvmTransactionUtil;
4042

4143
#[inline]
4244
fn parse_address(
@@ -100,6 +102,11 @@ impl CoinEntry for EthereumEntry {
100102
fn message_signer(&self) -> Option<Self::MessageSigner> {
101103
Some(EthMessageSigner)
102104
}
105+
106+
#[inline]
107+
fn transaction_util(&self) -> Option<Self::TransactionUtil> {
108+
Some(EvmTransactionUtil)
109+
}
103110
}
104111

105112
impl EvmEntry for EthereumEntry {

rust/chains/tw_greenfield/src/entry.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use tw_coin_entry::modules::json_signer::NoJsonSigner;
1414
use tw_coin_entry::modules::message_signer::NoMessageSigner;
1515
use tw_coin_entry::modules::plan_builder::NoPlanBuilder;
1616
use tw_coin_entry::modules::transaction_decoder::NoTransactionDecoder;
17+
use tw_coin_entry::modules::transaction_util::NoTransactionUtil;
1718
use tw_coin_entry::modules::wallet_connector::NoWalletConnector;
1819
use tw_coin_entry::prefix::NoPrefix;
1920
use tw_keypair::tw::PublicKey;
@@ -35,6 +36,7 @@ impl CoinEntry for GreenfieldEntry {
3536
type MessageSigner = NoMessageSigner;
3637
type WalletConnector = NoWalletConnector;
3738
type TransactionDecoder = NoTransactionDecoder;
39+
type TransactionUtil = NoTransactionUtil;
3840

3941
#[inline]
4042
fn parse_address(

0 commit comments

Comments
 (0)