Ethereum, tokens & smart contracts.

Notes on getting started Part 4. Smart Contracts

Previous notes in case you are just joining us:
Part 1. Setting up.
Part 2. Web3.js/node.
Part 3. Solidity.

Basic Storage:

FILE: basicStorage.sol/* Stolen from the docs */pragma solidity ^0.4.0;contract basicStorage {
uint storedData;
function set(uint x) {
storedData = x;
}
function get() constant returns (uint) {
return storedData;
}
}
// JAVASCRIPT ES6
// Source : dVvoWr
class basicStorage {
constructor(Data) {
this.storedData = Data;
}

set(x) {
this.storedData = x;
}

get() {
return this.storedData;
}

}

var BS = new basicStorage(0);
BS.set(10);
console.log(BS.get()); // 10

Compile and Deploy :

FILE: Compiler.jsconsole.log('Setting up...');
const fs = require('fs');
const solc = require('solc');
const Web3 = require ('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Reading contract Source...');
const input = fs.readFileSync('basicStorage.sol');
console.log('Compiling...');
const output = solc.compile(input.toString(), 1);
if (output.errors) {
console.log('Compiling failed with errors:' + output.errors);
process.exit();
}
const bytecode = output.contracts[':basicStorage'].bytecode;
const abi = output.contracts[':basicStorage'].interface;
console.log('saving ABI');
fs.writeFile("./basicStorage.json", abi, function(err) {
if (err) {
return console.log(err);
}
console.log("ABI Saved");
});
const basicStorage = web3.eth.contract(JSON.parse(abi));console.log('unlocking Coinbase account');const password = "yourPasswordHere";
try {
web3.personal.unlockAccount(web3.eth.coinbase, password);
} catch(e) {
return console.log(e);
}
console.log("Deploying contract...");
const basicStorageInstance = basicStorage.new({
data: '0x' + bytecode,
from: web3.eth.coinbase,
gas: 400000
}, function(err, res){
if (err) {
console.log('there were errors:' + err);
}
if (res.address) {
console.log('txHash:' + res.transactionHash);
console.log('Succesfully deployed Contract with address: ' + res.address);
}
});
Setting up...
Reading contract Source...
Compiling...
saving ABI
unlocking Coinbase account
Deploying contract...
ABI Saved
txHash:0x2d053628cea870c20d4757e706c4312ea3db14c74887131b7d4f5560ad0d04ee
Successfully deployed Contract with address: 0x20ed8cc5c767b100c6a5b018e533e38b44b36326
// FILE: setTransaction.jsconsole.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./basicStorage.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
const basicStorage = web3.eth.contract(contractABI);
var basicStorageInstance = basicStorage.at("0x20ed8cc5c767b100c6a5b018e533e38b44b36326");
console.log('unlocking Coinbase account');
const password = "your_password";
try {
web3.personal.unlockAccount(web3.eth.coinbase, password);
} catch(e) {
console.log(e);
return;
}
console.log ('sending Transaction to the contract');basicStorageInstance.set.sendTransaction(42, {from:web3.eth.coinbase}, function(err, txHash) {
if (err != null) {
console.error("Error while sending transaction: " + err);
}
else{
console.log("Transaction Sent here's you txHash: " + txHash);
}
});
// If you are not interested in the callback/want a shorter version you can use:
// basicStorageInstance.set(42, {from:web3.eth.coinbase});
Setting up...
Reading abi
Connecting
Creating contract instance
unlocking Coinbase account
sending Transaction to the contract
Transaction Sent here's you txHash: 0x05e71b56c95c66d6fe59984d9af0bee00cac7c62cd210571a5c0c96009f28d83
// FILE: getCall.jsconsole.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./basicStorage.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
const basicStorage = web3.eth.contract(contractABI);
var basicStorageI = basicStorage.at("0x20ed8cc5c767b100c6a5b018e533e38b44b36326");
console.log ('calling contract');var returner = parseInt(basicStorageI.get.call());
console.log(returner + 10);
// 52
Note: web3 is in active development, calling methods might be slightly different in the next version or 1.0.0.

Watching contracts:

// FILE: filterWatch.js// Watches the blockchain:
// filter can be 'latest' or 'pending' check :
// https://ethereum.stackexchange.com/questions/3400/filters-whats-latest-and-pending
console.log('Setting up...');
const solc = require('solc');
const Web3 = require('web3');
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
filter = web3.eth.filter('latest'); console.log('Watching');
filter.watch(function(error, result) {
console.log(result);
});
Setting up...
Connecting
Watching
0x3296600010cd439485a254e71cc5b88fcdcf3752858df9161b55eac1586d5e3d
0x2715f22c8b5bc5ebea25d2b76f0ad789eba692591d86d0d786120b2aa8d4b49c
0x0e35d29ed8dcf93c0b7b514b6cc4d9dd181372015346f85d4b680f650a181969
.....

Contract Events

// FILE : basicStorageEv.sol
//
Thanks to GregJeanmart for the snippet.
pragma solidity ^0.4.0;contract basicStorage {
uint storedData;
event SetEvent(
address indexed _from,
uint _x
)
;
function set(uint x) {
storedData = x;
// Log event inside set
SetEvent(msg.sender, x);
}
function get() constant returns (uint) {
return storedData;
}
}
console.log('Setting up...');
const fs = require('fs');
const solc = require('solc');
const Web3 = require ('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Reading contract Source...');
const input = fs.readFileSync('basicStorageEv.sol');
console.log('Compiling...');
const output = solc.compile(input.toString(), 1);
if (output.errors) {
console.log('Compiling failed with errors:' + output.errors);
process.exit();
}
const bytecode = output.contracts[':basicStorageEv'].bytecode;
const abi = output.contracts[':basicStorageEv'].interface;
console.log('saving ABI');
fs.writeFile("./basicStorageEv.json", abi, function(err) {
if (err) {
return console.log(err);
}
console.log("ABI Saved");
});
const basicStorageEv = web3.eth.contract(JSON.parse(abi));console.log('unlocking Coinbase account');const password = "your_password";
try {
web3.personal.unlockAccount(web3.eth.coinbase, password);
} catch(e) {
return console.log(e);
}
console.log("Deploying contract...");
const basicStorageEvInstance = basicStorageEv.new({
data: '0x' + bytecode,
from: web3.eth.coinbase
// gasPrice: '4000000',
// gas: 1000000 /
}, function(err, res){
if (err) {
console.log('there were errors:' + err);
}
if (res.address) {
console.log('txHash:' + res.transactionHash);
console.log('Succesfully deployed Contract with address: ' + res.address);
}
});
Setting up...
Reading contract Source...
Compiling...
saving ABI
unlocking Coinbase account
Deploying contract...
ABI Saved
txHash:0x344020880f594d9c776b750d84f9d1bec9f1c1d6ff6e66663e99cf3dde73c098
Succesfully deployed Contract with address: 0xac88d694726e84ae46e2450cc8e30ea882a0cc43
console.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./basicStorageEv.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
const basicStorageEv = web3.eth.contract(contractABI);
var basicStorageEvI = basicStorageEv.at("0xac88d694726e84ae46e2450cc8e30ea882a0cc43");
var myEvent = basicStorageEvI.SetEvent({}, {fromBlock: 0, toBlock: 'latest'});console.log("Start watching events");
myEvent.watch(function(error, result){
if (!error) {
console.log(result);
} else {
console.log(error);
}
});
FILE: watchEvents.jsSetting up...
Reading abi
Connecting
Creating contract instance
Start watching events
{ address: '0xac88d694726e84ae46e2450cc8e30ea882a0cc43',
blockHash: '0x69ee11dec3121715a8ec082ca386d4b4d547aa184739228307164a105dbb7c24',
blockNumber: 4061192,
logIndex: 1,
transactionHash: '0x4e75edab76bd83911caf003e6de05324f3f10cc7f90886e3d0112139956bc640',
transactionIndex: 1,
transactionLogIndex: '0x0',
type: 'mined',
event: 'SetEvent',
args:
{ _from: '0x001301ad1556fd419cf8970b174fe9af34267eb8',
_x: { [String: '10'] s: 1, e: 1, c: [Array] } } }
{ address: '0xac88d694726e84ae46e2450cc8e30ea882a0cc43',
blockHash: '0x9a09b2920072fd0eaf4bbc0fe5f38c431b80e747e8443b4eb1050114acbc5ddf',
blockNumber: 4061200,
logIndex: 3,
transactionHash: '0xd3eb8d1dd11e6db6140bb8a3741889462d7c4102c2c08eed405664fa5b30e91b',
transactionIndex: 1,
transactionLogIndex: '0x0',
type: 'mined',
event: 'SetEvent',
args:
{ _from: '0x001301ad1556fd419cf8970b174fe9af34267eb8',
_x: { [String: '10'] s: 1, e: 1, c: [Array] } } }
{ address: '0xac88d694726e84ae46e2450cc8e30ea882a0cc43',
blockHash: '0xad9d8038f8e0334046fe530306c980f773698eae1873e224899dce1fe3fbc276',
blockNumber: 4061224,
logIndex: 3,
transactionHash: '0x5c0fa62c3c3b7015fda363b8d973708d7526c998b4fb8ae53cfe7adbd76123fe',
transactionIndex: 1,
transactionLogIndex: '0x0',
type: 'mined',
event: 'SetEvent',
args:
{ _from: '0x001301ad1556fd419cf8970b174fe9af34267eb8',
_x: { [String: '10'] s: 1, e: 1, c: [Array] } } }

GAS :

console.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./basicStorage.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
const basicStorage = web3.eth.contract(contractABI);
var basicStorageInstance = basicStorage.at("0x20ed8cc5c767b100c6a5b018e533e38b44b36326");
console.log('unlocking Coinbase account');
const password = "your_password";
try {
web3.personal.unlockAccount(web3.eth.coinbase, password);
} catch(e) {
console.log(e);
return;
}
console.log ('sending Transaction to the contract');const transaction = {
from: web3.eth.coinbase,
gas: 0,
gasPrice: 0

}
basicStorageInstance.set.sendTransaction(220, transaction, function(err, txHash) {
if (err != null) {
console.error("Error while sending transaction: " + err);
}
else{
console.log("Transaction Sent here's you txHash: " + txHash);
}
});
Setting up...
Reading abi
Connecting
Creating contract instance
unlocking Coinbase account
sending Transaction to the contract
Error while sending transaction: Error: Transaction gas is too low. There is not enough gas to cover minimal cost of the transaction (minimal: 21464, got: 0). Try increasing supplied gas.
File: estimateGas.jsconsole.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./basicStorage.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
const basicStorage = web3.eth.contract(contractABI);
var basicStorageInstance = basicStorage.at("0x20ed8cc5c767b100c6a5b018e533e38b44b36326");
var estimatedTransactionGas = basicStorageInstance.set.estimateGas(220);console.log('Estimated Transaction Gas:' + estimatedTransactionGas);
Setting up...
Reading abi
Connecting
Creating contract instance
Estimated Transaction Gas:26586
var gasPrice = web3.eth.gasPrice;
console.log('Current Gas price:' + gasPrice.toString(10));
// Current Gas price:20000000000// See: https://ethereum.stackexchange.com/questions/27452/how-to-estimate-gas-cost
console.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./basicStorage.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
const basicStorage = web3.eth.contract(contractABI);
var basicStorageInstance = basicStorage.at("0x20ed8cc5c767b100c6a5b018e533e38b44b36326");
var estimatedTransactionGas = basicStorageInstance.set.estimateGas(220);
var gasPrice = web3.eth.gasPrice;
console.log('Cost estimates: ' );
console.log('Estimated Transaction gas: ' + estimatedTransactionGas );
console.log('gas Price: ' + gasPrice);
console.log('unlocking Coinbase account');
const password = "your_password";
try {
web3.personal.unlockAccount(web3.eth.coinbase, password);
} catch(e) {
console.log(e);
return;
}
console.log ('sending Transaction to the contract');const transaction = {
from: web3.eth.coinbase,
gas: estimatedTransactionGas,
gasPrice: gasPrice

}
basicStorageInstance.set.sendTransaction(220, transaction, function(err, txHash) {
if (err != null) {
console.error("Error while sending transaction: " + err);
}
else{
console.log("Transaction Sent here's you txHash: " + txHash);
}
});
Setting up...
Reading abi
Connecting
Creating contract instance
Cost estimates:
Estimated Transaction gas: 26586
gas Price: 20000000000 ( or 20 Gwei or 0.00000002 ether )
unlocking Coinbase account
sending Transaction to the contract
Transaction Sent here's you txHash: 0x9617338ce298b2da4d4610aeca6324c1c5aa05b21347aac6a572b3b7b9253d3b
Note: Gas estimation is not a perfect science, at least to me,your transaction might still fail due to sudden gas price changes or other network variables, so you might have to increase by a factor both gas price and the gas used if you want to insure your transactions succeed.

Want to take these notes offline ?
If you are looking for an introduction to Ethereum, Solidity and Smart Contracts these notes are now available in a paper and ebook form! ❤️📖❤️https://www.amazon.com/dp/B078CQ8L7V

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