Wistia video thumbnail

Transferring ETH Between Accounts

Let’s transfer ETH between accounts

If we’re going to spend some ether, we need to have someone to send it to. But right now, we only have one account:

eth.accounts

We could create a new account using the geth commandline, like last time, but we also can create an account from here:

# I'm going to use the same password as last time
personal.newAccount("abc123")

Now let’s check our list of accounts:

eth.accounts

Great, now let’s check the balances between them:

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

To send ether we need to specify:

  • the from address
  • the to address and
  • the value of the transaction

We’ll do this with the sendTransaction method:

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

Uh oh! We got an error. It says, “authentication needed” - why is that? Well, it’s because our “from” address is locked. This is a security mechanism to prevent you from sending funds when you didn’t intend to.

Let’s unlock our sending account and then try sending the funds again:

personal.unlockAccount(eth.accounts[0], "abc123")

# I'm hitting up-arrow here to search my history and find this transaction
eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(3, "ether")})

Great! This says, “submitted transaction” and it returned a hash. This hash is the identifier of our transaction. Let’s look at it more closely:

eth.getTransaction("XYZ123")

Take a look at the to and the from fields. You’ll notice that these match our account addresses. Also, the value field is the value we were sending, denominated in wei.

Since we submitted a transaction, sending 3 ether from one account to another, our balances should have changed, right? Let’s check:

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

Hmm - it looks the same as before. Why is that? Well, it’s because even though we submitted a transaction, that block hasn’t been processed by any miners.

Take look at the information returned by getTransaction again. Notice that the blockNumber says “null” and the blockHash is just zero. This transaction hasn’t been included in any block, so our account balances haven’t changed.

In order to process this transaction, we need our miners to include it in a block. We can do that by starting our miner again:

miner.start(1)
miner.stop()

Notice in our miner debug log that the txs equals 1 – this is saying that this particular block has one transaction. Notice that the rest of the txs are 0, that’s because we aren’t submitting any transactions, but the miner will still mine “empty” blocks, just to get the reward.

Now let’s try checking our balances again:

web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")

It’s N - well, it’s hard to tell if that worked, because this is our etherbase account, and so it’s earned rewards while we were mining. Let’s check the destination address:

web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")

Great! It has 3 ether at that account, so it worked.

Let’s take a look at our transaction hash again:

eth.getTransaction("XYZ123")

Notice that we now have a blockNumber M as well as a blockHash. We can take a closer look at the block this transaction was included in by using eth.getBlock:

eth.getBlock("XYZ123")

There’s a lot of data in here that will make more sense as we get further along, but take a look at the array of transactions, notice that it contains our transaction’s hash.

Each block stores a reference to it’s parent block. This is block number N, but it’s parent is block number N-1. We could look up the parent block by using parentHash. If we looked at parentHash we would see a list of transactions there, and then we could look at it’s parent, and so on, all the way back to the original genesis block.

This idea of a block being parented by another block is the “chain” part of a blockchain. Every transaction that has ever happened in Ethereum can be found in this way.