Truffle is the most widely used developer environment and a pipeline framework for writing, testing, and deployment of smart contracts on the Ethereum network designed to make life easier. This guide will show you the basics of how to deploy your solidity smart contract using Truffle Suite.


The truffle suite basically integrates all the necessary tools to get one started, including TestRPC (now known as Ganache) — a local full node simulation for testing our code’s behavior before deployment.


Before we proceed to dive in though, let’s stop to elucidate some of Solidity and smart contracts’ key features so as to get a more comprehensive understanding of the underlying logic. Above all, the EVM (Ethereum Virtual Machine) and the blockchain ledger necessitate complete determinism within the smart contract. That means that the same input will always produce the same output which allows for all the nodes to reach a global consensus about the state of the blockchain (thus, introducing non-deterministic behavior would make the whole network come to a halt).


The idea is to enable people across the globe to do business even if they don’t speak the same language or use the same currency (as Ethereum’s Mihai Alisie put it). This is why Solidity is a statically typed language where everything must be strictly defined within the intended context (and why Python is so difficult to integrate). Although not difficult to grasp and get the hang of after awhile, the devil is in the details (see the DAO hack), just like with traditionally notarized contracts.

Bitcoin Exchange CEX.IO


This is one of the reasons Ethereum has a peer-reviewed memorandum whereby common standards and best practices are developed and agreed upon (the ERC, or “Ethereum Request for Comment”, similar to IETF’s RFC), reducing the amount of errors in individual solutions and allowing parties to take advantage of what is already tried and tested without having to roll their own. The ERC-20, by now part of the common ‘crypto’ vernacular, is one such widely applied standardization which introduces a set of common features and a general interface for token issuance and transfer.


For the sake of a quick example we can go to, copy the contract code as per instructions and paste it in the Contract code field in the Ethereum wallet (after going to Contracts and Deploy Contract). Deploy Contract Code Screenshot


Solidity contract source code


It must be noted that the only mandatory parameter in a standard ERC-20 contract is the total supply. Name, symbol (roughly equivalent to the ticker) and decimals are optional, intended for improving usability and giving a token more unique identity.


Syntactically, the Solidity language is a mishmash of conventions from networking, web design and assembly code (in-line option for those mythical creatures that can deal with it). It looks like JavaScript, but has types and contracts look like Python classes/objects.


A Solidity contract typically contains mappings, state variables and functions. A mapping initializes a hash table that maps account balances and addresses (or any key to any value). In Solidity code it is the commonly encountered mapping (address => uint) balances; at the beginning of the contract and can be envisioned as something like this:


The total supply of tokens in this case is 124 + 210 = 334. A token may represent anything from physical objects to holder reputation, monetary value, software license or certificate, etc. This is important in the context of how we define the token.


Functions fall in two categories important to distinguish:


Read-only functions (designated as “constant”) which do not cause any state changes or write to the blockchain, thus require no gas to execute (audits are free, the ledger is public).


Transactional functions, which do perform state changes and therefore spend gas in order to execute and ‘write’ on the blockchain (the cost EVM operations in gas can be found here).


Generally, writing data to the network is called a transaction while reading data is called a call. Transactional functions usually do not return a value, but a transaction id (as seen on the blockchain explorer, Etherscan) and are not processed until the next block. Calls, on the other hand, are free to execute and immediately return a value.


The gas cost incurred for ‘writing’ is proportional to the computational work done and is meant to stay constant (i.e., when Ether goes up, the price of gas goes down). This prevents a whole range of attack vectors by making them prohibitively expensive (and with the migration to Proof-of-Stake this year, where the idea is that one risks what one stakes, Vlad Zamfir puts it thus: “if you participate in a failed 51% attack, PoS will burn your ASIC farm down”).


We should also mention that in Ethereum, accounts are identified by an address which is derived differently for external (usually owned by humans) and contract accounts. This is reminiscent of the ‘flat ontology’ in Actor-Network Theory and the Object-Oriented paradigm of “everything is an object” on an equal ontological footing.


Now, let’s get back to Truffle. Make sure you have NodeJS 5.0+ and run the following installation:

$ npm install -g truffle


Next, we spin up a set of default contracts and tests by running the following:

$ mkdir newProject
$ cd newProject
$ truffle init

Our current directory contains a truffle configuration file (truffle.js) and three subdirectories: contracts, migrations and tests (which are self-explanatory).


From there on we can run truffle compile, truffle migrate and truffle test correspondingly to compile our contracts, deploy them to the network and run their associated tests. If not connected to an ethereum client we can run Ganache as a local blockchain simulation (which is ideal for our purposes).


Another important component is truffle develop which spawns an integrated blockchain environment (running locally on port 9545) generating 10 accounts from a group of easy to remember words (called mnemonic, or mnemonic code/sentence). After launching it, we end up into a console where we can run truffle commands without the command-line prefix:

$ truffle develop
*text showing the accounts and private keys generation*


We use Truffle Develop or Ganache whenever we’re testing our project with no intention of immediately deploying on the mainnet and don’t need to use or interact with specific live accounts (which, amazingly enough, can themselves be libraries or factories).


Now let’s have a look at our contracts library.
All Solidity contracts, including associated libraries have the file extension .sol.

With a bare Truffle project (truffle init) we have a single Migrations.sol file for helping in the deployment process.


To compile a Truffle project we run truffle compile from the root of the directory where our project is located. At first run, all contracts will be compiled and subsequently only the contracts that have been changed since last compile (to override this, use the command with the –all option).


Dependencies in Solidity are declared using the import command. For example, if we want to import contracts from another file we must add the following in our code:

import "./SomeContract.sol";

The path is relative to where the current contract being written is localized. Contracts can also be imported from external package repositories (such as EthPM and NPM).

import "somepackage/SomeContract.sol";

After compilation the results will be placed in a build/contracts/ directory.


To run the migrations we run truffle migrate (as already mentioned) — this runs all the migrations located in the projects migrations directory. Migrations are essentially sets of managed deployment scripts in JavaScript format. A simple migration file looks like this:

var MyContract = artifacts.require("NewContract");

 module.exports = function(deployer) {
   deployment steps//


The artifacts.require() method is how we tell Truffle which contracts we want to interact with. The name specified should match the name of the contract as defined in the source file as a single .sol file can contain a number of contracts. To use more than one contract we need artifact.require() statements for each one:


Truffle requires a Migrations contract to take advantage of the Migrations feature — that contract is received by default when creating a new project with truffle init and can be found in contracts/Migrations.sol.


To take advantage of the Migrations feature one must deploy the contract inside his first migration. To do so create a file migrations/1_initial_migration.js which contains the following (migration filenames must begin with numbered prefixes):


From here, you can create new migrations with increasing numbered prefixes (2, 3, 4..) that deploy other contracts.


Truffle also comes with an automated testing framework which allows for writing simple and manageable tests in two ways — in JavaScript (for testing from the outside world) and in Solidity (for more advanced scenarios).


All tests are located in the /test directory, but one can also specify a path:

$ truffle test ./path/to/test/file.js


If just running truffle test this will test all files within /test which have the following extensions: .js, .es, es6, .jsx and .sol.


When running tests against Ganache or Truffle Develop, Truffle utilizes advanced snapshooting features to make sure the test files don’t share state with each other.


Now let’s create our own ERC-20 token and interact with it on a local instance of a running blockchain (Ganache) before deploying it on the Ropsten testnet.


We can use the Truffle Boxes, which are sets of ready-made interfaces, contracts, libraries, etc. One can find a list of them here.


So, let’s unbox OpenZeppelin’s tutorialtoken and install the zeppelin-solidity package with npm:


$ mkdir TokenProject
$ cd TokenProject
$ truffle unbox tutorialtoken
$ npm install zeppelin-solidity


Now, in our /contracts directory we create a TestToken.sol file with the following content:


Hereby we import the StandardToken.sol contract and use is to declare our token inherits from the StanndardToken contract — that includes all variables and functions, which can nonetheless be overwritten by redeclaring them in our contract.

So, we set the parameters of our own token that way:


We add the above four lines within our contract, between the curly braces with indentation of four spaces. The name and symbol variables specify our token’s unique identity, while the decimals determine the degree to which it can be subdivided.


Based on the nature of what our token should represent we ought to decide how or whether to subdivide it. For example, if the token represents an non-divisible entity such as a certificate or a software agreement it doesn’t make sense that somebody would hold a fraction of it, so we leave decimals to 0. By default, decimals are usually set to 18, meaning they can be subdivided to .0000000000000000001 tokens.


And lastly, INITIAL_SUPPLY determines the number of tokens created upon deployment. It must be considered however, that the total supply is correlated with the decimals, i.e. if decimal places are set to 18 and the amount of tokens to 100, then the supply would equivalate to 100000000000000000000 (18 zeroes after the amount).


And finally, we need to insert a constructor function (which is executed only ones and has the same name as the contract) which sets a totalSupply equivalent to the declared INITIAL_SUPPLY and gives the total supply to the address of the deploying account. So we add the following below the declared token parameters:


With balances[msg.sender] we set the amount of tokens to receive as the creator of the contract which will be sent to the ETH address of wherever we deploy the contract. The logic of token distribution could, of course, be set otherwise, but for now we’ll keep it simple.


Our final contract looks like this:


Now we can proceed with compilation and deployment.
In the migrations/ directory we create a file entitled 2_deploy_contracts.js with the following content:


Next, we launch Ganache which will generate a blockchain instance running locally on port 7545. And then, within our project’s root directory, we can run:

$ truffle compile

Once compiled, we deploy the contract to our blockchain:

$ truffle migrate


We get something like this:

Running migration: 1_initial_migration.js
Deploying Migrations…
… 0xda8eac2a451f036726f33e52c8d30d43b5b540fc7fd88976e814320c3304e43b
Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network…
… 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts…
Running migration: 2_deploy_contracts.js
Deploying TestToken…
… 0x053985eda138cf6599d0659b44b7a385b84fb324cfc1a7ceb1cf4fafa9c522e0
TestToken: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
Saving successful migration to network…
… 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0
Saving artifacts…


And the transactions will show up on the Ganache GUI.



In order to interact with our token, we must now fire up the MetaMask browser extension (in Chrome, Brave or FireFox) and connect it to our custom RPC at

When generating an account it’s important to use the Ganache mnemonic as shown in Accounts:

candy maple cake sugar pudding cream honey rich smooth crumble sweet treat


From here now on we can send and receive tokens between the ten addresses in Ganache (ours is the first) using MetaMask.


Now let’s finalize by deploying to the testnet. Open the Solidity Remix Compiler in a new browser tab. Then click on the folder icon that says “Add Local File to the Browser Storage Explorer” and add both our TestToken, the StandardToken from which it inherits, and the Token.sol from which StandardToken in turn inherits.


We then switch to the Ropsten testnet via MetaMask, compile our contract, go to the “Run” tab, click “Create” — and a notification pops up in MetaMask asking us to pay for the transaction. We hit “Submit”, go to “Sent” and click on the “Transaction Number” once the contract has been deployed.


Then from Etherscan we copy the contract address, go back to MetaMask and click “Add” in the Tokens tab. We paste the contract address, give the token symbol and decimal points, and that’s it — we’re in possession of our tokens.


Buy Cryptocurrency

Martin Banov

Martin Banov is a nerd of various stripes that seeks to cultivate a more nuanced, trans-disciplinary perspective with the underlying assumption that a chicken is just an egg's way of making more eggs. Hayekian in the economics department, Deleuzian in the philosophy wing and McLuhanist in his reasoning about technology.

Leave a Reply

Your email address will not be published. Required fields are marked *