© Wei-Meng Lee 2019
W.-M. LeeBeginning Ethereum Smart Contracts Programminghttps://doi.org/10.1007/978-1-4842-5086-0_6

6. Getting Started with Smart Contract

Wei-Meng Lee1 
(1)
Ang Mo Kio, Singapore
 

So far you have learned how to create your private test Ethereum network. You have also learned how to manage your Ethers using the MetaMask Chrome extension. In this chapter, you will learn about one of the most interesting and exciting features of Ethereum – Smart Contract. You will have a quick look at how a Smart Contract looks like as well as how to test it. In the next few chapters, we will dive into the details of Smart Contracts.

Your First Smart Contract

You are now ready to write your first Smart Contract. To do that, you can use any of your favorite code editors, such as Visual Studio Code or even vi.

Tip

Visual Studio Code has several solidity extensions that you can install to make the writing of Smart Contracts easy.

My personal favorite is the Remix IDE. The Remix IDE is a suite of tools to interact with the Ethereum blockchain. It can compile your Smart Contract into bytecode, generate the ABI (application binary interface), as well as deploy your contracts into the various Ethereum test networks (as well as the real Ethereum blockchain). The ability to compile the contract on-the-fly makes it a very handy tool to learn Smart Contracts programming. Hence, I strongly recommend that you use it to write your contracts.

For this book, we shall use the Remix IDE for writing Smart Contracts.

Note

To compile a Solidity Smart Contract, you need to use the solc compiler. But if you use Remix IDE, you don’t have to explicitly use it to compile your contract.

Using the Remix IDE

To use the Remix IDE, launch the Chrome browser and load the following URL: https://remix.ethereum.org/ . If you are loading the Remix IDE the first time, you will see a sample contract called ballot.sol as shown in Figure 6-1. This is a sample contract that you can look at if you want to know how Solidity works.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig1_HTML.jpg
Figure 6-1

Using the Remix IDE to create your Smart Contract

For now, you can just ignore the ballot.sol contract.

Tip

All contracts created using the Remix IDE is stored locally in your browser cache.

To create a new contract, click the + icon located at the top left corner of Remix IDE. Once you clicked that, you will be asked to give a new name to your contract. Name it as Calculator.sol (see Figure 6-2) and click OK.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig2_HTML.jpg
Figure 6-2

Creating and naming your new Smart Contract in the Remix IDE

Caution

You might want to close the current script before clicking the “+” icon.

Let’s now create a simple contract named Calculator. Populate the Remix IDE with the following:
pragma solidity ^0.5.2;
contract Calculator {
  function arithmetics(uint num1, uint num2) public
    pure returns (uint sum, uint product) {
    sum = num1 + num2;
    product = num1 * num2;
  }
  function multiply(uint num1, uint num2) public
    pure returns (uint) {
    return num1 * num2;
  }
}

Let’s quickly dissect the code and see how it works, and then we can run it and see the result.

First, the pragma statement means that the contract will compile with a compiler version beginning with 0.5.2; but it will not work with version 0.6.0 or higher.

Next, the contract keyword (think of it as the class keyword in languages like C# and Java) defines the contract named Calculator . It contains two functions:
  • arithmetics – This function takes in two arguments – num1 and num2, of type uint (unsigned integer). It has a public access modifier, and it returns a tuple containing two members – sum and product, each of type uint. The two statements within the function computes the sum and products of the two arguments, and their values are automatically returned from the function.

  • multiply – This function is similar to the preceding function, except that the return statement is a little different. Here, I specify that I want to return a single value of type uint, but I do not specify the name of the variable to return. Instead, I use the return keyword to return the specific variable.

Notice that both functions have the pure keyword in its declaration. The pure keyword indicates that the function will not access nor change the value of state variables. The use of this keyword is important – as no modification is made to the blockchain, values can be returned without network verifications. As such, it is also free to call this function without needing any gas.

Note

State variables are storage on the blockchain used to store values, such as the variables you declare in your contract. We will discuss more about state variables in the next chapter.

Compiling the Contract

The Remix IDE allows you to automatically compile the code as you type. To enable this, select the Compile tab on the right side of the screen and check the Auto compile option, as shown in Figure 6-3. If there are any warnings, you will see them in a blue box. Here, our code has two warnings.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig3_HTML.jpg
Figure 6-3

The Remix IDE automatically compiles your code as you type

Clicking on the warning will bring you to the Analysis tab (see Figure 6-4). For our case, the compile is warning me that my variables have similar names. That’s alright, for now.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig4_HTML.jpg
Figure 6-4

Viewing the warnings for your code

If there is a syntax error, then an error will appear under the Compile tab (see Figure 6-5). Clicking on the error will bring you to the code. In this example, a statement is missing a semicolon (;) at the end of the line, so that can be fixed easily.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig5_HTML.jpg
Figure 6-5

Viewing rhe syntax error of your code

Testing the Smart Contract Using the JavaScript VM

Once the code is compiled and error free, you can test it directly within Remix IDE. Click the Run tab. Click the drop-down list next to the Environment option and you should be able to see three options (see Figure 6-6):
  • JavaScript VM – Simulates running your Smart Contract locally without actually deploying it onto the blockchain.

  • Injected Web3 – Uses a plugin such as MetaMask in your web browser to inject a web3 object (see Chapter 9 for more information) so that your Smart Contract can be associated with an account.

  • Web3 Provider – Connects directly to an Ethereum node so that your Smart Contract can be associated with an account. Requires you to run an Ethereum node such as geth.

../images/471881_1_En_6_Chapter/471881_1_En_6_Fig6_HTML.jpg
Figure 6-6

The JavaScript VM allows you to test your code directly

Select the JavaScript VM so that you can test the contract without deploying it to a blockchain.

Next, click the Deploy button (see Figure 6-7). You should now see your contract under the Deployed Contracts section.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig7_HTML.jpg
Figure 6-7

Deploying and testing your Smart Contract in the Remix IDE

Click the arrow icons displayed to the left of the Calculator contract to reveal the two functions in your contract, each displayed in a blue colored box.

Enter the text as shown in Figure 6-8 and click the arithmetics button. The result will now be displayed underneath it.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig8_HTML.jpg
Figure 6-8

Testing the first function in the Smart Contract

Tip

The color of the button serves a purpose – blue-colored button means that it is free to call the function. Red-colored button, on the other hand, means that you need to incur gas to call it. We have a chance to see red-color button in the next chapter.

Enter the numbers for the next button and then click on it (Figure 6-9). You will see its output.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig9_HTML.jpg
Figure 6-9

Testing the second function in the Smart Contract

Getting the ABI and Bytecode of the Contract

Now that the contract has been tested to work correctly, it is time to test it on a real blockchain. But before you do it, there is something else you need to understand. When a contract is compiled, there are two items of interest:
  • ABI (application binary interface) – The ABI is a JSON string that describes the makeup of the contract – the functions as well as the parameter types of each function.

  • Bytecode – When a contract is compiled, it is compiled into opcodes (think of opcode as the assembly language for your computer). Each opcode has its hexadecimal counterparts. The bytecode is basically a collection of each opcode’s hexadecimal representation.

In the Compile tab, you will be able to see two icons representing ABI and Bytecode (see Figure 6-10). If you click the ABI icon, the ABI will be copied to the clipboard.
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig10_HTML.jpg
Figure 6-10

The ABI and Bytecode buttons provide easy access to the ABI and bytecode of the contract

The ABI looks like the following:
[
  {
    "constant": true,
    "inputs": [
      {
        "name": "num1",
        "type": "uint256"
      },
      {
        "name": "num2",
        "type": "uint256"
      }
    ],
    "name": "multiply",
    "outputs": [
      {
        "name": "",
        "type": "uint256"
      }
    ],
    "payable": false,
    "stateMutability": "pure",
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [
      {
        "name": "num1",
        "type": "uint256"
      },
      {
        "name": "num2",
        "type": "uint256"
      }
    ],
    "name": "arithmetics",
    "outputs": [
      {
        "name": "sum",
        "type": "uint256"
      },
      {
        "name": "product",
        "type": "uint256"
      }
    ],
    "payable": false,
    "stateMutability": "pure",
    "type": "function"
  }
]
For the byte code, you can click the bytecode icon, and similarly, the bytecode (along with the opcode and other details) will be copied to the clipboard. However, personally, I would like to obtain the bytecode by clicking the Details button. A pop-up window will now appear. Scroll down the list and look for the section labeled BYTECODE (see Figure 6-11). The bytecode you need is the one highlighted in the figure (the value of the “object” key).
../images/471881_1_En_6_Chapter/471881_1_En_6_Fig11_HTML.jpg
Figure 6-11

Locating the bytecode of the contract through the Details button

For your reference, the bytecode looks like this:
608060405234801561001057600080fd5b50610144806100206000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063165c4a16146100585780638c12d8f0146100a4575b600080fd5b61008e6004803603604081101561006e57600080fd5b8101908080359060200190929190803590602001909291905050506100f7565b6040518082815260200191505060405180910390f35b6100da600480360360408110156100ba57600080fd5b810190808035906020019092919080359060200190929190505050610104565b604051808381526020018281526020019250505060405180910390f35b6000818302905092915050565b60008082840191508284029050925092905056fea165627a7a72305820b9f9a0327fd83c277fb8803cb261ca4c887d5b961499230c7e454dda5f06f6720029

Loading the Smart Contract onto Geth

In Chapter 4, you learned how to create your own private Ethereum test network using the Geth client. Let’s now load the Calculator Smart Contract onto the test network and see how it can be called and used.

First, create two text files named Calculator.abi and Calculator.bin and save them in the ~/MyTestNet/ folder. Populate the Calculator.abi file with the following:
var CalculatorContract = eth.contract([ { "constant": true, "inputs": [ { "name": "num1", "type": "uint256" }, { "name": "num2", "type": "uint256" } ], "name": "multiply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "num1", "type": "uint256" }, { "name": "num2", "type": "uint256" } ], "name": "arithmetics", "outputs": [ { "name": "sum", "type": "uint256" }, { "name": "product", "type": "uint256" } ], "payable": false, "stateMutability": "pure", "type": "function" } ])

Basically, the Calculator.abi file contains a JavaScript statement that defines the Smart Contract named CalculatorContract using its ABI. Observe that earlier on when you extracted the ABI of the contract from the Remix IDE, it was formatted in multiple lines. In the preceding example, you need to condense the multilines ABI into a single line.

Tip

How do you convert a multiline JSON text into a single-line text? Easy. Paste the multiline JSON text into the address bar of the Chrome browser. Then, select it again and copy and paste it into the Calculator.abi file. Voila!

Next, populate the Calculator.bin file with the following:
personal.unlockAccount(eth.accounts[0])
var calculator = CalculatorContract.new(
    { from: eth.accounts[0], data:"0x608060405234801561001057600080fd5b50610144806100206000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063165c4a16146100585780638c12d8f0146100a4575b600080fd5b61008e6004803603604081101561006e57600080fd5b8101908080359060200190929190803590602001909291905050506100f7565b6040518082815260200191505060405180910390f35b6100da600480360360408110156100ba57600080fd5b810190808035906020019092919080359060200190929190505050610104565b604051808381526020018281526020019250505060405180910390f35b6000818302905092915050565b60008082840191508284029050925092905056fea165627a7a72305820b9f9a0327fd83c277fb8803cb261ca4c887d5b961499230c7e454dda5f06f6720029"
,gas:500000 })

The preceding first unlocks the first account in the node and then loads the Smart Contract using its bytecode. Essentially, you are deploying the Smart Contract onto the blockchain. Deploying a Smart Contract onto the blockchain requires Ether, and hence you need to specify the maximum amount of gas to be used, as well as unlock the account to use for the deployment.

Now that you have prepared the code to load the Smart Contract onto the private test network, let’s now spin up the nodes that make up the private test network.

Note

In Chapter 4, you learned how to create three nodes – node1, node2, and node3. For now, we are going to spin up node2 first.

In Terminal, type the following command to spin up node2:
$ geth --datadir ~/MyTestNet/data/node2 --port 30304 --nodiscover --networkid 2345 console 2>console2.log
In the Geth JavaScript Console for node2, type the following command:
> loadScript("Calculator.abi")
true
This will load the definition of the Smart Contract named CalculatorContract. Next, type in the following command:
> loadScript("Calculator.bin")
Unlock account 0xdf86b352fa089f7a047cb0928ca4b70bb8e2f753
Passphrase: <password>
true
You need to unlock your account as you are going to deploy the contract. Next, type the following command:
> calculator
{
  abi: [{
      constant: true,
      inputs: [{...}, {...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      stateMutability: "pure",
      type: "function"
  }, {
      constant: true,
      inputs: [{...}, {...}],
      name: "arithmetics",
      outputs: [{...}, {...}],
      payable: false,
      stateMutability: "pure",
      type: "function"
  }],
  address: undefined,
  transactionHash: "0xd1a680e5ba4ee45bee75dcdaf20c28037cdc7399981909e02dac1a59bce0abe9"
}
Type the following command:
> calculator.multiply
undefined
You get undefined because the contract has not been deployed yet. To do so, you need to start mining:
> miner.start(1)
null
After a while when the block containing the Smart Contract has been mined, you can try the command again:
> calculator.multiply
function()

If you see the preceding output, the contract is now deployed onto the blockchain. If not, wait a while for the mining to complete. It may take a while for the mining to complete, so you need to be patient.

Testing the Contract

Once a contract is deployed, it is officially added to the blockchain (in this case it is the private test network), and anyone with its contract address and ABI can interact with it. Type the following command to get the address of the Smart Contract:
> calculator.address
"0xfaa3aa5387da108ed7070d6dbae97a8cd630d3dd"
You can also examine the ABI of the contract:
> calculator.abi
[{
    constant: true,
    inputs: [{
        name: "num1",
        type: "uint256"
    }, {
        name: "num2",
        type: "uint256"
    }],
    name: "multiply",
    outputs: [{
        name: "",
        type: "uint256"
    }],
    payable: false,
    stateMutability: "pure",
    type: "function"
}, {
    constant: true,
    inputs: [{
        name: "num1",
        type: "uint256"
    }, {
        name: "num2",
        type: "uint256"
    }],
    name: "arithmetics",
    outputs: [{
        name: "sum",
        type: "uint256"
    }, {
        name: "product",
        type: "uint256"
    }],
    payable: false,
    stateMutability: "pure",
    type: "function"
}]

Tip

The preceding command returns the address and ABI of the contract. To call the contract from another node, you just need the address and ABI of the contract

Let’s now try out the contract to see if it works as expected. Type the following commands:
> calculator.multiply.call(7,8)
56
> calculator.arithmetics.call(3,4)
[7, 12]

If you see the preceding outputs, this means that the Smart Contract is loaded and running correctly.

Calling the Contract from Another Node

Now that the Smart Contract is loaded and deployed in node2, let’s try to call the contract from another node. Let’s start node1 using the following command:
$ geth --datadir ~/MyTestNet/data/node1 --networkid 2345 console 2>console1.log

Before proceeding with the following steps, be sure that node2 is paired and synchronized with node1, so that both have the same blockchain. Chapter 4 discussed how to pair them up using the admin.addPeer() function .

Note

Go ahead and pair the node1 with node2 before continuing.

Once the nodes are paired, type the following command in node1:
> var calculator = eth.contract([ { "constant": true, "inputs": [ { "name": "num1", "type": "uint256" }, { "name": "num2", "type": "uint256" } ], "name": "multiply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "num1", "type": "uint256" }, { "name": "num2", "type": "uint256" } ], "name": "arithmetics", "outputs": [ { "name": "sum", "type": "uint256" }, { "name": "product", "type": "uint256" } ], "payable": false, "stateMutability": "pure", "type": "function" } ]).at("0xfaa3aa5387da108ed7070d6dbae97a8cd630d3dd")

Tip

Replace 0xfaa3aa5387da108ed7070d6dbae97a8cd630d3dd with the actual address of your contract.

The preceding command loads the contract using the Smart Contract’s ABI and its address. The eth.contract() function takes in the two arguments in the following format: eth.contract(<contract_abi>).at(<contract_address>).

Next, type the following command:
> calculator
{
  abi: [{
      constant: true,
      inputs: [{...}, {...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      stateMutability: "pure",
      type: "function"
  }, {
      constant: true,
      inputs: [{...}, {...}],
      name: "arithmetics",
      outputs: [{...}, {...}],
      payable: false,
      stateMutability: "pure",
      type: "function"
  }],
  address: "0xfaa3aa5387da108ed7070d6dbae97a8cd630d3dd",
  transactionHash: null,
  allEvents: function(),
  arithmetics: function(),
  multiply: function()
}
The preceding output shows that the contract has been loaded successfully from the blockchain. To test if it works, try the following command:
> calculator.multiply.call(7,8)
56
> calculator.arithmetics.call(3,4)
[7, 12]

Summary

In this chapter, you had a quick look at how a Smart Contract looks like and how it works. In the next few chapter, we will dive into the details of a Smart Contract and the various ways you can interact with it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.203.96