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.

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.

  1. Using the private key, the owner encode the data, or better, signs the data. With this operation the owner guarantee that nobody forges he or she identity.
  2. Using the public key, everyone can decode the data, or better, checks the signature. With this operation the origin is who we are expecting.

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:

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

  • A retailer ordering goods from the manufacturer. The manufacturer checks for stock for the quantity, collects the products, packs, prepares and ships. 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 the common relation provided for manufacturer.
  • A trusted commercial relationship is so important because the traditional market needs this. The payment from retailer to manufacturer happens days after of received the goods. And, the payment from manufacturer to the courier happens days after the delivery confirmation. If there is no trust they would not believe each other and does not make deals. This doesn’t promote the competition for best prices, services and products.


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

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

  • B2C — goods: John wants a new smartphone, he went at the local mart and picks 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 order a nice portion of spaghetti. The Chef takes her order details, prepare the dish and the waiter serves it. When Maria is satisfied, she pays the bill and go 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 “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 transfer 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 a 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 packs and ship to Jong. When him receive the goods and the invoice the payment will 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 parts, using a smart contract on Ethereum blockchain network.

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 Product X with quantity equals 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. Theses coins goes to the smart contract account and waits there until the delivery.
  7. The Manufacturer sends the invoice with 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 payout the Manufacturer for the order.
  10. The Smart Contract payout the Courier for the shipment.

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:


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
$ npm -v

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)


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.

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.


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
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, into ~/blockchain directory.

$ git clone
$ 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:


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:


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”;
3. var Deal = artifacts.require(“./Deal.sol”);
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:

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.

  • Deploy once, use many: this work like an application, because we deploy a version of our smart contract and use many times until 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.

That’s all! Let some claps 👏!!




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

Fábio José

Written by

DevOps engineer and Blockchain enthusiast



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

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