|
1 |
| -use pallet_evm::{ |
2 |
| - BalanceConverter, ExitError, ExitSucceed, PrecompileHandle, PrecompileOutput, PrecompileResult, |
3 |
| -}; |
| 1 | +use pallet_evm::PrecompileHandle; |
| 2 | +use precompile_utils::EvmResult; |
| 3 | +use sp_core::H256; |
4 | 4 | use sp_runtime::traits::UniqueSaturatedInto;
|
5 |
| -use sp_std::vec; |
6 | 5 |
|
7 |
| -use crate::precompiles::{ |
8 |
| - contract_to_origin, get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call, |
9 |
| -}; |
| 6 | +use crate::precompiles::{contract_to_origin, parse_pubkey, PrecompileExt, PrecompileHandleExt}; |
10 | 7 | use crate::Runtime;
|
11 | 8 |
|
12 |
| -pub const BALANCE_TRANSFER_INDEX: u64 = 2048; |
13 |
| -// ss58 public key i.e., the contract sends funds it received to the destination address from the |
14 |
| -// method parameter. |
15 |
| -const CONTRACT_ADDRESS_SS58: [u8; 32] = [ |
16 |
| - 0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd, 0xfc, |
17 |
| - 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93, 0x70, 0x5d, |
18 |
| -]; |
19 |
| - |
20 | 9 | pub struct BalanceTransferPrecompile;
|
21 | 10 |
|
22 |
| -impl BalanceTransferPrecompile { |
23 |
| - pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { |
24 |
| - let txdata = handle.input(); |
25 |
| - |
26 |
| - // Match method ID: keccak256("transfer(bytes32)") |
27 |
| - let method = get_slice(txdata, 0, 4)?; |
28 |
| - if get_method_id("transfer(bytes32)") != method { |
29 |
| - return Ok(PrecompileOutput { |
30 |
| - exit_status: ExitSucceed::Returned, |
31 |
| - output: vec![], |
32 |
| - }); |
33 |
| - } |
34 |
| - |
35 |
| - // Forward all received value to the destination address |
36 |
| - let amount = handle.context().apparent_value; |
| 11 | +impl PrecompileExt for BalanceTransferPrecompile { |
| 12 | + const INDEX: u64 = 2048; |
| 13 | + const ADDRESS_SS58: [u8; 32] = [ |
| 14 | + 0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd, |
| 15 | + 0xfc, 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93, |
| 16 | + 0x70, 0x5d, |
| 17 | + ]; |
| 18 | +} |
37 | 19 |
|
38 |
| - // Use BalanceConverter to convert EVM amount to Substrate balance |
39 |
| - let amount_sub = |
40 |
| - <Runtime as pallet_evm::Config>::BalanceConverter::into_substrate_balance(amount) |
41 |
| - .ok_or(ExitError::OutOfFund)?; |
| 20 | +#[precompile_utils::precompile] |
| 21 | +impl BalanceTransferPrecompile { |
| 22 | + #[precompile::public("transfer(bytes32)")] |
| 23 | + #[precompile::payable] |
| 24 | + fn transfer(handle: &mut impl PrecompileHandle, address: H256) -> EvmResult<()> { |
| 25 | + let amount_sub = handle.try_convert_apparent_value()?; |
42 | 26 |
|
43 | 27 | if amount_sub.is_zero() {
|
44 |
| - return Ok(PrecompileOutput { |
45 |
| - exit_status: ExitSucceed::Returned, |
46 |
| - output: vec![], |
47 |
| - }); |
| 28 | + return Ok(()); |
48 | 29 | }
|
49 | 30 |
|
50 |
| - let address_bytes_dst = get_slice(txdata, 4, 36)?; |
51 |
| - let (account_id_dst, _) = get_pubkey(address_bytes_dst)?; |
| 31 | + let dest = parse_pubkey(address.as_bytes())?.0.into(); |
52 | 32 |
|
53 | 33 | let call = pallet_balances::Call::<Runtime>::transfer_allow_death {
|
54 |
| - dest: account_id_dst.into(), |
| 34 | + dest, |
55 | 35 | value: amount_sub.unique_saturated_into(),
|
56 | 36 | };
|
57 | 37 |
|
58 |
| - try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?) |
| 38 | + handle.try_dispatch_runtime_call(call, contract_to_origin(&Self::ADDRESS_SS58)?) |
59 | 39 | }
|
60 | 40 | }
|
0 commit comments