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 🤑

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.

Crypto Trading Bot

Reading Time: 6 minutes

Every year, N47 as a tech family celebrates a tech festival as Hackdays at the end of the year. In December 2019 we were in Budapest, Hungary for Hackdays. There were five different teams and each team had created some cool projects in a short time. I was also part of a team and we implemented a simple Trading Bot for Crypto. In this blog post, I want to share my experiences.

Trading Platform

To create a Trading Bot, you first need to find the right trading platform. We selected Binance DEX, which can offer a good volume for selected trading pairs, testnet for test purposes and was a Decentralized EXchange (DEX). Thanks to DEX, we can connect the wallet directly and use the credit directly from it.

Binance Chain is a new blockchain and peer-to-peer system developed by Binance and the community. Binance DEX is a secure, native marketplace that is based on the Binance Chain and enables the exchange of digital assets that are issued and listed in the DEX. Reconciliation takes place within the blockchain nodes, and all transactions are recorded in the chain, creating a complete, verifiable activity book. BNB is the native token in the Binance Chain, so users are charged the BNB for sending transactions.

Trading fees are subject to a complex logic, which can lead to individual transactions not being calculated exactly at the rates mentioned here, but instead between them. This is due to the block-based matching engine used in the DEX. The difference between Binance Chain and Ethereum is that there is no idea ​​of gas. As a result, the fees for the remaining transactions are set. There are no fees for a new order.

The testnet is a test environment for Binance Chain network, run by the Binance Chain development community, which is open to developers. The validators on the testnet are from the development team. There is also a web wallet that can directly interact with the DEX testnet. It also provides 200 testnet BNB so that you can interact with the Binance DEX testnet.

For developers, Binance DEX has also provided the REST API for testnet and main net. It also provides different Binance Chain SDKs for different languages like GoLang, Javascript, Java etc. We used Java SDK for the Trading Bot with Spring Boot.

Trading Strategy

To implement a Trading Bot, you need to know which pair and when to buy and sell Crypto for these pairs. We selected a very simple trading strategy for our project. First, we selected the NEXO / BINANCE trading pair (Nexo / BNB) because this pair has the highest trading volume. Perhaps you can choose a different trading pair based on your analysis.

For the purchase and sale, we made a decision based on Candlestick count. We considered the size of Candlestick for 15 minutes. If three are still red (price drops), buy Nexo and if three are still green (price increase), sell Nexo. Once you’ve bought or sold, you’ll have to wait for the next three. Continue with the red or green Candlestick. The purchase and sales volume is always 20 Nexo. You can also choose this based on your analysis.

Let’s Code IT

We have implemented the frontend (Vue.Js) and the backend (Spring Boot) for the Trading Bot, but here I will only go into the backend application as it contains the main logic. As already mentioned, the backend application was created with Spring Boot and Binance Chain Java SDK.

We used ThreadPoolTaskScheduler for the application. This scheduler runs every 2 seconds and checks Candlestick. This scheduler has to be activated once via the frontend app and is then triggered automatically every 2 seconds.

ThreadPoolTaskScheduler.scheduleAtFixedRate(task, 2000);

Based on the scheduler, the execute() method is triggered every two seconds. This method first collects all previous Candlestick for 15 minutes and calculates the green and red Candlestick. Based on this, it will buy or sell.

private double quantity = 20.0;
private String symbol = NEXO-A84_BNB; 
public void execute() {
        List<Candlestick> candleSticks = binanceDexApiRestClient.getCandleStickBars(this.symbol, CandlestickInterval.FIFTEEN_MINUTES);
        List<Candlestick> lastThreeElements = candleSticks.subList(candleSticks.size() - 4, candleSticks.size() - 1);
        // check if last three candlesticks are all red (close - open is negative)
        boolean allRed =
                .filter(cs -> Double.parseDouble(cs.getClose()) - Double.parseDouble(cs.getOpen()) < 0.0d).count() == 3;
        // check if last three candlesticks are all green (close - open is positive)
        boolean allGreen =
                .filter(cs -> Double.parseDouble(cs.getOpen()) - Double.parseDouble(cs.getClose()) < 0.0d).count() == 3;
        Wallet wallet = new Wallet(privateKey, binanceDexEnvironment);

        // open and closed orders required to check last order creation time
        OrderList closedOrders = binanceDexApiRestClient.getClosedOrders(wallet.getAddress());
        OrderList openOrders = binanceDexApiRestClient.getOpenOrders(wallet.getAddress());

        // order book required for buying and selling price
        OrderBook orderBook = binanceDexApiRestClient.getOrderBook(symbol, 5);
        Account account = binanceDexApiRestClient.getAccount(wallet.getAddress());

        if ((openOrders.getOrder().isEmpty() || openOrders.getOrder().get(0).getOrderCreateTime().plusMinutes(45).isBeforeNow()) && (closedOrders.getOrder().isEmpty() || closedOrders.getOrder().get(0).getOrderCreateTime().plusMinutes(45).isBeforeNow())) {
            if (allRed) {
                if (Double.parseDouble(account.getBalances().stream().filter(b -> b.getSymbol().equals(symbol.split("_")[1])).findFirst().get().getFree()) >= (quantity * Double.parseDouble(orderBook.getBids().get(0).getPrice()))) {
                    order(wallet, symbol, OrderSide.BUY, orderBook.getBids().get(0).getPrice());
                    System.out.println("Buy Order Placed  Quantity:" + quantity + "  Symbol:" + symbol + "  Price:" + orderBook.getAsks().get(0).getPrice());
                } else {
                    System.out.println("do not have enough Token: " + symbol + " in wallet for buy");

            } else if (allGreen) {
                if (Double.parseDouble(account.getBalances().stream().filter(b -> b.getSymbol().equals(symbol.split("_")[0])).findFirst().get().getFree()) >= quantity) {
                    order(wallet, symbol, OrderSide.SELL, orderBook.getAsks().get(0).getPrice());
                    System.out.println("Sell Order Placed  Quantity:" + quantity + "  Symbol:" + symbol + "  Price:" + orderBook.getAsks().get(0).getPrice());
                } else {
                    System.out.println("do not have enough Token:" + symbol + " in wallet for sell");

            } else System.out.println("do nothing");
        } else System.out.println("do nothing");


    private void order(Wallet wallet, String symbol, OrderSide orderSide, String price) {
        NewOrder no = new NewOrder();

        TransactionOption options = TransactionOption.DEFAULT_INSTANCE;

        try {
            List<TransactionMetadata> resp = binanceDexApiRestClient.newOrder(no, wallet, options, true);
  "TransactionMetadata", resp);
        } catch (Exception e) {
            log.error("Error occurred while order", e);

At first glance, the strategy looks really simple, I agree. After this initial setup, however, it’s easy to add more complex logic with some AI.


Since 12th December 2019, this bot is running on Google Cloud and did 1130 transactions (buy/sell) until 14th April 2020. Initially, I started this bot with 2.6 BNB. On 7th February 2020, the balance was 2.1 BNB in the wallet, but while writing this blog on 14th April 2020, it looks like the bot has recovered the loss and the balance is 2.59 BNB. Hopefully, in future it will make some profit💰🙂.

Let me know your suggestions in a comment on this bot and I would also like to answer your questions if you have anything on this topic. Thanks for the time.