Accounts¶
Some quick examples of using Accounts.
Dump All JSON Wallet Balances (in current directory)¶
const fs = require('fs');
const path = require('path');
const ethers = require('ethers');
let provider = ethers.getDefaultProvider();
// Geth
let dirname = path.join(process.env.HOME, '.ethereum', 'keystore');
// Parity (use the name of your chain for chainDirectory, such as "homestead")
//var dirname = path.join(process.env.HOME, '.parity', 'keys', chainDirectory, 'keys');
let filenames = fs.readdirSync(dirname);
filenames.forEach(async function(filename) {
// Get the Wallet JSON
let data = await fs.readFile(path.join(dirname,filename));
// Get the Wallet address
let address = ethers.utils.getJsonWalletAddress(data.toString());
// Look up the balance
let balance = await provider.getBalance(address);
console.log(address + ':' + ethers.utils.formatEther(balance));
});
Sweep an Account into Another¶
This will sweep all the funds from one account’s privateKey and place it in another account, newAddress.
const ethers = require('ethers');
async function sweep(privateKey, newAddress) {
let provider = ethers.getDefaultProvider();
let wallet = new ethers.Wallet(privateKey, provider);
// Make sure we are sweeping to an EOA, not a contract. The gas required
// to send to a contract cannot be certain, so we may leave dust behind
// or not set a high enough gas limit, in which case the transaction will
// fail.
let code = await provider.getCode(newAddress);
if (code !== '0x') { throw new Error('Cannot sweep to a contract'); }
// Get the current balance
let balance = await wallet.getBalance();
// Normally we would let the Wallet populate this for us, but we
// need to compute EXACTLY how much value to send
let gasPrice = await provider.getGasPrice();
// The exact cost (in gas) to send to an Externally Owned Account (EOA)
let gasLimit = 21000;
// The balance less exactly the txfee in wei
let value = balance.sub(gasPrice.mul(gasLimit))
let tx = await wallet.sendTransaction({
gasLimit: gasLimit,
gasPrice: gasPrice,
to: newAddress,
value: value
});
console.log('Sent in Transaction: ' + tx.hash);
});
Coalesce Jaxx Wallets¶
The Jaxx Wallet (for iOS, Android, desktop, et cetera) uses HD wallets on Ethereum the same way as Bitcoin, which results in each transaction being received by a separate address. As a result, funds get spread across many accounts, making several operations in Ethereum impossible.
This short recipe will coalesce all these accounts into a single one, by sending the funds from each account into a single one.
This also results in paying multiple transaction fees (1 fee per account to merge).
@TODO: This is incomplete!!
const ethers = require('ethers');
let provider = ethers.getDefaultProvider();
let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";
let hdnode = ethers.utils.HDNode.fromMnemonic(mnemonic);
let hdnode = hdnode.derivePath("m/44'/60'/0'/0");
// @TODO
Access Funds in a Mnemonic Phrase Wallet¶
@TODO: This is incomplete
const ethers = require('ethers');
let walletPath = {
"standard": "m/44'/60'/0'/0/0",
// @TODO: Include some non-standard wallet paths
};
let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";
let hdnode = ethers.HDNode.fromMnemonic(mnemonic);
let node = hdnode.derivePath(walletPath.standard);
let wallet = new ethers.Wallet(node.privateKey);
console.log(wallet.address);
// 0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9
// @TODO:
Random Mnemonic¶
Often you may simply want a random mnemonic that is valid. It is important to note that not all random sets of words are valid; there is a checksum included in the binary encoding of the entropy, so it is important to use a method that correctly encodes this checksum.
const ethers = require('ethers');
// All createRandom Wallets are generated from random mnemonics
let wallet = ethers.Wallet.createRandom();
let randomMnemonic = wallet.mnemonic;
const utils = require('ethers/utils');
// Chose the length of your mnemonic:
// - 16 bytes => 12 words (* this example)
// - 20 bytes => 15 words
// - 24 bytes => 18 words
// - 28 bytes => 21 words
// - 32 bytes => 24 words
let bytes = ethers.utils.random(16);
// Select the language:
// - en, es, fr, ja, ko, it, zh_ch, zh_tw
let language = ethers.wordlists.en;
let randomMnemonic = ethers.utils.HDNode.entropyToMnemonic(bytes, language)
Get Transaction History¶
Unfortunately, transaction history is not something that is easy to get. It is not indexed by the blockchain, not by a standard node, “out-of-the-box”. At the time of this recipe, the indices to store the entire history are around 800GB. For Parity you may enable tracing and disable pruning, in which case you can use some of the vendor specific JSON-RPC debug methods.
For many cases, you can probably rely on Etherscan, which dedicates large amounts of resources to tracking and storing this information.
let etherscanProvider = new ethers.providers.EtherscanProvider();
etherscanProvider.getHistory(address).then((history) => {
history.forEach((tx) => {
console.log(tx);
})
});
@TODO: Example of signing and verifying a hash in ethers and in Solidity.