In the last post we mentioned Truffle Boxes, now we will use one to create our own token and interact with it on a local instance of a running blockchain (Ganache).
First, we create a folder for our project, unbox OpenZeppelin's tutorialtoken in it 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:
pragma solidity ^0.4.17;
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
contract TestToken is StandardToken {
}
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:
string public name = 'TestToken';
string public symbol = 'TT';
uint8 public decimals = 2;
uint public INITIAL_SUPPLY = 12000;
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. Most tokens have 18 decimals, meaning they can be subdivided to .0000000000000000001 tokens (but one can also give it a value of 0, making the token non-divisible). 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 be 100000000000000000000 (18 zeroes after the amount).
And finally, we need to insert a constructor function (about which we talked about in previous posts) 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:
function TestToken() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
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:
pragma solidity ^0.4.17;
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
contract TestToken is StandardToken {
string public name = 'TestToken';
string public symbol = 'TT';
uint8 public decimals = 2;
uint public INITIAL_SUPPLY = 12000;
function TestToken() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
}
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:
var TestToken = artifacts.require("TestToken");
module.exports = function(deployer) {
deployer.deploy(TestToken);
};
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 exntension (in Chrome, Brave or FireFox) and connect it to our custom RPC at http://127.0.0.1:7545/.
When generating an account it's important to use the Ganache mnemonic as shown in Accounts:
MNEMONIC
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 conclude 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 Ethscan 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've in possession of our tokens.