So far, we have stored a record of transactions and the balances of its users in Ethereum's private blockchain (blockchain) that has been running. Below I will show how to put your own application in the blockchain and how to use it. We will use the already created chain for this, which we dealt with in the previous post.
Smart contracts
Applications placed in the blockchain are most often tasked with ensuring that certain obligations are fulfilled. For this reason, they are called contracts or smart**contracts ( smart contracts). There are several languages in which Ethereum-run contracts can be implemented. Currently, the most popular is Solidity.
Our first contract will be a simple application storing a string that can be read at any time after it is created. The data stored by the contract can only be fixed at the stage of its launch. It will not be possible to change them within a specific instance of the contract.
1/* identyfikator używanej wersji języka */ 2pragma solidity ^0.4.8; 3 4contract greeter { 5 /* zmienna przechowująca wartość typu string */ 6 string greeting; 7 8 /* konstruktor kontraktu */ 9 function greeter(string _greeting) public { 10 /* przypisanie wartości pola kontraktu */ 11 greeting = _greeting; 12 } 13 14 /* funkcja kontraktu, zwraca zapisaną wartość */ 15 function greet() constant returns (string) { 16 return greeting; 17 } 18}
We will create the contract using theMist client. After launching the node and the digging process in the private blockchain, we can enable the client application. In it, we select the Contracts tab, and then Deploy new Contract. We determine the account from which we will create the contract (it will bear the fee for the contract creation transaction), paste the source code of the contract and select the greeter contract to create, specifying the parameters of its constructor. We confirm the operation by pressing the Deploy key.
In the Create contract window, we set the maximum allowable fee for the contract creation transaction. Special attention should be paid to its value. It should not be lower than expected, because then our contract will not be created - there will not be enough funds for its creation.
After approving the transaction, you need to wait for the next block to be dug up, which will contain the contract. It will be visible in the Contracts tab. Using the function is free, because it does not modify the state of the blockchain, but only reads its contents. Mist will execute such a function automatically if it does not need any parameters.
Based on the above source code, you can create multiple independent instances of the contract. Each of them will have its own address, as will user accounts.
The instance contract will already forever use the greeting set in the constructor. By adding a new function, we can make it possible to change the stored string.
1 /* funkcja ustawiająca nowe pozdrowienia */ 2 function setGreeting(string _newgreeting) { 3 greeting = _newgreeting; 4 }
The option to call the function will appear in the tab of the given contract as a Write contract field. In it, we can select a specific function and set its parameters.
The operation of changing the greeting involves a fee and is performed as a transaction, since it changes the state of the blockchain. The above function can be called by any blockchain user. Previously set values will be stored in the history. We can read them by referring to a specific block. The greet function of the contract called from Mist will return the value from the last dug block.
We will still extend the example contract with the ability to modify the greeting, provided that this is done by the owner of the contract, i.e. the account from which the contract was created. To do this, we will extend the example contract to store the creator's address, and to check whether the salutation modification transaction comes from a predetermined address.
1pragma solidity ^0.4.8; 2 3contract greeter { 4 string greeting; 5 6 /* zmienna przechowująca adres tworzącego kontrakt */ 7 address owner; 8 9 function greeter(string _greeting) public { 10 owner = msg.sender; 11 greeting = _greeting; 12 } 13 14 function greet() constant returns (string) { 15 return greeting; 16 } 17 18 /* funkcja ustawiająca nowe pozdrowienie */ 19 function setGreeting(string _newgreeting) { 20 if (msg.sender == owner) 21 greeting = _newgreeting; 22 } 23}
Please try to change the greeting value in the above contract using different accounts.
New cryptocurrency
You can also use contracts to create a new cryptocurrency within the Ethereum blockchain. The contract below associates a balance with an address through a map structure. In the constructor, we set the initial number of tokens and assign it to the creator's account. Note that it does not have the option to create new tokens later. There will be as many of them in circulation as were created in the constructor.
In addition, the following contract records each transaction in the Ethereum log, which can be observed by blockchain clients. They do not need to keep track of the balances of all addresses, they will be informed of the transactions performed by reading the contents of the log in each block. This is realized through an event (event) Transfer, which stores information about the addresses of the payer and payee and the amount of the transaction. The event will only be written for completed transactions.
1pragma solidity ^0.4.8; 2 3contract Token { 4 /* mapa adresów w blockchain i przyporządkowanym im sald */ 5 mapping (address => uint256) public balanceOf; 6 7 /* zdarzenie w logu blockchain, poinformuje klientów o transakcji */ 8 event Transfer(address indexed from, address indexed to, uint256 value); 9 10 function Token(uint256 initialSupply) { 11 balanceOf[msg.sender] = initialSupply; 12 } 13 14 /* wykonanie transferu środków */ 15 function transfer(address _to, uint256 _value) { 16 /* sprawdź środki na koncie */ 17 if (balanceOf[msg.sender] < _value) throw; 18 /* sprawdź czy nie dojdzie do przepełnienia na koncie odbiorcy */ 19 if (balanceOf[_to] + _value < balanceOf[_to]) throw; 20 /* przekaż środki */ 21 balanceOf[msg.sender] -= _value; 22 balanceOf[_to] += _value; 23 /* poinformuj o transakcji */ 24 Transfer(msg.sender, _to, _value); 25 } 26}
There is no function implemented in the contract that returns the balance for a given address, but this operation is possible. This function is created automatically if you set the given variable as public. Reading the balance of a given account is free.
When ordering a transaction, we transfer tokens between accounts, but the fee for performing this operation itself is paid in Ethereum fuel, i.e. ether. After the transaction is executed and the option to observe events is enabled, the Latest events field in the tab of the given contract will show a list of them.
I encourage you to expand the above contract with the ability for the contract owner to create additional tokens. From the Mist client, we can also create a Wallet contract, which will be a wallet for storing Ether extended with additional features such as confirmation of transactions by several wallet owners and a maximum value for a single transaction.
Summary
Smart contracts allow you to implement your own ideas using a single instance of the Ethereum blockchain. In practice, this allows you to launch a new cryptocurrency, mutual fund or other application with implemented rules. Its maintenance will be paid for with ether, which is the fuel for Ethereum itself. This makes it easier to run distributed applications that should have a high level of trust on an untrusted network. Source codes for many classic contracts can be found on Ethereum's website.