Ethereum Developer Onboarding: Step 2

In step 2 of our 3-step Ethereum developer onboarding you're going to get set up with Truffle, Ganache, create your own smart contract, and explore Remix.

Second Steps

In this section we are going to introduce a few powerful tools to make your development experience as easy as possible. We will install a development environment called Truffle, explore Solidity, cover the fundamentals of a smart contract (we’ll even make our own!), and start our very own node on our local machine. Once we have successfully deployed locally, we will use Remix to interact with our contract and dive deeper into the development process!

Getting Familiar With Truffle

Truffle

Truffle is an excellent development environment that allows you to both connect with and test using the Ethereum Virtual Machine. Truffle was created to make development easier, and with interactions occurring locally this helps reduce the stress of deployment on both a testnet (such as Ropsten or Rinkeby) and mainnet.

For more documentation on Truffle take a look here:

Screen Shot 2020 08 26 at 5 49 43 PM

To install Truffle in your terminal go ahead and run the following:

npm install truffle -g

Note: Recommendations for Windows
If you’re running Truffle on Windows, you may encounter some naming conflicts that could prevent Truffle from executing properly. Please see the section on resolving naming conflicts for solutions.

Ganache 

While we are at it let’s go ahead and install the CLI for ganache

A quick rundown on ganache is that it’s a personal blockchain you can use locally to quickly spin up and test functionality of projects. Ganache is a tool you can use throughout the entirety of the development cycle. Not only are you able to develop, but also deploy, and test your dApps. All of this happens locally on your machine so this is the lowest friction / risk environment to work on your projects!

Using npm:

npm install -g ganache-cli

Ok, back to truffle!

Some of the offerings Truffle provides:

  • Built-in smart contract compilation, linking, deployment and binary management.
  • Automated contract testing for rapid development.
  • Scriptable, extensible deployment & migrations framework.
  • Network management for deploying to any number of public & private networks.
  • Package management with EthPM & NPM, using the ERC190 standard.
  • Interactive console for direct contract communication.
  • Configurable build pipeline with support for tight integration.
  • External script runner that executes scripts within a Truffle environment.

For our tutorial we are going to build something from the ground up, however you are absolutely encouraged to check out some of the boiler projects Truffle has already created called Truffle Boxes (found here).

Now that we have truffle and ganache installed, let’s discuss solidity!

Solidity 

Solidity is an incredibility popular object-oriented, high-level language for implementing smart contracts that run on the Ethereum Virtual Machine (EVM). Smart contracts are programs which govern the behavior of accounts within the Ethereum state. If you’ve never looked at a line of Solidity prior, but are familiar with C++ and or JavaScript you will notice more than a few similarities. 

Solidity is a statically typed language that supports inheritance, libraries, and complex user-defined types among other features. With Solidity you can create contracts for uses such as voting, crowdfunding, even blind auctions to name just a few uses cases. 

Solidity is compiled into bytecode that is executable on the EVM. With Solidity, developers are able to write applications that implement self-enforcing business logic embodied in smart contracts, leaving for a nonrepudiation record of transactions. Smart contracts allow users to trust the code, which assists in creating a trustless environment where potential human corruption is greatly removed. 

Keep in mind when deploying contracts, you should always pay attention to the version you’re using. Breaking changes, new features, and bug fixes are introduced regularly (remember this if you find yourself following tutorials online, running into errors can happen, so keep the documentation close to you). 

Starting a Truffle Project 

With that said let’s start our project and name it “eth-hello-world”

Jump in your terminal and let’s create a new empty folder 

mkdir eth-hello-world

Once we have our empty directory go ahead and jump into the folder and run the command

truffle init

Once the process finishes we should be able to view some the files that were created for us:

Screen Shot 2020 08 26 at 7 21 53 PM
We now have contacts, migrations, a test folder, and a truffle-config file. Let’s have a look into these files and discuss at a higher level  what they are.

Contracts

This folder will contain all of your smart contracts (which in this example we will be creating using Solidity). If you’ve never heard of smart contacts, a way to think about them is; pieces of code that run on the blockchain (this can be local, test, or mainnet) that are guaranteed to produce the same results for everyone running them. Smart Contracts are used within dApps (decentralized applications) and have a tremendous amount of use cases. Voting, gaming, supply chain, currencies, financial records, and that’s just to name a few!

To break this down even further Nick Szabo gives the vending machine example. If you put in the correct amount of coins into the machine, you (and everyone before / after you) can expect the same exact result in exchange. The same goes for smart contacts built on Ethereum, they contain a value and until their conditions are met (i.e. the right amount of coins in our example) it will then unlock and release the information you’re trying to retrieve.

We will come back to discussing Solidity and smart contracts a little later on, let’s move on to migrations!

Migrations

Migrations are Javascript files that allow you to deploy your contracts to the Ethereum network. What’s really interesting about them is there is an underlying assumption your work will evolve, and your deployment will change over time. As you make updates, you’ll make new migration scripts during your project’s evolution. A way to think about migration files is they are predominantly responsible for the staging and deployment of your tasks. A simple way to think about them is migrations are a set of managed deployment scripts. As you update your work, a log of your previously run migrations is recorded on-chain through a build-in Migrations contract.

Take a look for yourself, you already have a migration contract! Head over to your contract directory and open it up, you’ll see a Migrations.sol file that contains a contract that should look something like this:

Screen Shot 2020 08 27 at 4 49 03 AM

This is a default contract that is created for us when we run truffle init. Truffle by nature requires you to have a Migration contract in order to use the migration feature, so don’t delete this!

Note: You must deploy this contract inside your first migration in order to take advantage of the Migrations feature.

Now that we’ve had a chance to look at our Migration contract we can head over to the migration directory and we will see a file named 1_inital_migrations.js

Note: Take a look at the naming convention of this file, it is prefixed with a number and is suffixed by a description. The numbered prefix is required in order to record whether the migration ran successfully. The suffix is purely for human readability

Screen Shot 2020 08 27 at 5 09 25 AM
As you create contracts, you’ll need to make sure you have a migration.js file in conjunction to them. Without diving too deep into artifacts.require(), deployer.deploy, etc here is some excellent documentation from the truffle team to further explain the usage of these methods.

To compile a Truffle project, change to the root of the directory where the project is located and then type the following into a terminal:

truffle compile

To run your migrations in your terminal you’ll eventually run (hold on though, we don’t need to do this yet!)

truffle migrate

This will run all migrations located within your project’s migrations directory.
What’s interesting to note is this command will only run newly created migrations. So if your previous migration ran successfully, it will not rerun it. Also, if no new migrations exist to run, it simply won’t run. If needed you can use the –reset option to run all your migrations from the beginning.

Other command options are documented here.

Note: We installed earlier, but for local testing make sure to have a test blockchain such as Ganache installed and running before executing migrate.

Testing

When it comes to writing tests truffle comes loaded with some excellent tools to make this intuitive. Especially if you plan on deploying your contracts to mainnet, (but it’s good practice, even on testnet) it’s very important to run tests and check your contracts to the best of your abilities. Truffle has made it simple and manageable to review / test your development.

Truffle uses the Mocha testing framework and Chai for assertions to provide you with a solid framework from which to write your JavaScript tests. 

Note: If you’re unfamiliar with writing unit tests in Mocha, please see Mocha’s documentation before continuing.

Side note: An excellent tool to utilize to review your contracts thoroughly is Mythx, the premier security analysis service in the field offering in- depth reviews for smart contracts. Their mission is to not only ensure you avoid costly errors but to make Ethereum a more secure and trustworthy platform overall.

All test files should be located in the ./test directory. Truffle will only run test files with the following file extensions: .js, .ts, .es, .es6, .jsx, and .sol. All other files are ignored.

To run all tests, simply run:

truffle test

Now that we have covered what truffle init creates and the scaffolding of our project, let’s now go ahead and add our smart contract to our project!

Writing a Smart Contract

Let’s jump into the contract directory and write our first contract we plan on deploying to our local test environment (ganache)!

We will start out by creating our .sol file, which we will name HelloWorld.sol

Next we can add our basic contract which will look something like this

pragma solidity >=0.5.8 <0.7.0;

contract HelloWorld {
   string public message;

   constructor(string memory initMessage) public {
       message = initMessage;
   }

   function update(string memory newMessage) public {
       message = newMessage;
   }
}

Looking at our contract a little closer we can break down a few elements

Remember, a contract is a collection of functions and data (its state).

The pragma keyword can be used to enable certain compiler features or checks. A pragma directive is always local to a source file, so you have to add the pragma to all your files if you want enabled in your project. Without a declaration of pragma at the start of our (or any) solidity file, our contract will not know how to compile.
(here is a link to the solidity docs to learn the ins and outs of solidity nuances)

Ultimately, a contract is a collection of functions and data (its state) that resides at a specific address on the Ethereum blockchain.

Looking at the functionality of our contract we can see we are setting our message to be viewable public string. 
The keyword “public” makes variables accessible from outside a contract and creates a function that other contracts or SDKs can call to access the value string public message.

contract HelloWorld {
   string public message;

Here is a function that only runs during the creation of the contract 

 constructor(string memory initMessage) public {
       message = initMessage;
   }

It takes a string value and stores the value in the memory data storage area, setting message to that value message i.e. initMessage.

We can then initialize a message that is passed as a parameter and can be altered / updated with the update function.
This is publicly accessible function that takes a string as a parameter and updates `message` (see below).

   function update(string memory newMessage) public {
       message = newMessage;
   }
}

There you have it, a basic but digestible HelloWorld contract!

Now that we have our contract added we can now make sure it has the ability to compile!
Head over to the Migration folder in our project and we will now make a .js file dedicated to our HelloWorld contract.

We will create a new file and name is 2_deploy_contracts.js

Remember the note on naming conventions from earlier!

const HelloWorld = artifacts.require("HelloWorld");

module.exports = function (deployer) {
  deployer.deploy(HelloWorld, "string");
};

Nice work! We are almost ready to deploy our contract, but first we need to make sure our truffle-config files knows who to talk to. As mentioned earlier we are going to focus on our local environment in this section, but in section 3 (spolier) we not only create and deploy locally, we bring it on to a test network!

Scroll down in your truffle-config.js file until you see the section pertaining to networks
uncomment / add the following 

networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*",
    },

Now your file should look something like this:
 
Screen Shot 2020 08 31 at 6 14 45 AM
Whats happening here is we are tell our config file specific directions on what to connect with. In this case as you’ll see soon, we will be connecting to our ganache-cli tool.

Start Ganache

With that said let’s go ahead and start up our ganache 

in your terminal go ahead and run 

ganache-cli

Screen Shot 2020 08 31 at 6 20 12 AM
Check it out! You are now running your own TestRPC right there in your terminal! 
(more on this here)

Note: Keep this tab in your terminal open, but go ahead and open a new one to work out of.

Quick Review 

Let’s head back to our project and take a quick to review what we’ve done. 

  • We created a new project
  • Initialized Truffle
  • Took a quick tour of the scaffolding
  • Created our HelloWorld contract
  • Added logic to our migrations folder for our contract
  • Went into our config file and adjusted our network information 

Time to get our contract up and running! 

In our new terminal window (since we have ganache running in the other) 
let’s go ahead and run 

truffle compile

You should now see this as as result in your terminal:

Screen Shot 2020 08 31 at 7 07 17 AM
If you now go to your project you’ll see you now have a build / contracts folder above your contract folder containing two .json files. You should see: 

  • HelloWorld.json
  • Migrations.json 

The .json file at a high level describes the deployed contract and its functions. It allows us to contextualize the contract and call its functions.

If we take a look inside we can see a whole bunch of information:
 
Screen Shot 2020 08 31 at 8 01 28 AM
We dive into this information deeper in step three but something important to take a look at is the ABI.

The Application Binary Interface is a data encoding scheme used in Ethereum for working with smart contracts.
Taking a look at the information it’s relatively intuitive to understand. The ABI also defines how the user can call the functions — that is, the location of the function in relation to the smart contract address. A high level summarization is the ABI is the description of the contract interface. It does not contain code and doesn’t have the ability to run by itself. Then you have the bytecode, which is the executable EVM code but by itself it is without context.

Time to migrate

OK! 

So now that we have our ganache-cli running and we’ve compiled our smart contract so now it’s time to migrate our contracts! 

in your terminal go ahead and run 

truffle migrate

YES! You did it!

Screen Shot 2020 08 31 at 8 37 37 AM
We can see we have successfully deployed our smart contract. You can see some really helpful information was generated and if you head to your other tab with ganachi-cli running you should see a TransactionReceipt (take a look for yourself).

Test ETH 

Before we head over to Remix we need to get a hold of some test ETH so we can pay the gas fees on Remix (don’t worry this won’t cost you actually money). 
Head over to this faucet and grab some Rinkeby. We dive into what test ETH is in step 3, but in this step just know we will be using Rinkeby which is a Proof of Authority network opposed to let’s say Ropsten which is a Proof of Work testnet (which is more similar to the public main net). After completing steps 2 and 3 you’ll have some of both in your MetaMask wallet to experiment with!

Remix

Ok, now that we have some test EHT it’s time to head over to Remix and deploy our contract outside of our local environment and even have the ability to interact with it!

“what the heck is Remix?” 

Glad you asked! 

Remix is a powerful, open source tool that helps you write Solidity contracts straight from the browser. One really amazing element in particular about Remix is that it supports both usage in the browser and locally! Remix supports testing, debugging, and contract deployment to name a few key features. Remix should be considered a staple tool for a developer in their building process. Starting with local deployment (as we did earlier) with ganache is an excellent foundation, moving from local deployment we can experiment and interact with our contract on Remix.

Taking proper persuasions and testing (again and again) your development before a potential launch to the main ethereum network can save you perhaps more than a headache!

Now let’s take the same contract and deploy it outside of our local environment using Remix 
Link here 

Our contract 

Click on new file and let’s name it HelloWorld.sol

(here is the contract we will be using again) 

pragma solidity >=0.5.8 <0.7.0;

contract HelloWorld {
   string public message;

   constructor(string memory initMessage) public {
       message = initMessage;
   }

   function update(string memory newMessage) public {
       message = newMessage;
   }
}

We can now go ahead and add our contract in the field. (Check it out below) 

Screen Shot 2020 08 31 at 9 47 48 AM

Now let’s check out the left menu that asks for your selected compiler version.

Compiler

Keep in mind within our contract we have declared our compiler range.
Remember the pragma keyword is used to enable certain compiler features or checks. 

So we can set our compiler to 0.6.0 which falls between our provided range (see blow) 

Screen Shot 2020 09 08 at 8 44 41 AM

Our contract should automatically compile, if not go ahead and click Compile HelloWorld.sol

Next we will set up our Environment to deploy our contract! 

Deploy and run transactions

Environment 

You’ll notice a few different options when selecting your environment:

JavaScript VM: All the transactions will be executed in a sandbox blockchain in the browser. This means nothing will be persisted when you reload the page. The JsVM is its own blockchain and on each reload it will start a new blockchain, the old one will not be saved.

Injected Provider: Remix will connect to an injected web3 provider. Metamask is an example of a provider that inject web3.

Web3 Provider: Remix will connect to a remote node. You will need to provide the URL to the selected provider: geth, parity or any Ethereum client.

In this example we are going to use: Injected Web3

We will use our MetaMask wallet and make sure we are connected to our Rinkeby test Network 

We can see on the left side we are connected to Rinkeby and also see our connected account address! 

Screen Shot 2020 09 08 at 8 30 29 AM

Once we have everything set, let’s go ahead and deploy our contract!

Screen Shot 2020 09 08 at 8 57 35 AM

🎉We did it! 🎉 

Check out the provided terminal and you can see the confirmation

Screen Shot 2020 09 08 at 8 58 11 AM

Now we have the ability to view our deployed contract, we can update our message (we have to both sign and pay the gas fee for this since we are updating the state)

Once we have confirmation we can see our message has updated!

Screen Shot 2020 09 08 at 9 18 54 AM
🥳 Well done! 🥳 

We’ve taken the contract that we initially started with locally and have deployed that contract on Remix to have a visual representation of contract interaction. This is a healthy flow for developer as they start to build in this space. Remix is an incredible tool that should be utilized often. In Step 3 we are going to go a step further and tie all of the information we’ve learned in Steps 1 & 2 and tie  Truffle + Infura + React together!