// Contact // victor.deleau <at> gmx <.> com
My GitHub profile
Smart contract are a new software technology which are able to replace third-parties in a typical contractual situation. They are running in a decentralised manner on a blockchain network, are almost autonomous, and are secured by modern cryptography like Bitcoin. The first blockchain platform to have implemented and mature them is Ethereum.
In this post I will go through the different phases of deployment of an Ethereum smart contract. We will use the Solidity language. Here is the plot of the smart contract we will try to deploy: Whenever a business wants to invest into something and make it available to his clients, he will choose a first conservative price which will increase the probability for him to get his investment back. Then, if the product is successful, the business will lower the price in order to attract even more client and maximize his profit. In such situation, the first client are losing because they are paying more than they should. To solve this situation, we will first choose a first conservative price for the business. Then we will create a smart contract which will gather every new payment. When the sum of the money gathered reach the ReturnOverInvestment event (ROI), the smart contract will send the specified amount to the business. Then the smart contract will continue to gather payment until a specified end date. The remaining fund will then be equally distributed to every client, such that they would have paid the same amount of money for the object or service associated.
Now let's see how we could implement this idea. First we need to setup an Ethereum coding environment. In order to interact with the Ethereum network, we need to install an Ethereum node. They are several node software available; here we will use Geth, a Go implementation which is well maintained by the community. A Geth node support three kinds of synchronisation which determines what you can do with them: full node, fast node and light node. I won't go into details about it but because we want to have a fast and easy access we will use a light node which can synchronise in less than a minute. Personally I am running one on a RaspberryPi server and connect myself to it using SSH. We will add the '--rinkeby' option which will connect us to a testnet instead of the mainnet: it allows us not to spend real and valuable Ether while testing.
Unless you are extremely lucky, your address will be empty so you need to get some Ether. On the Rinkeby testnet, you can either receive them from someone or use the Rinkeby Faucet, a web application which will verify that your are not an automated program through one of your social media profile. If you are not on a social media, send me a message with your address and I will send you some. The returned string is our public address, which we can shared with others in order to receive Ether. The string specified in the newAccount field is our wallet password, which is encrypted on the node to create our private key.
We first need to compile the source code into an ABI (Application Binary Interface, which allows us to interact with the smart contract) and a BIN file (the binary code which will be stored in the blockchain). For this matter we use solc, the solidity compiler. I do not recommend the nodeJS implementation which is buggy, but rather to build it from source or to use the online compiler remix. Here is how to compile our source code using solc in the command line:
We will get the output files in the local compil/ directory. Now we need to deploy the smart contract. There are several ways to do this, but here we are going to use the most basic and proven method using the geth console. First, we want to store the parameters of our smart contract and other usefull variables:
Deploying a smart contract is nothing more than sending a transaction with some specific data included. We will build a transaction object piece by piece and then broadcast the transaction to the network. Manually store the content of the .bin file into a variable and create a contract object using the web3.eth.contract class with the content of the .abi file as parameter:
Create a new transaction object with the right Gas amount. Gas is a payment unit for miners in charge of processing your transaction. The Gas price is specified in wei (10**⁻18 Ether) and vary according to the network current state. When you want to make a transaction, you can specify your Gas price (in wei) and the maximum amount of Gas that you are willing to spend. Because miners are here to make profits, they will pick up in priority transactions with the highest Gas price. If your Gas price is too low, you take the risk that your transaction will never be mined. On the other side, if the maximum Gas amount that you allow to be used is to low for what you ask, your transaction will fail for running out of Gas, but you will still have to pay for the computation done by the miner. Here is how to estimate those parameters when you make a transaction:
So 0.000812873 Ether is the price we would have to pay in order to deploy our smart contract on the Ethereum blockchain. Not much right ? Also note that Gas not used by the miner will be returned to you. Because the size of the Ethereum blockchain is increasing exponentialy, Ethereum developers are thinking about creating a storage fee to keep our data or smart contract stored into the blockchain. While this might not be a very popular proposition, I believe it could actually be a long term benefit for Ethereum. Let's get back to the deployment of the smart contract. We can now update our transaction object, unlock our local wallet and then deploy the smart contract:
We created a 'fair' smart contract object which contain every thing we need to communicate with our smart contract (which is not mined until specified). If you wait a minute or so, the callback function will inform you that your contract has been mined (or not). In case of success, the smart contract address will be stored inside the fair object:
That's it, our contract is now on the Ethereum rinkeby blockchain, and the procedure is the same for the mainnet.
Let's imagine that I am a client and I want to pay for the specified object or service (described by the 'entity' variable):
We created a new transaction which will trigger the default function() of the smart contract. The string returned is the TX (transaction hash) of the transaction. It allows us to check the state of the transaction.
If you check the amount of ether you have on your address after a few minutes, you will see that it wasn't debited of the transaction of 0.2 Ether you just made. That is because the smart contract verified the amount of Ether received to see if it matched the price of the entity (which is of 0.1 ETH). Our transaction was therefore rejected ! We can also see that on a blockchain explorer. If we make another transaction with the right price now:
This time, we were indeed debited from the transaction amount. If we send three more transaction with the same amount of Ether, we will reach the target (0.3 ETH) and the smart contract will send us a payment for the ROI event, as specified in the source code, because we are the creator of the smart contract. While it hasn't been completely done here, it is extremely important to test a smart contract thoroughly. Huge amount of Ether were lost or stolen in the past because smart contract had flaws. Learning more by reading the documentation, trying to consider every possible cases, and creating a complete test procedure to apply is heavily recommended.