Introduction to Ethereum

In this Introduction to Ethereum tutorial, you will learn more about one of the most important Blockchain technologies, Ethereum. You’ll learn how to interact with it, create your own private blockchain, write your own smart contracts. Lastly, I’ll show you how to deploy your smart contracts to the test network and verify it using tools that most of the developers in Ethereum are using.

You must have heard about the prices of cryptocurrencies going up and about how blockchain technology is going to change the world. Blockchain and the Cryptocurrencies are the new paradigm in the world of technology, and it can make a real difference in our daily lives. It can change how we interact with our finances, government, energy and much more.
Before we jump into our Ethereum tutorial, let’s start by explaining what Blockchain is.

Blockchain

The blockchain is basically a database which is shared among everyone throughout the network to keep everyone updated. The blockchain is a Digital ledger system, where new data can only be appended to the Blockchain. When data is added it can’t be removed, it can’t be changed by anyone. New data is added to the Blockchain by making transactions on the network. Each transaction then is collected and stored in the blocks which are later added to the Blockchain. This makes everything visible to other users.

It all started with Bitcoin, where all transactions are just information about who owes whom how much money/coins. It’s purely a ledger. Wallet software is a program which tracks all of your bitcoins in the network and calculates how many bitcoins you own. Wallet applications can be run on mobile devices or on the computer, and is run locally. Wallets interact with the bitcoin network and can create new transactions and read data from other transactions. But what if we took that code for interacting with the blockchain and put it into the Blockchain to be later executed on the Blockchain itself? This is where Ethereum enters.

Ethereum tutorial

Ethereum is a platform featuring the smart contracts functionality, which acts as a “global computer”. This means that every node works as a computer and executes the same code as every other node on the network. This provides consensus on the outcome of the smart contracts as it’s executed on every node on the network.

This provides a huge opportunity for the creation of new application development, DApps. I’ve previously dived more into these: what are DApps. We’ve also discussed how to start an ICO if you’re interested in that.

Ethereum Geth

Enough talk about high-level concepts, it’s time to dive right into Ethereum itself! In this section of the Ethereum tutorial, we will install Geth. Then we’ll get familiar with Geth and, by extension, the mechanics of Ethereum.

Installation

We will install Geth on MacOs but if you are using a different operating system, the official install documentation is found here .

Installing Geth on Mac is very simple, just type

$ brew install geth

To check if it is installed correctly and check version, type:
$geth version
Version: 1.7.1-stable
Git Commit: 05101641455a754936acc5ddff92f35f5e33181c
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9
Operating System: Darwin
GOPATH=
GOROOT=/usr/local/Cellar/go/1.9/libexec
Run
Geth comes with a set of preconfigured settings which enables the user to connect to the Mainnet as well as test networks.

Main net

To connect to the main network, type
$ geth
Geth will now be syncing with the Main Net. You can see the data it creates in:
$ ls ~/Library/Ethereum/
geth geth.ipc history keystore testnet

$ ls ~/Library/Ethereum/
LOCK chaindata ethash nodekey nodes transactions.rlp

$ du -hs ~/Library/Ethereum
185M /Users/ahetman/Library/Ethereum

$ du -hs ~/.ethereum/geth/chaindata
7.6M /Users/ahetman/Library/Ethereum/geth/chaindata

Stop the process with CTRL-C. The main net has a lot of data and it would take a long time to have it synced. Worth noting:
geth.ipc exists if and only if Geth is running.
All downloaded and indexed data is stored in chaindata/ folder. To start afresh you may safely delete its content.

Test net

Now we know how to connect to the Main net, but due to the long syncing time, we will now connect to the Test Network. The Test net we will be using is called “Ropsten“, with id 3. It’s one of the most popular test networks as it also uses the same PoW consensus algorithm as MainNet and we will be using it in this Ethereum tutorial.
Start syncing with testnet by typing:
$ geth –testnet

Similarly, you should see it synchronizing from the test network. You can see the data it creates in:
$ ls ~/Library/Ethereum/testnet
geth geth.ipc history keystore

$ ls ~/Library/Ethereum/testnet/geth
LOCK chaindata ethash nodekey nodes transactions.rlp

$ du -hs ~/Library/Ethereum/testnet
72M /Users/ahetman/Library/Ethereum/testnet

You could let it sync, the default –sync mode is “fast“, it should take you a couple of hours to sync with the whole test network. Unless you don’t want to wait a couple of hours, then stop the process with CTRL-C and clear the chain data already downloaded :
$ geth –testnet removedb
/Users/ahetman/Library/Ethereum/testnet/geth/chaindata
Remove this database? [y/N] y
Remove this database? [y/N] y
INFO [01-28|21:36:08] Database successfully deleted database=chaindata elapsed=1.072ms
INFO [01-28|21:36:08] Database doesn’t exist, skipping database=lightchaindata path=/Users/ahetman/Library/Ethereum/testnet/geth/lightchaindata

$ geth removedb
WARN [01-28|21:36:45] No etherbase set and no accounts found as default
/Users/ahetman/Library/Ethereum/geth/chaindata
Remove this database? [y/N] y
Remove this database? [y/N] y
INFO [01-28|21:36:46] Database successfully deleted database=chaindata elapsed=184.153ms
INFO [01-28|21:36:46] Database doesn’t exist, skipping database=lightchaindata path=/Users/ahetman/Library/Ethereum/geth/lightchaindata

Now you know how to connect to the Main net and Test net, it’s time to move on in our Ethereum tutorial. Now, let’s create your own Private network.

Private network

Private networks are used to create your own blockchain. It’s entirely new and its transactions and blocks, including the first one, are not shared with other networks, or blockchains.
To define a new network, all you need is:

  • a network id
  • a genesis file

Another client will need the same network id and the same genesis file to connect to your blockchain.

A few notes:

If you want to connect to another node, you need to have its genesis file, having only a network ID won’t be enough.
The private network is not as private as you may think. Due to the Ethereum protocol, anyone with the right parameters can connect to it, unless you specifically customize Geth not to look for and accept connections.

Network id

The network id is any positive number you, except for these which are reserved:
1, which is reserved for the main chain, commonly referred to as “the” Ethereum network.
2, which is reserved for the late Morden test chain.
3, which is reserved for the Ropsten test chain.
4, which is reserved for the Rinkeby test chain..

Genesis block

The Genesis block is the first block and the only one without a predecessor. When accounts have been “pre-mined”, it is here that allocations are afforded.
When you create or recreate, your own chain, you need to create this genesis block only once.
For Geth, it will be a JSON file similar to this one and save it as genesis357.json:
{
“config”: {
“chainId”: 357,
“homesteadBlock”: 0,
“eip150Block”: 0,
“eip150Hash”:”0x0000000000000000000000000000000000000000000000000000000000000000″,
“eip155Block”: 0,
“eip158Block”: 0
},
“nonce”: “0x0000000000000042”,
“timestamp”: “0x00”,
“parentHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”,
“extraData”: “0x00”,
“gasLimit”: “0x4c4b40”,
“difficulty”: “0x0400”,
“mixhash”: “0x0000000000000000000000000000000000000000000000000000000000000000”,
“coinbase”: “0x0000000000000000000000000000000000000000”,
“alloc”: {
}
}

Notice how difficulty is set extremely low, here 0x400, i.e. 1,024. This is to ensure that Geth on your host is able to mine right away. The first blocks will be mined really fast before stabilizing to 10-15 seconds for every other block once Geth has adjusted the difficulty.

If you omitted this difficulty parameter it would start as per the main net, i.e. 0x400000000. You can confirm this later with > eth.getBlock(0).difficulty. The way to fix that is to delete the content of ~/Library/Ethereum/net357/geth/chaindata and start again.
The config element defines at which blocks this network uses certain protocol changes that have appeared later in the life of the main net.

You don’t need to preallocate ether to your account. With your own private network, you will be able to mine Ether. If you still want to preallocate Ether to certain accounts, you just need to add the balance in wei (1 eth = 10^18 wei):

“alloc”: {
“0x11111111111111111111111111111111111111111111”: {
“balance”: “10000000000000000000”
}
}
}

Start the chain

Our network id is 357 and the genesis file is in ~/ESPEO/genesis357.json. Beside the mentioned parameters, in order to avoid getting mixed up with the main chain data, you also need to specify a data folder, in our case let’s choose ~/Library/Ethereum/net357. Let’s save the following code in ~/ESPEO/launch357.sh. This will save you from repeatedly mis-typing it:

#!/bin/bash

#!/bin/bash

# Run this once, but it does not hurt to run it every time
geth –datadir ~/Library/Ethereum/net357 init ~/ESPEO/genesis357.json
# Run this every time you start your Geth “357”, and add flags here as you need
geth –rpc –rpcapi=”db,eth,net,web3,personal” –rpcport “8545” –rpcaddr “127.0.0.1” –rpccorsdomain “espeoblockchain.com” –datadir ~/Library/Ethereum/net357 –networkid 357 console

Make your file executable:
$ cd ~/ESPEO

$ chmod a+x launch357.sh

# Launch it now
$ ./launch357.sh

Confirm that you have these lines:
INFO [01-28|23:46:56] Writing custom genesis block
INFO [01-28|23:46:56] Successfully wrote genesis state database=chaindata hash=426ab4…c0a0c9
INFO [01-28|23:46:56] Allocated cache and file handles database=/Users/ahetman/Library/Ethereum/net357/geth/lightchaindata cache=16 handles=16
INFO [01-28|23:46:56] Writing custom genesis block
INFO [01-28|23:46:56] Successfully wrote genesis state database=lightchaindata hash=426ab4…c0a0c9

If you don’t see these lines, then the init ~/ESPEO/genesis357.json command was unsuccessful.
Check also if the IPC endpoint points to the proper geth.ipc.
INFO [01-28|23:46:56] IPC endpoint opened: /Users/ahetman/Library/Espeo/net357/geth.ipc

It’s possible at this point that it might synchronize by itself with random strangers on the network. If this happens, stop the process (CTRL-C) and choose another network id.

There’s also a possibility to give additional command line arguments for not being discovered by other nodes.

–nodiscover Disables the peer discovery mechanism (manual peer addition)

And even to stop geth from syncing
The init command has to be run once. In particular, if you clear the content of ~/Library/Ethereum/net357/chaindata , you need to run init again.

Geth console

In order to interact with our node, let’s add a console to it. Update the line in launch357.sh:

geth –rpc –rpcapi=”db,eth,net,web3,personal” –rpcport “8545” –rpcaddr “127.0.0.1” –rpccorsdomain “espeoblockchain.com” –datadir ~/Library/Espeo/net357 –networkid 357 console

Launch again: $ ./launch357.sh

The console is a Javascript console that lets you send commands to Geth. As it’s Javascript console, all javascript functionality applies here.
Type “eth,” that gives you the list of available methods. You can also type “eth.” then press TAB twice, for code suggestions. Let’s go through a few commands.
> eth.accounts
[]

No account, as we didn’t create any yet. This command and any other command typed like this, works in this way: the console is connected to Geth via the geth.ipc file. When you type and return eth.accounts you are making a synchronous call to Geth to retrieve its list of accounts.
Let’s make a synchronous call to get the latest block number:
> eth.blockNumber
0

We are still on the first block, as you have not synchronized or mined anything.
> eth.getBlock(0)
{
difficulty: 17179869184,
extraData: “0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa”,
gasLimit: 5000,
gasUsed: 0,
hash: “0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3”,
logsBloom: “0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”,
miner: “0x0000000000000000000000000000000000000000”,
mixHash: “0x0000000000000000000000000000000000000000000000000000000000000000”,
nonce: “0x0000000000000042”,
number: 0,
parentHash: “0x0000000000000000000000000000000000000000000000000000000000000000”,
receiptsRoot: “0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421”,
sha3Uncles: “0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347”,
size: 540,
stateRoot: “0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544”,
timestamp: 0,
totalDifficulty: 17179869184,
transactions: [],
transactionsRoot: “0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421”,
uncles: []
}

Here we again find the parameters of our custom genesis block. Notice also how receiptsRoot, stateRoot, and transactionsRoot are equal. These 3 roots are the 3 Merkle roots that each Ethereum block header contains. And since we have nothing but an empty tree for the 3 of them, they share the same root hash.

> eth.mining
false

No miner has started.
> net.version
“357”

Your network id
> net.peerCount
0

No one is connected to this network. A useful console shortcut to see the list of initial commands is to type 2 spaces then hit TAB twice.

Accounts

Before we start doing anything interesting with Geth in our Ethereum tutorial, we need accounts. You can create as many accounts as you want. Creating an account just means creating a private key locally. It doesn’t mean that other computers are aware of it.
Let’s create one:
> personal.newAccount()
Passphrase:
Repeat passphrase:
“0xfe894b9c85df02878b84e284c8a5fc092845878a”

> eth.accounts
[“0xfe894b9c85df02878b84e284c8a5fc092845878a”]

> eth.coinbase
“0xfe894b9c85df02878b84e284c8a5fc092845878a”

You will need the passphrase because it’s used to encrypt your private key on the disk. The same passphrase is then required to decrypt the private key when you need to use it:
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xfe894b9c85df02878b84e284c8a5fc092845878a
Passphrase:
true

Now the account is unlocked, but only for 5 minutes, after which time it is again locked. So, remember this personal.unlockAccount command, you will have to use it a fair number of times. If you don’t want to type this command many times along with the passphrase, as seen in this documentation, you can give it a password and a duration.

Now we will check how many Ethers this account holds:

> eth.getBalance(eth.accounts[0])
0
ethereum tutorial

Mining

We have our account, it’s time to start mining and make some ether. To start the mining process you will need to type a command. All mining rewards go to eth.coinbase which defaults to eth.accounts[0]. Confirm that eth.coinbase returns you an account and let’s start mining:
> eth.coinbase
“0xfe894b9c85df02878b84e284c8a5fc092845878a”

> miner.start(1)
true

1 means it will only start one process. As we run this command on our local machine and we don’t compete with other miners, it will be very quick.
The first launch will take time as it creates the 1.5GB Ethash file. This extra-large Ethash file is part of Ethereum’s pick of a hashing algorithm that foils ASIC-based mining.

After a few blocks you can type:
> miner.stop()
true

> eth.blockNumber
5

> eth.getBalance(eth.accounts[0])
25000000000000000000

> eth.getBalance(eth.coinbase)
25000000000000000000

> web3.fromWei(eth.getBalance(eth.accounts[0]), “ether”)
25

Here, we have mined 5 blocks. Each mined block awards 5 Ethers. We’re alone in this network so all rewards go to us.

Transactions

So far all the blocks you’ve mined were empty:
> eth.getBlock(0).transactions.length
0

> eth.getBlock(5).transactions.length
0

> eth.getBlock(5)

{
difficulty: 131264,
extraData: “0xd683010701846765746885676f312e398664617277696e”,
gasLimit: 4975641,
gasUsed: 0,
hash: “0x01a496e3850519b83eba82013d910c3533cbfa6be78b34972ce9363fcf3ed943”,
logsBloom: “0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”,
miner: “0xfe894b9c85df02878b84e284c8a5fc092845878a”,
mixHash: “0xf4a7dd29f00ecb4d70ccb79967747d22db54a178a5e0966b07c762ca80d42180”,
nonce: “0x5d253f5adc8e9a5e”,
number: 5,
parentHash: “0x960ffcac0cc211581577e0bf7579cdfd15788fb2c2c41cff7050ad2a26c616e7”,
receiptsRoot: “0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421”,
sha3Uncles: “0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347”,
size: 534,
stateRoot: “0xe94963cb09541968b052c753bb184b7431cb90765cfd33e01f9c68847578260b”,
timestamp: 1517341136,
totalDifficulty: 656768,
transactions: [],
transactionsRoot: “0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421”,
uncles: []
}

Let’s use a command that will no longer work when the blocks are too big:
> debug.dumpBlock(“0x5”)
{
accounts: {
fe894b9c85df02878b84e284c8a5fc092845878a: {
balance: “25000000000000000000”,
code: “”,
codeHash: “c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470”,
nonce: 0,
root: “56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421”,
storage: {}
}
},
root: “e94963cb09541968b052c753bb184b7431cb90765cfd33e01f9c68847578260b”
}

Now we will perform our first transaction. Before we do it we need to make sure that mining is not running, so type:

> eth.mining
false

Great, mining has stopped so now we need to create another account to which we can send a transaction.

> personal.newAccount()
Passphrase:
Repeat passphrase:
“0x054c5af2dbba57b4e67f7de9752f0c3570f96c92”

> eth.accounts
[“0xfe894b9c85df02878b84e284c8a5fc092845878a”, “0x054c5af2dbba57b4e67f7de9752f0c3570f96c92”]

> eth.getBalance(eth.accounts[1])
0

Let’s send some Ether to this second account:

> web3.toWei(1, “ether”)
“1000000000000000000”

> eth.sendTransaction({ from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, “ether”) })

The { from: … } JSON object is the transaction parameters object. With it, you can define all or part of the transaction parameters. We see that the key is one of the transaction parameters. Geth needs the private key of the sender’s account to sign the transaction. However, accounts are locked by default so you need to unlock them with the passphrase prior to any transaction.

After running this command we should get something similar to this.

INFO [01-30|21:23:06] Submitted transaction fullhash=0x7f855663701d2d8d5bd1fc922cf34cb8774a229583ae13c3054dc0df4eee2095 recipient=0x054C5aF2dbBA57b4e67f7de9752F0c3570f96c92
“0x7f855663701d2d8d5bd1fc922cf34cb8774a229583ae13c3054dc0df4eee2095”

If you instead receive an account is locked message it’s because the first account was unlocked with a 5-minute time mark. To unlock it you can type:
> personal.unlockAccount(eth.accounts[0])
Or you can type:
> web3.personal.unlockAccount(eth.accounts[0],”password”,150000)

The second way lets you specify how long your account can be unlocked.

The transaction went through, a transaction was sent and the resulting hash is that of the transaction. Notice that accounts[1], i.e. the recipient, did not need to be unlocked.

To make it a little bit easier for controlling the transaction, I will make the second transaction and save its hash to the variable.

> var txHash = eth.sendTransaction({ from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(5, “ether”) })
INFO [01-30|21:31:38] Submitted transaction fullhash=0x4ce85faff01cd027f08698468b5bee3119e557b41a497e9854f57294656ba744 recipient=0x054C5aF2dbBA57b4e67f7de9752F0c3570f96c92
undefined

> txHash
“0x4ce85faff01cd027f08698468b5bee3119e557b41a497e9854f57294656ba744”

Let’s see what the transaction represents:

> eth.getTransaction(txHash)
{
blockHash: “0x0000000000000000000000000000000000000000000000000000000000000000”,
blockNumber: null,
from: “0xfe894b9c85df02878b84e284c8a5fc092845878a”,
gas: 90000,
gasPrice: 18000000000,
hash: “0x4ce85faff01cd027f08698468b5bee3119e557b41a497e9854f57294656ba744”,
input: “0x”,
nonce: 1,
r: “0x352b40f8b985f481da2117d4cf0593c372aac7b7d09417f6a6713d3eed09b573”,
s: “0x2c8a4a2662359fdcc8f65635409cba763e33bcd850394d6c260947ffe963dce3”,
to: “0x054c5af2dbba57b4e67f7de9752f0c3570f96c92”,
transactionIndex: 0,
v: “0x2ed”,
value: 5000000000000000000
}

Notice how blockHash is 0x0, blockNumber is null and transactionIndex is null. These are indicators of a pending transaction, i.e. it has not been included in any block, i.e. it has not been mined. Let’s confirm that:
> txpool.content.pending
{
0xfE894b9C85Df02878B84E284C8a5fC092845878A: {
0: {
blockHash: “0x0000000000000000000000000000000000000000000000000000000000000000”,
blockNumber: null,
from: “0xfe894b9c85df02878b84e284c8a5fc092845878a”,
gas: “0x15f90”,
gasPrice: “0x430e23400”,
hash: “0x7f855663701d2d8d5bd1fc922cf34cb8774a229583ae13c3054dc0df4eee2095”,
input: “0x”,
nonce: “0x0”,
r: “0xf83f662179ddb4c7122f8e5f5b38b2ca3fe6b296bfbea12ef6d545e8ee3127ea”,
s: “0x4ea3b1e3a07b2a19b6f8dbf70ab2dbbe4e79d645cc36f12493617953788c09a8”,
to: “0x054c5af2dbba57b4e67f7de9752f0c3570f96c92”,
transactionIndex: “0x0”,
v: “0x2ee”,
value: “0x4563918244f40000”
},
1: {
blockHash: “0x0000000000000000000000000000000000000000000000000000000000000000”,
blockNumber: null,
from: “0xfe894b9c85df02878b84e284c8a5fc092845878a”,
gas: “0x15f90”,
gasPrice: “0x430e23400”,
hash: “0x4ce85faff01cd027f08698468b5bee3119e557b41a497e9854f57294656ba744”,
input: “0x”,
nonce: “0x1”,
r: “0x352b40f8b985f481da2117d4cf0593c372aac7b7d09417f6a6713d3eed09b573”,
s: “0x2c8a4a2662359fdcc8f65635409cba763e33bcd850394d6c260947ffe963dce3”,
to: “0x054c5af2dbba57b4e67f7de9752f0c3570f96c92”,
transactionIndex: “0x0”,
v: “0x2ed”,
value: “0x4563918244f40000”
}
}
}

We see two of the same transactions with values displayed as hexadecimal.

Notice also the gas field, at 90000, which:

  • is the total gas sent along the transaction
  • acts as the upper limit of consumable gas for this transaction.

We can also see the nonce at 0x0 and 0x1 which means this is the two first transactions ever for this account. All transactions are numbered sequentially. This helps assists miners in ordering your transactions.

Let’s check the balance of the second account to see if it is still at 0:
> eth.getBalance(eth.accounts[1])
0

Still, 0, because the transaction hasn’t been mined yet. All of these transactions are still pending and are in the txpool to be picked by the miner and put in the block i.e mined. Let’s start mining.

> miner.start(1)
INFO [01-30|21:42:00] Updated mining threads threads=1
INFO [01-30|21:42:00] Transaction pool price threshold updated price=18000000000
INFO [01-30|21:42:00] Starting mining operation
null
> INFO [01-30|21:42:00] Commit new mining work number=6 txs=2 uncles=0 elapsed=3.239ms

Wait for it to mine a few blocks, then:
> miner.stop()
true

You can see that in the “Commit new mining work” there is a number of the next block 6 because we mined 5 before and the number of pending transactions txs=2.
Now we can check if our second account got some ether.
> eth.getBalance(eth.accounts[1])
6000000000000000000
Yes, it has and it got 6 ether in total, the same value as we sent in two separate transactions.

With this command, we can get the transaction and see the cost, block number etc.
> eth.getTransaction(txHash)
{
blockHash: “0xb11b515e32c5544f0c0fdfc70dd9f6d9011a4f9f2a523424febd711671909f27”,
blockNumber: 6,
from: “0xfe894b9c85df02878b84e284c8a5fc092845878a”,
gas: 90000,
gasPrice: 18000000000,
hash: “0x4ce85faff01cd027f08698468b5bee3119e557b41a497e9854f57294656ba744”,
input: “0x”,
nonce: 1,
r: “0x352b40f8b985f481da2117d4cf0593c372aac7b7d09417f6a6713d3eed09b573”,
s: “0x2c8a4a2662359fdcc8f65635409cba763e33bcd850394d6c260947ffe963dce3”,
to: “0x054c5af2dbba57b4e67f7de9752f0c3570f96c92”,
transactionIndex: 1,
v: “0x2ed”,
value: 5000000000000000000
}

Introduction to Ethereum – conclusions

And that’s it! You’ve completed your Ethereum tutorial. You now know how a basic Blockchain concept works. You can install Geth and connect to the Main Net or Test Net, make transactions, create new accounts and mine. You know also how to create your own Private network and how to operate it. You’ve got the introduction to the Ethereum covered.

There are many more commands that are at your disposal. I encourage you to discover them on your own, go through another Ethereum tutorial and experiment with them to see what they can do. Or we can come to your office and teach you. Check out our blockchain training.