Skip to content

Instantly share code, notes, and snippets.

@Zuchos
Created September 28, 2017 06:59
Show Gist options
  • Save Zuchos/082b37c687c38f13a5d15e8f88579d00 to your computer and use it in GitHub Desktop.
Save Zuchos/082b37c687c38f13a5d15e8f88579d00 to your computer and use it in GitHub Desktop.

Introduction

There’s been a lot of buzz in the recent year around Ethereum cryptocurrency and not without cause. Smart contracts is a new exciting concept that Ethereum introduced. What is it? Ethereum is a distributed ledger (same as bitcoin) but this ledger may contain not only accounts and balances, but also computer programs. Programs are first class citizen on Ethereum blockchain and they are not only stored on it, but they provide functions that might be called (same as you may deposit or withdraw money on the ledger’s account) and store its state on the blockchain. For software developers it would be a good analogy that Ethereum Blockchain is a something similar to a VM. There is a virtual machine with instances of objects that are stored in its memory (smart contract). Instances contain not only code that might be executed but also its state. The main difference is that the everything is stored on distributed ledger instead of RAM. This metaphor is not perfect and simplifies things a bit, but it's a good starting point.

So smart contracts:

  • are instances of contracts deployed on blockchain
  • have functions that might be called from outside of blockchain or by other smart contracts
  • like regular distributed ledger accounts: may contain, receive and send Ethereum

Blockchain is run by the Ethereum network nodes. To interact with it you need to communicate with the Ethereum network node. Communication might be direct (with your own hosted node) or via a proxy (there are projects like Metamask or Infura that provides access to the existing Ethereum nodes).

Pet project

Cause I’m a programmer, from the day I heard about smart contracts, I was eager to use it. That’s why I decided to write payments gate for e-commerce. I guess that might be a good idea since this way e-commerce store may bypass payment providers and their fees. Moreover the payments might be done around the world in a fast, secure and anonymous way. Here is an example how e-commerce store works now with traditional payment provider from buyer’s perspective:

  • I place an order in an e-commerce store
  • I get redirected to a payment provider (e.g. Paypal)
  • I make a payment there (e.g. using credit card)
  • I got redirected back to the e-commerce store
  • My order changes its status to “paid”

My intention was to make it in the same way, just to replace interaction with payment provider with smart contract. To achieve that I needed a couple of building blocks:

  • Smart contract - written in solidity and deployed on public Ethereum blockchain
  • HTML web page that customer will use to make payment
  • Piece of code that will allow existing e-commerce store to communicate with smart contract to check payment status.

I named my pet project Petunia and you may find it on github. Below I described components that I created to achieve my goal.

Smart contract

There is a bunch of languages that might be used to write a smart contract. Most popular is Solidity and that was the main reason for choosing it. Solidity language is quite simple and only allows to perform basic operations on its basic types. You will not find there even string comparison or manipulation, and there is a reason for that. Smart contract’s code is executed by the Ethereum network (so it could be run on all nodes) so it cannot be heavy. Smart contract’s code is stored on blockchain, so all nodes need to keep all information about the code and its state. Calculations and storage are expensive and you will pay for it literally. Ethereum network is a distributed network of nodes that are calculating blockchain blocks (in terms of smart contract it means running code and storing its state changes) and those nodes are not doing it for free. For every call that changes blockchain state you need to pay. The currency used to pay for blockchain state changes is named gas. Gas is received by miners (nodes in the network that are calculating next blocks) as a reward for their computation power.

Enough theory, there is my smart contract. I removed implementation details not to blur it up (full code available here).

contract Petunia is owned {

  //constructor
  function Petunia(address _billingAddress)

  function getStatus(uint externalPaymentId) constant returns (string)

  function getPrice(uint externalPaymentId) constant returns(uint)

  function startNewPayment(uint externalPaymentId, uint price) onlyOwner

  function pay(uint externalPaymentId) payable

  function complete(uint externalPaymentId) onlyOwner

  function refund(uint externalPaymentId) onlyOwner
}

So the flow for Petunia smart contract is:

  1. Contract is deployed on blockchain (it’s done just once for each e-commerce store). _billingAddress is stored in smart contract.
  2. When customer places an order, the store calls smart contract function startNewPayment with paymentId (payment id is generated by the store) and price that needs to be paid. This calls tells smart contract that there is a new payment expected with given id and price.
  3. Customer calls (I will explain later how) pay function with payment id from store and with amount of Ethereum that needs to be paid. Smart contract checks if the id and amount of Ether sent matches. If yes it accepts the payment and changes the status.
  4. E-commerce store checks the payment status (it calls getStatus function) if status is Paid then e-commerce store will send goods to customer.
  5. Finally the e-commerce store calls complete function and Ethereum from given payment is transferred to the billing address. Now crypto money is on the store’s account.

There is also alternative path, when e.g. ordered product is not available then e-commerce store will call refund function and transfer money back to the account that was used by the customer. You will complete contract code in find it in solidity directory, but if you’re new to Ethereum don’t dive there yet (read the post first).

Payment page

Ok, but how customer will call a function on the blockchain? I know that it sounds scary to average e-commerce customer ;) But it’s not that hard these days and it will be even more user friendly in near future. So there are 2 ways of doing that:

  • Hard way is to run Ethereum network node on your own. You need to download (Mist)[https://github.com/ethereum/mist] install it, then wait until the whole blockchain gets downloaded on your computer. Then open payment page in the “Mist browser”. I guess this method will be used only by computer geeks.
  • Easy way, install Metamask Chrome Extension and open the payment page. Metamask will communicate with existing Ethereum nodes so there is no need to install one on your computer. To make a payment you will of course need an account with Ethereum currency on it. Then just add your account credentials to Metamask. Then click the “pay” button and it’s ready.

I recorded how it looks like. [Video]

The interaction between webpage (which is plain old good HTML and JavaScript page) and blockchain is done with web3j JavaScript library. Web3j instance is provided by Metamask chrome extension (or if you use Mist, by Mist Browser) and that’s the proxy to Ethereum network. It’s a global dependency like window variable in web application. Web3j provides all necessary methods to interact with Ehereum network. I used AngularJS as framework for this simple webpage. Code below creates EthClient service which is web3 instance and allows e.g. to fetch user accounts or build proxy for contract instance.

if (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {
  web3 = new Web3(web3.currentProvider);
} else if (typeof Web3 !== 'undefined') {
  console.log('No web3? You should consider trying MetaMask!')
  web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
}

myApp.config(function ($provide) {
  $provide.provider('ethClinet', function () {
    this.$get = function () {
      return web3;
    };
  });
});

myApp.service('Petunia', ['ethClinet', '$q', function (ethClinet, $q) {
  //here we build object that represents petunia smart contract
  const petunia = ethClinet.eth.contract(contractABI).at(contractAddress);

  var account = null;
  //here we fetch accounts that are available e.g. were added to Metamask
  $q((resolve, reject) => ethClinet.eth.getAccounts(function (e, r) {
    if (e) {
      reject(e);
    } else {
      account = r[0];
    }
  }));
  ///...
});

You will find rest of the code here. In my project payment page is a separate page that customer will get redirected to, but have in mind that it’s just HTML code, that could be embedded into the e-commerce store as well.

Web Service for e-commerce

The last part we need is a way our e-commerce store will communicate with smart contract. This actually could be anything, even additional lines of code within existing e-commerce store. However I believe that keeping it as separate web service with REST-like JSON API might be a good practice. I used NodeJS and Express to create it since it was the easiest and fastest way to do it, but it might be written in any language or technology. All you need is a library to communicate with Ethereum node. So again we need Ethereum node, we might have our own instance or your services like Infura to communicate with somebody else’s nodes (but usually it costs money). Since web services are the domain of programmers, it wouldn’t be a difficult task for them to set up an Ethereum node and communicate with it.

The Code is very similar to a webpage, since it also uses Web3js libary to interact with the Ethereum network. My implementation is naive and doesn’t implement security (it's just a pet project after all). You will find it in web service directory.

Web service expose methods of the smart contract thru HTTP JSON interface which is extremely easy to use by any e-commerce. E-commerce store will use it to call startNewPayment function on smart contract and then to check payments status and finally to complete or refund the payment.

Business value

Ok, but why to use smart contract as payment provider? What are pros and cons from business perspective? Pros:

  • No payment providers fee, no third party business dependencies
  • High availability, no maintenance brakes (maybe except hard fork once for a year)
  • Easy and fast payments around the world
  • Transparency, customer may check his payment status. Money are kept on smart contract until payment is completed.
  • Simple refunds
  • Security - funds cannot be stolen from the smart contract, they might just be transferred to billing account (specified at the deployment time) or back to customer (when there is a refund). Cons:
  • Creating, making and completing payment cost gas and gas costs actual money (~0.01 ETH by seller and ~0.032 ETH from buyer). Unlike providers fee this those fees are flat so don’t change with payment amount. Since Ethereum costs couple hundred of dollars (and gas price is as high as when it was much cheaper), that makes it too expensive for micro payments.
  • Transparency - competition may track transactions of our e-commerce store
  • Possible legal issues since cryptocurrencies are not regulated in all countries.

Conclusions

Smart contracts seem a very promising solution, but using them we need to be aware of their features such as transparency, storage and calculation costs. Not every problem might (or is worth to) be solved with smart contract or solution that is only implemented with smart contract. However I believe that blockchain and smart contracts will become a parts of other enterprise systems and applications (such as Fizzy).

Thanks to projects such as Metamask and Infura, end users (e.g. online store customer) should be able to use smart contracts without any technical knowledge behind the Ethreum Blockchain and without need to run their own Ethereum node.

What’s next?

If this post was interesting or you would like to hear more about tools that I used or just want me to elaborate more about some design choices, leave a comment. You may find also interesting article of my colleague Krzysztof Ciesielski about Event Sourcing and smart contracts. If you are looking for developer or technical team to design or implement your blockchain solution please contact me. I’m working at SoftwareMill and we specialize in backend solutions in various technological stacks (from JavaScript to Scala).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment