Introduction
Filecoin is an L1 blockchain with an EVM compatible interface. It consists of four account types which are all distinct and do not represent the same balance: F1, F2, F3 and F4, while F4 is the L1 representation of the EVM account (0x) on the EVM interface.
On Fireblocks, we implemented the Filecoin EVM interface while still allowing transfers between the EVM account (0x) and Filecoin’s native accounts (Fx).
Filecoin native transfers between wallet types
Below you can find the transfer options between the different types of Filecoin wallets.
Fireblocks vault to vault transfer
This is a standard vault to vault transfer in Fireblocks that leverage the Filecoin EVM interface. This transfer type uses the 0x addresses of each account, and issues a standard EVM transaction.
Fireblocks vault to external 0x Filecoin address
This is a standard vault to external EVM transfer in Fireblocks that leverage the Filecoin EVM interface. This transfer uses the 0x addresses of each account, and issues a standard EVM transfer transaction.
Fireblocks vault to external Fx Filecoin address
Fireblocks allows transfers between 0x and Fx Filecoin addresses by leveraging Filecoin’s native EVM to Fil transfer. This type of transfer is supported by using Filecoin’s FilForwader, which is an EVM contract call that is implemented on the blockchain level to help transfer funds from the EVM to the native Filecoin interface. In order to transfer funds from Fireblocks to an external Fx Filecoin address, see the below Transferring assets between address types section.
External 0x address to Fireblocks vault
This is a standard external EVM to Fireblocks vault transfer that leverages the Filecoin EVM interface. This transfer uses the 0x addresses of each account, and issues a standard EVM transfer transaction.
External Fx address to Fireblocks vault
On Filecoin, transactions to F4 addresses are considered equivalent to EVM transfers. Such F4 addresses allow a 1:1 conversion to the equivalent EVM 0x address. The conversion between F4 and 0x can be done using Filecoin-dedicated RPC calls: FilecoinAddressToEthAddress. For example, you can transfer funds from F1 to F4 addresses natively on Filecoin.
In order to transfer funds from an Fx address to a Fireblocks vault, you need to convert the Fireblocks 0x address to the matching F4 address, using Filecoin EthAddressToFilecoinAddress RPC call. Get the F4 address, and perform the desired transaction.
Once the transaction is performed, Fireblocks picks it up as an EVM transfer transaction, and it becomes visible to you on the UI and API.
Transferring assets from 0x to Fx
As mentioned above, in order to transfer funds from a Fireblocks vault which uses 0x address to a Filecoin Fx address, you must use a contract call to FilForwader.
How to create a contract call transaction
Use the Create a new transaction API endpoint to create a contract call to Filecoin’s FilForwader contract, while making sure to:
- Set the contractCallData parameter to correctly populate with the FilForwader call data generated by the Filecoin EVM FILForwarder Contract Input Generator Helper Script below.
- Use the official FilForwader destination address: 0x2b3ef6906429b580b7b2080de5ca893bc282c225
Example:
curl --request POST \
--url https://api.fireblocks.io/v1/transactions \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"operation": "CONTRACT_CALL",
"source": {
"type": "VAULT_ACCOUNT"
},
"destination": {
"type": "VAULT_ACCOUNT",
"oneTimeAddress": {
"address": "0x2b3ef6906429b580b7b2080de5ca893bc282c225"
}
},
"extraParameters": {
"contractCallData": "0xd948d4680000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001501a0eb81c6066e6514e2032b2e4179a52ee3955a530000000000000000000000"
},
"amount": "1",
"feeLevel": "MEDIUM"
}
'
Explanation
- The source address and amount for the transfer are extracted from the transaction itself
- The contractCallData is raw data produced by the script and requires only one input: the destination address in f1, f2, or f3 format
- Ensure that the destination address is provided correctly, as it is used to generate the required contract data for the transfer.
Filecoin EVM FILForwarder Contract Input Generator Helper Script
This Node.js script helps generate the appropriate call data for the FilForwader contract call.
Example:
import { base32 } from 'iso-base/rfc4648';
// Method id for 'forward': 0xd948d468
// type 2 - EIP-1159
// 0015 (f) network
let contractPrefix =
"0xd948d468000000000000000000000000000000000000000000000000000000000000002000000
00000000000000000000000000000000000000000000000000000000015";
let pedding = "0000000000000000000000";
// Get the destination address input
const destAddressInput = process.argv[2];
// Validate that the input length is between 41 and 86 characters
if (destAddressInput.length < 41 || destAddressInput.length > 86) {
console.error('Error: The destination address input must be between 41 and 86
characters long. Length of input address:', destAddressInput.length);
process.exit(1);
}
// Separate the prefix(f1/f2/f3) from the address string
const prefix = destAddressInput.slice(0, 2); // Get the first two characters as
the prefix
const restAddress = destAddressInput.slice(2); // Get the rest of the address
// Check for prefix and add corresponding value to the output
let prefixHex = '';
switch (prefix) {
case 'f1':
prefixHex = '01';
break;
case 'f2':
prefixHex = '02';
break;
case 'f3':
prefixHex = '03';
break;
default:
console.error('Exception: Invalid prefix');
process.exit(1);
}
// Decode the address string
let data;
try {
data = base32.decode(restAddress.toUpperCase()); // Decode the Base32 string
} catch (error) {
console.error('Error decoding Base32 string:', error.message);
process.exit(1);
}
// Convert the buffer to a hex array and remove the last 4 elements
const hexArray = Array.from(data)
.slice(0, -4) // Remove the last 4 elements
.map(byte => byte.toString(16).padStart(2, '0')) // Convert to hex with
padding
.join(''); // Join into a single string without commas or spaces
// Print the result with the prefix
console.log(`data (hex): ${prefixHex}${hexArray}`);
console.log(`Full contract Raw data (hex): ${contractPrefix}${prefixHex}$
{hexArray}${pedding}`);
- filecoin_evm_forward_contract_input_generator.mjs: Script for generating the call data
- f1udvydrqgnzsrjyqdfmxec6nff3rzkwstzdc6hoq: Example of the F1 destination address
Your output must be 202 characters in length. Here is an example of a script’s output:
$ node filecoin_evm_forward_contract_input_generator.mjs f1udvydrqgnzsrjyqdfmxec6nff3rzkwstzdc6hoq
data (hex): 01a0eb81c6066e6514e2032b2e4179a52ee3955a53
Full contract Raw data (hex):
0xd948d4680000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001501a0eb81c6066e6514e2032b2e4179a52ee3955a530000000000000000000000