Basic of Mappings in Solidity

Mappings are one of the most used complex data types in Solidity. Mappings act as hash tables which consist of key types and corresponding value type pairs – pretty similar to hash tables or dictionaries in other languages. They help in storing key-value pairs and enable retrieving values based on the supplied key.

Mappings are declared using the mapping keyword followed by data types for both key and value separated by the => notation. Mappings have identifiers like any other data type and they can be used to access the mapping and can only have type of storage and are generally used for state variables. Solidity automatically creates a getter function for it.

Although it is similar to a hash table and dictionary, Solidity does not allow iterating through mapping. A value from mapping can be retrieved if the key is known. The next example illustrates working with mapping.

Another characteristic about mapping is the absence of iteration support but there are ways to work round this limitation. Notice that iterating and looping are an expensive operation in Ethereum in terms of gas usage and should generally be avoided.

đź’ˇ Gotchas

  • Mappings do not have a length, nor do they have a concept of a key or a value being set
  • It is also possible to have nested mapping, that is mapping consisting of mappings
  • Mappings can only be used for state variables that act as storage reference types
  • Mapping cannot be declared within functions as memory mappings
  • When mappings are initialized every possible key exists in the mappings and are mapped to values whose byte-representations are all zeros

Additional Information

Types in Solidity – Solidity Docs v0.4.21


How is the structure of a smart contract

Smart contracts are the basic unit of deployment and execution for EVMs. A contract contains state variables, functions, function modifiers, events, structures, and enums. Contracts also support inheritance. Inheritance is implemented by copying code at the time of compiling. Smart contracts also support polymorphism.

Every transaction on Ethereum Virtual Machine costs us some amount of Gas. The lower the Gas consumption the better is your Solidity code. The Gas consumption of Memory is not very significant as compared to the gas consumption of Storage. Therefore, it is always better to use Memory for intermediate calculations and store the final result in Storage.

State variables

The variable can be used at multiple places within code and they will all refer to the value stored within it. Solidity provides two types of variable: state and memory.

The default for function parameters (including return parameters of functions) is memory, the default for local variables is storage.

Storage

Persistent data is referred to as storage and is represented by state variables. These values get stored permanently on the blockchain. You need to declare the type so that the contract can keep track of how much storage on the blockchain it needs when it compiles.

Structure

Structures or structs helps implement custom user-defined data types. A structure is a composite data type, consisting of multiple variables of different data types. They are very similar to contracts; however, they do not contain any code within them. They consist of only variables.

Additional Information

ANATOMY OF SMART CONTRACTS by Ethereum.org


EVM – Ethereum Virtual Machine

Intro

Solidity is a programming language targeting Ethereum Virtual Machine (EVM). Ethereum blockchain helps extend its functionality by writing and executing code known as smart contracts. Ethereum Virtual Machines have been successfully implemented in various programming languages including C++, Java, JavaScript, Python, Ruby, and many others.

EVM executes code that is part of smart contracts. Smart contracts are written in Solidity; however, EVM does not understand the high-level constructs of Solidity. EVM understands lower-level instructions called bytecode. Solidity code needs a compiler to take its code and convert it into bytecode that is understandable by EVM.

For every instruction implemented on the EVM, a system that keeps track of execution cost, assigns to the instruction an associated cost in Gas units (See our What is Gas? article). When a user wants to initiate an execution, they reserve some Ether, which they are willing to pay for this gas cost.

In order to facilitate Keccak-256 cryptographic hash scheme, the EVM is a stack-based architecture with a word size of 256-bits. This architecture also allows for the use of elliptic-curve cryptography in Ethereum’s signature scheme for validating the origin and integrity of transactions.

EVM

Additional Information

ETHEREUM VIRTUAL MACHINE (EVM) by Ethereum.org


Simplify your Android code with Coroutines

Kotlin Coroutines in an Android app—a new way of managing background threads that can simplify code by reducing the need for callbacks. Coroutines are a Kotlin feature that converts async callbacks into sequential code. Code written sequentially is typically easier to read, and can even use language features such as exceptions.

In the end, they do the exact same thing: wait until a result is available from a long-running task and continue execution. However, in code they look very different.

The keyword suspend is Kotlin’s way of marking a function, or function type, available to coroutines. When a coroutine calls a function marked suspend, instead of blocking until that function returns like a normal function call, it suspends execution until the result is ready then it resumes where it left off with the result. While it’s suspended waiting for a result, it unblocks the thread that it’s running on so other functions or coroutines can run.

Note

The pattern of async and await in other languages is based on coroutines. If you're familiar with this pattern, the suspend keyword is similar to async. However in Kotlin, await() is implicit when calling a suspend function.

Scopes

All coroutines run inside a CoroutineScope. A scope controls the lifetime of coroutines through its job. When you cancel the job of a scope, it cancels all coroutines started in that scope. On Android, you can use a scope to cancel all running coroutines when, for example, the user navigates away from an Activity. Scopes also allow you to specify a default dispatcher. A dispatcher controls which thread runs a coroutine.

GlobalScope - Lifetime of the new coroutine is limited only by the lifetime of the whole application

CoroutineScope - Is destroyed after all launched children are completed

MainScope - Scope for UI applications and uses Dispatchers.Main

Note

Libraries like Room and Retrofit offer main-safety out of the box when using coroutines, so you don't need to manage threads to make network or database calls. This can often lead to substantially simpler code.

Channels

Channels are a way to communicate (transfer data) between coroutines similar to a blocking queue. It Uses send and receive for normal values, produce and consume for streams. Moreover, Channels can be closed to indicate no more elements are coming.

Exception handling

Coroutines will delegate uncaught exceptions to the system’s uncaught exception handler. On Android, the handler will output the exception and crash the app.

try {
    GlobalScope.launch {
        throw NullPointerException()
    }
} catch (e: Exception) {
    // Exceptions will never land here because `launch` propagates uncaught exceptions
    // to the default handler and will never pass them to the outer scope.
    System.err.println("Caught exception! $e")
}

Additional Information

Use Kotlin Coroutines in your Android App by Google

Android Kotlin Fundamentals 06.2: Coroutines and Room by Google

Understand Kotlin Coroutines on Android at Google/IO 19


Coroutines basics

Intro

Kotlin, as a language, provides only minimal low-level APIs in its standard library to enable various other libraries to utilize coroutines. Unlike many other languages with similar capabilities, async and await are not keywords in Kotlin and are not even part of its standard library. Moreover, Kotlin’s concept of suspending function provides a safer and less error-prone abstraction for asynchronous operations than futures and promises.

On Android, coroutines help to solve two primary problems:

  • Manage long-running tasks that might otherwise block the main thread and cause your app to freeze.
  • Providing main-safety, or safely calling network or disk operations from the main thread.

Get Started

Essentially, coroutines are light-weight threads. They are launched with launch coroutine builder in a context of some CoroutineScope. Here we are launching a new coroutine in the GlobalScope, meaning that the lifetime of the new coroutine is limited only by the lifetime of the whole application.

See this example:

import kotlinx.coroutines.*

fun main() {
    GlobalScope.launch { // launch a new coroutine
	delay(1000L) // non-blocking delay
	println("World!")
}

	println("Hello,") // main thread continues
	Thread.sleep(2000L) // block main thread
}

Coroutines allows us to mix blocking and non-blocking code in the same place. See the following example which has two delays. The first one is a non-blocking code inside a courotine and the second is blocking. Both work correctly once they are wrapped bt another courotine.

Note: Delaying for a time while another coroutine is working is not a good approach.

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> { // start main coroutine
	GlobalScope.launch { // launch a new coroutine
	delay(1000L)
	println("World!")
}
    
	println("Hello,") // main coroutine continues
	delay(2000L)      // delaying
}

Designate a CoroutineScope

When defining a coroutine, you must also designate its coroutineScope. A coroutineScope manages one or more related coroutines. You can also use a coroutineScope to start a new coroutine within that scope. Unlike a dispatcher, however, a coroutineScope doesn’t run the coroutines.

One important function of coroutineScope is stopping coroutine execution when a user leaves a content area within your app. Using coroutineScope, you can ensure that any running operations stop correctly.

runBlocking and coroutineScope may look similar because they both wait for its body and all its children to complete. The main difference between these two is that the runBlocking method blocks the current thread for waiting, while coroutineScope just suspends, releasing the underlying thread for other usages. Because of that difference, runBlocking is a regular function and coroutineScope is a suspending function.