WTF are NFTs?!

Reading Time: 6 minutes

Before I start to explain what an NFT is, let’s have a look at some examples. I tried to gather different styles of NFTs in the high price segment. There are of course also NFTs for 100$ and less.

Sold for $210’000

LeBron James: Dunk, From the Top (Series 1)


Sold for $888’888

Hairy: Musician, fashion designer, and entrepreneur Steve Aoki recently collaborated with 3D illustrator Antoni Tudisco to produce the eclectic piece known simply as ‘Hairy’ (A blue bespectacled creature bopping to one of Aoki’s beats in a 36-second clip).


Sold for $2.9 million

First Twitter Tweet: First tweet posted by Twitter founder and CEO Jack Dorsey


Sold for $69 million

EVERYDAYS: THE FIRST 5000 DAYS: The artwork, created by famed digital artist Mike “Beeple” Winkelmann represents a collage of 5,000 of Beeple’s earlier artworks


What is an NFT?

As you saw in the few examples, NFTs can be anything. It could be a tweet, a digital painting, a video clip, an animation, music, a 3D model, a picture, a GIF or even virtual land in a blockchain-based game. To further explain what NFT exactly means, it’s easier to split the word and have a closer look at Non-Fungible and Token.

NFT = Non-fungible token


The official definition of fungible is “to be substituted for something of equal value or utility; interchangeable, exchangeable, replaceable”. For now, let’s replace the word fungible with replaceable. So non-fungible means non-replaceable. Let’s make some examples:

Physical fungible (replaceable)

  • CHF Coins and CHF Notes (my 10 Swiss Franc note has the same value as 10 x 1 Swiss Franc coins)
  • Precious metals like gold and silver (my 1kg gold bar has the same value as your 1kg gold bar)

Virtual fungible (replaceable)

  • Bitcoins and other crypto currencies (my 0.00001 BTC has the same value as your 0.00001 BTC)

Physical non-fungible (non replaceable)

  • Historic Coins (the first 1 Swiss Franc coin, or a limited special edition coin. The value is not really defined. Also the first 1 Swiss Franc coin has not the same value as the current 1 Swiss Franc coin)
  • Art (like paintings from Banksy. It’s unique and the value is only defined by the potential buyers. If a painting is destroyed, it’s not replaceable by another “similar” one)

Virtual non-fungible (non replaceable)

  • Tweets
  • NBA Dunks
  • Art (image, video, 3D model, music)


The token certifies a digital asset to be unique and therefore not interchangeable. It’s proof of ownership that is stored on the blockchain (in this case: Ethereum). While someone can sell an NFT representing his work, the buyer does not necessarily receive copyright privileges if ownership of the NFT changes, allowing the original owner to create further NFTs of the same work. An NFT is merely proof of ownership separate from copyright.

NFT Properties

UniqueProvably ScarceIndivisible
Each NFT has different properties that are usually stored in the token’s metadata.There is usually a limited number of NFTs with an extreme example of having only 1 copy, the number of tokens can be verified on the blockchain, hence its provability.Most NFTs cannot be split into smaller denominations, so you cannot buy or transfer a fraction of your NFT.

The dark side of NFTs

NFTs are stored on ETH (Ethereum) Blockchain, which is currently using 51 TWh/year. That’s 51’000’000’000 kWh/year (comparable to the power consumption of the whole of Portugal). If we calculate the carbon footprint, it’s 30’000’000 tons of CO2/year. You could drive 121’000’000’000 km with a car to have the same emissions as ETH has in one year.


Create your own NFT

The process is very simple and creating an NFT at OpenSea is done in a few minutes. I decided to go for OpenSea because it’s the most popular marketplace and easiest to use.

Create account, collection and item

  1. Create digital art (image, video, audio, or 3D model) with your favourite tools. I did it with Adobe Photoshop and Adobe Premiere.
  2. Create an account at OpenSea. I used MetaMask as my wallet. You can also choose other wallets. If using MetaMask, it’s the easiest to have it installed as a Chrome/Firefox addon.
  3. Create a collection and add a new item to it.
  4. Upload your art (file types supported: JPG, PNG, GIF, SVG, MP4, WEBM, MP3, WAV, OGG, GLB, GLTF. Max size: 40 MB) and give it a name. That’s all you need for now!

Sell your item

After you created your item inside your collection, it is ready for selling. You will have the option to sell for a fixed price or create an open auction (highest bid). I decided to go for an auction and I will let it run until the end of the year.

  1. Click on your item
  2. Click on the top right corner button “Sell”
  3. Select “Highest Bid” to create an open auction
  4. All other settings are customizable, like minimum bid, the reserve price and expiration date. I set the minimum bid to 0, the reserve price to 1 and the expiration date to 31.12.2021 (end of the year)
  5. Post the listing with the big blue button. Posting something the first time requires a gas fee. Depending on the time and day, this will vary. See
  6. Congratz! You created and listed your first NFT!

Our N47 NFT is up for sale!

Of course, I had to create an N47 NFT too! Our sale end of the year (December 31, 2021, at 12:00 am CEST). Check the listing at OpenSea and make a bid! It will be a great investment 🤑

Spring Boot password encryption with Jasypt

Reading Time: 5 minutes

Securing sensitive data is extremely important. In the following tutorial, we will go through the process of encrypting sensitive data in a Spring Boot application. We will take an easy approach to this very common procedure which takes place in any software project. This will be easy in the context of setup and usage of the given high-security java library. Without the need for deep knowledge/in-depth understanding of cryptography, encryption capabilities and encryption algorithms. Just following a simple setup with a few configuration steps. It is recommended to rely on the secure default configuration, but also Jasypt offers quite some customization if one needs it.

Jasypt (Java Simplified Encryption) provides utilities for encrypting user sensitive information, such as DB passwords, servers’ credentials, or other sensitive personal data. This information is key to users privacy, so we as developers need to make sure that no one gets the right to access them, irrelevant of the place where they are stored, they always need to be encrypted. Never store sensitive data in plain mode. It’s common sense we need to follow and it’s also something we need to honour if we want to gain our user’s trust. For this tutorial, we will use a specific library, Jasypt Spring Boot Starter, widely used across the Spring Boot community.

Jasypt setup steps

  1. Add jasypt-spring-boot-starter maven dependency in the pom.xml of the Spring Boot project
  2. Select a secret key to be used for encryption and decryption
  3. Generate Encrypted Key
  4. Add the Encrypted key in the config file
  5. Run the application

Let’s go into details in all of these steps:

Step 1. Adding maven dependency


This comes as a regular entry in the pom.xml file list of dependencies.

We should try to use latest stable versions. This version is the latest one at this moment and it offers better support for newer versions of Spring Boot. starting from 2.1.x and upwards. Also would advise using this because it comes with a more secure encryption algorithm by default, “PBEWITHHMACSHA512ANDAES_256”.

Step 2. Select a secret key to be used for encryption and decryption

This secret key will be used to encrypt and descript the data. You can think of it as a safeguard to further improve security. What it does, it actually adds a random string to the beginning or end of the input text prior to hashing or encrypting the value. This secret key goes in the property file, application.yml/ in the Spring Boot project itself.

           password: salting

Step 3. Generate Encrypted Key

Jasypt supplies a lot of (CLI) tools. In order to use these tools, you should download the distribution zip file (named jasypt-$ and unzip it. There will be an appropriate .bat or .sh file for the needed operation digest/encrypt/decrypt.

Example for encryption

$ ./ input="This is my message to be encrypted" password=MYPASSWORD

Example for decryption

$ ./ input="8fsdfdsafdsa9ffsad0fdsa0fdsfdsa3231x" password=MYPASSWORD

Another way of using Jasypt for encrypting your data is by using some online tools that provide Jasypt operations.

The simplest and most convenient way is a maven plugin. Not only that you can use it for a single value, it offers the capabilities to encrypt all sensitive data with a single command, meaning all placeholders will be updated in one step.


This jasypt-maven-plugin, by default, will check for configuration files under ./src/main/resources, or the regular Spring Boot resource folders. But also, Environment variables can be used to supply this master password. Instead of exposing the password “salting” inside the project itself, an Environment Variable can be created with, for instance, ENCRYPTION_MASTER_PASSWORD and then in the config file, password: ${ENCRYPTION_MASTER_PASSWORD}.

Example for encrypting a single value from a terminal.

This example uses the encryption password as an argument. Important, the terminal session needs to be opened where the pom.xml file with the maven plugin is located.

mvn jasypt:encrypt-value -Djasypt.encryptor.password=salting -Djasypt.plugin.value="secureDataWeNeedToEncrypt"

Example for encrypting all strings within projects property file.

The last argument is optional since Jasypt will scan that location anyway. What is important is that sensitive placeholders in the application property file MUST be wrapped in DEC() parenthesis. Activedirectory:password: DEC(supersecret) OracleDB:password: DEC(alsosupersecret).

mvn jasypt:encrypt -Djasypt.encryptor.password=salting -Djasypt.plugin.path="file:src/main/resources/application.yml"

If the previous statement completed successfully then, all sensitive data should be updated with their encrypted value. Updated properties output should be something like, Activedirectory:password: ENC(sFJDfdsfjjA8saT7YC65bsf71d0) OracleDB:password: ENC(34jjfsdfds+fds/fsd7Hs)

Step 4. Add the encrypted key in the config file

If you have been using the latest approach, then the files have already been updated with the newly encrypted values. All sensitive data wrapped with a DEC() is now encrypted, and all other strings in the configuration remained unchanged. If some of the other approaches were chosen, going one placeholder at a time, or using the cli, then we need to update the configuration file entries one by one. Still, the properties need to be wrapped in ENC() parenthesis anyway, since the output of the cli is only the encrypted value.

For the reverse process, it’s vice-versa, the first argument of the statement is: decrypt and all placeholders must be wrapped in ENC() parenthesis before execution.

Step 5. Run the application

That’s it. Your Spring Boot project will automatically decrypt all sensitive data when you start the application, no additional configuration is needed. Let me know in the comments section how was your experience. Was it smooth or are there some ongoing issues?

ERC20 Token Smart Contract for Ethereum Blockchain

Reading Time: 5 minutes

Since the inception of Blockchain technology; Bitcoin, Ethereum, or crypto-currencies are hot topics and buzzing around the world many startups based on Blockchain technologies are using cryptocurrencies, in other words, crypto tokens for the utilization of their products. These crypto tokens can be deployed on many Blockchain like Ethereum, Cardano, Binance, Polkadot, etc. It’s another topic of discussion, on which blockchain these crypto tokens need to be implemented but as Ethereum being the first market mover, this blog post explains, how you can create such a token on the Ethereum blockchain.

Before creating an Ethereum based token (ERC20 token), understand first the basics of Smart-contract and their native programming language Solidity.

Smart Contract

A smart contract is simply a set of rules that contains the business logic or a protocol according to which all the transactions on a Blockchain should happen. The general purpose of a Smart contract is to satisfy common contractual conditions like creating its token, perform arbitrary competitions, function to send and receive tokens, and store states of transactions.


Solidity is an object-oriented and high-level smart-contract programming language, which is developed on top of Ethereum Virtual Machine (EVM). Solidity compiler converts smart-contract code into EVM bytecode which is sent to the Ethereum network as a deployment transaction. It would be best to have a good understanding of Solidity programming language to efficiently write an Ethereum Smart Contract and build an application on smart-contract.

Coding example of smart-contract

This section contains the example of a smart-contract code written using the Solidity programming language.


Integrated development environment (IDE)

Remix as the IDE. It is a web-based IDE with built-in static analysis and a testnet EVM. Remix provides the possibility to compile and deploy it to Ethereum testnet with Metamask. Here is a good blog post for it.

There is also another web-based IDE available like EthFiddle. For more information related to IDE please visit here.

Programming Language


ERC20 Token Info
  • Symbol – N47
  • Name – N47Token
  • Decimals – 0
  • Total Supply – 1000000
Smart-contract Code
// SPDX-License-Identifier: unlicensed
pragma solidity 0.8.4;
// ----------------------------------------------------------------------------
// Safe maths
// ----------------------------------------------------------------------------
contract SafeMath {
    function safeAdd(uint a, uint b) public pure returns (uint c) {
        c = a + b;
        require(c >= a);
    function safeSub(uint a, uint b) public pure returns (uint c) {
        require(b <= a);
        c = a - b;
// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// ----------------------------------------------------------------------------
abstract contract ERC20Interface {
    function totalSupply() virtual public view returns (uint);
    function balanceOf(address tokenOwner) virtual public view returns (uint balance);
    function allowance(address tokenOwner, address spender) virtual public view returns (uint remaining);
    function transfer(address to, uint tokens) virtual public returns (bool success);
    function approve(address spender, uint tokens) virtual public returns (bool success);
    function transferFrom(address from, address to, uint tokens) virtual public returns (bool success);
    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals
// assisted token transfers
// ----------------------------------------------------------------------------
contract N47Token is ERC20Interface, SafeMath {
    string public symbol;
    string public  name;
    uint8 public decimals;
    uint public _totalSupply;
    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;
    // ------------------------------------------------------------------------
    // Constructor
    // ------------------------------------------------------------------------
    constructor() {
        symbol = "N47";
        name = "N47Token";
        decimals = 0;
        _totalSupply = 1000000;
        balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    // ------------------------------------------------------------------------
    // Total supply
    // ------------------------------------------------------------------------
    function totalSupply() public override view returns (uint) {
        return _totalSupply - balances[address(0)];
    // ------------------------------------------------------------------------
    // Get the token balance for account tokenOwner
    // ------------------------------------------------------------------------
    function balanceOf(address tokenOwner) public override view returns (uint balance) {
        return balances[tokenOwner];
    // ------------------------------------------------------------------------
    // Transfer the balance from token owner's account to receiver account
    // - Owner's account must have sufficient balance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transfer(address receiver, uint tokens) public override returns (bool success) {
        balances[msg.sender] = safeSub(balances[msg.sender], tokens);
        balances[receiver] = safeAdd(balances[receiver], tokens);
        emit Transfer(msg.sender, receiver, tokens);
        return true;
    // ------------------------------------------------------------------------
    // Token owner can approve for spender to transferFrom(...) tokens
    // from the token owner's account
    // recommends that there are no checks for the approval double-spend attack
    // as this should be implemented in user interfaces 
    // ------------------------------------------------------------------------
    function approve(address spender, uint tokens) public override returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    // ------------------------------------------------------------------------
    // Transfer tokens from sender account to receiver account
    // The calling account must already have sufficient tokens approve(...)-d
    // for spending from sender account and
    // - From account must have sufficient balance to transfer
    // - Spender must have sufficient allowance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transferFrom(address sender, address receiver, uint tokens) public override returns (bool success) {
        balances[sender] = safeSub(balances[sender], tokens);
        allowed[sender][msg.sender] = safeSub(allowed[sender][msg.sender], tokens);
        balances[receiver] = safeAdd(balances[receiver], tokens);
        emit Transfer(sender, receiver, tokens);
        return true;
    // ------------------------------------------------------------------------
    // Returns the amount of tokens approved by the owner that can be
    // transferred to the spender's account
    // ------------------------------------------------------------------------
    function allowance(address tokenOwner, address spender) public override view returns (uint remaining) {
        return allowed[tokenOwner][spender];

Using the above code, smart-contract can be deployed on Ethereum Mainnet or Testnet. Deploying a smart contract is technically a transaction, that needs to pay Gas (fees) in terms of ETH (Native token for Ethereum network), in the same way, that needs to pay gas for a simple ETH transfer. However, Gas costs for contract deployment are far higher.

** To create another token, simply change those values in the smart contract marked as highlight lines.


Blockchain technology is way deeper than token and smart contracts. There are many technical aspects like Consensus, Blocks, Wallets, Transactions, Decentralization, mining, etc. The goal of this article was just to provide an overview of smart-contract creation. Just feel free to write down your valuable comments.