Migrating an Ethereum Smart Contract to a Live Network with Truffle
The next step once you have built your first Ethereum smart contract is to deploy it to a live network, because lonely smart contracts running onlocalhost
are sad and lonely.
This tutorial will use the simple react truffle box as a starting point, for the sake of simplicity. First we will test and run this app on a local test ethereum environment, then we will deploy the smart contracts to the Rinkeby test net and run it from there.
**disclaimer ** This tutorial is aimed at people who are familiar with the basics of ethereum and smart contracts already. If you are new to ethereum it is possible to follow along with this tutorial, but recommend starting with a simple ‘built your first dapp’ kind of tutorial first.
Setup
(If you have an existing truffle project running locally feel free to skip this section, and go to the Deploy to Rinkeby section below.)
The first requirement is to set up your javascript environment (if you already have npm installed you’re golden). My preferred method of installing node/npm is with nvm (node version manager) for Linux/Mac, or just use the standard installer. You will also need a web3/ethereum enabled browser, I recommend using MetaMask for this purpose.
Next you will need to install truffle and ganache; do this with npm install -g truffle ganache-cli
.
Then open the terminal in a folder you are want to work from and run truffle unbox react
. This will download the pre-made boilerplate which is a minimal set-up of truffle and react, be prepared to wait quite a few minutes for it to download and configure everything.
Thereafter run npm start
to fire up the UI and view it in your browser at http://localhost:3000 and see the interface as below.
On the surface everything looks good but if you open the browser console you will see the following error:
This is error is because the contract hasn’t been deployed to the ethereum network that MetaMask is injecting into the browser (yay, to reading error messages!). If you don’t get the line saying ‘Injected web3 detected.’ please make sure that your MetaMask is set up correctly.
So what we need to do is to deploy the smart contract to the network. We do this by opening another terminal and running ganache-cli -m “your twelve work pass phrase from metamask …”
. When we open MetaMask and set the network to ‘Localhost 8545’ we will see 100.0 Eth has appeared in our account.
Now we need to tell Truffle about this network so that it can deploy to it. Edit the ‘truffle.js’ (or ‘truffle-config.js’ on Windows) file contain the following:
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*' // Match any network id
}
}
};
Now run truffle compile
followed by truffle migrate --network development
. Reload the UI and a MetaMask dialogue asking you to confirm a transaction will display; provided MetaMask is unlocked. Once you accept the transaction the code will set a variable in the smart contract to ‘5’ and display that in the browser.
So far so good! Onwards to Rinkeby my dear friends.
Deploy to Rinkeby
Set MetaMask to use the ‘Rinkeby Test Network’. If your balance is zero go to this faucet to get hands on some test ether for your primary ethereum address (your first address in MetaMask). Deploying contracts to ethereum is an expensive process (it can be as much as 50 USD for complex contracts), so I highly recommend practising with test ether.
We will be using Infura as a hosted node for the sake of convenience; so go ahead and create an Infura account here and record the key that you receive. I will cover how to use a locally running ethereum node in the next section.
Next, runnpm i -s truffle-hdwallet-provider
to install a provider that will connect you to the chosen network, sign your transactions and submit these transactions to the network.
A ‘provider’ is used by web3 to submit transactions to the ethereum network and in this case sign these transactions. To use the provider add the following to your truffle.js
file. We are using a network_id
of 3 for rinkeby, but other network IDs that may be of interest are 1, 4, 42 for main-net, ropsten and kovan respectively.
const HDWalletProvider = require("truffle-hdwallet-provider");
const memonic = "your twelve work pass phrase from metamask …"
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*' // Match any network id
},
rinkeby: {
provider: function() {
return new HDWalletProvider(memonic, "https://rinkeby.infura.io/<<your_infura_access_token>>")
},
network_id: 3
}
}
};
Now you are ready to run the migrations again truffle migrate --network rinkeby
. This will take a bit longer than last when we used Ganache before since we need to wait for the blocks to be mined by the network.
You can then copy the hash from the transaction, in this case 0xbdf619456e2a48065c176304b806b9d334bfd8b5cd389d477ac8d5007f9ba9e5
, and search for it on rinkeby etherscan to confirm and view the details of your transaction.
Open the user interface again and confirm the transaction to set the storage and confirm that the transaction went through on etherscan.
Congratulations, you have deployed your first contract to a public network!
Challenge
If you want to try something slightly more difficult you can try deploying your contract with this modified provider engine that uses a private key directly rather than a memonic phrase. This is directly modified from the original truffle-hdwallet-provider.
Using a locally running node
You can also deploy directly to a local node with an unlocked account. Please be extremely careful with this method, as if your ethereum node is opened up to the public they can execute a transaction with your unlocked account (read steal all your ethereum). This can be done with parity or geth running locally. Please refer to their respective documentation to set them up.
Once your node is running correctly you can deploy your contract in exactly the same way as you did with Ganache, since it also just provides you with a set of unlocked accounts.
Another fun way to deploy your contracts to public networks
You can use https://remix.ethereum.org, paste your code there or use remixd, chose your environment (injected web3 is refering to metamask, as seen in the image below), and click deploy. If you use this method you will need to manually save and link the contract address to Truffle if you want to use Truffle for your UI.
I hope you had fun deploying your first dapp to the world!
Please leave a comment below if you have any issues or suggestions.