Writing your first smart contract. This article is the second part on what are smart contracts and what you need to do to get a test environment up and ready for creating your first smart contract. We will see how to use the Truffle console along with the Ganache personal Ethereum-based blockchain for creating a smart contract that will let you register domain names, a simple but powerful concept that can give you an idea of one of the many applications of smart contracts and the blockchain technology in general.This self-evaluating code let’s you check whether the domain has already been registered and, if not, you can use it for registering it.
This piece assumes that the reader have already gone through the first part of this article, which describes what are smart contracts and how to setup a personal development blockchain using Ganache from Truffle. If you haven’t, please go ahead and read it here.
To continue with the exercise of creating your first smart contract, you need to install the Truffle Suite; a development framework for Ethereum, which makes it a little easier to create and test your contracts before deploying them to the real network.
Setting up Truffle
In the first part we saw how to install nodejs and npm. Now, to install the Truffle Suite we can simply issue the next command.
npm install -g truffle
Then, create a folder and change directory into it. After that, initialize Truffle using the init command.
truffle init
Truffle will create all the files required for a smart contract project, here we need to add a little configuration to make sure that the framework correctly integrates with our personal Ethereum blockchain (Ganache).
If you haven’t, run Ganache with the following command:
./ganache-1.2.1-x86_64.AppImage
Once Ganache comes up, go to the Settings option on the top right corner:
Take note of the server settings:
Now, we need to configure our truffle project to use this development environment. Head back to the folder where you initialized truffle, look for a file called truffle.js and edit the module export section like this:
module.exports = { networks: { development: { host: "localhost", port: 7545, network_id: "5777" } } };
The file would then look like the following:
Now, to make sure everything is setup correctly, run both of the next commands:
truffle compile
truffle migrate
Writing your first smart contract
Now that everything is setup, we want to create our first smart contract. In this case we will be creating a small simple contract that let’s you keep records of domain names. To create the smart contract simply run the next command:
truffle create contract domainRegistry
After that, you can see the newly created contract under the Contracts folder:
You can see that the file has a .sol extension, that’s because the Truffle framework works with the Solidity: “a contract-oriented, high-level language for implementing smart contracts“. Open the file with your preferred text editor, I’ll be using nano, and put the next code on it:
pragma solidity ^0.4.22; contract domainRegistry { mapping (bytes32 => bool) private domains; function saveDomainProof(bytes32 domain) private { domains[domain] = true; } function calculateSha256(string domain) private pure returns (bytes32) { return sha256(abi.encodePacked(domain)); } function hasSha256Proof(bytes32 sha256Proof) private constant returns (bool){ return domains[sha256Proof]; } function checkDomain(string domain) public constant returns (bool){ bytes32 sha256Proof = calculateSha256(domain); return hasSha256Proof(sha256Proof); } function registerDomain(string domain) public { bytes32 sha256Proof = calculateSha256(domain); saveDomainProof(sha256Proof); } }
Drilling down the code
The first thing you would notice is the pragma line, which specifies which version of the Solidity language will be used, in this case 0.4.22. The next part, the smart contract declaration, looks very similar to a class declaration on most object-oriented programming languages.
The mapping directive can be though of as a hash table or a dictionary, it is a data structure that lets you store key-value pairs. In this case we are creating pairs of bytes32 (key) and bool (value). The general structure of a mapping is as follows:
mapping (key_type => value_type) access_modifier mapping_name
This private mapping will serve the function of maintaining the list of domains that our smart contract uses. The following code consists of the actual functionality of the contract, these are functions that do stuff. In this case, functions can change the state of the contract’s storage, execute logic and return values.
Let’s dive into one of the functions, the other are very similar and should be easily understood. Let’s see the calculateSha256 function, which, as it’s name states, it simply calculates the SHA256 hash of a given domain provided as parameter:
function calculateSha256(string domain) private pure returns (bytes32) { return sha256(abi.encodePacked(domain)); }
Then comes the private access modifier; since we need only to invoke the function from within the contract. The pure modifier is used to specify that the function cannot change or read the contract’s storage. Then comes returns (bytes32), which specifies what type of data the function will return. Finally, we have the body of the function, in this case it simply calculates and returns the SHA256 value of a given domain. The abi.encodePacket was used for encoding as recommended by the compiler.
Deploying the smart contract
Now we need to deploy the smart contract to the personal development Ethereum blockchain (Ganache), to do that you can, first you need to edit the migrations file under the migrations folder, in our case this file is named 1_initial_migration.js and make it look like the following:
var domainRegistry = artifacts.require("./domainRegistry.sol"); module.exports = function(deployer) { deployer.deploy(domainRegistry); };
Now, run the migrate command with the –reset flag, this is to make sure that the contract is correctly deployed.
truffle migrate --reset
Let’s take a look at Ganache and see if something has changed, it should, since deploying the contract requires to make a transaction into the development Ethereum blockchain. We can see that the balance of the first address (used by default) has changed.
Interacting with the smart contract
Now that the smart contract has been deployed, we need to interact with it, this will let us call the public functions within the contract. To do that we use the truffle console and first create a variable that holds an instance of the contract, then we can use that variable to invoke the contract’s functions.
truffle console truffle (development)> domainRegistry.address '0x5a198e...' truffle (development)> var dr = domainRegistry.at(domainRegistry.address) undefined truffle (development)> dr.address '0x5a198e' truffle (development)> dr.checkDomain('securitygrind.com') false truffle (development)> dr.registerDomain('securitygrind.com') { tx: '0x0e59d...' truffle (development)> dr.checkDomain('securitygrind.com') true
Conclusion
The true power of blockchain lies behind the ability to execute code on the blockchain itself. The Ethereum blockchain was designed specifically for the purpose of running smart contract, which is why it is widely used nowadays for creating decentralized applications. The Truffle framework along with Ganache provides a versatile development environment for writing smart contracts.
1 Response
[…] Find second part below or here! […]