Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Building a Smart Contract to Sell Goods

DZone's Guide to

Building a Smart Contract to Sell Goods

Interested in learning how to work with the Ethereum blockchain? In this article, we look at how to get an Ethereum instance set up using Node.js, Solidity, and JS.

· Security Zone ·
Free Resource

Discover how to provide active runtime protection for your web applications from known and unknown vulnerabilities including Remote Code Execution Attacks.

No doubt, Bitcoin has changed the way we see and understand money, value, and, recently, ownership due to smart contracts. It’s interesting because almost everyone has heard about it or cryptocurrency. People from many areas of business, it’s not just us, the IT workers.

In this article I will show my first smart contract on Ethereum, that is part of my personal studies about Blockchain.

Blockchain for Beginners

There are many concepts involving blockchain technology, but, in this section, I will try to explain this amazing and disruptive technology.

As the name implies, blockchain is made up of blocks (#1) of data chained (#3) together using it’s hash data, signeted by user’s private key (#2). These blocks, generally, are limited to the size of 1MB and store as many transactions as possible due to this limitation.

Concept #1blocks: they are blocks storing transactions. Think that these blocks are tables with some few tuples and each one stores the transactions.

The blocks

Concept #2asymmetrical cryptography, public and private key-pair: everybody can access our public-key and only we have access to our private-key. And, asymmetrical cryptography means that when we encode one of those keys, it’s only possible decode it with the other key. No exceptions.

Authenticity: if we want to sign data, we use the private-key to encode, because everyone can decode using our public-key and securely certify that they are us. But nobody can change the data and sign it again because it’s will be rejected by the destiny. This is used when authenticity is an issue. This the case of Blockchain.

Sign the data to guarantee the authenticity

  1. Using the private key, the owner encodes the data, or better, signs the data. With this operation, the owner guarantees that nobody forges his or her identity.
  2. Using the public key, everyone can decode the data, or better, check the signature. With this operation, the origin is what we are expecting.

Concept #3 — the inviolable nature of Blockchain resides in the mechanism that links the blocks: when a new block is generated, a hash is also generated from the current block’s data, including its signature. Then, a new block is generated, the hash from the previous block is combined with current block’s data, and a new hash is generated and signed with the user’s private key, and so on. If someone tries to change a block’s data to forge a transaction, he or she must generate all subsequent blocks so fast before then that the entire network starts to invalidate all these regenerated blocks.

In the beginning, there were no lights …

Everything starts with the genesis block, this block is responsible for starting the blockchain network and setting many parameters' values, such as the difficulty to mining coins, for example.

How the chain is created?

Based on all the data from the current block, including the signature, a hash is generated and included in the newly generated block’s header. At this moment, this new block becomes the current block and starts to register transactions.

Amazing. isn’t?!

Here is an amazing video with a good explanation of what blockchain is: https://www.youtube.com/watch?v=NTNQMKB0A3A

Case Study

I chose a very common use case to make easy to understand, leaving all the complexity only with the implementation of smart contracts logic and technical details.

Business-to-Business — B2B

  • A retailer is ordering goods from the manufacturer. The manufacturer checks their stock for the quantity, collects the products, packs, prepares and ships them. The retailer and the manufacturer have a trusted commercial relationship.
  • The shipment is made by a courier requested from the manufacturer and they have a trusted commercial relationship too.
  • The trusted commercial relationship between retailer and courier is transitive because of the common relation provided by the manufacturer.
  • A trusted commercial relationship is so important because the traditional market needs this. The payment from retailer to manufacturer happens days after the receipt of goods. And, the payment from the manufacturer to the courier happens days after the delivery confirmation. If there is no trust they would not believe each other and not make a deal. This doesn’t promote the competition for best prices, services, and products.

Generalization

The most fine-grained of commercial transactions is composed of three parts: buyer, goods, and seller. The most basic process is the transfer of ownership of the goods in exchange for cash, from the seller to the buyer. What do you think about this?

We can refer to this model as buy-goods-ownership-from-seller or bogos.

Image title

Let me show some examples and translate them to the bogos model.

  • B2C — goods: John wants a new smartphone, he went to the local mart and picked the best one and paid with his credit card. In this example “John” is the buyer, “smartphone” is the goods and “local mart” is the seller. Until John pays, the “local mart” owns the smartphone and after the payment, the ownership is transferred to him.
  • B2C — services: Maria is hungry, she goes to the Mama’s Pasta and orders a nice portion of spaghetti. The Chef takes her order details, prepares the dish and the waiter serves it. When Maria is satisfied, she pays the bill and goes home. In this example, “Maria” is the buyer, the “dish” is the goods, and “Mama’s Pasta” is the seller. After payout, the ownership of the “dish” is transferred from “Mama’s Pasta” to “Maria.”
  • C2C — goods: Joseph is selling his car. After some weeks Berta wants to buy the car from him. They close the deal, Berta pays the accorded value, and Joseph transfers the ownership to her. In this case, “Berta” is the buyer, “car” is the goods and “Joseph” is the seller. The ownership is transferred to “Berta” after payout.
  • B2B — goods: Jong, the buyer, is an electronics reseller and has a store, he orders goods from Beijing Inc., the seller. When the goods are ready to ship they are packed and a courier called Overseas takes the packages and ships them to Jong. When he receives the goods and the invoice the payment will be performed.

The (Smart) Solution

As we saw in the case study section, the trust between the parts is the main concern to traditional business. The objective with this proof of concept is to establish a trustless way to make deals between partners, using a smart contract on the Ethereum blockchain network.

Image title

To define a sequence of events, external interactions, and payments, I propose a new flow for the case study.

  1. The Manufacturer deploys the smart contract exclusively for the Retailer’s account.
  2. The Retailer orders ProductX with quantity equal to N at Manufacturer’s smart contract. Through an event, so-called order send, the manufacturers could receive the order data and process it.
  3. The Manufacturer looks for best shipping price on the Courier smart contract.
  4. The Manufacturer sends the order price and the Retailer receives this through the event called price sent.
  5. The Manufacturer sends the shipment price and the Retailer receives this through the event called price sent.
  6. The Retailer performs the safe payment of the grand total: order price + shipment price. These coins go to the smart contract account and waits there until the delivery.
  7. The Manufacturer sends the invoice with a delivery date and some other data. The Retailer receives the invoice data through the event called invoice sent.
  8. The Courier, after delivery the order to the Retailer, marks the order as delivered on the Smart Contract. The courier could be a robot, a drone. Think with me! Today we have many possibilities.
  9. The Smart Contract pays out the Manufacturer for the order.
  10. The Smart Contract pays out the Courier for the shipment.

Ok, enough theory, let’s code!

The Development Tools

To accelerate our development, there is a good option called the Truffle Framework. This framework has a lot of stuff to help us to develop smart contracts in Solidity, the Ethereum programming language.

To have a quick view of Solidity, I recommend this site: http://solidity.readthedocs.io/en/develop/solidity-by-example.html

Truffle

Truffle is a tool to compile, test, and deploy smart contracts written in Solidity to the Ethereum Blockchain. To use it we need Node.js. Then, check the version of installed node tools.

If you do not haveNode.js on your computer, follow these instructions.

node -v
v6.11.5

npm -v
3.10.10

Install Truffle globally with the following command.

sudo npm install -g truffle

Check the Truffle version by typing truffle version.

truffle version

Truffle v4.0.5 (core: 4.0.5)
Solidity v0.4.18 (solc-js)

Then, try to run it by typing ganache-cli in the terminal. You will see something like the below listening on port 8545 on the localhost.

ganache-cli
Ganache CLI v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0x8baae15bf75ffdb6fcde77ecc4e2aa8063ad820c
(1) 0x1f6c6fa7aceb8124e9db0bd283dbe99489cd7b80
(2) 0x85e1e869e57004618481539c1ee8b2a55195892b
(3) 0x05dd0af1306a4537ca25e651f97df23c68d9b2d7
(4) 0x84a9964a2a9d8136498b26f27311c1ecd244733a
(5) 0x79e21b3f20eca854fa6ca822a8550b1fbdda3c30
...
HD Wallet
==================
Mnemonic:      stereo pistol pulp advance same transfer eight deal unhappy charge attitude lock
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

After starting, we have ten accounts (or wallets, or addresses) with 100.00 ETH of balance in each one and a full working and private blockchain to play with, try some things, loose coins and do everything we want until we get a stable code.

If you want a more visual way to see the things happening, then install Ganache instead of ganache-cli. This tool does what ganache-cli does, plus it has a really cool GUI that allows you to navigate using the mouse.

Image title

These tools, ganache-cli and Ganache GUI, do not maintain state after shutdown, so for every restart we need to redeploy the contract.

MyEtherWallet is one more GUI that is interesting for beginners and it’s more visual than Ganache GUI because we can choose the function to call on a drop-down list. It’s so useful for demonstrations and screencasts, too.

MyEtherWallet is just an additional tool to interact with the Ethereum Blockchain. We must run ganache-cli or Ganache GUI beforehand.

Download the package here, extract it, and open the index.html file in your favorite browser and add a custom node pointing to your running blockchain.

Setup

With this article, I do not pretend to show how to become a Solidity programmer, but if you want to start a greenfield project, proceed as follows.

mkdir my-contract

cd my-contract

truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

Compile:          truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test

To effectively deploy our contracts we must create a migration file in the migrations directory. Below, you can see the content of the 2_deploy_contract.js file that is responsible f0r deploying the Deal.sol contract. With this approach, we can pass arguments to the contract constructor and a lot of other possibilities.

“use strict”;

var Deal = artifacts.require(“./Deal.sol”);

module.exports = function(deployer, network, accounts){
 deployer.deploy(Deal, accounts[1]);
};

Create a directory to work in. The following command will create the blockchain directory.

mkdir -p ~/blockchain

cd ~/blockchain

Go ahead and see the code. Clone the source code from https://github.com/fabiojose/ethereum-ex, into the ~/blockchain directory.

git clone https://github.com/fabiojose/ethereum-ex.git

cd ethereum-ex

Install the dependencies.

npm install

A vanilla truffle project does not need npm install, but if we want more libraries just create a package.json file and put the dependencies there.

Build and Deploy

To execute truffle commands we need access to our private blockchain. In order to do this, edit the truffle.js file by adding the lines below.

module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8545,
      network_id: "*"
    }
  }
};

By default, the Ganache GUI binds on port number 7545. So you'll need to change to this port if you choose Ganache GUI instead of ganache-cli.

In Solidity, we need to compile the .sol files. To do this we just type the following command in the project’s directory

truffle compile

Compiling ./contracts/Deal.sol...
Writing artifacts to ./build/contracts

To deploy our compiled .sol files we must to use the migrate command. This command will deploy the contracts in the network configured in truffle.js file.

truffle migrate

Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0xa74ff1912d2a53a3d77d2678e9fc617f9baa838a46e57a4182d1da6ff4a0cc4f
  Migrations: 0xd86037f19f3adac9bdf3331298b3e9709baabb2e
Saving successful migration to network...
  ... 0x221758e993424fa81581100e2cdd278ed45f9c84820f3ced69362813e409a098
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying Deal...
  ... 0x16f5149e71dd77f8891278e824c9d6e477f7408253fbc2f36560da4aa2a7c6f0
  Deal: 0x3c7396d30e70b4deec5b33582b59766249b6ea83
Saving successful migration to network...
  ... 0x0631419bcf68146a50f524b1d6735f62fca5a825858e57458d4f8cf45e0e70aa
Saving artifacts...

To get a better understanding of migration, check the Truffle docs

Test

Unit Testing: Yes! We can do unit testing with our smart contracts. After all, a simple error can cause us to lose all our coins.

Behind the scenes, we have Mocha and Chai and the main difference is the use of a keyword contract instead of describe to create test scenarios.

To execute the tests, just enter the command below in the project directory.

truffle test

Using network 'development'.

Contract: Deal
    ✓ should the seller account owns the contract (72ms)
    ✓ should the second account was the buyer (72ms)
    ✓ should first order was number 1 (154ms)
    ✓ should the shipment price was set (189ms)
    ✓ should the order's price was set (169ms)
    ✓ should the safe pay was correct (218ms)
    ✓ should the contract's balance was correct after the safepay (186ms)
    ✓ should the first invoice was number 1 (177ms)
    ✓ should the invoice 1 it is for order 1 (190ms)
    ✓ should the courier was correct (186ms)
    ✓ should the contract's balance was correct after the delivery (268ms)

11 passing (2s)

It is possible to implement the test in JavaScript, as I do for this article, as well as in Solidity. You can get more details about tests here.

Coding

To implement the solution I apply generalization and use these entities: Buyer, Seller, Goods, Order, Invoice, and a smart contract called Deal. You could see the implementation by cloning the source.

The Seller deploys one smart contract, i.e. an instance of Deal, for every Buyer that wants to make deals with it. For this, we need a constructor with one argument: the Buyer account address.

/// The smart contract’s constructor
function Deal(address _buyerAddr) public payable {

  /// The seller is the contract’s owner
  owner = msg.sender;

  buyerAddr = _buyerAddr;
}

Note that, like many languages, Solidity has a constructor with the same name of the class, or better, the same name of the contract.

To pass arguments to the constructor, we do this using the deployment file located at migrations/2_deploy_contracts.js, this is a .js file used by Truffle when we call truffle compile or truffle test.

Below we have the content of migration/2_deploy_contract.js. On line 3, we have the requirement to load our Solidity implementation for the smart contract. On line 6, we use the deployer instance, injected by Truffle, to perform the deployment of Deal. And the second argument of the deploy()function will be passed to the first constructor argument. In this case, we are passing the second account from the accounts array provided by ganache.

“use strict”;

var Deal = artifacts.require(“./Deal.sol”);

module.exports = function(deployer, network, accounts){
  deployer.deploy(Deal, accounts[1]);
};

To send the order for goods we have the sendOrder function. It is useless to return data in functions that change the state of the contract because they start a transaction that will be processed (or mined) asynchronously. Just the function that queries the state of the contract could return data.

  /// The function to send purchase orders
  /// requires fee
  /// Payable functions returns just the transaction object, with no custom field.
  /// To get field values listen to OrderSent event.
  function sendOrder(string goods, uint quantity) payable public {
    /// ...
  }

To get the order number, after sendOrder has been executed, we must to listen to events. In the case of this method, we must listen to OrderSent with the following signature.

/// Event triggered for every new order
event OrderSent(address buyer, string goods, uint quantity, uint orderno);

As a practice, for every function that changes the state of a contract, trigger an event to get the new state of the data.

And for every stage in our sequence diagram, we have a method to perform it: sendPrice, sendSafepay, sendInvoice, and delivery. The Retailer is the Buyer and the Manufacturer is the Seller.

The full code is pushed to my GitHub.

Clone it and have fun!

Final Words

Now it’s the time to experience the capabilities of smart contracts, trying to solve real-world problems. Go, try it, and let me know! We could share our experiments.

About Patterns

At this point, we should think about some patterns. I noticed these two that are connected to the deployment approach.

  • Deploy once, use many: this works like an application because we deploy a version of our smart contract and use it many times until we destroy it. This is the approach used by this article.
  • One deploy, one use: in this approach we deploy a version of our smart contract, use it once time for all we need for a very specific goal and destroy at the end.

Find out how Waratek’s award-winning application security platform can improve the security of your new and legacy applications and platforms with no false positives, code changes or slowing your application.

Topics:
blockchain ,ethereum development ,solidity ,blockchain development ,security

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}