
Ethereum is a multi-purpose blockchain platform. It serves developers and programmers in the creation and management of smart contracts and decentralized applications. It stands out among other platforms in terms of community widespread, presence of multiple developer guides and technologies, efficiency, and security in the deployment process. In this article, we will discuss smart-contract features, structure, and types while pointing out the main steps for Ethereum Smart Contract Development. We’ll provide examples and a tutorial on how to write an Ethereum smart contract qualitatively.
Currently, the use of the Ethereum blockchain and others is somewhat experimental. However, it is gaining more and more popularity in the crypto community due to the rapid development of modern technologies and appearance of the new ones. It is a well-known fact that safety and security are significant issues to deal with while using any blockchain platform. Therefore, one should pay attention to regular changes and updates in the field of security.
Considering the high number of system bugs, vulnerabilities, and associated risks, it is crucial to highlight Ethereum smart contract best practicesto guarantee a greater level of security while programming on Ethereum.
What Is a Smart Contract?
A smart contract is a digital agreement between two or more parties that guarantees the enforcement of obligations in order to meet a common goal. For instance, smart contracts serve as a tool to conduct currency exchanges and sell or purchase property, shares, or any other valuable commodities. What’s interesting is that there is no need for third-party intervention. Smart contracts are conflict-free, and provide a high level of trust and transparency between participants. They set certain rules and conditions that must be met by participants in order to set a deal. If one of the participants doesn’t comply with the obligations, the smart contract function will fail to execute.
In a practical sense, smart contracts function just like ordinary ones. According to their nature, however, to be executed, they have to be called by person, being signed by his private key. This means that any participant can dictate the rules and obligations required to set a deal, thereby eliminating any central authorities.
Structurally, each smart contract could be used like a data storage, of course in case of being extended with methods for modifying the data it contains. Considering the fact that smart contracts could interact with each other or even be replicated as well as reused, the data stored in them cannot migrate to another one. In order to change contract data, users call various methods and functions, which can be repeated in the network of nodes. This process enables the distributed consensus mechanism required to carry out whole network transaction confirmation.
Each contract has an interface (ABI) generated from the source code, that contains function properties and parameters. Users can change contract data by conducting transactions, that include information about the sender, recipient, and the amount of funds.
Let’s take a look at the basic transaction structure. The following parameters are defined as conventional for all transactions:
Here is an example of a transaction:
Smart-Contract Types
Smart contracts are widely usedby a number of businesses and enterprises due to the range of benefits and opportunities they provide. Financial, crowdfunding, the supply chain, healthcare, and other industries apply smart contract in the context of their business strategies because of:
- elimination of third-party involvement
- increased trust
- enhanced security
- decentralization
- data immutability
Various types of smart contracts can satisfy business needs and requirements:
Development Philosophy: What to Keep in Mind before Writing a Smart Contract
Before getting started with Ethereum smart contract development, consider the following security practices to eliminate possible risks:
1. Be ready to fail
There are no perfect contracts. All of them happen to have errors, and this is quite common. That is why contract user-flow testing and Test Driven Development (TDD) is crucial. While in the midst of Ethereum smart contract development, make sure your code is capable of responding to all sorts of attacks, potential vulnerabilities and weaknesses gracefully. Don’t hurry, and pause if things do not go according to the plan. Manage and improve the contract by using efficient upgrade paths, regarding the common security patterns.
2. Take your time to roll out
Just do it carefully, in phases. It is better to find possible mistakes and improvements before the complete release. Always run the test-outs starting from the alpha version.
3. Stick with simplicity
This is one of Ethereum’s main features. The simpler the contract, the fewer potential issues. Divide your contract into separate modules, and keep the functions small, this will ease the code and help to avoid stack-overflow. Consider using official Solidity documentation and source code provided by the famous contributors, like ConsenSys or OpenZeppelin.
4. Stay updated
Keeping an eye on all sorts of upgrades will help you succeed in smart-contract development. Keep track of the latest updates, and check official bug reports regularly. Make sure the tools you use in the deployment process are the latest versions and include recently-adopted techniques.
5. Find out more about blockchain properties and coding
Being aware of blockchain programming aspects is crucial if you want to avoid unpredictable outcomes. Additionally, be careful with function modifiers, external functions could be exposed to malicious attacks. Keep track of the data settled in public blockchains, as it is publicly accessible. Mind the fees needed to execute the data and legal limitations.
6. Check out the Primary trade-offs
Differentiate between simple and complex cases. In certain cases, simplicity isn’t the best choice. There is a range of primary tradeoffs to pay attention to while evaluating smart-contract structure. Ideally, a smart contract should:
- be modular
- be simple
- reuse code (inheritance) instead of duplicating
- maintain upgrades
On the other hand, in certain cases, it is important to maintain a balance and mix certain properties depending upon conditions and contract requirements:
Now that we have familiarized ourselves with basic security practices, we are ready to move on to the smart-contract development tutorial. But first, it is important to go through the Ethereum programming basics.
First things first.
Getting Started: Setting up
How to code Ethereum smart contracts?First, you need to download the latest Node.js version. At the time of this writing, the latest features are provided in the 10.11.0 version.
Install Node.js and make sure it’s installed, as well as npm:
1 2 3 4 5 6 7 8 |
node -v Output: // v10.1.0 npm -v Output: // v6.0.1 |
Next, download an IDE or code editor (integrated development environment) application. It’s up to you which IDE or editor to use, but it’s better to choose VS (Visual Studio) Code or Atom, as they best match Solidity (one of Ethereum smart contract languages).
If you choose VS Code, install it, go to the extensions bar, and choose Solidity as the programming language. You can use the following preferences and add them to the VS Code settings:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ "editor.dragAndDrop": false, "editor.fontSize": 12, "editor.formatOnSave": true, "editor.formatOnType": true, "editor.formatOnPaste": true, "editor.wordWrap": "on", "editor.quickSuggestions": { "other": true, "comments": true, "strings": true }, "explorer.confirmDragAndDrop": false, "explorer.confirmDelete": false, "files.autoSave": "onFocusChange", "workbench.colorTheme": "Default Light+", "solidity.enabledAsYouTypeCompilationErrorCheck": true, "solidity.linter": "solium", "solidity.packageDefaultDependenciesContractsDirectory": "", "solidity.packageDefaultDependenciesDirectory": "", "solidity.validationDelay": 1500 } |
The next step is to install the Truffle framework, one of the most widely-used options for smart-contract testing. For this, run the following function:
1 |
npm install -g truffle |
And verify the installation:
1 2 3 4 5 |
truffle -v Output: // Truffle v4.1.8 (core: 4.1.8) // Solidity v0.4.23 (solc-js) |
Then, for enhanced convenience, create the project structure by calling ‘truffle init’, and make sure the following directories structure is present:
- contracts/
- migrations/
- test/
- Truffle.js/ configuration file
Now that you’re all set, let’s begin with simple smart-contract creation.
Ethereum Smart Contract Tutorial
How to create an Ethereum smart contract?Before moving on to the Ethereum smart contract examples,let’s take a look at contract structure.
Solidity smart contracts are comparable to classes. All contracts can include state variables, a range of functions and their modifiers, various events, struct and enum types. mart contracts are be capable of being inherited from another smart contract.
The Contract Structure
1. State Variable. This is a value that is kept in contract storage on a permanent basis:
1 2 3 4 5 6 |
pragma solidity ^0.4.0; contract SimpleStorage { uint storedData; // State variable // ... } |
2. Functions. These are the contract code units that can be executed within it:
1 2 3 4 5 6 |
pragma solidity ^0.4.0; contract SimpleAuction { function bid() public payable { // Function // ... } } |
One can call these functions internally or externally. In addition, they can be visible or protected from view.
3. Function Modifiers. You can add modifiers to change the contract’s function semantics:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
pragma solidity ^0.4.22; contract Purchase { address public seller; modifier onlySeller() { // Modifier require( msg.sender == seller, "Only seller can call this." ); _; } function abort() public onlySeller { // Modifier usage // ... } } |
4. Events. These are convenient interfaces within Ethereum Virtual Machine facilities:
1 2 3 4 5 6 7 8 9 10 |
pragma solidity ^0.4.21; contract SimpleAuction { event HighestBidIncreased(address bidder, uint amount); // Event function bid() public payable { // ... emit HighestBidIncreased(msg.sender, msg.value); // Triggering event } } |
5. Struct Types. These are defined types capable of grouping numerous state variables:
1 2 3 4 5 6 7 8 9 10 |
pragma solidity ^0.4.0; contract Ballot { struct Voter { // Struct uint weight; bool voted; address delegate; uint vote; } } |
6. Enum Types. You can use enums for custom type creation with value limitation:
1 2 3 4 5 |
pragma solidity ^0.4.0; contract Purchase { enum State { Created, Locked, Inactive } // Enum } |
Ethereum Smart-Contract Examples
Now let’s consider the most basic smart-contract example. Start with the storage:
1 2 3 4 5 6 7 8 9 10 |
pragma solidity ^0.4.24; contract SimpleStorage { uint storedData; function set(uint x) public { storedData = x; } function get() public view returns (uint) { return storedData; } } |
Here, we state that the written code relates to the 0.4.24 version of Solidity programming. We call pragma to determine Solidity compiler version.
A Solidity smart contract is a set of functions, values and data kept at a specific Ethereum blockchain address. The “uint storedData” holds the value of type uint variable. This storage is similar to a database unit that can be requested and modified when one calls code functions. In our case, you can use these code functions to change and reclaim variable values.
The featured contract allows participants to store a single accessible number. It can be viewed by any network member worldwide, yet this doesn’t prevent you from publishing it.
When the basic contract is ready, you can also add cryptocurrency features to it. You can actually generate/create coins, as you are the smart-contract creator. Furthermore, other users will be able to exchange coins without being required to register their usernames. To do so, you will need an Ethereum key value storage, so called “mapping”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
pragma solidity ^0.4.21; contract Coin { // The keyword "public" makes those variables // readable from outside. address public minter; mapping (address => uint) public balances; // Events allow light clients to react on // changes efficiently. event Sent(address from, address to, uint amount); // This is the constructor whose code is // run only when the contract is created. function Coin() public { minter = msg.sender; } function mint(address receiver, uint amount) public { if (msg.sender != minter) return; balances[receiver] += amount; } function send(address receiver, uint amount) public { if (balances[msg.sender] < amount) return; balances[msg.sender] -= amount; balances[receiver] += amount; emit Sent(msg.sender, receiver, amount); } } |
Let’s review some of the above-mentioned functions and their concepts:
- mapping (address => uint) public balances. This line declares a public state variable. However, this type of data is more obscure and dynamic. It maps addresses to unsigned integers in which one can view mappings as hash tables. In the practical sense, it is initialized such a way that any key occurs and maps to a value with zero-byte representation.
- event Sent(address from, address to, uint amount). This line declares an “event” released in the last function line. Back-End microservices can listen these events with minimal charges. Since it has been released, all listeners would get it in the form as it’s defined in the smart contract.
You can use the following function to listen for this event:
1 2 3 4 5 6 7 8 9 10 |
Coin.Sent().watch({}, '', function(error, result) { if (!error) { console.log("Coin transfer: " + result.args.amount + " coins were sent from " + result.args.from + " to " + result.args.to + "."); console.log("Balances now:\n" + "Sender: " + Coin.balances.call(result.args.from) + "Receiver: " + Coin.balances.call(result.args.to)); } }) |
Now that you’re ready with the basic smart contract, it is up to you which features, functions, and modifiers to add. The next step is compiling.
As one of the IDEs mentioned above is Visual Studio Code, all you have to do is run the application and compile your smart contract. For this, right click on the .sol file to choose “Compile” command:
After this step, you can deploy your contract directly into the blockchain. But first, it is better to test it out in the Truffle framework. The graph below provides an example of deploying a contract named “Contract1”.
That’s it! Your contract is ready for interaction.
Hope you’ve found our tutorial helpful.