Building a Smart Contract to Sell Goods

Fábio José
Feb 18, 2018 · 12 min read

No doubt, Bitcoin have been changed the manner how we see and understand what is money, value, and recently, ownership due to smart contracts. It’s interesting because almost everyone have 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 the blockchain technology, but in this section I will try to explain this amazing and disruptive technology.

As the name implies, blockchain are 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 the size of 1MB and store how 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 just us has access to our private-key. And, asymmetrical cryptography means: which we encode with one of those keys, it’s only possible decode with the other. No exception.

Authenticity: if we want to sign data, we use the private-key to encode, because everyone can decode using our public-key and securely certifying that are us. But nobody can change the data and sign 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

Concept #3 — the inviolable nature of Blockchain resides in the mechanism that links the blocks: when a new block will be generated an hash is generated from the current block’s data, including it’s signature. Then, a new block is generated, the hash from previous block is combined with current block’s data and a new hash is generated and signed with user’s private-key and so on. If someone try to change a block’s data to forge a transaction, he or she must to generate all subsequent blocks so fast before than 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 to start the blockchain network and set many parameters values, the difficulty to mining coins, for example.

How the chain is created?

Based in all data from the current block, including the signature, a hash is generated and included in the new 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 good explanation of what is Blockchain: https://www.youtube.com/watch?v=NTNQMKB0A3A

Case study

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

Business-to-Business — B2B

Generalization

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

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

The buy-ownership-goods-from-seller diagram model

Let me show some examples and translate then to bogos model.

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 parts, using a smart contract on Ethereum blockchain network.

Sequence diagram with the (smart) solution

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

Ok, enough theory, let’s code!

The Development Tools

To accelerate our development there is a good option called Truffle Framework. This framework have a lot of stuffs 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 into Ethereum Blockchain. To use it we need nodejs. Then, check the version of installed node tools.

If you do not have nodejs in you 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 typing truffle version.

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

Ganache

Install ganache CLI globally to run a private ethereum blockchain network at localhost.

$ sudo npm install -g ganache-cli

Then, try to run typing ganache-cli in the terminal. You must see anything like below listening on port 8545 at 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 start, we have ten accounts (or wallets, or address) with 100.00 ETH of balance in each one and a full working and private blockchain to play, try-and-error, loose coins and do everything we want until get a stable code.

It you want a more visual way to see the things happening, then install the Ganache instead of ganache-cli. This tool do what ganache-cli does, plus a really cool GUI to use the mouse clicks.

Really cool! Hun?

These tools, ganache-cli and Ganache GUI does not maintain state after shutdown, them 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 demonstration and screencast, too.

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

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 green field 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 to create a migration file in migrations directory. Below I show to you the content of 2_deploy_contract.js file that is responsible to deploy 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. The following command will create the blockchain directory in your home.

$ mkdir -p ~/blockchain
$ cd ~/blockchain

Go ahead and see the code. Clone the source code from https://github.com/fabiojose/ethereum-ex, into ~/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 & Deploy

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

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

By default the Ganache GUI binds on port number 7545. Well, change to this port if you choose it instead of ganache-cli.

In Solidity we need to compile the .sol files. To do this we just type the following command in 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 understand about migration, read it: http://truffleframework.com/docs/getting_started/migrations

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 keyword contract instead 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 test in JavaScript, as I do for this article, and tests in Solidity. You can get more details about tests here: http://truffleframework.com/docs/getting_started/testing.

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. a 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 constructor with same name of class, or better, the same name of contract.

contract Deal {
/// ...
}

To pass arguments to 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. At line 3 we have the require to load our Solidity implementation for the smart contract. At line 6 we use the deployer instance, injected by truffle, to perform the deployment of Deal. And the second argument of deploy() function will be passed to the first constructor argument. In this case, we are passing the second account from accounts array provided by ganache.

1. “use strict”;
2.
3. var Deal = artifacts.require(“./Deal.sol”);
4.
5. module.exports = function(deployer, network, accounts){
6. deployer.deploy(Deal, accounts[1]);
7. };

To send the order for goods we have the sendOrder function. It is useless return data in functions that changes the state of contract, because they start a transaction that will be processed (or mined) asynchronously. Just the function that query the state of 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 execution we must to listen to events. In the case of this method we must listen to OrderSent with 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 contract, trigger an event to get the new state of 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: https://github.com/fabiojose/ethereum-ex.

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 too and let me know!! We could share our experiments.

About Patterns

At this point we should thing about some patterns. I noticed these two that is connected to deployment approach.

That’s all! Let some claps 👏!!

References

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Fábio José

Written by

DevOps engineer and Blockchain enthusiast

Coinmonks

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade