I'm trying to send hbar to a long zero address using ethers.js and it's not working.
I converted an accountId (0.0.5465603) to a solidity address (0x0000000000000000000000000000000000536603) but I can't send funds to it using ethers.js, I keep running out of gas.
For example:
let tx = {
to: "0x0000000000000000000000000000000000536603",
gasLimit: 200000,
value: ethers.parseEther('2', 'wei'),
};
let transaction = await signer.sendTransaction(tx);
For the code snippet to work, we need to import ethers
and initialise an instance of signer
.
The minimal code to reproduce is thus:
import dotenv from 'dotenv';
import { ethers } from 'ethers';
import { Wallet } from '@ethersproject/wallet';
import { JsonRpcProvider } from '@ethersproject/providers';
async function main() {
dotenv.config();
const privateKey = process.env.PRIVATE_KEY;
const rpcUrl = process.env.RPC_URL;
if (!privateKey || !rpcUrl) {
console.log('Please set the PRIVATE_KEY and RPC_URL in the .env file');
process.exit(1);
}
const rpcProvider = new JsonRpcProvider(rpcUrl);
const signer = new Wallet(privateKey, rpcProvider);
const accountAddress = await accountWallet.getAddress();
console.log({ accountAddress, rpcUrl});
let tx = {
to: "0x0000000000000000000000000000000000536603",
gasLimit: 200000,
value: ethers.parseEther('2', 'wei'),
};
let transaction = await signer.sendTransaction(tx);
}
You will also need a .env
file:
# Obtain a create and fund an account, and then copy its private key.
# 3 methods to do so are listed here:
PRIVATE_KEY=""
# Hashio by default, can switch another one if preferred
RPC_URL=";
I'm trying to send hbar to a long zero address using ethers.js and it's not working.
I converted an accountId (0.0.5465603) to a solidity address (0x0000000000000000000000000000000000536603) but I can't send funds to it using ethers.js, I keep running out of gas.
For example:
let tx = {
to: "0x0000000000000000000000000000000000536603",
gasLimit: 200000,
value: ethers.parseEther('2', 'wei'),
};
let transaction = await signer.sendTransaction(tx);
For the code snippet to work, we need to import ethers
and initialise an instance of signer
.
The minimal code to reproduce is thus:
import dotenv from 'dotenv';
import { ethers } from 'ethers';
import { Wallet } from '@ethersproject/wallet';
import { JsonRpcProvider } from '@ethersproject/providers';
async function main() {
dotenv.config();
const privateKey = process.env.PRIVATE_KEY;
const rpcUrl = process.env.RPC_URL;
if (!privateKey || !rpcUrl) {
console.log('Please set the PRIVATE_KEY and RPC_URL in the .env file');
process.exit(1);
}
const rpcProvider = new JsonRpcProvider(rpcUrl);
const signer = new Wallet(privateKey, rpcProvider);
const accountAddress = await accountWallet.getAddress();
console.log({ accountAddress, rpcUrl});
let tx = {
to: "0x0000000000000000000000000000000000536603",
gasLimit: 200000,
value: ethers.parseEther('2', 'wei'),
};
let transaction = await signer.sendTransaction(tx);
}
You will also need a .env
file:
# Obtain a create and fund an account, and then copy its private key.
# 3 methods to do so are listed here: https://docs.hedera.com/hedera/tutorials/more-tutorials/create-and-fund-your-hedera-testnet-account
PRIVATE_KEY=""
# Hashio by default, can switch another one if preferred
RPC_URL="https://testnet.hashio.io/api"
Share
Improve this question
edited 11 hours ago
bguiz
28.6k49 gold badges163 silver badges251 bronze badges
asked yesterday
Greg ScullardGreg Scullard
4714 silver badges13 bronze badges
2 Answers
Reset to default 4So, for now, transferring to what we call a long-zero address (an address obtained by converting an accountId to its solidity expression 0.0.536603
-> 0x0000000000000000000000000000000000536603
) via a JSON-RPC transaction will fail.
However, transferring to an EVM address using a JSON-RPC transaction will work, see example below:
console.log("Transfer to EVM address");
let tx = {
to: `0xb8482dc06049cdff56a6b747330f06de3cc1efc0`,
value: ethers.parseEther('3', 'wei')
};
let transaction = await signer.sendTransaction(tx);
The EVM address for an account only exists if the account was first created by sending hbar or tokens to this address. An account created with the SDK will only have a long-zero EVM address.
Alternatively, you can use the SDK to transfer to any of the three address types:
import {
AccountId,
Client, Hbar,
PrivateKey, TransferTransaction
} from "@hashgraph/sdk";
import dotenv from "dotenv";
dotenv.config();
async function main() {
let client = Client.forName(process.env.HEDERA_NETWORK).setOperator(
AccountId.fromString(process.env.OPERATOR_ID),
PrivateKey.fromString(process.env.OPERATOR_KEY)
);
console.log("Transfer to accountId");
response = await new TransferTransaction()
.addHbarTransfer(client.operatorAccountId, new Hbar(1).negated())
.addHbarTransfer(AccountId.fromString("0.0.5465603"), new Hbar(1))
.execute(client);
await response.getReceipt(client);
console.log("Transfer to solidity address");
response = await new TransferTransaction()
.addHbarTransfer(client.operatorAccountId, new Hbar(1).negated())
.addHbarTransfer("0x0000000000000000000000000000000000536603", new Hbar(1))
.execute(client);
await response.getReceipt(client);
console.log("Transfer to EVM address");
let response = await new TransferTransaction()
.addHbarTransfer(client.operatorAccountId, new Hbar(1).negated())
.addHbarTransfer("0xb8482dc06049cdff56a6b747330f06de3cc1efc0", new Hbar(1))
.execute(client);
await response.getReceipt(client);
client.close();
}
void main();
It turns out to be a little more nuanced than the above, you can indeed send to a long-zero address, however...
If the account has an EVM address, you have to use the EVM address.
For example: account 0.0.5465603 was created by sending hbar to 0xb8482dc06049cdff56a6b747330f06de3cc1efc0, as a result, only this address can be used with ethers.js.
If the account was created via the SDK and doesn't have an EVM address, but a long-zero address, you can use ethers.js to send to the long zero address.
For example: account 0.0.220237 was created with the SDK and has a long zero address: 0x0000000000000000000000000000000000219b07 which can be used by ethers.js
Also tried through a contract
pragma solidity ^0.8.26;
contract SendTest {
function send(address payable to) public payable {
to.transfer(msg.value);
}
}
deployed here on testnet: 0x000000000000000000000000000000000053da1a
Sending to the long zero address of an account (0.0.536603) created by sending hbar to an evm address fails
const testContract = new ethers.Contract(`0x${contractAddress}`, abi, signer)
const options = {
value: 20000000000, // 2 tinybar
gasLimit: 100000
}
await testContract.send("0x0000000000000000000000000000000000536603", options);
Sending to the EVM address of that account (0.0.536603) works
const testContract = new ethers.Contract(`0x${contractAddress}`, abi, signer)
const options = {
value: 20000000000, // 2 tinybar
gasLimit: 100000
}
await testContract.send("0xb8482dc06049cdff56a6b747330f06de3cc1efc0", options);
Sending to the long zero address of an account created with the SDK (0.0.2202375) works
const testContract = new ethers.Contract(`0x${contractAddress}`, abi, signer)
const options = {
value: 20000000000, // 2 tinybar
gasLimit: 100000
}
await testContract.send("0x0000000000000000000000000000000000219b07", options);