Skip to content

Commit 881d3dd

Browse files
authored
Merge pull request #139 from bitfinity-network/more_eth_methods
Add eth_getCode method
2 parents bb97ffc + 5274955 commit 881d3dd

5 files changed

Lines changed: 171 additions & 179 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ include = ["src/**/*", "LICENSE", "README.md"]
2424
license = "MIT"
2525
name = "bitfinity-evm-sdk"
2626
repository = "https://github.com/bitfinity-network/bitfinity-evm-sdk"
27-
version = "0.13.0"
27+
version = "0.14.0"
2828

2929
[workspace.dependencies]
3030
alloy-primitives = { version = "0.6", default-feures = false }

src/ethereum-json-rpc-client/src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use anyhow::Context;
55
use did::certified::CertifiedResult;
66
use did::transaction::StorableExecutionResult;
77
use ethers_core::types::{
8-
Block, BlockNumber, Log, Transaction, TransactionReceipt, H160, H256, U256, U64,
8+
Block, BlockNumber, Log, Transaction, TransactionReceipt, TransactionRequest, H160, H256, U256,
9+
U64,
910
};
1011
use itertools::Itertools;
1112
use jsonrpc_core::{Call, Id, MethodCall, Output, Params, Request, Response, Version};
@@ -23,10 +24,12 @@ pub mod http_outcall;
2324

2425
const ETH_CHAIN_ID_METHOD: &str = "eth_chainId";
2526
const ETH_GET_BALANCE_METHOD: &str = "eth_getBalance";
27+
const ETH_GET_CODE_METHOD: &str = "eth_getCode";
2628
const ETH_GET_TRANSACTION_COUNT_METHOD: &str = "eth_getTransactionCount";
2729
const ETH_GET_BLOCK_BY_NUMBER_METHOD: &str = "eth_getBlockByNumber";
2830
const ETH_BLOCK_NUMBER_METHOD: &str = "eth_blockNumber";
2931
const ETH_GET_TRANSACTION_RECEIPT_METHOD: &str = "eth_getTransactionReceipt";
32+
const ETH_CALL_METHOD: &str = "eth_call";
3033
const ETH_SEND_RAW_TRANSACTION_METHOD: &str = "eth_sendRawTransaction";
3134
const ETH_GET_LOGS_METHOD: &str = "eth_getLogs";
3235
const IC_GET_TX_EXECUTION_RESULT_BY_HASH_METHOD: &str = "ic_getExeResultByHash";
@@ -162,6 +165,16 @@ impl<C: Client> EthJsonRpcClient<C> {
162165
.await
163166
}
164167

168+
/// Returns code of the given contract.
169+
pub async fn get_code(&self, address: H160, block: BlockNumber) -> anyhow::Result<String> {
170+
self.single_request(
171+
ETH_GET_CODE_METHOD.to_string(),
172+
make_params_array!(address, block),
173+
Id::Str("eth_getCode".to_string()),
174+
)
175+
.await
176+
}
177+
165178
/// Returns transaction count of the address.
166179
pub async fn get_transaction_count(
167180
&self,
@@ -177,12 +190,26 @@ impl<C: Client> EthJsonRpcClient<C> {
177190
.map(|v| v.as_u64())
178191
}
179192

193+
/// Performs eth call and return the result.
194+
pub async fn eth_call(
195+
&self,
196+
params: TransactionRequest,
197+
block: BlockNumber,
198+
) -> anyhow::Result<String> {
199+
self.single_request(
200+
ETH_CALL_METHOD.to_string(),
201+
make_params_array!(params, block),
202+
Id::Str("eth_call".to_string()),
203+
)
204+
.await
205+
}
206+
180207
/// Sends raw transaction and returns transaction hash
181208
pub async fn send_raw_transaction(&self, transaction: Transaction) -> anyhow::Result<H256> {
182209
let bytes = transaction.rlp();
183210
let transaction = format!("0x{}", hex::encode(bytes));
184211

185-
self.single_request::<H256>(
212+
self.single_request(
186213
ETH_SEND_RAW_TRANSACTION_METHOD.to_string(),
187214
make_params_array!(transaction),
188215
Id::Str(ETH_SEND_RAW_TRANSACTION_METHOD.to_string()),

src/ethereum-json-rpc-client/tests/reqwest/mod.rs

Lines changed: 130 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use ethereum_json_rpc_client::reqwest::ReqwestClient;
22
use ethereum_json_rpc_client::{EthGetLogsParams, EthJsonRpcClient};
3-
use ethers_core::types::{BlockNumber, Log, H256};
3+
use ethers_core::abi::{Function, Param, ParamType, StateMutability, Token};
4+
use ethers_core::types::{BlockNumber, Log, TransactionRequest, H160, H256};
45

56
const ETHEREUM_JSON_API_URL: &str = "https://cloudflare-eth.com/";
67
const MAX_BATCH_SIZE: usize = 5;
@@ -25,23 +26,94 @@ async fn should_get_block_number() {
2526

2627
#[tokio::test]
2728
async fn should_get_balance() {
28-
let erc_1820_address = "0xa990077c3205cbDf861e17Fa532eeB069cE9fF96"
29+
let erc_1820_deployer_address = "0xa990077c3205cbDf861e17Fa532eeB069cE9fF96"
2930
.parse()
3031
.unwrap();
3132
let result = reqwest_client()
32-
.get_balance(erc_1820_address, BlockNumber::Latest)
33+
.get_balance(erc_1820_deployer_address, BlockNumber::Latest)
3334
.await
3435
.unwrap();
3536
assert_eq!(result, 1409174700000000000u64.into());
3637
}
3738

39+
#[tokio::test]
40+
async fn should_get_code() {
41+
let erc_1820_address = "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24"
42+
.parse()
43+
.unwrap();
44+
let result = reqwest_client()
45+
.get_code(erc_1820_address, BlockNumber::Latest)
46+
.await
47+
.unwrap();
48+
assert_eq!(result, ERC_1820_EXPECTED_CODE);
49+
}
50+
51+
/// Calls the funtction of ERC-1820:
52+
///
53+
///```solidity
54+
/// function getManager(address _addr) public view returns(address)
55+
///```
56+
#[tokio::test]
57+
async fn should_perform_eth_call() {
58+
let erc_1820_address = "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24"
59+
.parse::<H160>()
60+
.unwrap();
61+
62+
let caller = "0xf990077c3205cbDf861e17Fa532eeB069cE9fF96"
63+
.parse()
64+
.unwrap();
65+
66+
#[allow(deprecated)]
67+
let func = Function {
68+
name: "getManager".to_string(),
69+
inputs: vec![Param {
70+
name: "getManager".to_string(),
71+
kind: ParamType::Address,
72+
internal_type: None,
73+
}],
74+
outputs: vec![Param {
75+
name: "".to_string(),
76+
kind: ParamType::Address,
77+
internal_type: None,
78+
}],
79+
constant: None,
80+
state_mutability: StateMutability::View,
81+
};
82+
83+
let params = TransactionRequest {
84+
from: Some(caller),
85+
to: Some(erc_1820_address.into()),
86+
gas: Some(1000000u64.into()),
87+
gas_price: None,
88+
value: None,
89+
data: Some(func.encode_input(&[Token::Address(caller)]).unwrap().into()),
90+
..Default::default()
91+
};
92+
93+
let result = reqwest_client()
94+
.eth_call(params, BlockNumber::Latest)
95+
.await
96+
.unwrap();
97+
98+
let result_address = func
99+
.decode_output(&hex::decode(result.trim_start_matches("0x")).unwrap())
100+
.unwrap()
101+
.first()
102+
.cloned()
103+
.unwrap()
104+
.into_address()
105+
.unwrap();
106+
107+
assert_eq!(result_address, caller);
108+
}
109+
38110
#[tokio::test]
39111
async fn should_get_transaction_count() {
40-
let erc_1820_address = "0xa990077c3205cbDf861e17Fa532eeB069cE9fF96"
112+
let erc_1820_deployer_address = "0xa990077c3205cbDf861e17Fa532eeB069cE9fF96"
41113
.parse()
42114
.unwrap();
43115
let result = reqwest_client()
44-
.get_transaction_count(erc_1820_address, BlockNumber::Latest)
116+
.get_transaction_count(erc_1820_deployer_address, BlockNumber::Latest)
45117
.await
46118
.unwrap();
47119
assert_eq!(result, 1u64);
@@ -195,3 +267,56 @@ async fn should_get_transaction_receipts() {
195267
assert_eq!(receipts[0].gas_used, Some(21000.into()));
196268
assert_eq!(receipts[1].gas_used, Some(52358.into()));
197269
}
270+
271+
const ERC_1820_EXPECTED_CODE: &str = "0x608060405234801561001057600080fd5b50600436106100a557600035\
272+
7c010000000000000000000000000000000000000000000000000000000090048063a41e7d5111610078578063a41e7d51\
273+
146101d4578063aabbb8ca1461020a578063b705676514610236578063f712f3e814610280576100a5565b806329965a1d\
274+
146100aa5780633d584063146100e25780635df8122f1461012457806365ba36c114610152575b600080fd5b6100e06004\
275+
80360360608110156100c057600080fd5b50600160a060020a038135811691602081013591604090910135166102b6565b\
276+
005b610108600480360360208110156100f857600080fd5b5035600160a060020a0316610570565b60408051600160a060\
277+
020a039092168252519081900360200190f35b6100e06004803603604081101561013a57600080fd5b50600160a060020a\
278+
03813581169160200135166105bc565b6101c26004803603602081101561016857600080fd5b8101906020810181356401\
279+
0000000081111561018357600080fd5b82018360208201111561019557600080fd5b803590602001918460018302840111\
280+
640100000000831117156101b757600080fd5b5090925090506106b3565b60408051918252519081900360200190f35b61\
281+
00e0600480360360408110156101ea57600080fd5b508035600160a060020a03169060200135600160e060020a03191661\
282+
06ee565b6101086004803603604081101561022057600080fd5b50600160a060020a038135169060200135610778565b61\
283+
026c6004803603604081101561024c57600080fd5b508035600160a060020a03169060200135600160e060020a03191661\
284+
07ef565b604080519115158252519081900360200190f35b61026c6004803603604081101561029657600080fd5b508035\
285+
600160a060020a03169060200135600160e060020a0319166108aa565b6000600160a060020a038416156102cd57836102\
286+
cf565b335b9050336102db82610570565b600160a060020a031614610339576040805160e560020a62461bcd0281526020\
287+
6004820152600f60248201527f4e6f7420746865206d616e61676572000000000000000000000000000000000060448201\
288+
5290519081900360640190fd5b6103428361092a565b15610397576040805160e560020a62461bcd028152602060048201\
289+
52601a60248201527f4d757374206e6f7420626520616e2045524331363520686173680000000000006044820152905190\
290+
81900360640190fd5b600160a060020a038216158015906103b85750600160a060020a0382163314155b156104ff576040\
291+
5160200180807f455243313832305f4143434550545f4d4147494300000000000000000000000081525060140190506040\
292+
516020818303038152906040528051906020012082600160a060020a031663249cb3fa85846040518363ffffffff167c01\
293+
000000000000000000000000000000000000000000000000000000000281526004018083815260200182600160a060020a\
294+
0316600160a060020a031681526020019250505060206040518083038186803b15801561047e57600080fd5b505afa1580\
295+
15610492573d6000803e3d6000fd5b505050506040513d60208110156104a857600080fd5b5051146104ff576040805160\
296+
e560020a62461bcd02815260206004820181905260248201527f446f6573206e6f7420696d706c656d656e742074686520\
297+
696e74657266616365604482015290519081900360640190fd5b600160a060020a03818116600081815260208181526040\
298+
808320888452909152808220805473ffffffffffffffffffffffffffffffffffffffff1916948716948517905551869291\
299+
7f93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db15391a450505050565b600160a060020a03\
300+
818116600090815260016020526040812054909116151561059a5750806105b7565b50600160a060020a03808216600090\
301+
815260016020526040902054165b919050565b336105c683610570565b600160a060020a031614610624576040805160e5\
302+
60020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e61676572000000000000000000\
303+
0000000000000000604482015290519081900360640190fd5b81600160a060020a031681600160a060020a031614610643\
304+
5780610646565b60005b600160a060020a03838116600081815260016020526040808220805473ffffffffffffffffffff\
305+
ffffffffffffffffffff19169585169590951790945592519184169290917f605c2dbf762e5f7d60a546d42e7205dcb1b0\
306+
11ebc62a61736a57c9089d3a43509190a35050565b60008282604051602001808383808284378083019250505092505050\
307+
6040516020818303038152906040528051906020012090505b92915050565b6106f882826107ef565b6107035760006107\
308+
05565b815b600160a060020a03928316600081815260208181526040808320600160e060020a0319969096168084529582\
309+
52808320805473ffffffffffffffffffffffffffffffffffffffff19169590971694909417909555908152600284528181\
310+
209281529190925220805460ff19166001179055565b600080600160a060020a038416156107905783610792565b335b90\
311+
5061079d8361092a565b156107c357826107ad82826108aa565b6107b85760006107ba565b815b925050506106e8565b60\
312+
0160a060020a0390811660009081526020818152604080832086845290915290205416905092915050565b600080806108\
313+
1d857f01ffc9a70000000000000000000000000000000000000000000000000000000061094c565b909250905081158061\
314+
082d575080155b1561083d576000925050506106e8565b61084f85600160e060020a031961094c565b9092509050811580\
315+
61086057508015155b15610870576000925050506106e8565b61087a858561094c565b909250905060018214801561088f\
316+
5750806001145b1561089f576001925050506106e8565b506000949350505050565b600160a060020a0382166000908152\
317+
600260209081526040808320600160e060020a03198516845290915281205460ff1615156108f2576108eb83836107ef56\
318+
5b90506106e8565b50600160a060020a03808316600081815260208181526040808320600160e060020a03198716845290\
319+
91529020549091161492915050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b\
320+
6040517f01ffc9a70000000000000000000000000000000000000000000000000000000080825260048201839052600091\
321+
82919060208160248189617530fa90519096909550935050505056fea165627a7a72305820377f4a2d4301ede9949f163f\
322+
319021a6e9c687c292a5e2b2c4734c126b524e6c0029";

src/minter-client/src/lib.rs

Lines changed: 11 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use candid::{Nat, Principal};
1+
use candid::Principal;
22
use did::build::BuildData;
33
use did::H160;
44
use ic_canister_client::{CanisterClient, CanisterClientResult};
55
use minter_did::error::Result as McResult;
66
use minter_did::id256::Id256;
7-
use minter_did::init::OperationPricing;
87
use minter_did::order::SignedMintOrder;
98
use minter_did::reason::Icrc2Burn;
109

@@ -84,40 +83,10 @@ impl<C: CanisterClient> MinterCanisterClient<C> {
8483
.await
8584
}
8685

87-
/// Returns operation points number of the user.
88-
pub async fn get_user_operation_points(
89-
&self,
90-
user: Option<Principal>,
91-
) -> CanisterClientResult<u32> {
92-
self.client
93-
.query("get_user_operation_points", (user,))
94-
.await
95-
}
96-
97-
/// Returns operations pricing.
98-
/// This method is available for canister owner only.
99-
pub async fn set_operation_pricing(
100-
&mut self,
101-
pricing: OperationPricing,
102-
) -> CanisterClientResult<McResult<()>> {
103-
self.client
104-
.update("set_operation_pricing", (pricing,))
105-
.await
106-
}
107-
108-
/// Returns operation pricing.
109-
pub async fn get_operation_pricing(&self) -> CanisterClientResult<OperationPricing> {
110-
self.client.query("get_operation_pricing", ()).await
111-
}
112-
113-
/// Creates ERC-20 mint order for ICRC-2 tokens burning.
114-
pub async fn create_erc_20_mint_order(
115-
&self,
116-
reason: Icrc2Burn,
117-
) -> CanisterClientResult<McResult<SignedMintOrder>> {
118-
self.client
119-
.update("create_erc_20_mint_order", (reason,))
120-
.await
86+
/// Creates ERC-20 mint order for ICRC-2 tokens burning and sends it to the BFTBridge.
87+
/// Returns operation id.
88+
pub async fn burn_icrc2(&self, reason: Icrc2Burn) -> CanisterClientResult<McResult<u32>> {
89+
self.client.update("burn_icrc2", (reason,)).await
12190
}
12291

12392
/// Returns `(nonce, mint_order)` pairs for the given sender id.
@@ -131,39 +100,15 @@ impl<C: CanisterClient> MinterCanisterClient<C> {
131100
.await
132101
}
133102

134-
/// Approves ICRC-2 token transfer from minter canister to recipient.
135-
/// Returns approved amount.
136-
///
137-
/// # Arguments
138-
/// - `user` is an address of wallet which has been used for Wrapped token burning.
139-
/// - `operation_id` is an ID retuned by `BFTBridge::burn()` operation.
140-
pub async fn start_icrc2_mint(
141-
&self,
142-
user: &H160,
143-
operation_id: u32,
144-
) -> CanisterClientResult<McResult<Nat>> {
145-
self.client
146-
.update("start_icrc2_mint", (user, operation_id))
147-
.await
148-
}
149-
150-
/// Transfers ICRC-2 tokens from minter canister to recipient.
151-
///
152-
/// Before it can be used, ICRC-2 token must be approved by `start_icrc2_mint` which approves the transfer.
153-
/// After the approval, user should finalize Wrapped token burning, using `BFTBridge::finish_burn()`.
154-
pub async fn finish_icrc2_mint(
103+
/// Returns mint order for the given parameters.
104+
pub async fn get_mint_order(
155105
&self,
106+
sender: Id256,
107+
src_token: Id256,
156108
operation_id: u32,
157-
address: &H160,
158-
icrc2_token: Principal,
159-
recipient: Principal,
160-
amount: Nat,
161-
) -> CanisterClientResult<McResult<Nat>> {
109+
) -> CanisterClientResult<Option<SignedMintOrder>> {
162110
self.client
163-
.update(
164-
"finish_icrc2_mint",
165-
(operation_id, address, icrc2_token, recipient, amount),
166-
)
111+
.query("get_mint_order", (sender, src_token, operation_id))
167112
.await
168113
}
169114

0 commit comments

Comments
 (0)