Transferring ETH
You can use the IMA for managing ETH between Ethereum and SKALE. The following steps guide you through a complete transfer from Ethereum to SKALE and back. Unlike ERC20, ERC721, and ERC1155, ETH is natively supported so there is no need for you to set up and map ETH on your SKALE Chain.
Also, note that the following steps apply to transferring Ethereum ETH to SKALE Chains. SKALE Chains do not require ETH to conduct transactions, but do require cost-free SKALE Chain FUEL (sFUEL) for conducting transactions, which has no monetary value and is used exclusively on SKALE Chains.
1. Deposit ETH on Ethereum
To send ETH from a user’s wallet to the IMA Deposit Box on Ethereum, you will need to use the deposit function within the DepositBox IMA Contract on Ethereum.
This method is called from Ethereum to lock the funds.
The DepositBox contract is on Rinkeby testnet and Mainnet. To get the ABIs to interact with IMA on Rinkeby, check out the current release page.
In all ima-js code samples we’re assuming that library is already inited. See init instructions here. For the 2 objects usage drop ima.
prefix.
See IMA-JS deposit.js sandbox
Unresolved include directive in modules/ROOT/pages/transferring-eth.adoc - include::deposit-eth-imajs.js[]
Using raw Web3.js, create and sign the deposit()
transaction.
Unresolved include directive in modules/ROOT/pages/transferring-eth.adoc - include::deposit-eth-web3.js[]
2. Exit from SKALE Chain
To send ETH back to Ethereum, you will need to use the exitToMain function within the TokenManager contract on the SKALE Chain.
This method is called from the SKALE Chain to send funds and move the token back to Ethereum.
Note that the SKALE Chain user must have:
-
sFUEL to conduct the exitToMain transaction on the SKALE Chain TokenManager contract.
-
a sufficient balance of ETH in the Community Pool to initiate the exit to Ethereum *See Funding Exits.
The TokenManager contract is on your SKALE Chain. Check out the current release page for ABIs.
In all ima-js code samples we’re assuming that library is already inited. See init instructions here. For the 2 objects usage drop ima.
prefix.
See IMA-JS deposit.js sandbox
// import & init ima-js here
export async function withdrawETH(ima) {
let address = "[YOUR_ADDRESS]";
let privateKey = "[YOUR_PRIVATE_KEY]";
let txOpts = {
address: address,
privateKey: privateKey // remove privateKey from txOpts to use Metamask signing
};
await schain.withdrawETH(
schain.web3.utils.toWei("1", "ether"),
txOpts
);
}
const Web3 = require('web3');
const Tx = require('ethereumjs-tx').Transaction;
let schainABIs = require("[YOUR_SKALE_CHAIN_ABIs]");
let privateKey = Buffer.from('[YOUR_PRIVATE_KEY]', 'hex')
let account = "[YOUR_ACCOUNT_ADDRESS]";
let schainEndpoint = "[YOUR_SKALE_CHAIN_ENDPOINT]";
const tokenManagerAddress = schainABIs.token_manager_eth_address;
const tokenManagerABI = schainABIs.token_manager_eth_abi;
const web3 = new Web3(new Web3.providers.HttpProvider(schainEndpoint));
let contract = new web3.eth.Contract(
tokenManagerABI,
tokenManagerAddress
);
/*
* Prepare exitToMain(address to)
*/
let exitToMain = contract.methods.exitToMain(
web3.utils.toWei('1', 'ether')
)
.encodeABI();
//get nonce
web3.eth.getTransactionCount(account).then((nonce) => {
//create raw transaction
const rawTx = {
chainId: chainId,
nonce: "0x" + nonce.toString(16),
from: account,
nonce: "0x" + nonce.toString(16),
data : exitToMain,
to: tokenManagerAddress,
gasPrice: 100000000000,
gas: 8000000
}
//sign transaction
const tx = new Tx(rawTx);
tx.sign(privateKey);
//serialize transaction
const serializedTx = tx.serialize();
//send signed transaction
web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).
on('receipt', receipt => {
//record receipt to console
console.log(receipt);
}).
catch(console.error);
});
3. Retrieve ETH
Since you have withdrawn your ETH, you will need to retrieve it from DepositBox.
In all ima-js code samples we’re assuming that library is already inited. See init instructions here. For the 2 objects usage drop ima.
prefix.
See IMA-JS deposit.js sandbox
// import & init ima-js here
export async function retrieveETH(ima) {
let address = "[YOUR_ADDRESS]";
let privateKey = "[YOUR_PRIVATE_KEY]";
let txOpts = {
address: address,
privateKey: privateKey // remove privateKey from txOpts to use Metamask signing
};
// retrieve all ETH from DepositBox
await ima.mainnet.getMyEth(txOpts);
}
Using Web3js, create and sign getMyEth()
in DepositBox.
const Web3 = require('web3');
const Tx = require('ethereumjs-tx').Transaction;
let rinkebyABIs = require("[YOUR_RINKEBY_ABIs]");
let privateKey = new Buffer('[YOUR_PRIVATE_KEY]', 'hex')
let account = "[YOUR_ACCOUNT_ADDRESS]";
let rinkeby = "[YOUR_RINKEBY_ENDPOINT]";
let chainId = "[RINKEBY_CHAIN_ID";
const depositBoxAddress = rinkebyABIs.deposit_box_eth_address;
const depositBoxABI = rinkebyABIs.deposit_box_eth_abi;
const web3 = new Web3(rinkeby);
let DepositBox = new web3.eth.Contract(depositBoxABI, depositBoxAddress);
/*
* prepare the function
* getMyEth()
*/
let getMyEth = DepositBox.methods.getMyEth().encodeABI();
//get nonce
web3.eth.getTransactionCount(account).then((nonce) => {
//create raw transaction
const rawTxGetMyEth = {
chainId: chainId,
from: account,
nonce: "0x" + nonce.toString(16),
data: getMyEth,
to: depositBoxAddress,
gas: 6500000,
gasPrice: 100000000000
};
//sign transaction
const txGetMyEth = new Tx(rawTxGetMyEth, {
chain: "rinkeby",
hardfork: "petersburg"
});
txGetMyEth.sign(privateKey);
//serialize transaction
const serializedTxGetMyEth = txGetMyEth.serialize();
//send signed transaction
web3.eth
.sendSignedTransaction("0x" + serializedTxGetMyEth.toString("hex"))
.on("receipt", (receipt) => {
//record receipt to console
console.log(receipt);
})
.catch(console.error);
});