1. Overview

The ability to run smart contracts is what has made the Ethereum blockchain so popular and disruptive.

Before we explain what a smart contract is, let’s start with a definition of blockchain:

Blockchain is a public database that keeps a permanent record of digital transactions. It operates as a trustless transactional system, a framework in which individuals can make peer-to-peer transactions without needing to trust a third party or one another.

Let’s see how we can create smart contracts on Ethereum with solidity:

2. Ethereum

Ethereum is a platform that allows people to write decentralized applications using blockchain technology efficiently.

A decentralized application (Dapp) is a tool for people and organizations on different sides of an interaction used to come together without any centralized intermediary. Early examples of Dapps include BitTorrent (file sharing) and Bitcoin (currency).

We can describe Ethereum as a blockchain with a built-in programming language.

2.1. Ethereum Virtual Machine (EVM)

From a practical standpoint, the EVM can be thought of as a large, decentralized system containing millions of objects, called accounts, which can maintain an internal database, execute code and talk to each other.

The first type of account is probably the most familiar for the average user who uses the network. Its name is EOA (Externally Owned Account); it is used to transmit value (such as Ether) and is controlled by a private key.

On the other hand, there is another type of account which is the contract. Let’s go ahead and see what is this about:

3. What Is a Smart Contract?

A smart contract is a stand-alone script usually written in Solidity and compiled into binary or JSON and deployed to a specific address on the blockchain. In the same way that we can call a specific URL endpoint of a RESTful API to execute some logic through an HttpRequest, we can similarly execute the deployed smart contract at a specific address by submitting the correct data along with the necessary Ethereum to call the deployed and compiled Solidity function.

From a business standpoint, it means that smart contract functions can be inherently monetized (similar to an AWS Lambda function which allows users to pay per compute cycle rather than per instance). Importantly, smart contract functions don’t have to cost Ethereum to be run.

In simple terms, we can see a smart contract as a collection of code stored in the blockchain network that defines conditions to which all parties using the contract agree upon.

This enables developers to create things that haven’t been invented yet. Think about it for a second – there is no need for a middleman, and there is also no counterparty risk. We can create new markets, store registries of debts or promises and rest assure that we have the consensuses of the network that validates the transactions.

Anyone can deploy a smart contract to the decentralized database for a fee proportional to the storage size of the containing code. Nodes wishing to use the smart contract must somehow indicate the result of their participation to the rest of the network.

3.1. Solidity

The main language used in Ethereum is Solidity – which is a Javascript-like language developed specifically for writing smart contracts. Solidity is statically typed, supports inheritance, libraries and complex user-defined types among other features.

The solidity compiler turns code into EVM bytecode, which can then be sent to the Ethereum network as a deployment transaction. Such deployments have more substantial transaction fees than smart contract interactions and must be paid by the owner of the contract.

4. Creating a Smart Contract With Solidity

The first line in a solidity contract sets the source code version. This is to ensure that the contract doesn’t suddenly behave differently with a new compiler version.

pragma solidity ^0.4.0;

For our example, the name of the contract is Greeting and as we can see the creation of it’s similar to a class in Java or another object-oriented programming language:

contract Greeting {
    address creator;
    string message;

    // functions that interact with state variables
}

In this example, we declared two states variables: creator and message. In Solidity, we use the data type named address to store addresses of accounts.

Next, we need to initialize both variables in the constructor.

4.1. Constructor

We declare a constructor by using the function keyword followed by the name of the contract (just like in Java).

The constructor is a special function that is invoked only once when a contract is first deployed to the Ethereum blockchain. We can only declare a single constructor for a contract:

function Greeting(string _message) {
    message = _message;
    creator = msg.sender;
}

We also inject the initial string _message as a parameter into the constructor and set it to the message state variable.

In the second line of the constructor, we initialize the creator variable to a value called msg.sender. The reason why there’s no need for injecting msg into the constructor is because msg is a global variable that provides specific information about the message such as the address of the account sending it.

We could potentially use this information to implement access control for certain functions.

4.2. Setter and Getter Methods

Finally, we implement the setter and getter methods for the message:

function greet() constant returns (string) {
    return message;
}

function setGreeting(string _message) {
    message = _message;
}

Invoking the function greet will simply return the currently saved message. We use the constant keyword to specify that this function doesn’t modify the contract state and doesn’t trigger any writes to the blockchain.

We can now change the value of the state in the contract by calling the function setGreeting. Anyone can alter the value just by calling this function. This method doesn’t have a return type but does take a String type as a parameter.

Now that we’ve created our first smart contract the next step will be to deploy it into the Ethereum blockchain so everybody can use it. We can use Remix, which’s currently the best online IDE and it’s effortless to use.

5. Interacting With a Smart Contract

To interact with a smart contract in the decentralized network (blockchain) we need to have access to one of the clients.

There’re two ways to do this:

Infura is the most straightforward option, so we’ll request a free access token. Once we sign up, we need to pick the URL of the Rinkeby test network: “https://rinkeby.infura.io/<token>”.

To be able to transact with the smart contract from Java, we need to use a library called Web3j. Here is the Maven dependency:

<dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>3.3.1</version>
</dependency>

And in Gradle:

compile ('org.web3j:core:3.3.1')

Before starting to write code, there are some things that we need to do first.

5.1. Creating a Wallet

Web3j allow us to use some of its functionality from the command line:

  • Wallet creation
  • Wallet password management
  • Transfer of funds from one wallet to another
  • Generate Solidity smart contract function wrappers

Command line tools can be obtained as a zip file/tarball from the releases page of the project repository, under the downloads section, or for OS X users via homebrew:

brew tap web3j/web3j
brew install web3j

To generate a new Ethereum wallet we simply type the following on the command line:

$ web3j wallet create

It will ask us for a password and a location where we can save our wallet. The file is in Json format, and the main thing to keep in mind is the Ethereum address.

We’ll use it in the next step to request an Ether.

5.2. Requesting Ether in the Rinkeby Testnet

The Rinkeby testnet is now deprecated. You can try Sepolia testnet instead.

To prevent malicious actors from exhausting all available funds, they ask us to provide a public link to one social media post with our Ethereum address.

This is a very simple step, almost instantly they provide the Ether so we can run the tests.

5.3. Generating the Smart Contract Wrapper

Web3j can auto-generate smart contract wrapper code to deploy and interact with smart contracts without leaving the JVM.

To generate the wrapper code, we need to compile our smart contract. We can find the instruction to install the compiler here. From there, we type the following on the command line:

$ solc Greeting.sol --bin --abi --optimize -o <output_dir>/

The latter will create two files: Greeting.bin and Greeting.abi. Now, we can generate the wrapper code using web3j’s command line tools:

$ web3j solidity generate /path/to/Greeting.bin 
  /path/to/Greeting.abi -o /path/to/src/main/java -p com.your.organisation.name

With this, we’ll now have the Java class to interact with the contract in our main code.

6. Interacting With the Smart Contract

In our main class, we start by creating a new web3j instance to connect to remote nodes on the network:

Web3j web3j = Web3j.build(
  new HttpService("https://rinkeby.infura.io/<your_token>"));

We then need to load our Ethereum wallet file:

Credentials credentials = WalletUtils.loadCredentials(
  "<password>",
 "/path/to/<walletfile>");

Now let’s deploy our smart contract:

Greeting contract = Greeting.deploy(
  web3j, credentials,
  ManagedTransaction.GAS_PRICE, Contract.GAS_LIMIT,
  "Hello blockchain world!").send();

Deploying the contract may take a while depending the work in the network. Once is deployed, we might want to store the address where the contract was deployed. We can obtain the address this way:

String contractAddress = contract.getContractAddress();

All the transactions made with the contract can be seen in the url: “https://rinkeby.etherscan.io/address/<contract_address>”.

On the other hand, we can modify the value of the smart contract performing a transaction:

TransactionReceipt transactionReceipt = contract.setGreeting("Hello again").send();

Finally, if we want to view the new value stored, we can simply write:

String newValue = contract.greet().send();

7. Conclusion

In this tutorial, we saw that Solidity is a statically-typed programming language designed for developing smart contracts that run on the EVM.

We also created a straightforward contract with this language and saw that it’s very similar to other programming languages.

The smart contract is just a phrase used to describe computer code that can facilitate the exchange of value. When running on the blockchain, a smart contract becomes a self-operating computer program that automatically executes when specific conditions are met.

We saw in this article that the ability to run code in the blockchain is the main differentiation in Ethereum because it allows developers to build a new type of applications that go way beyond anything we have seen before.

As always, code samples can be found over on GitHub.

Course – LSS (cat=Security/Spring Security)

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security:

>> CHECK OUT THE COURSE
Course – LS (cat=Java)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – Security (video) (cat=Security/Spring Security)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.