The Complete Tutorial On Getting Started With Smart Contracts On Ethereum

Author: Decentral Inc
General Inquiries: lqm@decentral.finance

Download and install Node.js

dev@MacBook-Pro ~ % node -vv12.18.3dev@MacBook-Pro ~ % npm -v6.14.6

Download and install an IDE

{
"editor.dragAndDrop": false,
"editor.fontSize": 12,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.formatOnPaste": true,
"editor.wordWrap": "on",
"editor.quickSuggestions": {
"other": true,
"comments": true,
"strings": true
},
"explorer.confirmDragAndDrop": false,
"explorer.confirmDelete": false,
"files.autoSave": "onFocusChange",
"workbench.colorTheme": "Default Light+",
"solidity.enabledAsYouTypeCompilationErrorCheck": true,
"solidity.linter": "solium",
"solidity.packageDefaultDependenciesContractsDirectory": "",
"solidity.packageDefaultDependenciesDirectory": "",
"solidity.validationDelay": 1500
}

Install Truffle

mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
source ~/.profile
npm install -g truffle
dev@MacBook-Pro ~ % truffle vTruffle v5.1.41 (core: 5.1.41)Solidity v0.5.16 (solc-js)Node v12.18.3Web3.js v1.2.1
/Users/dev/Applications

Truffle Boxes

  1. Create a new directory for your Truffle project:
mkdir MetaCoin
cd MetaCoin
truffle unbox metacoin
code .

Using Truffle and Open Zeppelin to create an ERC20 Token

cd ..
mkdir ERC20Token
cd ERC20Token
truffle init
code .
function Migrations() public {owner = msg.sender;}
constructor() public {owner = msg.sender;}
npm init -y
npm install -E openzeppelin-solidity
pragma solidity ^0.4.23;
import "openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol";
"solidity.packageDefaultDependenciesContractsDirectory": "",
"solidity.packageDefaultDependenciesDirectory": "",
/**
* @title ERC20Token
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
* Note they can later distribute these tokens as they wish using `transfer` and other
* `StandardToken` functions.
*/
contract ERC20Token is StandardToken {
string public constant name = "ERC20Token"; // solium-disable-line uppercase
string public constant symbol = "ERC"; // solium-disable-line uppercase
uint8 public constant decimals = 18; // solium-disable-line uppercase
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(decimals));/**
* @dev Constructor that gives msg.sender all of existing tokens.
*/
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
emit Transfer(0x0, msg.sender, INITIAL_SUPPLY);
}
}
const ERC20Token = artifacts.require('ERC20Token');contract('ERC20Token', accounts => {
let token;
const creator = accounts[0];
beforeEach(async function () {
token = await ERC20Token.new({ from: creator });
});
it('has a name', async function () {
const name = await token.name();
assert.equal(name, 'ERC20Token');
});
it('has a symbol', async function () {
const symbol = await token.symbol();
assert.equal(symbol, 'ERC');
});
it('has 18 decimals', async function () {
const decimals = await token.decimals();
assert(decimals.eq(18));
});
it('assigns the initial total supply to the creator', async function () {
const totalSupply = await token.totalSupply();
const creatorBalance = await token.balanceOf(creator);
assert(creatorBalance.eq(totalSupply));
});
});
truffle test
Contract: ERC20Token
✓ has a name
✓ has a symbol
✓ has 18 decimals
✓ assigns the initial total supply to the creator
4 passing (356ms)
build/
node_modules/
*.sol linguist-language=Solidity

Deploying to Ganache (Local)

npm install -g ganache-cli
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
}
}
};
ganache-cli
truffle compile
Compiling ./contracts/ERC20Token.sol...
Compiling ./contracts/Migrations.sol...
Compiling openzeppelin-solidity/contracts/math/SafeMath.sol...
Compiling openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol...
Compiling openzeppelin-solidity/contracts/token/ERC20/ERC20.sol...
Compiling openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol...
Compiling openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol...
Writing artifacts to ./build/contracts
var ERC20Token = artifacts.require("./ERC20Token.sol");module.exports = function(deployer) {
deployer.deploy(ERC20Token);
};
truffle migrate --network development
Using network 'development'.Running migration: 1_initial_migration.js
Deploying Migrations...
... 0x4f87ddd3c299752294356431998d511e1879b08d3a6b5acff36d4727f92690e0
Migrations: 0x90678eeba892762d1d456ae58872c94eba2c2e52
Saving successful migration to network...
... 0x09bbbf050c015ed94a48a92f842605b9f2f857a18cc2c90bd6c9b5b37b630aa1
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying ERC20Token...
... 0x94e4617012532bcd90a9f92ef349fd5990430596dd4e1c2733c543ebb1d35c0b
ERC20Token: 0x395892c139c59533941c87a6dad33e2889fd5de3
Saving successful migration to network...
... 0x06dc8833243d8fb100c8bd2117ad246721488273eac79bab40a4c70437262dc2
Saving artifacts...
truffle console --network development
ERC20Token.deployed().then(inst => ERC20TokenInstance = inst)
ERC20TokenInstance.name()// 'ERC20Token'ERC20TokenInstance.totalSupply().then(function(i) {totalSupply = i})// undefinedtotalSupply.toNumber()// 1e+22

Deploying to Rinkeby (Testnet)

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew tap ethereum/ethereum
brew install ethereum
geth version// Geth
Version: 1.8.8-stable
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10.2
Operating System: darwin
GOPATH=
GOROOT=/usr/local/Cellar/go/1.10.2/libexec
mkdir rinkeby
cd rinkeby
curl -O https://www.rinkeby.io/rinkeby.json
geth --datadir=. init rinkeby.json
geth --datadir=. --rpc --rinkeby --rpcapi "web3,eth,net,personal" --cache=1024
INFO [05-14|21:08:37] Maximum peer count                       ETH=25 LES=0 total=25
INFO [05-14|21:08:37] Starting peer-to-peer node instance=Geth/v1.8.7-stable-66432f38/windows-amd64/go1.10.1
INFO [05-14|21:08:37] Allocated cache and file handles database=C:\\Users\\ricox\\Documents\\GitHub\\projects\\rinkeby\\geth\\chaindata cache=768 handles=1024
INFO [05-14|21:08:37] Persisted trie from memory database nodes=355 size=65.27kB time=467.9µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [05-14|21:08:37] Initialised chain configuration config="{ChainID: 4 Homestead: 1 DAO: <nil> DAOSupport: true EIP150: 2 EIP155: 3 EIP158: 3 Byzantium: 1035301 Constantinople: <nil> Engine: clique}"
INFO [05-14|21:08:37] Initialising Ethereum protocol versions="[63 62]" network=4
WARN [05-14|21:08:37] Head state missing, repairing chain number=2263453 hash=24f662…e2ea0b
INFO [05-14|21:08:37] Rewound blockchain to past state number=2263053 hash=33b947…61815f
INFO [05-14|21:08:37] Loaded most recent local header number=2263453 hash=24f662…e2ea0b td=4237648
INFO [05-14|21:08:37] Loaded most recent local full block number=2263053 hash=33b947…61815f td=4236848
INFO [05-14|21:08:37] Loaded most recent local fast block number=2263453 hash=24f662…e2ea0b td=4237648
INFO [05-14|21:08:37] Loaded local transaction journal transactions=6 dropped=0
INFO [05-14|21:08:37] Regenerated local transaction journal transactions=6 accounts=1
WARN [05-14|21:08:37] Blockchain not empty, fast sync disabled
INFO [05-14|21:08:38] Starting P2P networking
INFO [05-14|21:08:40] UDP listener up self=enode://fdad6fb872dc90d587b0225a5b7f3c7d2d53efef6574415a1cf8f0c42da0791b80553a1753403d2c118b33a2b9cb474673e9c759394a92f1c0435edbaddf756f@76.102.174.73:30303
INFO [05-14|21:08:40] RLPx listener up self=enode://fdad6fb872dc90d587b0225a5b7f3c7d2d53efef6574415a1cf8f0c42da0791b80553a1753403d2c118b33a2b9cb474673e9c759394a92f1c0435edbaddf756f@76.102.174.73:30303
INFO [05-14|21:08:40] IPC endpoint opened url=\\\\.\\pipe\\geth.ipc
INFO [05-14|21:08:40] HTTP endpoint opened url=http://127.0.0.1:8545 cors= vhosts=localhost
geth attach \\\\.\\pipe\\geth.ipc
Welcome to the Geth JavaScript console!instance: Geth/v1.8.7-stable-66432f38/windows-amd64/go1.10.1
modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
eth.syncing// {
currentBlock: 35191,
highestBlock: 2290216,
knownStates: 68389,
pulledStates: 52406,
startingBlock: 0
}
eth.syncing// false
cd rinkeby
geth --datadir=. account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {f6e9dc98fe5d2951744967133b3c31765be657c1}
eth.accounts
// ["0xf6e9dc98fe5d2951744967133b3c31765be657c1"]
eth.coinbase
// "0xf6e9dc98fe5d2951744967133b3c31765be657c1"
eth.getBalance(eth.coinbase)
// 0
eth.getBalance(eth.coinbase)
// 3000000000000000000
personal.unlockAccount(eth.coinbase)
// Unlock account 0xf6e9dc98fe5d2951744967133b3c31765be657c1
// Passphrase:
// true
cd ERC20Token
code .
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
},
rinkeby: {
host: "localhost",
port: 8545,
network_id: "4", // Rinkeby ID 4
from: "0xf6e9dc98fe5d2951744967133b3c31765be657c1" // account from which to deploy
}
}
};
truffle migrate --network rinkeby
Using network 'rinkeby'.Running migration: 1_initial_migration.js
Deploying Migrations...
... 0x657f08c640c5427b5c6ceba4b0a357a990540b117173ec8152d7c95ce1ae01ed
Migrations: 0xd1ac4c1f8695ff626ddc172080ebfa3c68b0ade9
Saving successful migration to network...
... 0xc4805b117afcb4541722b3428966f14389166bac7c39e3909f544c1634ee8da6
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying ERC20Token...
... 0x13da61f42445b7809700de645232e514b7757154ba030b4a962516c72d3716e9
ERC20Token: 0x17db24765fc009a5b42360ef500daf839f51a040
Saving successful migration to network...
... 0x8af12b2773de916acf8be3ec67a3ec4c1d0cb9a493ac675cc0910eef50fd6e52
Saving artifacts...
geth --datadir ./rinkeby --rpc --rinkeby --rpcapi "web3,eth,net,personal" --cache=1024 --unlock "0xacfa76dbd4a46d5497f8d657cfc8a343c69b584d"// Unlocking account 0xacfa76dbd4a46d5497f8d657cfc8a343c69b584d | Attempt 1/3
Passphrase:
geth attach \\\\.\\pipe\\geth.ipc
eth.syncing
truffle migrate --network rinkeby
truffle console --network rinkeby
ERC20Token.deployed().then(inst => ERC20TokenInstance = inst)
ERC20TokenInstance.name()

Deploying to Ethereum (Mainnet)

--

--

Decentral develops full-service blockchain tech as cutting-edge solutions for businesses, governments & decentralized organizations: https://ondecentral.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
Decentral

Decentral develops full-service blockchain tech as cutting-edge solutions for businesses, governments & decentralized organizations: https://ondecentral.com