Intro
OK developers welcome back!
In this video I think it’s time for us to revisit Ganache.
Ganache is part of the Truffle suite of tools
and they’ve just released version 7, boasting some serious new features!
We are looking at – Forking the Ethereum mainnet 30x faster – Massive 1GB+ transaction traces. – and intergration with Infura’s Ethereum archive nodes for free!
If you’re new here, I’m Calvin and at Eat The Blocks we help Web2 developers transition into Web3.
Revisiting Ganache
If you’ve followed or developed in the web3 space, you’ve not doubt heard of Ganache.
Ganache is a local development blockchain that simulates the Ethereum network, so you can see how your dapp will work before pushing to production.
They were the first to launch and allow web3 developers to run automated tests on Ethereum and they’ve been making developer’s lives easier for a while now.
They’ve also been saving us from the lengthy and complicated process of setting up clients with Geth or OpenEthereum just to get access to the Ethereum Virtual Machine.
With Ganache all we need to do is install it on the command line or use their cool UI.
Once you start up Ganache you instantly get 10 unlocked accounts pre funded with Eth so you can start testing your dapp quickly.
They allow us to fail fast and fail often so we can rest assured that our Solidity contracts are battle tested before deployment.
30x Faster than v6
A lot of web3 developers already use Ganache to fork and test smart contracts in a local environment so they can feel confident that everything works as expected before deployment.
However, word on the street was Ganache version 6 was a little slow to install and there were some memory leaks that were making devs a little sad, but it looks like Ganache was taking notes and took massive action.
They’ve pretty much rewrote Ganache from the ground up to make things so much faster, stable and flexible.
Ganache now has advanced caching which ensures 30x faster performance, which we’ll look at in just a second.
Their integration with infura now gives us fast and free access to historical data even without the need to pass in a URL like other tools require. I mean that’s a paid feature in other clients and it’s definitely not cheap either.
We can now run Ganache indefinately with having memory leaks or random crashes.
Common operations are around 3x faster than v6 and they’re now boasting the ability to support the largest complex transactions beyond a GB in size.
Cache Levels = Speed
So, how exactly have they added so much speed? Turns out they have 2 levels of caching.
- Hot Cache: This happens when a transaction trace is run a second time, without closing down Ganache. Its the fastest cache.
- Warm Cache: Like hot cache, happens when the exact same transaction trace is run again, but this time, after Ganache has been restarted. Which is also very fast. Warm cache also saves the forking state, so it dramatically increases startup speed when forking.
I’d say that’s quite a vast improvement and there’s been a lot of hard work to bring us features like this, let’s look into how we can get this set up on our machine asap.
Installing Ganache cli.
Ok, let’s run npm install ganache -global
.
This will give us access to run Ganache anywhere from the command line. So we can simply type Ganache and power up the cli tool.
Nice, so by default you can see the 10 unlocked accounts we get access to and their private keys and we also get 1000 fake ether.
The mnemonic phrase is also included so we can get up and with things like metamask super quick.
We can customise account creation during the start up of Ganache by passing in a few options. For example, we can modify the starting balances of the dummy accounts we start with.
ganache --wallet.accounts "0xfd485338e322f5930f7cf475f385341ec88bfc4f8a0a16f30b2fb417d1bb5427, 1000000000000000000000" "0x05bba0b9f7a251080aa23feee4eab3f75a1abee905c0271008c93e5d2e2e7541, 10000000000000000000000"
We’re also able to modify the mnemonic phrase, miner gas price and the block gas limit.
ganache --miner.defaultGasPrice 200 --miner.blockGasLimit 90071 --miner.callGasLimit 898989 --wallet.mnemonic "alarm cause brave super lab glide awake hunt rose win sugar idea"
And if you’re like me and just always lost we can run the command ganache --help
for a list of all the available options we can pass to Ganache, which is super useful.
Forking Mainnet
Ganache uses the zero config mainnet forking feature under the hood, allowing us to simulate having the same state as the Ethereum mainnet, but on your local machine.
Ganache 7 and Infura integration lets us access free historical data on Ethereum. With no extra configuration and a single command, you can instantly fork Ethereum’s Mainnet.
To run Ganache in full archive mode, use this command: ganache --fork
.
Ganache then connects to an existing archive node – So either Infura’s by default or to a specific node if we pass in a url, so let’s go with the default for now.
We’ll have a quick look at making requests to blocks older than 128 blocks from the head, which would be the archive data feature.
Ganache fetches five blocks back from the latest by default to avoid missing blocks due to reordering.
So we’ll start off with ganache --fork
which will give us our mainnet fork.
Now in a new terminal window we’ll run a request that fetches the balance of an address at block 0.
We’ll use the eth_getBalance RPC method that take an address as well as an optional block param.
The number after the address specifies the block number from where we want our result, for demonstration purposes, let’s use block 0.
Taking a look at etherscan, this account received 1000 ETH from the genesis block at block 0.
ganache --fork
. curl --data '{"method":"eth_getBalance","params":["0xe5Fb31A5CaEE6a96de393bdBF89FBe65fe125Bb3", "0x1"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST http://localhost:8545
What we get back as a response the number 0x36… is hex representation of 1 x 10^21 (WEI) which is equal to 1000 ETH, so leave a comment below with more ideas on how we could query this data now that it’s available free with Ganache.
Fork Testnets without sync time
In addition to being able to fork the Ethereum main network with zero configuration, Ganache also allows you to fork from any Ethereum test network, including Ropsten, Kovan, Rinkeby, and Görli.
You can do that by running the fork command ganache --fork.network rinkeby
.
We can see at the Forked Chain location section we have the Ethereum rinkeby via infura. They’ve made it that easy.
Fast forward time
Ganache exposes two RPC methods for manipulating time on your development blockchain.
A typical use case would be a smart contract that requires that a specific time passes before users can take certain actions; if the set time isn’t something you want to wait for, you can use the evm_increaseTime
to increase the blockchain current timestamp by the specified amount of time in seconds (passed in as hexadecimal).
Increase Time (mainnet fork example) curl --data '{"method":"evm_increaseTime","params":["0x15180"],"id": 1,"jsonrpc": "2.0"}' -H "Content-Type: application/json" http://localhost:8545
Not Just The CLI
As much as working in the terminal makes me feel like a hacker, I’d like to use Ganache in my projects.
We can use Ganache in node several ways. – As a stand alone EIP-1193 provider – As a JSON RPC and EIP Provider – A web3.js provider AND – An ethers.js provider.
That’s a lot.
Let’s add it to a node as an EIP-1193 provider. CODE Inside our node we use npm install ganache
no Global flag this time, then we simply add it to our scripts object in the package.json.
const ganache = require("ganache");
const options = {};
const provider = ganache.provider(options);
const accounts = await provider.request({ method: "eth_accounts", params: [] });
As a JSON-RPC web server and an EIP-1193 provider. -> 10x speed coding demo, zoom out to full screen code block
const ganache = require("ganache");
const options = {};
const server = ganache.server(options);
const PORT = 8545;
server.listen(PORT, err => {
if (err) throw err;
console.log(`ganache listening on port ${PORT}...`);
const provider = server.provider;
const accounts = await provider.request({ method: "eth_accounts", params:[] });
});
As a Web3.js provider -> 10x speed coding demo, zoom out to full screen code block
const Web3 = require("web3");
const ganache = require("ganache");
const web3 = new Web3(ganache.provider());
As an Ethers.js provider -> 10x speed coding demo, zoom out to full screen code block
const ganache = require("ganache");
const provider = new ethers.providers.Web3Provider(ganache.provider());
Ah I forgot to mention, we can just import it directly into the browser using the script tag, and then we can access Ganache from our project.
<script src="https://cdn.jsdelivr.net/npm/ganache@7.0.0/dist/web/ganache.min.js"></script>
const options = {};
const provider = Ganache.provider(options);
Pending transactions
In Ethereum, every transaction has a nonce. The nonce is the number of transactions sent from a given address to date, and anytime you send a transaction, the nonce increases by 1.
For a transaction to be mined, it has to have a nonce greater than that of the previous transaction by 1. In earlier versions of Ganache, if you send a transaction with a nonce greater than the last nonce by more than 1, Ganache would error, and the transaction would be rejected.
With Ganache 7, if the nonce of the previous transaction is 1 and you send a transaction with the nonce set to 3 for whatever reason, this transaction will sit in the transaction pool until a transaction with nonce 2 is sent, at which time both transactions will be mined and added to the blockchain state.
Impersonating Addresses
Ganache allows you to impersonate another account during development. You can fork Mainnet and impersonate any account.
Here’s an example of how you can fork Mainnet, impersonate an account, and send some tokens to another account!
Forking as the Impersonator CODE
ganache --fork --wallet.unlockedAccounts '0xe5Fb31A5CaEE6a96de393bdBF89FBe65fe125Bb3'
Check balance of impersonation CODE This returns the balance in WEI encoded as a hex number.
curl --data '{"method":"eth_getBalance", "params":["0xe5Fb31A5CaEE6a96de393bdBF89FBe65fe125Bb3"],"id": 1,"jsonrpc":"2.0"}' -H 'Content-Type: application/json' http://localhost:8545
Send the transaction CODE Send some ether from the unlocked account to another account:
curl --data '{"method":"eth_sendTransaction","params": [{"from": "0xe5Fb31A5CaEE6a96de393bdBF89FBe65fe125Bb3", "to": "0x7F00520332f2bACE518d0B61760155d3ff9D7B87", "value": "0x1"}],"id": 1,"jsonrpc":"2.0"}' -H 'Content-Type: application/json' http://localhost:8545
The impersonator is deducted. CODE Now we can verify that the unlocked account’s balance has been reduced.
curl --data '{"method":"eth_getBalance", "params":["0xe5Fb31A5CaEE6a96de393bdBF89FBe65fe125Bb3"],"id": 1,"jsonrpc":"2.0"}' -H 'Content-Type: application/json' http://localhost:8545
Conclusion.
The team working behind Truffle Suite and Ganache have obviously been listening to thier users and it shows. The number of improvements and new features, speaks volumes.
We’ll leave a link in the description below https://trfl.io/g7 to the new v7 docs so you can check out the full list of new additions and let us know how you’re going to be using these new features to power up your web3 development work flow!
Leave a Reply