idflores / ethereum-example

An example implementation of Ethereum's Smart Contracts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ethereum Example

Motivation

After performing research in Blockchain technology, I discovered major blockchain implementations that needed their own repository to continue performing personal in-depth studies. This repository is purposed as a growing knowledge-base for the Ethereum blockchain and is focused on the technology beyond its CryptoCurrency applications.

Usage

  1. Copy and paste the desired contract code from contracts/savings.sol to Ethereum's Remix IDE.

  2. Create a contract instance and test by depositing and withdrawaling Ether.

Prerequisites

  • Install the Ganache Desktop Client and have it running
    • Make sure Ganache's RPC server is set to http://127.0.0.1:7545
    • Make sure you are using the following mnemonics to ensure your address hash's are the same: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat
  • Make sure you have Node v8.9.4 "Carbon" installed
  • Make sure you have NPM v5.6.0 installed

Procedure

Clone the repository and run the server by doing the following:

cd ethereum-example/dapps/aquarium-shop
sh run

The run script will set up your environment, install any necessary dependencies and run the server.

Take a look at the demonstration running on localhost:8080. You should see the example illustrated in the section Example DApp - Aquarium Shop.

Clean Up

Because some packages are necessary to install on NPM's global scope, a clean script has been included to remove them should you wish to remove the demonstration after viewing. Perform the following:

cd ethereum-example/dapps/aquarium-shop
sh clean

WARNING: This will uninstall webpack from the NPM's global scope. You will need to install webpack again if you use this script and wish to keep webpack.

"White Paper"

Ethereum Defined

Ethereum is an implementation of the BlockChain technology. Unlike its predecessor, Bitcoin, who used blockchain solely for CryptoCurrency applications, Ethereum was built to focus on decentralized conditional data development, or blockchain Smart Contracts. Ethereum still has a crypto coin, Ether; however, its primary purpose is to serve as a basis for incentivizing blockchain miners.

The data property in Ethereum blocks, like Bitcoin, is an accumulator of transactions which come in two types. Most notably, one type of transaction has a data property which holds contract opcode to be executed by the Ethereum Virtual Machine. The lifecycle of an Ethereum transaction is further illustrated:

Smart Contracts and Accounts

An Ethereum contract, or colloquially, Smart Contract, is a data structure that resides, at a given address, on the Ethereum blockchain and maintains the state and function of specified data. One could simply think of an Ethereum contract similar to a traditional "class" definition. More technically, however, an Ethereum contract is an addressable set of compiled opcodes written in and executable by the Ethereum Virtual Machine (EVM).

An Ethereum contract is one of the two types of Ethereum accounts; this concept of "accounts" is important since it implies inherent autonomy, whether through automation or human input. Indeed, given a valid invocation, Ethereum contracts are capable of performing automated functions and communication with other contracts and/or External Accounts; additionally, Ethereum contracts are capable of generating new contracts. This ability of function execution, account communication, and contract generation warrant the Ethereum contract's account definition.

The other account type is the External Account, named such because, unlike the contract, External Accounts do not reside on the blockchain. These accounts generally describe a human presence and form the basis which all contract accounts foundationally originate.

Transactions and Messages

At its core, Ethereum is a "State Transition Machine" that uses transactions to change the current state of the blockchain. A Transaction is a signed data structure from an External Account. The origination is what gives the transaction its definition; a transaction may occur from an External Account to another External Account or to a contract but never from a contract. A transaction has the following architecture:

  • Recipient Address
  • Sender Cryptographic Signature
  • Amount of Ether
  • Data (optional)
  • STARTGAS -- maximum gas allowance
  • GASPRICE -- fee, in Ether, sender is willing to pay miner

A Message describes a non-serialized transaction from a contract to either another contract or an External Account. Messages only exist in the Ethereum runtime and cannot originate from External Accounts. The following architecture describes messages:

  • Recipient Address
  • Sender Address (implicit)
  • Amount of Ether
  • Data (optional)
  • STARTGAS -- maximum gas allowance
  • GASPRICE -- fee, in Ether, sender is willing to pay miner

It is important to note that the Sender Address for messages is implicit. In general, messages are only ever instantiated as a result of a transaction. This is logical to assume since, at its origin, a contract can never execute one of its functions without an invocation which results from a transaction. Additionally, there are two types of transactions -- the first resulting in one or more message calls as just described, and the second resulting in contract creation.

It is also important to note that a transaction is different from a call. Transactions broadcast their existence and activity to the Peer2Peer network and are published to the blockchain. However, a call is a simple invocation to a specified contract function on the blockchain whose execution does not broadcast activity to the Peer2Peer network nor is published to the blockchain.

Gas

Gas in Ethereum is the cost of execution of a transaction, message or contract by a miner. It is calculated by quantifying the "computational steps" (i.e. opcode execution by the EVM) and their associated cost. The Gas Cost is a universally standard designated cost for each "computational step", usually just 1 Gas; however, more complicated computations have higher Gas Costs. In addition, Gas Price, included with each transaction, is the amount in Ether for each Gas of computation.

Gas is the primary metric of computation used to calculate miner fees. Higher Gas and Gas Prices result in higher miner fees which incentivize a miner to mine transactions and publish it to the block (Miners and Mining Incentive).

The primary purpose of Gas, however, is to prevent Denial of Service (DoS) attacks to miner nodes. Consider the consequences of an infinite looping contract function placed on the blockchain. During validation or any execution of this function, a miner would be infinitely incapable of further computation as a result of the infinite loop. Gas and transaction Gas Limits effectively make such an attack impossible by both dissuading the attacker by charging for mining resources (computation power, storage, etc.) and automatically halting infinite loop executions when a Gas Limit has been reached. Moreover, Gas costs Ether, further discouraging such an attack and preventing an infinite Gas Limit allocation by the attacker.

Furthermore, Gas is used to limit the amount of work a block is allowed to experience before being included to the blockchain. This is called the Block Gas Limit and performs part of the similar function provided by Bitcoin difficulty -- to regulate how often blocks are added to the chain.

Ether

Ether is the digital asset of the Ethereum blockchain purposed primarily as a means to pay miner transaction fees. The most basic denomination of Ether coin is Wei; however, there are multiple measures of the coin, the major of such as follows:

Measure Amount in Wei Other Names
1 Gwei 1,000,000,000 Wei Nanoether
1 Szabo 1,000,000,000,000 Wei Microether
1 Finney 1,000,000,000,000,000 Wei Milliether
1 Ether 1,000,000,000,000,000,000 Wei Ether

The Gwei denomination is commonly used to describe miner fees. Szabo and Finney are commonly used to describe wallet balances. Ether, of course, is the most well known denomination commonly used in trading.

Unlike Bitcoin, Ether has a surprisingly small importance in comparison to other benefits of the Ethereum blockchain. Again, its existence is purely out of the necessity for miner fees and incentives.

Miners and Mining Incentive

All Ethereum miners carry a copy of the Ethereum Client to perform contract creation, inter-contract communication via messages, validate and execute transactions, etc. Miners quantify these operations through the Gas metric. Each computation that takes place on the Ethereum Client's EVM corresponds to a standard amount of expended Gas, for example:

  • 1 Gas for each general opcode execution
  • 5 Gas for each byte included in the transaction data property

Many specialized computations cost much more. The total Gas is then summed and multiplied by the Gas Price in Ether the transaction specified. This amount is awarded to the Miner as a fee.

TOTAL_GAS_EXPENDED * TX_GAS_PRICE = MINER_FEE
Miner's Economy

It is important to note that Ethereum account holders ultimately determine the fee that they pay to miners; however, miners are free to refuse the processing of any transaction should they feel the specified Gas Price is too low. Therefore, Ethereum account holders are encouraged to be more generous in their transaction fees should they desire their transactions to be mined in a timely fashion (or at all). But, miners are also encouraged to keep fees low by broadcasting the minimum transaction Gas Price they are willing to accept, encouraging users. The phenomena is quite analogous to real gas stations.

The Ethereum Client

The Ethereum Client is responsible not only for providing the runtime environment for the compiled contracts through its virtual machine but is also responsible for Peer2Peer network communication, blockchain management and consensus, account management, etc. Currently, there are 4 official "flavors" of the Ethereum Client maintained by the Ethereum Foundation:

  • Go-Ethereum -- a GoLang implementation, also known as "Geth", geared toward web and ÐApp development and official Ethereum Foundation offerings such as the Mist wallet; it is the most popular client.
  • CPP-Ethereum -- a C++ implementation, also known as "Eth", focused specifically on speed for serious mining applications; also serves as the reference client and bundled with the Mist wallet.
  • EthereumJS -- an alternative JavaScript implementation meant for web and ÐApp development.
  • PyEthApp -- a Python implementation focused on making Ethereum readable for beginners or for those who wish to easily hack at the Ethereum core.

There are other clients for Ruby, Java and Haskell but the most notable and very popular 3rd party implementation is the Rust client maintained by the ParityTech team. Each client implementation, both official and 3rd party, apply the protocol from the Ethereum Yellow Paper, which defines, in detail, every aspect of the Ethereum blockchain including data structures, message and transaction handling, etc. Incidentally, the Yellow Paper was written by the founder of both Ethereum and the Parity client, Gavin Wood, Ph.D.

The Ethereum Virtual Machine

Ethereum Contracts, as mentioned before, are addressable sets of compiled opcodes. The Ethereum Virtual Machine (EVM) is an abstract, Turing-Complete computation machine similar to the Java Virtual Machine (JVM) in both purpose and operation. It is meant to provide both a language to interpret contract opcodes and a common runtime environment in which all miner nodes may execute contract implementations.

Solidity

The Ethereum Virtual Machine is only a runtime environment for compiled contracts, which necessitates a high-level language to provide and compile readable contract code to EVM opcodes. The most popular, Solidity, is a high-level, compiled, Domain Specific Language (DSL), written in C++ and maintained by the Ethereum Foundation as their primary DSL for contract development. Its compiled by the C++ solc compiler and was developed to be heavily related to JavaScript and C in structure, keywords, types and style.

More research and reference notes on the Solidity language can be found in docs/Solidity.md

Other Contract-Oriented DSLs

There are other High-Level DLSs to handle Ethereum contract development. The next most popular is Serpent, also developed in C++ and maintained by the Ethereum Foundation, and as the name suggests, it was designed to be heavily related to Python. The following quote from Serpent's repo aptly describes its usage:

Being a low-level language, Serpent is NOT RECOMMENDED for building applications unless you really really know what you're doing. The creator recommends Solidity as a default choice, LLL if you want close-to-the-metal optimizations, or Viper if you like its features though it is still experimental.

Another contract-oriented DSL is the Low-Level Lisp-Like Language (LLL). As described by its name, LLL is meant to "feel" like Lisp and be a lower level implementation of Solidity for optimization. LLL's definition, parser and compiler, however, are actually a part of the Solidity repo. This quote aptly describes LLL's current purpose and development state:

LLL was always meant to be very simple and minimalistic; essentially just a tiny wrapper over coding in ASM directly. In my opinion just use serpent; it has direct access to opcodes so it is a superset of LLL but it also has a whole bunch of high-level features as well for when you want them. The downside is that the compiler is more complex and so theoretically might contain more bugs. -- Vitalik Buterin

Viper, is yet another contract-oriented DSL written in entirely in Python. The software is still in alpha by the Ethereum Foundation but looks promising from its examples. An LLL definition is also included in the repo allowing for an alternative definition from Solidity's C++ to Python.

There are still others including Mutan which was written in and heavily related to GoLang. Mutan was deprecated in March 2015, however, and replaced by Solidity.

Web3.js

The Ethereum Client is meant to offer a platform for mining, wallet and account management, and contract development. Interfacing with the client on your local node and the Peer2Peer network, however, is handled by the web3.js framework. Web3.js applies the JSON-RPC Ethereum protocol and allows developers to:

  • query the Ethereum Peer2Peer network,
  • dynamically generate, compile, and publish Solidity contracts,
  • execute contract functions on the blockchain,
  • etc.

Like the Ethereum Client, there are a few implementations of the web3.js framework including:

The ÐApp

Given this ability to programmatically define the state and behavior of data through Smart Contracts, it is logical to conclude that entire applications can be built on this programmatic framework. Consequently, the development of BlockChain applications has been formalized since Ethereum's inception and are colloquially termed "ÐApps."

A ÐApp is a Decentralied Application commonly built on the Ethereum BlockChain. More technically, a ÐApp is a collection of related Ethereum contracts that reside on the blockchain and perform various functions, most notably the storage of data. It's commonly used for some user-based application and is usually accompanied by some "front-end" interface.

While perhaps not beneficial in all cases, this distinctly implies that most modern web applications could be implemented using a ÐApp. An excellent example is the pet shop adoption service from the Truffle Suite team. Instead of maintaining a centralized database including information of all pet adoptions, the data is maintained on the blockchain using Ethereum contracts to manage and store adoption transactions. A front-end is easily implemented with web3.js and common frameworks like MeteorJS or SailsJS. Additionally, we gained some clear advantages:

  • transaction security is enforced by blockchain,
  • complete transaction payment through CryptoCurrency,
  • a little more work, and USD can still be used for secure payment, and
  • a decentralized and permanent transaction history.

Proof-of-Concept

The purpose of the enclosing repository is to prove to myself deep understanding of the concepts above. Consequently, I performed the following test and created both an Ethereum example contract and example ÐApp.

Example Contract - Savings

An offline version of Ethereum's Remix was used to compile and execute in a test environment the example contract. The test was performed using JavaScript VM environment supplied by Remix with Google Chrome as the host browser. Details can be found in Development Environment.

The example contract, Savings, is a simple implementation of an Ether savings account. It was designed to be instantiated with an Ether amount and solely accessible by the contract creator. The deposit() and withdrawal() functions are present for obvious utility and care was taken to prevent a "double dipping" vulnerability which can occur if a request is made to withdrawal multiple times before the transaction has complete execution. The source code can be found at contracts/savings.sol.

Example DApp - Aquarium Shop

The example ÐApp, Aquarium Shop was used to demonstrate how a business might use a decentralized application to implemement an Ether point-of-sale system. The AquariumShop.sol file actually has 2 contracts developed with the following ability:

  • AquariumShop
    • buy() - allows purchase of items from the shop and stores the Ether in the contract
    • layaway() - generates a new smart contract that allows payments over time
    • withdrawal() - allows only the shop owner to withdrawal Ether from the contract to his own account
  • Layaway
    • makePayment() - allows customer to make a payment to the contract and automatically deducts from the payoff amount

The Front-End uses a very clean, simple design with ReactJS. A template engine like HandlebarsJS could have been easily used here; however, it seemed more advantageous to demonstrate ÐApp concept with a web framework meant for building lightweight, production web applications. Webpack was used as the module loader to bundle our files into a minified, production-ready build file for running our Proof-of-Concept.

There are 2 major ReactJS components, StoreFront and Item. StoreFront is the main page layout of the application; it includes the header bar, main body, and copyright footer. Each product for sale in the body is described by Item which lists the name, price and a purchase option shown by the illustration:

The Ether price is calculated by taking the 24 hour high and low market price from the GDAX exchange. We average them to get our day's Ether-USD market price a perform the following equation:

Product_Ether_Price = 1 Ether / Market_Price_USD  *  USD_Product_Price  *  Quantity_of_Product

A database for the available products with all this information is kept as a hardcoded script in store.js. A database engine like MongoDB could have been easily used; however, it was a bit "overkill" for the purpose of this demonstration.

The purchase button activates a script that communicates via Truffle-Contract, a wrapper for the Web3.js, to the Ethereum blockchain for purchasing the product. The layaway button creates a new contract giving the user the contract address to make payments in purchasing the product. The Proof-of-Concept is demonstrated by the illustrations respectively:

To further implement a "layaway", one should develop a notification system to ship the product to the client. In general, the system should also include a webpage to get the client's credentials, shipping address, etc. One could also implement a login and accounts feature to handle layaway payments and transaction history viewing. Such enhancements are outside of the scope of this demonstration.

Furthermore, it should be noted that there are plenty of other ways this ÐApp can be implemented. The developer must decide, for instance, how much they would like the Smart Contract to handle. Arguably, the Smart Contract could handle most operations in this Proof-of-Concept including even the database of customers. But doing this, we begin to experience large overhead when considering the Ether fees necessary to execute and maintain such a Smart Contract. This inherently implies that smart contracts may not be advantageous in all applications. Consequently, this Proof-of-Concept was developed to demonstrate a harmony between centralized and decentralized operations and their respective advantages.

Development Environment

  • MacOS High Sierra v10.13.2
    • MacBook Pro 13", Early 2015
    • Intel Core i7 3.1GHz
    • 16GB 1867MHz DDR3
  • Atom v1.23.3 (downloaded)
  • Hyper Terminal v1.4.8 (downloaded)
  • Ethereum Mist Wallet v0.9.3 [Rinkeby] (downloaded)

Example Contracts

Example ÐApps

Docker was not used for ÐApps development. Since Docker for Mac runs in a virtual machine, it is very challenging to reliably connect docker to the Ganache local server on localhost. Alternatively, one could use the Ganache-CLI; however, during tests, the CLI version was not equivalent to the desktop version often breaking on basic features -- citing calls and transactions that did not exist and giving unpredictable results. Therefore, the Docker version of the Ganache-CLI was ruled out as well, and Shell scripts were developed for ease of demonstration.

Disclaimer

This project is meant to be a personal knowledge-base and example of the Ethereum blockchain technology principles. Several features are intentionally missing. While the repository will grow with new research, examples and algorithms, it is never recommended to be used for production.

Resources

About

An example implementation of Ethereum's Smart Contracts

License:BSD 3-Clause "New" or "Revised" License


Languages

Language:JavaScript 92.4%Language:Shell 5.7%Language:HTML 1.9%