anychain_core/
transaction.rs

1use {
2    crate::{
3        address::{Address, AddressError},
4        amount::AmountError,
5        format::Format,
6        no_std::{
7            fmt::{Debug, Display},
8            hash::Hash,
9            String, Vec,
10        },
11        public_key::PublicKey,
12        utilities::crypto::keccak256,
13    },
14    thiserror::Error,
15};
16
17/**
18 * 返回合约函数签名,取keccak256 hash值的前4个Bytes
19 */
20pub fn func_selector(func_signature: &str) -> [u8; 4] {
21    let mut func_id = [0u8; 4];
22    func_id.clone_from_slice(&keccak256(func_signature.as_bytes())[..4]);
23    func_id
24}
25
26/// The interface for a generic transaction id.
27pub trait TransactionId:
28    Clone + Debug + Display + Send + Sync + 'static + Eq + Sized + Hash
29{
30}
31
32/// The interface for a generic transactions.
33pub trait Transaction: Clone + Send + Sync + 'static {
34    type Address: Address;
35    type Format: Format;
36    type PublicKey: PublicKey;
37    type TransactionId: TransactionId;
38    type TransactionParameters;
39
40    /// Returns an unsigned transaction given the transaction parameters.
41    fn new(parameters: &Self::TransactionParameters) -> Result<Self, TransactionError>;
42
43    /// Returns a signed transaction bytes given the (signature,recovery_id)
44    fn sign(&mut self, signature: Vec<u8>, recid: u8) -> Result<Vec<u8>, TransactionError>;
45
46    /// Returns a transaction given the transaction bytes.
47    fn from_bytes(transaction: &[u8]) -> Result<Self, TransactionError>;
48
49    /// Returns the transaction in bytes.
50    fn to_bytes(&self) -> Result<Vec<u8>, TransactionError>;
51
52    /// Returns the transaction id.
53    fn to_transaction_id(&self) -> Result<Self::TransactionId, TransactionError>;
54}
55
56#[derive(Debug, Error)]
57pub enum TransactionError {
58    #[error("{0}")]
59    AddressError(#[from] AddressError),
60
61    #[error("{0}")]
62    AmountError(#[from] AmountError),
63
64    #[error("witnesses have a conflicting anchor")]
65    ConflictingWitnessAnchors(),
66
67    #[error("{0}: {1}")]
68    Crate(&'static str, String),
69
70    #[error("Failed note decryption for enc_cyphertext: {0}")]
71    FailedNoteDecryption(String),
72
73    #[error("invalid binding signature for the transaction")]
74    InvalidBindingSig(),
75
76    #[error("invalid chain id {0}")]
77    InvalidChainId(u8),
78
79    #[error("invalid ephemeral key {0}")]
80    InvalidEphemeralKey(String),
81
82    #[error("insufficient information to craft transaction. missing: {0}")]
83    InvalidInputs(String),
84
85    #[error("invalid output address: {0}")]
86    InvalidOutputAddress(String),
87
88    #[error("invalid ouptut description for address: {0}")]
89    InvalidOutputDescription(String),
90
91    #[error("invalid transaction RLP length: expected - 9, found - {0}")]
92    InvalidRlpLength(usize),
93
94    #[error("invalid script pub key for format: {0}")]
95    InvalidScriptPubKey(String),
96
97    #[error("invalid segwit flag: {0}")]
98    InvalidSegwitFlag(usize),
99
100    #[error("invalid spend description for address")]
101    InvalidSpendDescription,
102
103    #[error("invalid transaction id {0}")]
104    InvalidTransactionId(usize),
105
106    #[error(
107        "invalid transaction - either both sender and signature should be present, or neither"
108    )]
109    InvalidTransactionState,
110
111    #[error("invalid variable size integer: {0}")]
112    InvalidVariableSizeInteger(usize),
113
114    #[error("{0}")]
115    Message(String),
116
117    #[error("missing diversifier, check that the address is a Sapling address")]
118    MissingDiversifier,
119
120    #[error("missing outpoint address")]
121    MissingOutpointAddress,
122
123    #[error("missing outpoint amount")]
124    MissingOutpointAmount,
125
126    #[error("missing outpoint script public key")]
127    MissingOutpointScriptPublicKey,
128
129    #[error("missing output parameters")]
130    MissingOutputParameters,
131
132    #[error("missing spend description")]
133    MissingSpendDescription,
134
135    #[error("missing spend parameters")]
136    MissingSpendParameters,
137
138    #[error("missing signature")]
139    MissingSignature,
140
141    #[error("Null Error")]
142    NullError(()),
143
144    #[error("Joinsplits are not supported")]
145    UnsupportedJoinsplits,
146
147    #[error("unsupported preimage operation on address format of {0}")]
148    UnsupportedPreimage(String),
149
150    #[error("Reaching end of Ripple SerializedType 'Object'")]
151    EndOfObject,
152
153    #[error("Reaching end of Ripple SerializedType 'Array'")]
154    EndOfArray,
155}
156
157impl From<crate::no_std::io::Error> for TransactionError {
158    fn from(error: crate::no_std::io::Error) -> Self {
159        TransactionError::Crate("crate::no_std::io", format!("{:?}", error))
160    }
161}
162
163impl From<&'static str> for TransactionError {
164    fn from(msg: &'static str) -> Self {
165        TransactionError::Message(msg.into())
166    }
167}
168
169impl From<()> for TransactionError {
170    fn from(error: ()) -> Self {
171        TransactionError::NullError(error)
172    }
173}
174
175impl From<base58::FromBase58Error> for TransactionError {
176    fn from(error: base58::FromBase58Error) -> Self {
177        TransactionError::Crate("base58", format!("{:?}", error))
178    }
179}
180
181impl From<bech32::Error> for TransactionError {
182    fn from(error: bech32::Error) -> Self {
183        TransactionError::Crate("bech32", format!("{:?}", error))
184    }
185}
186
187impl From<core::num::ParseIntError> for TransactionError {
188    fn from(error: core::num::ParseIntError) -> Self {
189        TransactionError::Crate("core::num", format!("{:?}", error))
190    }
191}
192
193impl From<core::str::ParseBoolError> for TransactionError {
194    fn from(error: core::str::ParseBoolError) -> Self {
195        TransactionError::Crate("core::str", format!("{:?}", error))
196    }
197}
198
199impl From<hex::FromHexError> for TransactionError {
200    fn from(error: hex::FromHexError) -> Self {
201        TransactionError::Crate("hex", format!("{:?}", error))
202    }
203}
204
205// impl From<rlp::DecoderError> for TransactionError {
206//     fn from(error: rlp::DecoderError) -> Self {
207//         TransactionError::Crate("rlp", format!("{:?}", error))
208//     }
209// }
210
211// impl From<libsecp256k1::Error> for TransactionError {
212//     fn from(error: libsecp256k1::Error) -> Self {
213//         TransactionError::Crate("libsecp256k1", format!("{:?}", error))
214//     }
215// }
216
217impl From<serde_json::error::Error> for TransactionError {
218    fn from(error: serde_json::error::Error) -> Self {
219        TransactionError::Crate("serde_json", format!("{:?}", error))
220    }
221}
222
223#[cfg(test)]
224mod tests {
225    use crate::func_selector;
226
227    #[test]
228    fn test_func_selector() {
229        let selector = func_selector("transfer(address,uint256)");
230        assert_eq!("a9059cbb", hex::encode(selector));
231    }
232}