cpchain_rust_sdk/
types.rs1use rlp::RlpStream;
2use serde::{Deserialize, Serialize};
3use web3::{signing::{self, Signature}, types::{SignedTransaction, CallRequest}};
4
5pub type Result = web3::Result;
6pub type U256 = web3::types::U256;
7pub type U128 = web3::types::U128;
8pub type U64 = web3::types::U64;
9pub type H160 = web3::types::H160;
10pub type H256 = web3::types::H256;
11pub type Bytes = web3::types::Bytes;
12pub type Options = web3::contract::Options;
13pub type Transaction = web3::types::Transaction;
14pub type TransactionReceipt = web3::types::TransactionReceipt;
15pub type TransactionLog = web3::types::Log;
16pub type BlockWithHash = web3::types::Block<H256>;
17pub type BlockWithTx = web3::types::Block<Transaction>;
18
19#[derive(Debug, Clone, Deserialize, Serialize)]
20pub struct TransactionParameters {
21 #[serde(rename="type")]
23 pub tx_type: U256,
24 pub nonce: U256,
26 pub to: Option<H160>,
28 pub gas: U256,
30 #[serde(rename="gasPrice")]
32 pub gas_price: U256,
33 pub value: U256,
35 pub data: Bytes,
37 pub chain_id: u64,
39}
40
41impl TransactionParameters {
42 pub fn new(
43 chain_id: u64,
44 nonce: U256,
45 to: Option<H160>,
46 gas: U256,
47 gas_price: U256,
48 value: U256,
49 data: Bytes,
50 ) -> TransactionParameters {
51 Self {
52 nonce,
53 to,
54 gas,
55 gas_price,
56 value,
57 data,
58 chain_id,
59 tx_type: U256::from(0)
60 }
61 }
62 pub fn to_call_request(&self) -> CallRequest {
63 CallRequest {
64 from: None,
65 to: self.to,
66 gas: None,
67 gas_price: Some(self.gas_price),
68 value: Some(self.value),
69 data: Some(self.data.clone()),
70 transaction_type: None,
71 access_list: None,
72 max_fee_per_gas: None,
73 max_priority_fee_per_gas: None,
74 }
75 }
76 fn rlp_append_legacy(&self, stream: &mut RlpStream) {
77 stream.append(&self.tx_type);
79 stream.append(&self.nonce);
80 stream.append(&self.gas_price);
81 stream.append(&self.gas);
82 if let Some(to) = self.to {
83 stream.append(&to);
84 } else {
85 stream.append(&"");
86 }
87 stream.append(&self.value);
88 stream.append(&self.data.0);
89 }
90 fn rlp_append_signature(&self, stream: &mut RlpStream, signature: &Signature) {
91 stream.append(&signature.v);
92 stream.append(&U256::from_big_endian(signature.r.as_bytes()));
93 stream.append(&U256::from_big_endian(signature.s.as_bytes()));
94 }
95 fn encode(&self, chain_id: u64, signature: Option<&Signature>) -> RlpStream {
96 let mut stream = RlpStream::new();
97 stream.begin_list(10);
98
99 self.rlp_append_legacy(&mut stream);
100
101 if let Some(signature) = signature {
102 self.rlp_append_signature(&mut stream, signature);
103 } else {
104 stream.append(&chain_id);
105 stream.append(&0u8);
106 stream.append(&0u8);
107 }
108 stream
109 }
110 pub fn sign(&self, sign: impl signing::Key) -> SignedTransaction {
111 let encoded = self.encode(self.chain_id, None).out().to_vec();
112
113 let hash = signing::keccak256(encoded.as_ref());
114
115 let signature = sign.sign(&hash, Some(self.chain_id)).expect("hash is non-zero 32-bytes; qed");
116
117 let signed = self.encode(self.chain_id, Some(&signature)).out().to_vec();
118 let transaction_hash = signing::keccak256(signed.as_ref()).into();
119
120 SignedTransaction {
121 message_hash: hash.into(),
122 v: signature.v,
123 r: signature.r,
124 s: signature.s,
125 raw_transaction: signed.into(),
126 transaction_hash,
127 }
128 }
129}