Compiling, Deploying, Testing TNS tokens — SitePoint

In part 2 of this tutorial series on building DApps with Ethereum, we wrote the TNS token’s code. But we haven’t yet compiled it, deployed it, tested it or verified it. Let’s do all that in this part so that we’re ready for what comes next.


At this point we have a file containing some Solidity code. But to make the Ethereum Virtual Machine understand it, we need to turn it into machine code. Additionally, in order to communicate with it from a web application, we need an ABI (application binary interface), which is a universally readable description of the functions that exist in a certain smart contract — be it a token or something more complex. We can create machine code for the EVM and the ABI all at once by using Truffle’s compiler.

In the project folder, run:

truffle compile

This command will look inside the contracts subfolder, compile them all and place their compiled version into the build subfolder. Note that if you used the alternative development flow from the last part, all the parent contracts from which our TNSToken contract is inheriting functionality will also be compiled one by one each in its own file.

Feel free to inspect the contents of the generated JSON files. Our TNSToken should have over 10000 lines of JSON code.

Deploying to Ganache

Now let’s see if we can deploy this to our simulated Ganache blockchain. If Ganache isn’t running already in a tab of your terminal or among your operating system’s applications, run it with:


Or run the app to get a screen like this one:

Ganache UI

Then, back in the folder where we just compiled the contracts, we have to add a migration. Create the file migrations/2_deploy_tnstoken.js. If you’re not familiar with migrations in the Truffle ecosystem, see this guide.

Let’s put the following into that file:

var Migrations = artifacts.require("./Migrations.sol");
var TNSToken = artifacts.require("./TNSToken.sol");

module.exports = function(deployer, network, accounts) {
  deployer.deploy(TNSToken, {from: accounts[0]});

First the ability to do migrations at all is imported by requesting Migrations.sol. This is required in every migration. Next, deploying a token means we need to import its Solidity code, and we do this by pulling in TNSToken.sol, the code we wrote in the previous part. Finally, this is cookie cutter migrating with only the part between function(deployer, network, accounts) { and the last } changing.

In this case, we tell the deployer to deploy the TNSToken and pass in the from argument in order to set the initial token holder. The address used here is a random one generated by Ganache, but by using the accounts array automatically passed to the deployer, we make sure we have access to the list of accounts present in the running node (be it a live Geth node or Ganache). In my particular example, the account[0] address was 0xdFb659D556d926dd3585d0f18d4F8eD7939E8061, also evident in the screenshot above.

Let’s also not forget to configure a development environment in truffle.js:

module.exports = {
  networks: {
    development: {
      host: "",
      port: 7545,
      network_id: "*"

Note: take care of the port and IP; yours might be different!

Finally, in the project folder, run truffle migrate. You should see something like this:

A successful migration

Notice the Ethereum address next to TNStoken: 0x3134bcded93e810e1025ee814e87eff252cff422. This is where our token was deployed. Now let’s see it in action.

Testing the Token

Automated tests are not necessary in this case. Token contracts are highly standardized and battle tested. If we had used some functionality that goes beyond the scope of a traditional token, then automated tests would have come in handy. As it is, though, testing it by sending it around to and from addresses is quite enough.

Open a wallet UI like MyEtherWallet and in the top right menu select a custom network. In the dialog, enter the information given to you by your private blockchain — either Ganache or an actual PoA blockchain, whichever you’re running based on part 1 of this tutorial series. In my example, that’s for the address, and 7545 for the port.

Configuring the network in MEW

Open the wallet which you set as the from value in the deployment script. If you’re using Ganache, you’ll see its private key printed on screen in the Ganache UI or the ganache output in the terminal.

The private key is accessible in the Ganache UI

Finally, MEW needs to be told that this token exists. We do this by adding a custom token.

Adding a custom token in MEW

Immediately after having added the token, you’ll notice that the account now has a balance of 100 million of them, and that it’s able to send them in the currency dropdown selection menu. Let’s try sending some to another address.

Sending some tokens

Transaction is being prepared

Tokens have been received

Go ahead and send those back now to get the original account back to 100 million again. We’ve just made sure our token’s basic functionality works as intended.

Deploying to a Live Network

This wouldn’t be a real token test without also deploying it on a live network. Let’s not use the mainnet, though, but a testnet like Rinkeby.

In truffle.js, let’s add a new network — rinkeby — so that our file looks like this:

const WalletProvider = require("truffle-wallet-provider");
const Wallet = require('ethereumjs-wallet');
const Web3 = require("web3");
const w3 = new Web3();

const PRIVKEY = process.env["PRIVKEY"];
const INFURAKEY = process.env["INFURAKEY"];

module.exports = {
  networks: {
    development: {
      host: "",
      port: 7545,
      network_id: "*"
    rinkeby: {
      provider: function() {
        return new WalletProvider(
            Buffer.from(PRIVKEY, "hex")), ""+INFURAKEY

      gas: 4600000,
      gasPrice: w3.utils.toWei("50", "gwei"),
      network_id: "3",

Yikes! What is all this now?

Let’s process it line by line.

The first few lines import some node modules so we can use the functions below. If you get a missing module message for any of those, just running npm install web3-wallet-provider truffle-wallet-provider web3 dotenv --save should fix things.

Next, we load the private key of the wallet from which we’re running the contract (so the wallet which will be getting the 100 million tokens; we can’t use the from value here) from a .env file in the root of the project folder. If it doesn’t exist, create it. That same file also has an access key, which is a website that hosts Ethereum nodes and lets apps connect to them so developers don’t need to run full Ethereum nodes on their computers.

The .env file is hidden by default and can be ignored in .gitignore so there’s no danger of your private key ever leaking — a very important precaution! This is what the file contains:


You can get your Infura key by registering here. The private key can easily be obtained if you just install Metamask, switch it to Rinkeby, and go to Export Private Key. Any method will work, though, so choose whatever you like. You can also use Ganache’s private key. A single private key unlocks the same wallet on all Ethereum networks — testnet, rinkeby, mainnet, you name it.

Back to our config file. We have a new network entry: rinkeby. This is the name of the Ethereum testnet we’ll be deploying to and the code inside the provider is basically cookie-cutter copy paste telling Truffle “grab my private key, hex-encode it, make it into an unlocked wallet, and then talk to Infura through it”.

Lastly, we define the gas limit we want to spend on executing this contract (4.6 million is enough, which can be changed if needed), how much the gas will cost (50 Gwei is actually quite expensive, but the Ether we’re playing with is simulated so it doesn’t matter) and the network ID is set to 4 because that’s how the Rinkeby testnet is labeled.

There’s one more thing we need to do. The migration file we wrote earlier is targeting a from address, but the address for Rinkeby is different. Does this mean we need to change the deployment script depending on the network? Of course not! Let’s change the 2_deploy_tnstoken.js file to look like this:

var Migrations = artifacts.require("./Migrations.sol");
var TNSToken = artifacts.require("./TNSToken.sol");

module.exports = function(deployer, network, accounts) {
  if (network == "development") {
    deployer.deploy(TNSToken, {from: accounts[0});
  } else {

As you can see, deployment scripts are simple JavaScript and the second parameter given to the deployer is always the network’s name — which is what we can use to differentiate between them.

If we try to run the migration now with truffle migrate --network rinkeby, it will fail if the address we used is new:

A failing migration

This is because the address has no Ether to spend on deploying the contract. That’s easy to solve, though. Just head over to the Rinkeby Faucet and ask for some. It’s free.

Asking for Rinkeby test ether

Now re-run the migration and the token contract will be deployed live on the Rinkeby network. It can be tested just like in the Ganache use case above. Everything should work exactly the same, only now you can also test it with your friends and colleagues. Progress!

Bonus: Verification and ENS

For extra trust points, it’s recommended that you verify the token on Etherscan and register an ENS domain for it.


Verification means submitting the source code of the token to Etherscan so it can compare it to what’s deployed on the network, thereby verifying it as backdoor-free. This is done on the Code tab of the token’s address. Since our token uses some third-party code and those can’t be easily pulled into the code window in the Verify screen, we need to flatten our contract. For that, we’ll use a tool called truffle-flattener:

npm install --global truffle-flattener

This tool will copy all the dependencies and the token’s source code into a single file. We can run it like this:

truffle-flattener contracts/TNSToken.sol >> ./contracts/TNSTokenFlat.sol

A new file should be present in the contracts folder now, virtually identical to our source code but with dependency code pasted in (so SafeMath.sol, for example, will be pasted at the top of the file).

Paste the contents of that new file into the code window of the Verify screen, set the compiler to whatever version you get by running truffle version, and set Optimization to No. Click Verify and Publish, and once the process completes, your token’s address screen will have new tabs: Read Contract and Write Contract, and the Code tab will have a green checkmark, indicating that the code has been verified. This gives you additional trust points with the community.

The token is now marked as trusted


The ENS is the Ethereum Name System. It’s used to give Ethereum addresses human-readable names so you don’t have to remember the 0xmumbojumbo strings and can instead remember addresses like bitfalls.eth. You can then even register subdomains like token.bitfalls.eth. The process of registering an ENS domain is not simple and it takes time, so if you’d like to do that I recommend you read this guide and follow the instructions here.


In this part we went through compiling and deploying a custom token. This token is compatible with all exchanges and can be used as a regular ERC20 token.

Be the first to comment

Leave a Reply

Your email address will not be published.


Privacy Policy is committed to safeguarding your privacy. Contact us at if you have any questions or problems regarding the use of your Personal Data and we will gladly assist you.

By using this site or/and our services, you consent to the Processing of your Personal Data as described in this Privacy Policy.

Table of Contents

  1. Definitions used in this Policy
  2. Data protection principles we follow
  3. What rights do you have regarding your Personal Data
  4. What Personal Data we gather about you
  5. How we use your Personal Data
  6. Who else has access to your Personal Data
  7. How we secure your data
  8. Information about cookies
  9. Contact information


Personal Data – any information relating to an identified or identifiable natural person.
Processing – any operation or set of operations which is performed on Personal Data or on sets of Personal Data.
Data subject – a natural person whose Personal Data is being Processed.
Child – a natural person under 16 years of age.
We/us (either capitalized or not)

Data Protection Principles

We promise to follow the following data protection principles:

  • Processing is lawful, fair, transparent. Our Processing activities have lawful grounds. We always consider your rights before Processing Personal Data. We will provide you information regarding Processing upon request.
  • Processing is limited to the purpose. Our Processing activities fit the purpose for which Personal Data was gathered.
  • Processing is done with minimal data. We only gather and Process the minimal amount of Personal Data required for any purpose.
  • Processing is limited with a time period. We will not store your personal data for longer than needed.
  • We will do our best to ensure the accuracy of data.
  • We will do our best to ensure the integrity and confidentiality of data.

Data Subject’s rights

The Data Subject has the following rights:

  1. Right to information – meaning you have to right to know whether your Personal Data is being processed; what data is gathered, from where it is obtained and why and by whom it is processed.
  2. Right to access – meaning you have the right to access the data collected from/about you. This includes your right to request and obtain a copy of your Personal Data gathered.
  3. Right to rectification – meaning you have the right to request rectification or erasure of your Personal Data that is inaccurate or incomplete.
  4. Right to erasure – meaning in certain circumstances you can request for your Personal Data to be erased from our records.
  5. Right to restrict processing – meaning where certain conditions apply, you have the right to restrict the Processing of your Personal Data.
  6. Right to object to processing – meaning in certain cases you have the right to object to Processing of your Personal Data, for example in the case of direct marketing.
  7. Right to object to automated Processing – meaning you have the right to object to automated Processing, including profiling; and not to be subject to a decision based solely on automated Processing. This right you can exercise whenever there is an outcome of the profiling that produces legal effects concerning or significantly affecting you.
  8. Right to data portability – you have the right to obtain your Personal Data in a machine-readable format or if it is feasible, as a direct transfer from one Processor to another.
  9. Right to lodge a complaint – in the event that we refuse your request under the Rights of Access, we will provide you with a reason as to why. If you are not satisfied with the way your request has been handled please contact us.
  10. Right for the help of supervisory authority – meaning you have the right for the help of a supervisory authority and the right for other legal remedies such as claiming damages.
  11. Right to withdraw consent – you have the right withdraw any given consent for Processing of your Personal Data.

Data we gather

Information you have provided us with
This might be your e-mail address, name, billing address, home address etc – mainly information that is necessary for delivering you a product/service or to enhance your customer experience with us. We save the information you provide us with in order for you to comment or perform other activities on the website. This information includes, for example, your name and e-mail address.

Information automatically collected about you
This includes information that is automatically stored by cookies and other session tools. For example, your shopping cart information, your IP address, your shopping history (if there is any) etc. This information is used to improve your customer experience. When you use our services or look at the contents of our website, your activities may be logged.

Information from our partners
We gather information from our trusted partners with confirmation that they have legal grounds to share that information with us. This is either information you have provided them directly with or that they have gathered about you on other legal grounds. See the list of our partners here.

Publicly available information
We might gather information about you that is publicly available.

How we use your Personal Data

We use your Personal Data in order to:

  • provide our service to you. This includes for example registering your account; providing you with other products and services that you have requested; providing you with promotional items at your request and communicating with you in relation to those products and services; communicating and interacting with you; and notifying you of changes to any services.
  • enhance your customer experience;
  • fulfil an obligation under law or contract;

We use your Personal Data on legitimate grounds and/or with your Consent.

On the grounds of entering into a contract or fulfilling contractual obligations, we Process your Personal Data for the following purposes:

  • to identify you;
  • to provide you a service or to send/offer you a product;
  • to communicate either for sales or invoicing;

On the ground of legitimate interest, we Process your Personal Data for the following purposes:

  • to send you personalized offers* (from us and/or our carefully selected partners);
  • to administer and analyse our client base (purchasing behaviour and history) in order to improve the quality, variety, and availability of products/ services offered/provided;
  • to conduct questionnaires concerning client satisfaction;

As long as you have not informed us otherwise, we consider offering you products/services that are similar or same to your purchasing history/browsing behaviour to be our legitimate interest.

With your consent we Process your Personal Data for the following purposes:

  • to send you newsletters and campaign offers (from us and/or our carefully selected partners);
  • for other purposes we have asked your consent for;

We Process your Personal Data in order to fulfil obligation rising from law and/or use your Personal Data for options provided by law. We reserve the right to anonymise Personal Data gathered and to use any such data. We will use data outside the scope of this Policy only when it is anonymised. We save your billing information and other information gathered about you for as long as needed for accounting purposes or other obligations deriving from law, but not longer than 1 year.

We might process your Personal Data for additional purposes that are not mentioned here, but are compatible with the original purpose for which the data was gathered. To do this, we will ensure that:

  • the link between purposes, context and nature of Personal Data is suitable for further Processing;
  • the further Processing would not harm your interests and
  • there would be appropriate safeguard for Processing.

We will inform you of any further Processing and purposes.

Who else can access your Personal Data

We do not share your Personal Data with strangers. Personal Data about you is in some cases provided to our trusted partners in order to either make providing the service to you possible or to enhance your customer experience. We share your data with:

Our processing partners:


Our business partners:


Connected third parties:


We only work with Processing partners who are able to ensure adequate level of protection to your Personal Data. We disclose your Personal Data to third parties or public officials when we are legally obliged to do so. We might disclose your Personal Data to third parties if you have consented to it or if there are other legal grounds for it.

How we secure your data

We do our best to keep your Personal Data safe. We use safe protocols for communication and transferring data (such as HTTPS). We use anonymising and pseudonymising where suitable. We monitor our systems for possible vulnerabilities and attacks.

Even though we try our best we can not guarantee the security of information. However, we promise to notify suitable authorities of data breaches. We will also notify you if there is a threat to your rights or interests. We will do everything we reasonably can to prevent security breaches and to assist authorities should any breaches occur.

If you have an account with us, note that you have to keep your username and password secret.


We do not intend to collect or knowingly collect information from children. We do not target children with our services.

Cookies and other technologies we use

We use cookies and/or similar technologies to analyse customer behaviour, administer the website, track users’ movements, and to collect information about users. This is done in order to personalize and enhance your experience with us.

A cookie is a tiny text file stored on your computer. Cookies store information that is used to help make sites work. Only we can access the cookies created by our website. You can control your cookies at the browser level. Choosing to disable cookies may hinder your use of certain functions.

We use cookies for the following purposes:

  • Necessary cookies – these cookies are required for you to be able to use some important features on our website, such as logging in. These cookies don’t collect any personal information.
  • Functionality cookies – these cookies provide functionality that makes using our service more convenient and makes providing more personalised features possible. For example, they might remember your name and e-mail in comment forms so you don’t have to re-enter this information next time when commenting.
  • Analytics cookies – these cookies are used to track the use and performance of our website and services
  • Advertising cookies – these cookies are used to deliver advertisements that are relevant to you and to your interests. In addition, they are used to limit the number of times you see an advertisement. They are usually placed to the website by advertising networks with the website operator’s permission. These cookies remember that you have visited a website and this information is shared with other organisations such as advertisers. Often targeting or advertising cookies will be linked to site functionality provided by the other organisation.

You can remove cookies stored in your computer via your browser settings. Alternatively, you can control some 3rd party cookies by using a privacy enhancement platform such as or For more information about cookies, visit

We use Google Analytics to measure traffic on our website. Google has their own Privacy Policy which you can review here. If you’d like to opt out of tracking by Google Analytics, visit the Google Analytics opt-out page.

Read more about cookies on our Cookie Policy

Contact Information

email: [email protected]

Changes to this Privacy Policy

We reserve the right to make change to this Privacy Policy.

You can configure your Internet browser, by changing its options, to stop accepting cookies completely or to prompt you before accepting a cookie from the website you visit. If you do not accept cookies, however, you may not be able to use all portions of the WideBitcoin Websites or all functionality of the Services.

Please note that disabling these technologies may interfere with the performance and features of the Services.

You may also disable cookies on the WideBitcoin Sites by modifying your settings here:

Visitor comments may be checked through an automated spam detection service.

Last Update: May 25, 2018