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.
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 #1 — blocks: they are blocks storing transactions. Think that these blocks are tables with some few tuples and each one stores the transactions.
Concept #2 — asymmetrical 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.
- 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.
- 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.
Here is an amazing video with a good explanation of what blockchain is: https://www.youtube.com/watch?v=NTNQMKB0A3A
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.
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.
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.
To define a sequence of events, external interactions, and payments, I propose a new flow for the case study.
- The Manufacturer deploys the smart contract exclusively for the Retailer’s account.
- 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.
- The Manufacturer looks for best shipping price on the Courier smart contract.
- The Manufacturer sends the order price and the Retailer receives this through the event called price sent.
- The Manufacturer sends the shipment price and the Retailer receives this through the event called price sent.
- 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.
- 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.
- 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.
- The Smart Contract pays out the Manufacturer for the order.
- 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 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.
Install Truffle globally with the following command.
Check the Truffle version by typing
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.
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.
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.
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.
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.
Create a directory to work in. The following command will create the blockchain directory.
Go ahead and see the code. Clone the source code from https://github.com/fabiojose/ethereum-ex, into the
Install the dependencies.
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.
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
To deploy our compiled .sol files we must to use the migrate command. This command will deploy the contracts in the network configured in
To get a better understanding of migration, check the Truffle docs.
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.
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.
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
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.
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.
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.
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!
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.
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.