Contracts
Prepare your folder for your dapp
mkdir dapp
inside this folder, we’ll create one folder for truffle, one for geth.
cd dapp
mkdir truffle geth
inside the geth folder, simply put the customGenesis block you can find in the ethereum-dev-environment blog post.
We are going to use two Ethereum clients, one for tests and devs, testrpc and one for a more real interaction, geth.
Let’s install truffle and testrpc
npm install ethereumjs-testrpc truffle
Truffle
Truffle is a-m-a-z-i-n-g for contract development. It will allow you to unit test the contracts and compile them into usable javascript objects usable in web3! Just what we needed!
First, init truffle scaffolding (I don’t like -g install XD, so bear with my node_modules folder).
node_modules/truffle/cli.js init
This will create different folders. You can have a look at http://truffle.readthedocs.io/ to have more details.
Testrpc
Let’s launch the ethereumjs-testrpc
node_modules/ethereumjs-testrpc/bin/testrpc
You will see it will create a new chain, in memory and create 10 new accounts for you to test.
Standard token contracts
Don’t try to reinvent the wheel, Consensys has given standard contracts to issue your own token. Have a look here: https://github.com/ConsenSys/Tokens
Just copy to your contract folder:
- Tokens/Token_Contracts/contracts/HumanStandardToken.sol
- Tokens/Token_Contracts/contracts/StandardToken.sol
- Tokens/Token_Contracts/contracts/Token.sol
Migrate
Here is the simple migration script I used
module.exports = (deployer) => {
deployer.deploy(
HumanStandardToken,
1000000,
'mold',
'0',
'M'
);
};
In order to compile and deploy your contracts in the rpc node you configured in truffle.js, you need to launch the following command:
node_modules/truffle/cli.js migrate
If your code compiles, it will create javascript objects for each of your contract in the folder build/contracts.
Testing
Here is an example of tests on HumanStandardToken (ES6)
const it = require('mocha').it;
const assert = require('chai').assert;
contract('HumanStandardToken', (accounts) => {
it('should put 1000000 molds in the first account', () => {
const molds = HumanStandardToken.deployed();
const initSupply = 1000000;
return molds.balanceOf(accounts[0])
.then(balance => assert.equal(
balance.valueOf(), initSupply,
`${initSupply} molds weren't in the first account`
)
);
});
it('should transfer molds to another user', () => {
const molds = HumanStandardToken.deployed();
return molds.transfer(accounts[1], 100, { from: accounts[0], gas: 400000 })
.then(
() => molds.balanceOf(accounts[1])
)
.then(balance => assert.equal(
balance.valueOf(), 100,
`${accounts[1]} didn't was not transfered 100 molds but ${balance.valueOf()}`
)
);
});
it('should emit a transfer event when there is a transfer', (done) => {
const transferredAmt = 1;
const transferWatcher = molds.Transfer({ fromBlock: 'latest' },
(error, results) => {
assert.equal(
results.args._value.valueOf(), transferredAmt,
`transfer event amount not equal to ${transferredAmt}`
);
transferWatcher.stopWatching();
done();
});
// trigger the event
molds.transfer(accounts[1], transferredAmt, { from: accounts[0], gas: 400000 });
});
});
** / ! \ ** I was stuck for hours because of the way contract functions can be called. There are two types of actions on the Ethereum blockchain. Action which change the contract states (like transfer funds for example), and the one which don’t (like get balance, for example). In truffle, you call the latter with a “call” on the contract object, whereas the former doesn’t need it… Confusing, isn’t it? I found out later that there are constant functions in solidity, which basically mean functions that don’t change the contract state. When you specify these functions in you contract definition as “constant”, then, truffle doesn’t need the call… Problem solved, everything now looks uniform.
Now you can try if everything works fine, launch testrpc
node_modules/ethereumjs-testrpc/bin/testrpc
and open a new terminal and launch the tests
node_modules/truffle/cli.js test
Creation of the contracts on a private geth or even morden
Modify your truffle.js to whichever node you want to migrate your contracts to. Mine is local geth, listening on port 9012, so truffle.js will become
module.exports = {
rpc: {
host: 'localhost',
port: 9012,
},
};
then migrate
node_modules/truffle/cli.js migrate
Et voila! if everything is ok, truffle should have created your contracts and updated the built contracts with the right contract addresses in build/contracts.
Now, let’s play with these contracts on geth! See you on part 2.