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.

REMIX

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.
If you want to copy the contract address use the small file copy icon, our contracts address is: 0x008b85cf793e9860aa24f2eab1f2008551f59b09

Transaction Details:

Debug and conquer.

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

Setting Up :

In use :

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 MigrateThe migrations folder is also where we store our deployment instructions: 2_deploy_contract.js which we'll try now:

Deploying :

// File: 2_deploy_contract.jsvar basicStorage = artifacts.require("./basicStorage.sol");module.exports = function(deployer) {
deployer.deploy(basicStorage);
};
Before deploying start TestRPC: $ testrpcAvailable Accounts==================(0) 0x64d37bd909091ecc8f97483065ce69e0e5a9ea57
(1) 0xa646f9b0cf2cdaa5404f02cb4f8fcf0886ce75a2...etc
Listening on localhost:8545
$ truffle migrate

Interacting with contracts :

$ truffle console$ .exit // to exit.
$ 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.
basicStorage.at("0xd32463887bfe0139eb03d817d795a03296955a04").set.sendTransaction(72,{from:"0x64d37bd909091ecc8f97483065ce69e0e5a9ea57"});
basicStorage.at("0xd32463887bfe0139eb03d817d795a03296955a04").get.call();// Results in :{ [String: '72'] s: 1, e: 1, c: [ 72 ] }

Running Scripts:

// File: scripts/interactTruffle.jsmodule.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 )
$ truffle exec scripts/interactTruffle.jsNote: 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.
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.
// File: scripts/102030.jsmodule.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 ,30Note the use of chained promises.

Testing in Truffle

// 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
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)
// File : TestbasicStorage.solpragma 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:
TestbasicStoragetestInitialBalance (60ms)Contract: basicStorage✓ set & get methods should work (62ms)2 passing (583ms)

Look how far you’ve come !

✨✨  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/B078CQ8L7VGet it ! 🙏 😊

AI, Software Developer, Designer : www.k3no.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store