# Conflux docs: Transferring Funds Across Spaces ## Overview Since the Hydra hard fork in 2022, Conflux has two spaces: Core Space and eSpace. Both spaces use CFX as their native token and they run on the same blockchain. For more details, please refer to the [documentation](link) or to [this article](https://medium.com/conflux-network/conflux-espace-a-high-level-overview-cdca29bc422a). It is possible to move CFX or ERC20 tokens between Core Space and eSpace. This operation is called *cross-space transfer*. In the next section, we will explain how you can make such transfers. ## ConfluxHub The easiest way to transfer assets between Core Space and eSpace is to use [ConfluxHub](https://confluxhub.io/espace-bridge/cross-space). We recommend that you set up two wallets: [Fluent](https://fluentwallet.com) for Core Space and [MetaMask](https://metamask.io) for eSpace. ![](https://i.imgur.com/yySr5Tp.png) Follow these steps to make a cross-space transfer: - Start by clicking on `Connect Wallet` to connect your Fluent and MetaMask wallets to ConfluxHub. - `To: Conflux eSpace` at the top shows that you are making a transfer from Core Space to eSpace. If you would like to make a transfer in the other direction, click on the arrow next to this text. - In the `Conflux eSpace Destination Address` field, type in your eSpace address or click the MetaMask icon on the right to fill this field automatically. - Next, select the token that you want to transfer and enter the transfer amount. - If the button on the bottom says `Approve`, click on it to submit an ERC20 token approval first. - Once the button on the bottom says `Transfer`, click on it to make the transfer. Making a cross-space transfer from eSpace to Core Space follows a similar process but it has two main steps: First, transfer the token to the bridge on eSpace. Second, withdraw the token from the bridge on Core Space. Please follow the site's instructions. ⚠️ **When making a cross-space transfer, always double check your addresses to avoid accidental asset loss.** ## Cross-Space Transfers for Developers Below we will discuss how to make cross-space transfers programmatically. ### Internal Contract [CIP-90](https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-90.md) introduced the concept of two spaces running on one blockchain, and defined a new [internal contract](link) to connect the two. This contract is available under the address [`cfx:aaejuaaaaaaaaaaaaaaaaaaaaaaaaaaaa2sn102vjv`](https://confluxscan.io/address/cfx:aaejuaaaaaaaaaaaaaaaaaaaaaaaaaaaa2sn102vjv) (hex: `0x0888000000000000000000000000000000000006`) on Core Space. ```solidity interface CrossSpace { /* methods for cross-space CFX transfers */ function transferEVM(bytes20 to) external payable returns (bytes memory output); function withdrawFromMapped(uint256 value) external; function mappedBalance(address addr) external view returns (uint256); /* methods for other cross-space operations */ function callEVM(bytes20 to, bytes calldata data) external payable returns (bytes memory output); function staticCallEVM(bytes20 to, bytes calldata data) external view returns (bytes memory output); // ... } ``` Each Core Space account has a *mapped account* in eSpace. The mapped address is calculated the following way: ```js function cfxMappedEVMSpaceAddress(address) { const { hexAddress } = decode(address); const mappedBuf = keccak256(hexAddress).slice(-20); return checksumAddress(`0x${mappedBuf.toString('hex')}`); } ``` You can get the mapped address simply using [`js-conflux-sdk`](https://www.npmjs.com/package/js-conflux-sdk): ```js const { address } = require('js-conflux-sdk'); address.cfxMappedEVMSpaceAddress('cfx:aamgvyzht7h1zxdghb9ee9w26wrz8rd3gj837392dp'); // '0x62954816cE133B41Ab888e1b68b62549DE2f32e0' ``` ### Bridging CFX For bridging CFX from Core Space to eSpace, you can use `CrossSpace.transferEVM`. When you call this internal contract method, the attached CFX tokens are first transferred from your account to its mapped account on eSpace, then transferred from the mapped account to the destination address `to`. ```js const { address, Conflux, Drip } = require('js-conflux-sdk'); // private key of the sender account on Core Space const PRIVATE_KEY = '0x...'; // receiver address on eSpace const to = '0x1111111111111111111111111111111111111111'; async function main() { const conflux = new Conflux({ url: 'https://main.confluxrpc.com', networkId: 1029 }); const account = conflux.wallet.addPrivateKey(PRIVATE_KEY); const CrossSpace = conflux.InternalContract('CrossSpaceCall'); console.log(`Sender: ${account.address}`); console.log(`Mapped: ${address.cfxMappedEVMSpaceAddress(account.address)}`); console.log(`Receiver: ${to}`); const receipt = await CrossSpace .transferEVM(to) .sendTransaction({ from: account, value: Drip.fromCFX(1) }) .executed(); console.log(receipt); } main(); ``` ⚠️ It is important to note that this whole process happens within a single transaction. Through this atomicity, cross-space transfers generally offer much better security than cross-*chain* operations. For bridging CFX from eSpace back to Core Space, you first need to send the tokens to the receiver account's mapped account on eSpace. After this, the receiver account can call `CrossSpace.withdrawFromMapped` to withdraw the tokens to Core Space. ```js const { address, Conflux, Drip } = require('js-conflux-sdk'); // private key of the receiver account on Core Space const PRIVATE_KEY = '0x...'; async function main() { const conflux = new Conflux({ url: 'https://main.confluxrpc.com', networkId: 1029 }); const account = conflux.wallet.addPrivateKey(PRIVATE_KEY); const CrossSpace = conflux.InternalContract('CrossSpaceCall'); console.log(`Sender: ${account.address}`); console.log(`Mapped: ${address.cfxMappedEVMSpaceAddress(account.address)}`); const receipt = await CrossSpace .withdrawFromMapped(Drip.fromCFX(1)) .sendTransaction({ from: account }) .executed(); console.log(receipt); } main(); ``` ### Bridging ERC20 Tokens For ERC20 cross-space transfers, Conflux offers an [ERC20 bridge](https://github.com/Conflux-Chain/conflux-evm-bridge). This bridge consists of two main contracts, one in Core Space (`ConfluxSide.sol`), one in eSpace (`EvmSide.sol`). Let us assume that you want to transfer some USDT from Core Space to eSpace. 1. You first need to approve the bridge and initiate the transfer, at which point your USDT gets locked in the `ConfluxSide` contract on Core Space. 2. `ConfluxSide` notifies `EvmSide` of the transfer through `CrossSpace.callEVM`. 3. `EvmSide` checks if the token (USDT) have a corresponding ERC20 token on eSpace. If not, then it deploys one. 4. `EvmSide` mints the same amount of eSpace USDT as was locked in Core Space. ![](https://i.imgur.com/enuysZh.png) When transferring your USDT back to Core Space, the tokens are first burnt on eSpace, and then the corresponding tokens are unlocked on Core Space. The process is analogous for tokens originally deployed on eSpace. Please refer to the [code](https://github.com/Conflux-Chain/conflux-evm-bridge) for details.