Ethereum, tokens & smart contracts.

Notes on getting started Part 10. Remix/Truffle/TestRPC

Previous notes in case you are just joining us:
Part 1. Setting up.
Part 2. Web3.js/node.
Part 3. Solidity.
Part 4. Smart Contracts.
Part 5. Smarter Contracts.
Part 6. Tokens & Inheritance.
Part 7. ERC20 Token Standard.
Part 8. Crowdfunding and ICOs.
Part 9. Dapps & MetaMask.

In this quasi finale note, I’d like to check and cover a few related tools ( Remix, Truffle & TestRPC) I left these for last but not least since I believe it is better to have some basic knowledge about contracts, tokens, Dapps & compiling before using them, they can also be viewed as helpful tooling for becoming more productive writing smart contracts.

REMIX

Remix is a debugger, compiler & IDE for smart contracts, it is very accesible since you can start working with the online version immediately and a provider ( like metaMask ).

Note: Why not start with remix ? A lot of tutorials (including Ethereums ) recommend Remix as a starting point and that might work for some,I found it very confusing from the beginning, so I chose the path in these notes and I am glad I did since I believe working with clients, making your own compiler and interacting with the blockchain in other ways gives you a more robust foundation.

Let’s start by going to remix and opening basicStorage.sol contract from part 4 of this notes :

You could of course create a new file and type it from scratch( or copy paste into remix) .Off the bat, remix proves useful by raising warnings…

In order to interact with the blockchain, you need to connect remix to it, here’s how you would connect it to MetaMask by unlocking your account ( you could also use parity or mist), notice how remix pulls our account information…

Once connected you can deploy a contract with the create button:

After creation, you will be asked by MetaMask to confirm the transaction as usual and then your contract transaction will be processed, notice you instantly get the getter and setter.

If you want to copy the contract address use the small file copy icon, our contracts address is: 0x008b85cf793e9860aa24f2eab1f2008551f59b09

You also get a console with the Tx History :

Transaction Details:

Transactions are simply done by the getter and setter in this example, for instance let’s set x to 10,20,and 30:

Each transaction gives you a lot of details by simply clicking the details button on the console.

Debug and conquer.

Another useful tool is the debugger. In order to use it you need to switch to the Javascript VM:

In the Javascript VM you will not need to connect to a blockchain( notice you get 100 ether as a balance); it’s a great way to try out your contracts before releasing them on a blockchain. ( Truffle + Test RPC which we will cover later being another more complex one).

Another feature of the debugger is that of step debugging, you could for instance call the set method (10) and go through the VM machines inner processing ( it seems to have a limited stack, so take that into consideration) …

This is particularly helpful when estimating gas costs of transactions since they are displayed step by step, there are also warnings on gas costs at writing time which together work to help you manage gas on your transactions.

Note: There seems to be a way of working with remix locally via cloning the repo and using geth as the backend, it is not fully documented or fleshed right now, but if you want to go that route check the remix repo for instructions.

TRUFFLE + TestRPC

Truffle is a very popular framework for developing smart contracts while TestRPC is a test and development focused Ethereum client, together they are meant to streamline and make writting smart contracts better and faster, let’s see how they stack up.

Setting Up :

As is sometimes expected from more complex tooling, there is some setup to take care off before we begin…

Upon initializing your project via npm a series of files and folders are created:

Basically folders for contracts, migrations and testing (which we’ll explain soon),pre populated with sample code along with a config file (truffle.js). You can eventually delete some of it for clarity or import “truffle boxes” with preconfigured contract templates.

In use :

Let’s say we want to deploy and interact with one of our previous contracts through truffle, let’s pick once more the basicStorage.sol we used for Remix as a minimal example, let’s also clear the folder- file structure to the bare minimum, the result would be:

Note: There are still a few extra files here that need explaining, contracts is where our contract ( basicStorage.sol ) lives, but there is also the Migrations.sol contract, this contract along with the file 1_initial_migration.js is required for the migration feature to work. 

- What is the Migration feature you ask?
The Migration feature allows you to stage your deployments in incremental steps,add specific environmental variables and keep track of successful migrations, in Migrations.sol which is required in 1_initial_migrations.js, some of these features are initialized..In other words scaffolding for truffle's features, look here for an in depth discussion: Demystifying Truffle Migrate
The migrations folder is also where we store our deployment instructions: 2_deploy_contract.js  which we'll try now: 

Deploying :

In order to deploy we need a deployer…

// File: 2_deploy_contract.js
var basicStorage = artifacts.require("./basicStorage.sol");
module.exports = function(deployer) {
deployer.deploy(basicStorage);
};

The deployer file is handy for deploying one or multiple contracts and performing extra steps ( like calling a contract method) after deploying.

Before deploying start TestRPC: 
$ testrpc
Available Accounts
==================
(0) 0x64d37bd909091ecc8f97483065ce69e0e5a9ea57
(1) 0xa646f9b0cf2cdaa5404f02cb4f8fcf0886ce75a2...etc
Listening on localhost:8545

On another terminal or tab in your initialized Truffle directory (/minimal_truffle in my case)…

$ truffle migrate

If deployed succesfully you will get step by step logs on both your sessions:

Interacting with contracts :

To interact with our contract we first need to start Truffles console:

$ truffle console
$ .exit // to exit.

Getting all the contract information:

$ basicStorage.deployed().then(function(o){console.log(o)});
Spews out a ton of information including the ABI,bytecode, methods and address (0xd32463887bfe0139eb03d817d795a03296955a04) in our case.

Sending a transaction to our contract (notice the web3 syntax) :

basicStorage.at("0xd32463887bfe0139eb03d817d795a03296955a04").set.sendTransaction(72,{from:"0x64d37bd909091ecc8f97483065ce69e0e5a9ea57"});

Calling our contract ( still web3 ):

basicStorage.at("0xd32463887bfe0139eb03d817d795a03296955a04").get.call();
// Results in :
{ [String: '72'] s: 1, e: 1, c: [ 72 ] }

Doing this via Truffles console is not really an improvement over our previous node setup, so we need to figure out a better alternative… ( i.e. more setup).

Running Scripts:

To replicate what we just did in the console in script form, we need to create a new .js file ( I am doing so inside a scripts folder to keep things tidy ):

// File: scripts/interactTruffle.js
module.exports = function(callback) {
var basicStorage = artifacts.require("basicStorage");
basicStorage.deployed().then(function(instance) {
contract = instance;
console.log(contract);
})
}
// Note: the artifacts line, in Truffles parlance it is a contract abstraction and it encapsulates your contract for use within Truffles framework, the equivalent of instantiating a contract with an ABI and/or Bytecode in web3,for an in depth look and extra features check out truffle-contract ( the abstraction module )

And to run it on a terminal in you Truffle directory…

$ truffle exec scripts/interactTruffle.js
Note: You will need to run again truffle migrate if you closed your previous session and change contract & account variables.
...
Spews out a ton of information including the ABI,bytecode, methods and address like before.

By running scripts we can now automate and standarize repetitive or complex interactions with contracts, for instance let’s start by using set() & get() together…

module.exports = function(callback) {
var account = "0xf8c09220dfc59e74727c9db4d58df8ae120d2e93";
var basicStorage = artifacts.require("basicStorage");
var contractInstance = basicStorage.at("0x27974f214310b7977492396f981a93c930297f81");
contractInstance.set.sendTransaction(10, {
from: account
}).then(function(result) {
console.log(result);
// tx : 0x5d899a8a22b4a1599728c6b3fb772d64492f6a94d78365ef88330fb910f06bed
contractInstance.get.call().then(function(result){
console.log(result);
// { [String: '10'] s: 1, e: 1, c: [ 10 ] }
});
});
}
Note we are using the deployed contract Instance at a specific address, also the use of promises for flow.

And a more complex one where we use set and call 3 times in succesion…

// File: scripts/102030.js
module.exports = function(callback) {
var account = "0xc9b3bb2bd6d3ebd4ebf9816052cd84da5c61c116";
var basicStorage = artifacts.require("basicStorage");
var contractInstance = basicStorage.at("0xe32d1865f5e37a20b4b3cf3939cc247a27ff302d");
contractInstance.set.sendTransaction(10, {
from: account
}).then
contractInstance.get.call().then(function(result){
console.log(result);
}).then
contractInstance.set.sendTransaction(20, {
from: account
}).then
contractInstance.get.call().then(function(result){
console.log(result);
}).then
contractInstance.set.sendTransaction(30, {
from: account
}).then
contractInstance.get.call().then(function(result){
console.log(result);
});
}
// String: 10, 20 ,30
Note the use of chained promises. 

This is more useful, for starters we don’t need to be online, and second we can script,log and debug complex behavior with minimal effort beyond the original setup and Truffles learning curve.

Testing in Truffle

Running scripts is one way of testing your contracts, but more likely you will want to do some unit testing, Truffle allows you to do so in a number of ways:

In Js, Truffle uses Mocha as the test library and Chai for assertions, here’s a minimal and silly example with our basicStorage contract:

// File: test/basicStorage.js 
var basicStorage = artifacts.require("basicStorage");
var song = '';
// var song = 'la la la';
contract('basicStorage', function() {
it("should sing you a song !", function() {
assert(song !== '', 'I have no song');
})
});
                     - - - - - - - - - - - - 
To run ( on your Truffle folder ) :
$ truffle test

Results:

Like with scripts, you first need to import your contract ( the artifacts line), the rest employs a standard unit testing syntax ( except you use contract() instead of describe() ).

Moving on, here’s a more realistic test with a deployed contract and method testing( note that testrpc accounts is included just by adding it to the contract):

var basicStorage = artifacts.require("basicStorage");
var testValue = 10;
contract('basicStorage', function(accounts) {
it("set & get methods should work", function() {
return basicStorage.deployed().then(function(instance) {
return instance.set.sendTransaction(testValue, {
from: accounts[0]
}).then(function() {
return instance.get.call().then(function(result) {
assert(result == testValue, 'get value is not set value');
});
});
});
});
});

✓ set & get methods should work (64ms)
1 passing (83ms)

This small example shows how to test for methods on deployed contracts, and much like scripts uses promises to control the flow of information, just make sure to use return at each step that needs to be included in the test ( you can also use async/await for a somehow cleaner syntax ).

Testing with solidity: The other way that Truffle allows you to test your contracts is with solidity via .sol files that run next to the previously discussed tests, a simple example would look like this:

// File : TestbasicStorage.sol
pragma solidity ^0.4.2;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/basicStorage.sol";
contract TestbasicStorage {
basicStorage bs = new basicStorage();
function testInitialBalance() {
Assert.balanceIsZero(bs, 'Assert failed');
}
}

Results:
TestbasicStorage
testInitialBalance (60ms)
Contract: basicStorage
✓ set & get methods should work (62ms)
2 passing (583ms)

Solidity tests are basically contracts with an Assertion interface (another contract) , and they seem to work closer to the base contract which allows you to test somethings like balances & functions in a simpler way,the difference is nuanced but might come in handy if you feel you are drowning in promises with the Js tests,check the Assert.sol contract to look at what’s possible. It was also brought to my attention that with solidity tests you can test behavior when contracts interact with each other, not when Truffle interacts with contracts, but that is an advanced subject best left for later…


To recap, Remix and Truffle ( + test RPC ) are 2 very capable tools for testing your smart contracts, remix is a bare bones affair whereas Truffle brings the smart contract kitchen sink along with a considerable learning curve, I believe that rather than go for one vs the other, a combination of both along with bare node + web3 ( or a wrapper like ethjs) for deploying on testnets could cover all the bases. I should also mention that these tools are in active development and new ones might become available in the near future. For now I would like to close these notes on getting started with a collection of intermediate subjects which will be the subject of next notes, for now, let’s summarize the road traveled so far:

Look how far you’ve come !

  • Notes Part 1 : Setting up : Getting a wallet/client , connecting to a test Ethereum blockchain and getting some test ether.
  • Notes Part 2: web3.js/node : Interacting with the blockchain through web3.js and node for more convenience and ease of development.
  • Notes Part 3: Solidity : Installing solidity (Ethereums contract writing language ) , Creating a very basic contract, compiling it, deploying it to the blockchain ( the test one) and interacting with it.
  • Notes Part 4: Smart Contracts : We modified our simple contract so we could store and retrieve information (making it smart), in the process we also covered how to watch the blockchain and contracts and finally we took a look at gas and how to estimate it.
  • Notes Part 5: Smarter Contracts: In order to allow contracts more complex behavior (make them smarter) , we need to delve a bit deeper into contract creation via constructors and a few more complex types which we will use in making a token contract.
  • Notes Part 6: Tokens & Inheritance : We made our first Token and interacted with it by transferring some of it from one account to another, we also briefly covered inheritance which is used in more complex contracts.
  • Notes Part 7: ERC20 Token Standard : We made and deployed an erc20 token which can be considered the parting standard for working sub currencies. We examined the code and talked about transfers in between tokens.
  • Notes Part 8: Crowdfunding and ICOs : We explored the subject of crowdfunding via smart contracts in the form of ICOs and the exchange of ether for tokens, we made contracts that can receive ether, collect ether and can be used for exchanging ether and creating an unlimited supply of tokens.
  • Notes Part 9: Dapps & MetaMask : We looked into what a Dapp is and where we are in terms of development ( very early), we then introduced MetaMask which helps make Dapps accessible in the browser , we looked at various ways to interact with MetaMask via Javascript and we integrated them into a fully fledged test Dapp that uses our previously made token smart contract, we also touched on the future of Dapps and server implementations.
  • Notes part 10: Remix/Truffle/TestRPC (This post): A look into Ethereums current tooling ecosystem, Remix, which allows you to quickly validate contracts online, testRPC which recreates an offline blockchain in your computer, and Truffle, which has a bit of a learning curve in exchange for complex testing and deploying options.
✨✨  Now a Book !  ✨✨
If you are looking for an introduction to Ethereum, Solidity and Smart Contracts these notes were edited and revised into a convenient book !
Available in ebook and paperback:
https://www.amazon.com/dp/B078CQ8L7V
Get it ! 🙏 😊

Cheers !

Keno

About the Author :

Born Eugenio Noyola Leon (Keno) I am a Designer,Web Developer/programmer, Artist and Inventor, currently living in Mexico City, you can find me at www.k3no.com