Ethereum
Overview
Ether (ETH) is the native asset of the Ethereum blockchain. It utilizes:
- Account model
- ECDSA signature algorithm
Ethereum is a decentralized, open-source blockchain that natively supports self-executing code without intermediaries, known as smart contracts. Ethereum launched in 2015, expanding blockchain use beyond cryptocurrency. Ether, the native token, powers the network by paying for transactions and computational services. Ethereum transitioned from Proof of Work (PoW) to Proof of Stake (PoS) in 2022, improving energy efficiency and scalability. Ethereum is critical infrastructure in DeFi, NFTs, DAOs, and many Web3 innovations.
Explorerhttps://etherscan.io/
Wallets Types
BitGo enables holding ether in the following wallet types:
Multisig Cold | Multisig Hot | MPC Cold | MPC Hot | |
---|---|---|---|---|
Custody | ✅ | ❌ | ✅ | ❌ |
Self-Custody | ✅ | ✅ | ✅ | ✅ |
Ethereum MPC wallets use wallet version 6. To learn more about wallet versions, see Wallet and Forwarder Versions.
Ticker Symbols
Mainnet | Testnet |
---|---|
eth | hteth |
Faucet
You can use a faucet to obtain free testnet ether for development and testing purposes.
Faucet: https://holesky-faucet.pk910.de
Units
Ether is divisible by 1018 and the base unit is a wei:
- 1 ether = 1,000,000,000,000,000,000 wei
- 1 wei = 0.000000000000000001 ether
Ether denotes gas fees in gwei. Gwei are divisible by 109 and the base unit is also a wei:
- 1 gwei = 1,000,000,000 wei
- 1 wei = 0.000000001 gwei
Therefore:
- 1 ether = 1,000,000,000 gwei
- 1 gwei = 0.000000001 ether
Ether balances are only in string format.
Tokens
The Ethereum blockchain natively support tokens. To view all BitGo supported tokens on the Ethereum blockchain, see Ethereum - ERC20 Tokens.
Fees
Ethereum fees are dynamic - there are no minimum or default fee rates. Instead, Ethereum uses:
- Units of gas used: The more complex the transaction is, the more gas it uses.
- Base fee: A fee set by the network to pay for a transaction.
- Priority fee: An optional tip that incentivizes node operators to include your transaction.
The dynamic gas fee is determined by the following equation:
units of gas used * (base fee + priority fee)
Learn more about fees at ethereum.org.
Gas Tank
BitGo uses a Gas Tank to pay for gas fees on Ethereum. Gas fees pay for on-chain operations like transactions, wallet and address creation, and more.
To use Ethereum wallets at BitGo, you must first deposit ether into your gas tank, and then keep it adequately funded. Creating wallets and address on Ethereum requires BitGo to deploy a smart contract to the blockchain, which costs gas.
Note: The ether in your gas tank is only for gas fees - you can't withdraw it.
After you fund your gas tank, you can check the balance by calling the Get gas tank balance endpoint.
1 2 3 4 5 6 7 8
export COIN="hteth" export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" curl -X GET \ https://app.bitgo-test.com/api/v2/$COIN/enterprise/$ENTERPRISEID/feeAddressBalance -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN"
Create Wallet
You can create an Ethereum wallet using the Generate wallet Express endpoint. To learn more about creating wallets, see the Create Wallets guide.
Note: Ethereum wallets and addresses must initialize on chain before you can use them. Do not try to deposit into a wallet or address until it's confirmed on chain. Attempting to deposit while still pending on-chain initialization can result in loss of assets.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>" export COIN="hteth" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" export LABEL="<YOUR_WALLET_NAME>" export PASSPHRASE="<YOUR_BITGO_LOGIN_PASSPHRASE>" export ENCRYPTION="<DECRYPTS_PASSPHRASE_DURING_RECOVERY>" export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>" curl -X POST \ http://$BITGO_EXPRESS_HOST:3080/api/v2/$COIN/wallet/generate \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -d '{ "label": "'"$LABEL"'", "passphrase": "'"$PASSPHRASE"'", "passcodeEncryptionCode": "'"$ENCRYPTION"'", "enterprise": "'"$ENTERPRISE_ID"'", "multisigType": 'tss', "walletVersion": 6 # To enable v6 wallets in your enterprise, contact support@bitgo.com }'
Create Address
You can create an Ethereum address using the Create address endpoint. To learn more about creating addresses, see the Create Addresses guide.
Note: Ethereum wallets and addresses must initialize on chain before you can use them. Do not try to deposit into a wallet or address until it's confirmed on chain. Attempting to deposit while still pending on-chain initialization can result in loss of assets.
1 2 3 4 5 6 7 8
export COIN="hteth" export WALLET_ID="<YOUR_WALLET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" curl -X POST \ https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/address \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN"
Consolidate Balance
Ether held in a native MPC wallet ("walletVersion": 6
) requires consolidating to the base address in order to use the maximum spendable amount. Ether held in other wallet versions doesn't require manual consolidations, because those wallets use automatic forwarder smart contracts.
Consolidation transactions require gas, and therefore require sufficient ETH in your gas tank. Even the gas fee for token consolidations is paid for in ETH - not the token itself. Further more, when consolidating token balances, you must also have ether in each of the receive addresses that you're consolidating. You can consolidate only one asset at a time. When making multiple consolidations, you must wait for confirmation of the prior consolidation before initiating a new consolidation transaction.
You can manually consolidate your balances to the base address using the Consolidate account (simple) Express endpoint. To learn more about consolidating, see the Consolidate Account Balance guide.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>" export COIN="hteth" export WALLET_ID="<YOUR_WALLET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" export ADDRESS_1="<RECEIVE_ADDRESS_1>" export ADDRESS_2="<RECEIVE_ADDRESS_2>" export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>" curl -X POST \ http://$BITGO_EXPRESS_HOST:3080/api/v2/$COIN/wallet/$WALLET_ID/consolidateAccount \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -d '{ "consolidateAddresses": [ { "address": "'"$ADDRESS_1"'" }, { "address": "'"$ADDRESS_2"'" } ], "walletPassphrase": "'"$WALLET_PASSPHRASE"'" }'
Estimate Fee
You can estimate transaction fees using the Get Fee Estimate endpoint. To learn more about estimating fees, see the Estimate Fees guide.
1 2 3 4 5 6 7
export COIN="hteth" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" curl -X GET \ https://app.bitgo-test.com/api/v2/$COIN/tx/fee \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN"
Transact
You can use the sendMany
function to send native ether to multiple recipients in one transaction. However, this functionality is unavailable for ERC-20 tokens, which only support single-recipient transactions.
For simple MPC flows, this functionality uses the BitGo JavaScript SDK, to invoke the Create a signature share for the transaction request and Get transaction requests by wallet endpoints. To learn more about transacting, see the Transact guide.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
import * as dotenv from "dotenv"; import {EnvironmentName} from "bitgo"; import {BitGoAPI} from "@bitgo/sdk-api"; import {Hteth} from "@bitgo/sdk-coin-eth"; dotenv.config(); const config = { USERNAME: process.env.USERNAME as string, PASSWORD: process.env.PASSWORD as string, ENV: process.env.ENV as EnvironmentName, OTP: process.env.OTP as string, ENTERPRISE_ID: process.env.ENTERPRISE_ID as string, WALLET_ID: process.env.WALLET_ID as string, WALLET_PASS_PHRASE: process.env.WALLET_PASS_PHRASE as string }; const bitgo = new BitGoAPI({env: config.ENV}); bitgo.register("hteth", Hteth.createInstance); const coin = bitgo.coin("hteth"); async function auth() { await bitgo.authenticate({ username: config.USERNAME, password: config.PASSWORD, otp: config.OTP, }); await bitgo.lock(); await bitgo.unlock({otp: "000000", duration: 3600}); } async function main() { await auth(); const destinatonAddress = "0x1037c88b10fbd0754b9fbd3ba7be41fe7cb61f59"; const wallet = await coin.wallets().get({id: config.WALLET_ID}); const sendAmount = wallet.balanceString() ?? 0; const res = await wallet.sendMany({ walletPassphrase: config.WALLET_PASS_PHRASE, recipients: [{address: destinatonAddress, amount: sendAmount}], type: "transfer", }); console.log(res); } main().catch((err) => console.error(err));
Stake
You can stake ether in multiples of 32 ETH to a whitelisted validator node. Validators propose and attest blocks, earning rewards for securing the network.
You can stake ether from your self-custody wallets using the Create staking request endpoint. To learn more about staking, see the Staking guide.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
export COIN="hteth" export WALLET_ID="<YOUR_WALLET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" export CLIENT_ID="<CLIENT_ID>" export AMOUNT="<AMOUNT_IN_BASE_UNITS>" export GAS_PRICE="<GAS_PRICE>" export TYPE="STAKE" curl -X POST \ http://api/staking/v1/$COIN/wallets/$WALLET_ID/requests \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -d '{ "clientId": "'$CLIENT_ID'", "amount": "'$AMOUNT'", "gasPrice": "'$GAS_PRICE'", "type": "STAKE" }'