Developing Smart Contracts for Ethereum -- Part 1
As an exercise I started to look into Ethereum Smart Contracts a couple of months ago. This journey has been quite interesting and I did learn a lot in that time. I took me a while to find the right tools and setup my environment before I could actually focus on developing smart contracts. This tutorial will point towards the tools I'm currently using and help set them up. Hopefully this will save some time for interested people so that they can focus on the actual development sooner.
Why Ethereum?
After Bitcoin Ethereum is currently the crypto-currency with the second largest market cap. In contrast to Bitcoin its blockchain is focused on smart contracts. Ethereum tries to make the smart contracts really powerful entities on the blockchain. For that purpose it provides a turing-complete development language call Solidity. It syntax is loosely based on Javascript and thus easier to learn than the Bitcoin Script. The high level Solidity programs (called "contracts" in the ethereum space) compile down into the actual code that is stored on the blockchain.
Apart from the lower entry barriers to contract development, Ethereum has a large developer community that works on various pieces for Ethereum. There are different, independent clients (eg. Geth or Parity, to name just the two largest ones) for the blockchain, development frameworks (Truffle or Embark), different development languages (Solidity or Serpent) and nice and useful development/enduser tools (Testrpc, Mist or the Solditiy Realtime Compiler). All of these tools are actively being developed. As such the environment is a friendly one.
Which Chain is Right For Me?
There are a couple of steps to start developing properly. A smart contract is a program that is stored on the blockchain and it is run by the nodes running the blockchain. There are currently two public blockchains:
Mainnet: The mainnet is the public blockchain that is used for production. Ether on this blockchain have real value and are actively traded. All the clients connect to this chain by default (ie. without providing any other parameters). For development purposes this chain is of course fairly useless.
Morden/Testnet: The morden blockchain is used for development. Ether on this chain are more or less easy to come by and do not have real value. This chain should be used for final testing/integration before releasing a contract on to the Mainnet.
Both public blockchains are useful in the later stages of development. To start it is better to setup a private blockchain that makes it really easy to mine new blocks or to use a "blockchain simulator" locally. At each start it provides a new in memory blockchain. It provides most operations that are permitted on the real blockchain, but is significantly faster as there is no delay as blocks are mined on demand locally.
Using Testrpc as In-Memory Blockchain
Testrpc is a blockchain simulator. It is easy to install via:
npm install -g ethereumjs-testrpc
For windows users there are installation instructions on the webpage. Just running testrpc
will start the simulator. It creates a new blockchain with ten accounts by default. Those accounts are equipped with 100 ether by default. Testrpc print the addresses and private keys for the accounts to the console (I left out account 1-8 here):
Available Accounts
==================
(0) 0x6958d360f3752c2820bd4e3dbca6e240597f3ee5
...
(9) 0xeec30f0ad8d6d32707f843673ffe4f116d330f4a
Private Keys
==================
(0) 8677a4fc469a8a9b3799efa85df75fcd2ce10a8e4eb3b0f00183910126ef167e
...
(9) dd803ca83548de759cbd7a59e3db7cc0dcb2574fea53daeb2aee153dbba02f38
HD Wallet
==================
Mnemonic: oyster sight emerge prize umbrella focus laptop truth online shove direct employ
Base HD Path: m/44'/60'/0'/0/{account_index}
These accounts will be generated randomly at each start.
How Do I Program a Contract?
Contracts are written in Solidity and then compiled into a script for the blockchain. After compiling they need to be deployed on the blockchain. A user can use a contract if he knows the contract's address on the blockchain as well as the ABI as a JSON file.
A deployed contract can be used either directly with the right RPC calls or via a wallet like Mist. It does not have a useful GUI on its own. To make it user-friendly, we need to provide a frontend to enable users to interact with it in a non-developer way. Such a frontend can be written in Html/Javascript. The Web3 Javascript Ðapp API library provides access to the blockchain from Javascript.
Using Truffle as Framework
Frameworks like Truffle automate the deployment tasks and allow to focus on the actual contract and frontend development. So far I've always used Truffle; thus I focus on truffle for now.
Truffle needs to be installed. If using npm, the installation is a simple
npm install -g truffle
To start a new project, create a folder for the project and cd
into it. Running truffle init
will scaffold a project structure in the directory. Furthermore it will create an example contract called "Metacoin" This contract is useful for education purposes. It gets referred to in various tutorial by the Truffle team.
Truffle creates quite some files. For starters the most important ones are:
$(PROJECT)/contracts/
: The contracts folder has the contract(s) as solidity files in it. Solidity files use the suffix.sol
.$(PROJECT)/app/javascripts/
: This folder contains a fileapp.js
, which provides the code for the frontend website.$(PROJECT)/truffle.js
: This file configures truffle. It has various sections that define how the code gets deployed.
As a first step the truffle config needs to be customized to the local environment.
Configuring Truffle
The truffle.js
consists of various sections. Each of them is explained in detail in the official documentation. For now, only a few parts need modifications.
truffle init
provides a config with the sections build and rpc. Build defines how the frontend codes ends up being deployed and does not need to be changed. Rpc defines the host and port for rpc calls. Truffle expects a client to a blockchain running on this host and listening at the specified port. Localhost
on port 8545 is the default setting that most clients use. Therefore, the default values do not need to be changed either.
It is, however, useful to add a networks section to the config file. Networks define the chains that the contract can be deployed to. When they are configured, one can use a parameter when calling truffle to choose the correct chain. A useful setting for networks is:
networks: {
"live": {
network_id: 1, // Ethereum public network
},
"morden": {
network_id: 2, // Official Ethereum test network
},
"development": {
network_id: "default"
}
This configures three networks for truffle:
- live: The main network for production purposes.
- morden: The public testnet for integration tests.
- development: The local chain for development. This is the blockchain that is provided by Testrpc.
The configuration defines a network_id
for each of the networks. While the ids are defined for the live (1
) and the test chain (2
), they can be set to an arbitrary value for local or private chains. By setting the network_id of the development chain to default
. This value matches for any network id that does not match any other id in the list. This is useful for development with Testrpc as we want to start with a fresh network each time we start Testrpc and do not care for long-term storage of deployed contracts.
Deploying a Contract
To deploy a contract to a blockchain, the blockchain must be accessible for truffle. As per the configuration, truffle expects the node to listen on localhost:8545
. Thus, before we can deploy a contract with truffle we must start the node. By running testrpc
on the console, the node will simulate the in-memory blockchain. By default it listens on localhost:8545
, just as truffle expects.
Once the node has started, we can deploy a contract. truffle init
has provided us with the Metacoin contract. As a first contract we will deploy this contract to our development blockchain:
truffle migrate
deploys the contracts to the blockchain. Without any parameters, it uses the development network from our configuration.
The actual deployment is a rather long sequence of rpc calls to the node. To see, which calls truffle makes and what responses it receives, the command would be
truffle migrate --verbose-rpc
Truffle saves the latest migrations in a separate contract on the blockchain. Another useful parameter for the migration command is --reset
, which will start the migration from scratch as if there had not been any prior migrations for the contract.
Interacting With the frontend
Truffle already provides us with a web frontend for the Metacoin contract. This frontend can be used to interact with the contract. This is more user-friendly than to expect a user to do the rpc call manually. Truffle can serve the web frontend. The command is
truffle serve
It will serve the website and watch for changes in the Html/JS files. If they are changed, it will redeploy the frontend on the fly. Pointing your browser to http://localhost:8080 will show you the frontend.
The app.js
file automatically uses the Web3 JS library to interact with the blockchain. In the metacoin example, the frontend uses the first available contract on the blockchain to deploy and interact with the contract.
Summary And Next Steps
To start smart contract development, I have found the combination of Truffle and Testrpc quite useful. So far, we have installed both tools, started a local in-memory blockchain and deployed a first contract. The contract already has a user-friendly interface that can be accessed in a browser.
The next part of the tutorial will introduce another tool to the mix that simplifies the account handling considerably. After that, we are ready to move on to the public testnet and see if our contract works on morden too.
Thanks, this helped get myself bootstrapped
Happy to hear that!
Congratulations @chrisdotn! You have received a personal award!
Happy Birthday - 1 Year on Steemit Happy Birthday - 1 Year on Steemit
Click on the badge to view your own Board of Honor on SteemitBoard.
For more information about this award, click here