0% found this document useful (0 votes)
11 views93 pages

Intro CD BENv 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views93 pages

Intro CD BENv 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 93

See discussions, stats, and author profiles for this publication at: https://www.researchgate.

net/publication/370120309

Introduction to Blockchain, Smart Contracts and Decentralized Applications

Preprint · April 2023


DOI: 10.17605/OSF.IO/FQ3P9

CITATIONS READS

2 1,447

1 author:

Manuel José Fernández Iglesias


atlanTTic - University of Vigo
245 PUBLICATIONS 1,388 CITATIONS

SEE PROFILE

All content following this page was uploaded by Manuel José Fernández Iglesias on 11 February 2024.

The user has requested enhancement of the downloaded file.


Introduction to Blockchain, Smart Contracts and Decentralized
Applications
Version 4.1/EN – February 2024

Manuel José Fernández Iglesias


atlanTTic - University of Vigo, Spain
Abstract

Blockchains, smart contracts and decentralized applications (dApps) are three essential components
of the emerging field of decentralized technology. A blockchain can be viewed as a decentralized
database that allows secure and transparent peer-to-peer transactions to be recorded without the
need for intermediaries. Smart contracts are self-executing computer programs that automatically
enforce the terms of an agreement between parties, without the need for intermediaries such as fi-
nancial or regulatory entities. Smart contracts are built using programming languages such as Solidity
and deployed on blockchain networks. dApps are decentralized applications that leverage blockchain
technology and smart contracts to support decentralized transactions and services without the need
for a central oversight body. dApps are designed to operate autonomously, without the need for a
central authority, and can be used for a wide range of applications in very diverse fields such as fi-
nance, supply chain management, social networking or gaming. Combined, blockchains, smart con-
tracts and dApps offer a revolutionary new way to orchestrate and provide services in a decentralized,
secure and transparent way. Blockchain as a new player in the cloud emerges to support the develop-
ment and deployment of dApps. Cloud computing provides developers with access to scalable and
flexible computing resources that can be used to run dApps and store data in a blockchain network.
Through the cloud provisioning model, developers can create and deploy dApps without significant
upfront investment in infrastructure or technical expertise, enabling access to the world of decentral-
ized technologies and the adoption of solutions based on those technologies, which in turn are the
foundation for a new generation of online services based on decentralization: the Web3 or Web 3.0.

Under the Attribution-NonCommercial-NoDerivatives 4.0 International License (CC BY-NC-ND 4.0)


(the “License”). You may reuse this material free of charge in accordance with the License. You may distribute it freely and
at no cost as is, in its original language (View License). Anyway, if you find this content useful and interesting you can buy
me a cup of coffee: 0x932F438AC00eBF608142Bf0fB48Aba0B5fF4AF7d
Cite as: Manuel J. Fernández Iglesias (2023) Introduction to Blockchain, Smart Contracts and Decentralized Applications,
Ver 3.0/EN. Technical report. atlanTTIc, University of Vigo, Spain.
DOI: 10.17605/OSF.IO/FQ3P9 .

Version 4.1/EN. Build: Sunday 11th February, 2024, 17:35 CET.

1
2
Contents

1 Introduction 5

2 Blockchain Types 6
2.1 Permissionless Blockchains: Cryptocurrency . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Permissioned Blockchains: Enterprise Chains . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Basic Structure and Operation of a Blockchain 7


3.1 Actors in a Blockchain Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2 Blockchain Consensus Mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3 Adding Blocks to the Chain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

4 Advantages and Disadvantages of Blockchain Technologies 16


4.1 Security Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5 Smart Contracts and dApps 18


5.1 Smart Contract and dApp Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.2 Smart Contracts and Cryptocurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5.3 Security Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.4 Non-fungible Tokens: NFT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6 Decentralized Finance (DeFi) 37


6.1 Decentralized Exchanges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
6.2 Decentralized Lending . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.3 Liquidity Mining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.4 DeFi Derivatives and Asset Management . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.5 Challenges and Policy Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

7 Oracles 43
7.1 Oracle Architectures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
7.2 Oracles and DeFi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
7.3 Random number generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
7.4 Oracle Networks and Cross-chain Oracles . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.5 Security Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

8 Peer-to-peer File Systems 62


8.1 Limitations of Traditional File Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
8.2 Fundamentals of Decentralized File Systems . . . . . . . . . . . . . . . . . . . . . . . . . 63
8.3 Architecture and Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

3
8.4 InterPlanetary File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
8.5 IPFS and Blockchain: Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
8.6 Other Decentralized File Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

9 Blockchain as a Service 68

10 Conclusion 68
10.1 To Learn More . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

A Public Key Cryptography 73

B Hash Functions 75

C Merkle Trees 77

D Ethereum’s Proof-of-stake 78

E Peer-to-peer Networks 79

Glossary 83

4
1 Introduction

A blockchain is a decentralized information storage distributed across a network of computers, known


as nodes. Nodes create blocks to construct a chain of blocks, that is, the blockchain. In some cases,
this process involves solving complex mathematical problems and is called mining. Each block on the
chain records a set of transactions or operations, and once a block is added to the chain, it cannot be
altered without the consensus of the network peers. In other words, once a transaction is added to the
blockchain, it is permanent and immutable. Transactions represent the records of any movement of
data, assets or value between people or entities. Therefore, a blockchain can be viewed as a database
that keeps track of all transactions that occurred on that network since its creation. Another common
simile to describe a blockchain is that of a distributed and immutable accounting ledger, where all
transactions made are recorded. Blockchains use cryptographic techniques, such as public key cryp-
tography or hash functions (cf. Appendices A and B), to secure the network and guarantee the privacy
and security of the data stored in them.
The nodes in a blockchain network interact with each other using a peer-to-peer network protocol
(P2P, cf. Appendix E and Fig. 9). Each node is connected to several nodes in the network and can send
and receive data to and from these nodes. When a node joins the network, it first has to find other
nodes to connect to. To do this, it can use a start node, which is a well-known node in the network that
has a list of other nodes to which the new node can connect. Once the new node is connected, it can
use a discovery protocol to find additional nodes in the network. Once a node is connected to other
nodes, it can exchange messages with them using the P2P protocol. These messages can include
transactions, blocks and other blockchain-related data. Each node verifies the data that it receives
from other nodes to ensure that it is valid and was not tampered with.
Nodes can also communicate with each other to reach consensus on the state of the blockchain.
This is done using a consensus algorithm, which ensures that all nodes agree on the same set of
transactions and blocks. Depending on the consensus algorithm used, nodes may have to perform
different functions, such as validating transactions or mining new blocks. In general, interaction be-
tween nodes in a blockchain network is essential to maintain the integrity and security of the network,
as well as to ensure that all nodes have a consistent view of the blockchain.
The blockchain’s decentralized nature means that there is no central authority controlling it, making
it resistant to hacking and manipulation. Instead, each node in the network has a copy of the complete
chain. This ensures that there is no single point of failure in the network and that the blockchain itself
is tamper-resistant. Each block on the chain contains a set of transactions, and once a block is added
to the chain, it cannot be altered. This also makes it a system that does not require a trusted central
authority, meaning that participants can trust the data stored on the blockchain without relying on any
intermediary. As discussed above, the blockchain uses instead a consensus mechanism to ensure
that all nodes in the network agree on the state of the chain.
Blockchains are already used in a wide range of applications, such as cryptocurrencies, supply
chain management, financial asset management, Internet of Things ecosystem management, voting
systems, education (Delgado-von-Eitzen, Anido-Rifón, & Fernández-Iglesias, 2021b) and many others.
The best known blockchain is Bitcoin, which is used to store and transfer the Bitcoin cryptocurrency
(BTC). This was the original chain proposed by Satoshi Nakamoto (2008), the individual or group of
people credited with the first successful application of this technology.
Another popular chain is Ethereum 2014, a programmable blockchain that allows developers to
create decentralized applications (dApps) using smart contracts. It also has its own cryptocurrency
(Ethereum, ETH) and is the second largest blockchain by market capitalization, after Bitcoin. Other
popular chains, with their respective cryptocurrencies, are Binance Smart Chain (BSC) (Chain, 2020),
Cardano (ADA) (Hoskinson, 2017), Polkadot (DOT) (Wood, 2016) or Solana (SOL) (Yakovenko, 2017).

5
The evolving and expanding world of blockchain, smart contracts and dApps gave rise to a wide
range of technologies and applications that bound to transform various sectors of society. In these lec-
ture notes, we will explore the fundamentals of blockchain, introducing the different types of blockchains,
their basic structure and operation, as well as their advantages and disadvantages. In addition, we will
delve into the world of smart contracts and dApps, discussing their programming, security and their
relationship with cryptocurrencies and non-fungible tokens (NFTs). We will also explore the field of
decentralized finance or DeFi, ranging from decentralized financial markets to lending and liquidity
mining. Additionally, we will examine oracles and decentralized file systems, as well as the concept
of Blockchain as a Service (BaaS). Finally, we will conclude our tour by exploring the most recent de-
velopments in the blockchain arena and offering additional resources for those interested in knowing
more about the topic.
It is important to note that the blockchain ecosystem is evolving rapidly, with continuous advances
in technology, standards and best practices. Similarly, the supporting tools and libraries used to de-
velop smart contracts and interact with blockchain networks are also evolving at a rapid pace. As a
result, while the code provided here is accurate and functional at the time of writing, it may require
updates or fixes in the near future to remain compatible with the latest versions of blockchain plat-
forms, libraries and standards. Developers are advised to keep abreast of the latest developments in
blockchain, to check the compatibility of the code with current versions of the software, and to exercise
caution when deploying the code in production environments.

2 Blockchain Types

The most general blockchain classification is based on the requirements imposed on users to be able
to transact on them (Miller, 2019). In a permissioned or private blockchain network, access to the net-
work and participation in the validation and verification of transactions are restricted to a specific group
of authorized participants. These participants are typically identified and verified through some form
of identity verification process. Permissioned blockchain networks are typically used in enterprise or
government applications where privacy, security and compliance are critical operational requirements.
In contrast, a permissionless or public blockchain network is open to anyone who wishes to par-
ticipate in it, with no restrictions or identity verification requirements. These networks are generally
considered more decentralized and offer greater transparency, but may also be more susceptible to
attacks or other malicious activity due to their open nature.
Cryptocurrency blockchains are the straightforward example of permissionless networks, while,
as indicated, enterprise blockchains would perhaps be the best example of permissioned networks.
The most relevant characteristics of these chains are discussed below.

2.1 Permissionless Blockchains: Cryptocurrency

A cryptocurrency blockchain is a decentralized, distributed digital ledger used to track and record trans-
actions in a digital currency, such as Bitcoin or Ethereum. It enables peer-to-peer transactions with-
out the need for intermediaries, such as banks or financial institutions, and is designed to be secure,
transparent and immutable. Cryptocurrencies became hugely popular among investors and the gen-
eral public as a technology that has the potential to revolutionize traditional financial systems and
transform the way in which people transact and exchange value.
In a cryptocurrency blockchain, transactions are grouped into blocks and added to the blockchain
in chronological order. As with any blockchain, each block contains a unique cryptographic hash that
links it to the previous block, creating an immutable, secure and tamper-proof ledger. The security and

6
integrity of a cryptocurrency blockchain is maintained by a consensus mechanism, which is a set of
rules and protocols that ensure that all network participants agree upon the validity of transactions
and the order in which they were added to the blockchain (cf. Sect. 3.2). Being permissionless, cryp-
tocurrency blockchains are designed to be transparent and publicly auditable, meaning that transac-
tion details are visible to network peer. In terms of scalability, cryptocurrency blockchains can handle a
large volume of transactions, but they may also experience scalability issues due to energy-consuming
consensus mechanisms such as proof-of-work.

2.2 Permissioned Blockchains: Enterprise Chains

In contrast, enterprise blockchains are designed to facilitate the secure and transparent exchange of
data and collaboration among different stakeholders of a business network, such as suppliers, cus-
tomers, employees and partners. Permissioned blockchains require authorization from a central entity
or a consortium in order to operate, and are designed to support specific business applications. Unlike
public blockchains used for cryptocurrencies, enterprise blockchains are typically designed for use by
a specific group of participants and are not open to the public.
Enterprise blockchains offer several advantages to businesses, such as increased transparency,
security and efficiency. By using a shared and distributed database, participants can access and
verify data in real time, which reduces the risk of errors, fraud and disputes. In addition, enterprise
blockchains help streamline business activities and reduce costs by eliminating intermediaries, au-
tomating the flow of information and optimizing processes.
Common use cases for enterprise blockchains include supply chain management, digital iden-
tity verification, trade finance and payments. For example, a blockchained supply chain could enable
manufacturers, distributors and retailers to track the movement of goods from production to customer
delivery, ensuring transparency and reducing the risk of product counterfeiting. Similarly, a digital iden-
tity blockchain could enable secure and efficient identity verification for individuals and businesses,
reducing the risk of fraud and identity theft. Ultimately, enterprise blockchains offer companies a way
to leverage the benefits of decentralized database technology, while addressing the challenges and
requirements of specific use cases.
Enterprise blockchains can offer greater privacy and confidentiality, using techniques such as data
encryption or selective information sharing. They also tend to scale better, as they can be designed
with a specific application in mind. Besides, they do not need to support the same volume of transac-
tions as a cryptocurrency blockchain.
In general, while both permissioned and permissionless blockchains use decentralized ledger tech-
nology, they have different design considerations and serve different purposes. Permissionless block-
chains, such as cryptocurrency blockchains, prioritize decentralization, transparency and security for
peer-to-peer transactions, while permissioned blockchains prioritize scalability, privacy and interoper-
ability for the secure and efficient exchange of data within a network composed of peers that, in turn,
are explicitly given permission to operate on the network.

3 Basic Structure and Operation of a Blockchain

As discussed above, a blockchain is composed of a series of blocks linked to each other. A block on
the blockchain is a data record that packs a group of transactions that were validated and added to the
blockchain ledger. Each block is linked to the previous block, forming a chain that contains a complete
and unalterable history of all transactions made on the network, since its creation.

7
As depicted in Fig. 1, each block starts with a header containing metadata about the block, in-
cluding the hash of the block, the hash of the previous block, a timestamp and, if necessary, a nonce.
The nonce is a random value used in the mining process of proof-of-work networks, different for each
mined block, needed to solve the computational challenge of such a consensus mechanism (Wang
et al., 2019).

Figure 1: Illustrative example of a blockchain structure.

In addition, each block contains a list of validated transactions that are included in the block. To
protect this content against tampering and other attacks and to ensure its integrity and immutability,
the block also contains a hash key that summarizes all transactions in the block. This key corresponds
to the root of the transactions’ Merkle tree (cf. Appendix C and Fig. 8).
Blocks have also a field indicating its size in bytes. This is an important element in blockchain net-
works with limited storage capacity. Another field indicates the position of the block in the blockchain,
called block height. Each block in the blockchain has a unique height, and the height of each block is
based on the height of the previous block. The block height field along with the hash of the previous
block and the timestamp serve to ensure the ordering of the blocks in the chain and their immutability.
The hash of the block itself serves to guarantee that none of the fields in the block were altered.
Finally, in the proof-of-work networks (cf. Sect. 3.2) a difficulty field is included that indicates
the level of computational difficulty required to mine the block. This value is adjusted periodically to
maintain a constant rate of block creation in these networks.

3.1 Actors in a Blockchain Network

The key participants in a blockchain network may vary depending on the type of blockchain, but com-
mon elements to most of them are network nodes, miners or validators depending on the consensus
mechanism, users, developers and regulators.
Nodes are computers or servers connected to the network that play a crucial role in the operation of
a blockchain by validating transactions, maintaining a copy of the ledger and transmitting information
to other nodes in the network. They use a P2P protocol to communicate with each other. Each node
in the blockchain network has a unique address that identifies it within the network. In addition to
performing the tasks indicated to ensure the proper functioning of the chain, it shares information
about its status and capabilities with the rest of the nodes. For example, the version of the blockchain
software that the node is running is relevant because nodes running obsolete software may be at risk
of vulnerabilities and not be able to participate in some network activities. In addition, a node keeps
track of the number of blocks on the chain validated by it. This helps other nodes in the network
determine the validity and accuracy of the blockchain. The connection status information indicates
whether the node is currently connected to other nodes in the network. Nodes that are not connected
to the network cannot validate transactions or exchange information. The amount of memory and
storage available to the node is directly related to its participation in the network, as nodes with limited
memory or storage capacity may not be able to perform certain network functions. Finally, the node’s
hash rate indicates the computational power that the node is contributing to the network. This is

8
particularly relevant in proof-of-work blockchains, where mining requires significant computational
power.
Miners are those nodes in a proof-of-work blockchain that compete to solve complex mathematical
challenges with the goal of adding new blocks to the chain and thereby earning rewards. Validators, on
the other hand, are nodes in a proof-of-stake or Byzantine fault-tolerant blockchain that are responsible
for validating transactions and adding new blocks to the blockchain. Validators are chosen based on
their participation in the network, usually measured by the amount of a cryptocurrency endorsement,
and they also earn rewards for their participation.
Users are individuals or organizations that use the blockchain network to send and receive trans-
actions. They can also participate in the consensus mechanism of the blockchain network by con-
tributing their collateral in a proof-of-stake network. Users participate freely and anonymously in per-
missionless networks and require identification and registration in permissioned networks.
Developers are individuals or organizations that create and maintain blockchain software and ap-
plications that run on the top layer of the network, such as smart contracts and dApps.
Finally, regulators are government agencies or other organizations that oversee and regulate the
use of the blockchain network, especially in cases where it involves the exchange of securities, com-
modities or other regulated assets. Their role is more relevant in enterprise networks, especially those
operating in regulated markets.
In short, participants in a blockchain network work together to ensure the security, reliability and
functionality of the network. Each has its roles and responsibilities, but all together play a crucial role
in the operation and success of the blockchain.

3.2 Blockchain Consensus Mechanisms

As pointed out in Sect. 2, consensus mechanisms are the rules and processes used to ensure that all
nodes in a blockchain network agree on the current state of the ledger. These mechanisms are used
to address vulnerabilities in blockchain networks such as the Byzantine generals problem, the Sybil
attack or the 51% attack (cf. Sect. 4.1).
In practice, several consensus mechanisms are used, each with its own advantages and disad-
vantages. The most commonly used consensus mechanisms are proof-of-work (PoW), proof-of-stake
(PoS) and the Byzantine fault tolerance algorithm, in its classical or practical versions (BFT and PBFT).
Each consensus mechanism has its own strengths and weaknesses, and the choice of consensus
mechanism depends on the specific needs and objectives of the blockchain network (Wang et al.,
2019).
In a proof-of-work blockchain, nodes compete to solve complex mathematical challenges utilizing
their computational power. The first node to solve the problem is rewarded with cryptocurrency and
the right to create the next block on the chain. For example, Bitcoin uses a proof-of-work consensus
mechanism (Nakamoto, 2008).
In a proof-of-stake blockchain, nodes are selected to create new blocks based on the amount of
cryptocurrency that they offer as collateral. Validators are selected to create new blocks and, if they
are found to be acting maliciously, the collateral is forfeited. Ethereum switched from using a proof-
of-work mechanism to a proof-of-stake mechanism in September 2022 (Buterin & Schneider, 2022).
Appendix D summarizes Ethereum’s consensus mechanism.
Delegated proof-of-stake (DPoS) is a variant of the PoS mechanism where cryptocurrency holders
elect a smaller group of validators tasked with creating new blocks (Snider, Samani, & Jain, 2018).
These validators are paid for their services and can be terminated from their duties if they are found to
be acting against the interests of the network. EOS and Tron cryptocurrencies use a delegated proof-

9
of-stake consensus mechanism. The main difference between PoS and DPoS is the way validators
are selected. In a PoS blockchain, validators are selected based on the amount of cryptocurrency they
own and provide as collateral, whereas in a DPoS blockchain, validators are chosen by cryptocurrency
holders. This gives the latter more direct control over the consensus process and allows them to hold
the validators accountable for their actions. Another difference is the number of validators required.
PoS networks may have hundreds or thousands of validators, while DPoS networks typically have
a limited number of validators. This can make DPoS networks more efficient and faster than PoS
networks, since fewer validators means faster consensus.
In a Byzantine fault-tolerant (BFT) blockchain, nodes collaborate to agree on the state of the ledger.
Some nodes are responsible for proposing new blocks, and other nodes vote on the validity of the
proposed blocks. If a supermajority (more than 51%) of nodes agree on the validity of a block, it is
added to the blockchain. Hyperledger Fabric uses a Byzantine fault-tolerant consensus mechanism
(Barger et al., 2021) .
Practical Byzantine fault tolerance (PBFT) is a variant of BFT where nodes proposing blocks and
nodes validating the proposed blocks take turns (Castro & Liskov, 2002). Quorum, a blockchain plat-
form based on Ethereum, uses this consensus mechanism. One of the main differences between BFT
and PBFT is the way nodes validate transactions and create new blocks. In a BFT blockchain, nodes
propose new blocks and other nodes validate them by running a series of cryptographic checks. The
acceptance of a block is decided by a supermajority. In contrast, PBFT uses a more complex process
in which nodes take turns proposing new blocks, and other nodes validate the proposed blocks before
adding them to the blockchain. PBFT requires a node to receive a threshold of votes from other nodes
in order to propose a block. This process ensures that each block is validated by multiple nodes and
helps protect against malicious nodes. Another difference between BFT and PBFT is the number of
faulty or malicious nodes that the consensus mechanism can tolerate. BFT requires at least two-thirds
of the nodes in the network to be honest and agree on the validity of a block for it to be added to the
blockchain, while PBFT requires at least two-thirds of the nodes to be honest, but it can tolerate up
to one-third of dishonest nodes. Finally, PBFT is generally considered to be more efficient than BFT
in terms of network overhead, as PBFT uses a more complex voting process that helps to eliminate
duplicate messages and reduce the amount of data that needs to be transmitted among nodes. Both
BFT and PBFT work in permissioned networks only, since the participating nodes’ identity has to be
known.
Other existing consensus mechanisms include proof-of-authority (PoA), proof-of-weight (PoW),
proof-of-importance (PoI), proof-of-space-and-time (PoST) and proof-of-coverage (PoC).

3.3 Adding Blocks to the Chain

In a proof-of-work blockchain such as Bitcoin, the process of adding new blocks to the blockchain
is called mining and involves solving complex mathematical challenges. Miners compete to solve a
cryptographic riddle using their computers. Typically, the riddle consists of finding a specific hash key
for the new block that meets a certain difficulty requirement. The first miner that finds the solution
to the challenge and transmits it to the network receives a reward for the block thus mined, usually
consisting of newly created cryptocurrency and/or commissions for each validated transaction. This
strategy reasonably protects the blockchain against attacks, as it would be too costly to involve a
sufficient number of dishonest miners to be successful.
The mining process takes place in several stages:
1. Transaction validation: miners receive new transactions from the network and validate them to
ensure that they are legitimate and comply with network rules.

10
2. Block creation: once a miner validated a set of transactions, it groups them into a block and adds
a special transaction to collect the reward for mining the block and credit it to the miner’s wallet.
3. Challenge resolution: the miner uses its computing power to try to find a solution to the crypto-
graphic riddle associated with the block.
4. Solution dissemination: once a miner found a valid solution, the newly mined block is transmitted
to the network, and other nodes in the network verify that the solution is indeed correct.
5. Adding the block to the blockchain: once the solution is verified as valid, the new block is added
to the blockchain and the miner receives its reward for mining that block.

The difficulty of the mathematical puzzle is dynamically adjusted to ensure that new blocks are
added to the blockchain at a constant rate. The mining process is designed to be computationally in-
tensive and resource-intensive to prevent fraud and ensure the security and integrity of the blockchain.
Proof-of-work mining can be illustrated with the example below. Imagine that in a certain blockchain
network, in order to contribute a new block, it is required as a challenge that the hash key of the block
starts with a certain number of bits to zero. The following JavaScript function illustrates how such a
hash key would be calculated from a string of data.

1 //
2 // Example function of a simple proof-of-work mechanism.
3 // The findNonce function returns a SHA-256 hash key
4 // for the character string ’payload’.
5 // that satisfies the condition of having the first ’n’ bits
6 // set to zero.
7 //
8 // The function returns an object with the nonce used and
9 // the value of the hash key.
10 // The value of the nonce returned
11 // is an indication of the required workload.
12 // (the higher the value, the higher the workload).
13
14 // We use the crypto module to obtain the hash key.
15 const crypto = require(’crypto’);
16
17 function findNonce(payload, n) {
18 let nonce = 0;
19 while (true) {
20 // create a SHA-256 crypto hash object
21 const hash = crypto.createHash(’sha256’);
22 // concatenate input data with the nonce
23 const data = payload + nonce;
24 // compute hash key
25 hash.update(data);
26 const hex = hash.digest(’hex’);
27 // check if leading-0’s condition met
28 if (hex.slice(0, n / 4) === ’0’.repeat(n / 4)) {
29 return { nonce, hash: hex };
30 }
31 // the nonce value is incremented until a key
32 // that meets the condition is obtained.
33 nonce++;
34 }
35 }

This function adds a nonce to the input string and computes the hash key of the ensemble. It tries
successive nonces until it manages to generate a key with the required number of leading zeros. For
example, if the string Proof-of-work testing data is passed to the function with three different
values of n (i.e., 8, 16 and 20) and execution times is measured in each case:

11
1 //
2 // Code excerpt to test the function above.
3 //
4 const st2 = new Date().getTime();
5 const r2 = findNonce(’Proof-of-work testing data’, 8);
6 const end2 = new Date().getTime();
7 console.log(‘Nonce: ${r2.nonce}, Hash: ${r2.hash}, Time: ${end2 - st2}ms‘);
8
9 const st3 = new Date().getTime();
10 const r3 = findNonce(’Proof-of-work testing data’, 16);
11 const end3 = new Date().getTime();
12 console.log(‘Nonce: ${r3.nonce}, Hash: ${r3.hash}, Time: ${end3 - st3}ms‘);
13
14 const st4 = new Date().getTime();
15 const r4 = findNonce(’Proof-of-work testing data’, 20);
16 const end4 = new Date().getTime();
17 console.log(‘Nonce: ${r4.nonce}, Hash: ${r4.hash}, Time: ${end4 - st4}ms‘);

The results in Table 1 are obtained.


Table 1: Proof-of-work: workload for different values of ’n’ in ’findNonce’.

n Nonce Hash Tiempo


8 94 0x008c75d1b061036... 4 ms
16 41910 0x00002e9d649ecb7... 135 ms
20 643201 0x000006ddbf25d3d... 1631 ms

Although the time required to compute the hash key depends on the input string, on average the
computation time, and therefore the work required to solve the challenge, will grow exponentially with
the number of leading bits to zero required. By adjusting the number of zeros, the difficulty of the
challenge can be modified. The following function illustrates the mining of a block using this system.

1 //
2 // Example to mine a block by means of proof-of-work.
3 //
4 // This function uses the findNonce() function of the previous examples
5 // to calculate the hash and nonce of the new block.
6 // It takes four parameters:
7 // * transaction (string representing the transaction
8 // to include in the block),
9 // * prev_hash (hash of the previous block),
10 // * height (height of the previous block),
11 // * diff (parameter n to be passed to the findNonce() function
12 // to find the hash of this block).
13 //
14 // The function concatenates the four input parameters into a string,
15 // and passes it to findNonce() to find the nonce and hash of the new block.
16 // The time required to find the nonce and hash is also computed
17 // using new Date().getTime(). The resulting transaction, prev_hash,
18 // height, hash, nonce, diff, time required to find the nonce
19 // and hash key are stored in a blockNode object and returned.
20 //
21 const crypto = require(’crypto’);
22
23 function createBlockNode(transaction, prev_hash, height, diff) {
24 // mining timestamp
25 const start = new Date().getTime();
26 // increase height by 1
27 height++;

12
28 // compute hash key with the difficulty passed as a parameter
29 const { nonce, hash } = findNonce(transaction + prev_hash + height + diff, diff);
30 //mining completion timestamp
31 const end = new Date().getTime();
32 // mining time in microseconds
33 const time = end - start;
34 // build new block
35 const blockNode = { height, nonce, diff, time, prev_hash, hash, transaction };
36 // return block built
37 return blockNode;
38 }

If two miners simultaneously mine a valid block, a temporary fork in the blockchain is created and
the network will have two valid versions of the blockchain. The rest of the nodes in the network will
add the block that they receive first to their local copy of the blockchain and, from there, continue to
expand the chain. This creates a situation where some nodes have one version of the blockchain and
other nodes have the alternate version.
Eventually, the network will converge by choosing the longer chain, as nodes must always choose
to extend the longest chain they know of. This means that one of the two competing chains will be
discarded, and the network will continue to build on the longer chain. Consequently, miners must wait
for their block to be confirmed by the network before assuming that it was definitively added to the
blockchain. Otherwise, they risk wasting resources on a block that may ultimately be discarded in
favor of a competing block.
In a proof-of-stake blockchain, the process of creating new blocks is different from mining, and
most of the time it is called just block creation. Unlike proof-of-work, which relies on computational
power and cryptographic puzzle solving, proof-of-stake relies on a different set of rules to achieve
consensus and validate transactions. In this case, participants that hold a certain amount of the
blockchain’s native cryptocurrency can become validators. Validators are responsible for verifying
transactions and adding them to the blockchain, and are selected based on their participation, un-
derstood as the amount of cryptocurrency they deposit as collateral, or the amount of cryptocurrency
they own. The more cryptocurrency a validator owns or contributes, the greater their chances of being
selected to construct the next block.
Block creation in a proof-of-stake blockchain typically involves the following steps:

1. Collateral deposit: validators place a certain amount of cryptocurrency as collateral, which serves
as a guarantee and incentivizes good behavior. If a validator is found to be acting maliciously,
their collateral can be forfeited as a penalty.
2. Selection: validators are selected to create a new block based on their participation, and become
responsible for verifying transactions and creating a block.
3. Block creation: selected validators create a new block and transmit it to the network for verifica-
tion.
4. Verification: other validators in the network verify the block and add it to the blockchain if it is
valid.

As in the case of proof-of-work consensus, validators who successfully add a block to the blockchain
are rewarded with transaction fees or newly minted cryptocurrency.
Proof-of-stake is considered a more energy-efficient alternative to proof-of-work, as it does not
require the same level of computing power. It is also considered more environmentally friendly, as it
does not require specialized hardware such as dedicated integrated circuits (ASIC) or graphics pro-
cessors (GPU). Moreover, the validator selection process avoids in most cases the creation of forks
in the blockchain. Still, proof-of-stake has some drawbacks, such as the risk of centralization and the
challenge of ensuring that validators act in the network’s interest and not their own.

13
In a Byzantine fault-tolerant blockchain (BFT), nodes work together to agree on the state of the
network and create new blocks. The process of creating new blocks in a BFT blockchain also consists
of several steps:
1. Node selection: in a BFT blockchain, a subset of nodes is selected to propose new blocks to
the network. The number of nodes selected and the selection process depends on the specific
implementation of the consensus algorithm, but is typically between a few dozen and a few
hundred.
2. Proposal: the selected nodes create a new block by broadcasting it to the network. The block
contains a list of transactions that the proposing node deemed valid.
3. Validation: once a block is proposed, other nodes in the network validate it. The validating nodes
perform a series of cryptographic checks to ensure that the block is valid and that the trans-
actions that it contains are also valid. If the block is not valid, it is rejected and the process of
creating a new block begins again.
4. Pre-commitment: if the validating nodes consider a block to be valid, these nodes enter a pre-
commitment phase. During this phase, they signal their intention to add or to discard the block
by broadcasting a message to the network.
5. Commitment: once a supermajority of validating nodes (typically two-thirds or more) signaled
their intention to add the block to the blockchain, the block is added and nodes move on to the
next block.
The JavaSCript code below illustrates the evolution of the BFT algorithm with three nodes. The
function begins by generating a random initial message for each node, to indicate whether that node
accepts the new block. That decision may be honest (i.e., the block is actually valid or invalid, and
the node tells the truth) or dishonest (i.e., the node intends to deceive the rest of validating nodes).
Then, each node sends its message to the other nodes. Each node receives the messages from the
other nodes and decides a final verdict based on the received messages using the helper function
decideMessage. Finally, the function checks whether all nodes agreed on the same message and
displays the result on the console.

1 //
2 // This function takes three arguments representing the
3 // three nodes in the system. Each node is assumed to have
4 // a send method with two arguments (the two messages to
5 // send to the other two nodes) and a receive method with two arguments,
6 // which receives the messages from the other nodes.
7 //
8 // We assume that the nodes that will participate in the consensus have
9 // been previously selected (node11, node2 and node3), and
10 // that the forger nodes have proposed a new block.
11 //
12 function byzantineFaultTolerant(node1, node2, node3) {
13 // Beginning of the Validation phase. In this example
14 // each node validates or not the block randomly
15 // with an initial message (0 or 1).
16 let node1Message = Math.round(Math.random());
17 let node2Message = Math.round(Math.random());
18 let node3Message = Math.round(Math.random());
19
20 // and broadcasts its verdict to the network, i.e.,
21 // each node sends its message to the other nodes.
22 node1.send(node2Message, node3Message);
23 node2.send(node1Message, node3Message);
24 node3.send(node1Message, node2Message);
25
26 // each node receives the messages from the other nodes
27 let node1ReceivedMessages = [node2Message, node3Message];
28 let node2ReceivedMessages = [node1Message, node3Message];

14
29 let node3ReceivedMessages = [node1Message, node2Message];
30
31 // Pre-commitment Phase. Each node expresses its intention
32 // to add or not to add the new block, depending on the
33 // messages received.
34 let node1FinalMessage = decideMessage(node1ReceivedMessages);
35 let node2FinalMessage = decideMessage(node2ReceivedMessages);
36 let node3FinalMessage = decideMessage(node3ReceivedMessages);
37
38 // Commitment Phase. If all nodes agree to add the
39 // block (1), the node is added to the network.
40 // Check if all nodes have agreed on the same message
41 // and that the message is 1.
42 if (node1FinalMessage === node2FinalMessage
43 && node1FinalMessage === node3FinalMessage) {
44 if (node1FinalMessage == 1) {
45 console.log("Accept block");
46 } else {
47 console.log("Discard block");
48 }
49 } else {
50 console.log("Discard block");
51 }
52 }
53
54 // helper function to decide on a final message
55 // based on the received messages
56 function decideMessage(receivedMessages) {
57 // count the number of 0 and 1 messages
58 let count0 = 0;
59 let count1 = 0;
60 for (let message of receivedMessages) {
61 if (message === 0) {
62 count0++;
63 } else if (message === 1) {
64 count1++;
65 }
66 }
67
68 // if there are more 0 messages than 1 messages,
69 // decide on 0; otherwise, decide on 1
70 if (count0 > count1) {
71 return 0;
72 } else {
73 return 1;
74 }
75 }

This is a simplified version of the BFT algorithm that does not take into account all possible fail-
ure scenarios. In practice, the algorithm is considerably more complex to ensure fault tolerance and
security. Furthermore, in this simple example it is assumed that the majority to accept the new block
is reached by consensus of all validating nodes (i.e., more demanding than the two-thirds majority
discussed above).
The BFT consensus mechanism is designed to be tolerant of Byzantine faults, which are situations
that cause nodes to behave unexpectedly or maliciously. By requiring a qualified majority (usually two-
thirds or more) to agree on the validity of a block, the BFT consensus is able to protect against attacks
involving a small number of malicious nodes.

15
4 Advantages and Disadvantages of Blockchain Technologies

The main advantages of blockchain technology stem from its distinctive features, namely its decen-
tralized nature, immutability, transparency, security and computational efficiency.
The decentralized nature of blockchain means that it does not require a central authority to control
or manage it, which makes it particularly resistant to cyber attacks and manipulation. Even in the
case of permissioned networks, where a central authority authorizes certain user profiles to interact
with the network, its decentralized inception makes it resistant to both internal and external threats
because there is no single point of failure or risk of attack.
The immutability of blockchains guarantees that once a block is added to the blockchain, it cannot
be altered or deleted without the consensus of the network. In the event of a decision to modify or
delete a block or a transaction within a block, the action is materialized by a new transaction or a new
block that declares the original transaction invalid or materializes the modified version of the original
transaction. In other words, changes in the blockchain are noted in the ledger incrementally. The
original entries are not modified. This guarantees the integrity, traceability and immutability of the
data stored on the blockchain.
As a consequence of the above, since blockchains are decentralized and immutable, they do not
require a trusted third party in facilitating transactions, which means that trust is distributed as a re-
sponsibility among participants in the blockchain. All transactions on the blockchain are transparent
and can be traced back to their origin, either by the general public in permissionless networks or by en-
tities authorized to interact in the case of permissioned networks (i.e., users, regulators, applications,
oracles, etc.). This provides an unprecedented level of transparency and accountability.
In terms of security, every blockchain uses advanced cryptographic techniques to secure the net-
work and guarantee the privacy and security of data stored on the blockchain.
In terms of operational efficiency, blockchain technology facilitates faster and more efficient trans-
actions by eliminating intermediaries and singular points of control. In addition, blockchain technol-
ogy can significantly reduce operational costs by eliminating the need for intermediaries and reduc-
ing transaction fees. The emergence of smart contracts discussed in Sect. 5, support automated
transactions and can be used for a wide range of applications, increasing efficiency and reducing the
possibility of errors or fraud.
However, some drawbacks of blockchain networks can also be identified. For example, current
blockchain technology can be slow and have limited scalability, making it difficult to handle a large
number of transactions at once. This can result in slower transaction times and higher fees, despite
the savings from eliminating middlemen and simplifying each transaction.
While blockchain networks are generally an improvement in operational efficiency, they may not be
as much of an improvement in energy efficiency. In the case of proof-of-work blockchains, the mining
process can eventually require a significant amount of electricity, resulting in high energy consumption
and social backlash due to its potential environmental impact (Islam et al., 2023).
Blockchain networks also pose significant regulatory challenges. The decentralized and anony-
mous nature of permissionless blockchains, common in the cryptocurrency field, can make it difficult
for regulators to monitor activities and enforce regulations. This situation is made even more appar-
ent by the current lack of standardization in the blockchain industry, with different platforms using
different protocols, which in turn hinders interoperability among different blockchains, complicates
application development, and challenges monitoring and oversight.
Another challenge lies in meeting the requirements of personal information protection standards
such as European data protection regulations(i.e., the General Data Protection Regulation, GDPR).
Rights such as the right to object to personal data processing or the right to be forgotten in the dig-

16
ital world are difficult to achieve when storing personal data on a blockchain, due to its immutability
characteristics (Delgado-von-Eitzen, Anido-Rifón, & Fernández-Iglesias, 2021a).
The lack of standardization coupled with the complexity of blockchain technology can make it
difficult for non-technical users to understand and use blockchain technologies effectively, limiting
its potential adoption and increasing security risks. Although blockchain technology is considered
secure, there is always a risk of attacks and security breaches due to vulnerabilities or programming
errors, especially in newer or less consolidated blockchains. The following section discusses the most
important security issues.
Finally, the operation of all blockchains, given their distributed nature, depends on good Internet
connectivity, which can be a challenge in areas with poor infrastructure or limited network access.

4.1 Security Issues

The security of a blockchain network depends on several factors, such as the consensus mechanism
used, the size and topology of the network, the cryptographic algorithms used, and the behavior of
participants. If a blockchain network uses a secure, decentralized consensus mechanism such as
those in Sect. 3.2, and has a large and diverse network of nodes, it can be considered relatively secure.
If the cryptographic algorithms used comply with the usual standards and the participants behave
honestly, the security of the network is further enhanced.
However, no system is completely immune to attacks, and blockchain networks are no exception.
For example, a determined attacker with sufficient resources could, at least in theory, launch a 51%
attack on a proof-of-work network or a long-range attack on a proof-of-stake network, among other
attacks.
The Byzantine node attack occurs when a malicious node (i.e., a Byzantine node) may attempt to
disrupt the consensus process by broadcasting an alternate block or withholding valid blocks. This
can lead to forks in the blockchain, where different nodes have different views of the blockchain state.
The name of this attack comes from the Byzantine generals problem formulated by Leslie Lamport,
Robert Shostak, and Marshall Pease (1982). The situation discussed in their work refers to a group
of Byzantine generals camped outside a city, each commanding a part of the army, who must coordi-
nate their attack or retreat on the city, but they can only communicate with each other by exchanging
messages to each other through unreliable messengers. Some of the generals are traitors and may
send contradictory or false messages to confuse the loyal generals. Nevertheless, loyal generals must
reach a consensus on whether to attack or retreat, even in the presence of traitors. The problem has
important implications for distributed systems and computer networks, where messages can be lost
or corrupted, and nodes can fail or behave maliciously.
The 51% attack pointed out above occurs when a single entity or group of entities controls 51%
or more of the computational power of A proof-of-work network, allowing them to manipulate the
blockchain by creating fraudulent transactions, double-spending or excluding other miners from the
network.
A long-range attack is a type of attack that relies on creating a new blockchain from the genesis
block, using an alternate history different from that of the original network (Deirmentzoglou, Papakyri-
akopoulos, & Patsakis, 2019). This type of attack may occur because the security of many blockchain
networks, especially proof-of-stake networks, is based on the assumption that a large proportion of
validators have a long and continuous history of participation in the network. If an attacker can stake
a significant amount of cryptocurrency or control a large number of nodes in the network, it can poten-
tially create a new blockchain longer than the original one, and thus become the dominant blockchain.
The Sybil attack occurs when a single user creates multiple identities or nodes, which would allow
it to control a significant portion of the nodes or the computational power and manipulate transac-

17
tions. This type of attack is possible because many blockchain networks, especially permissionless
networks that rely on proof-of-work or proof-of-stake, do not require any identity verification or previ-
ous client knowledge to join the network. An attacker can create multiple fake identities or nodes and
use them to gain disproportionate influence over the network, for example by controlling the consen-
sus process or censoring transactions. The name of this attack is inspired by a 1973 book titled Sybil,
a woman who is diagnosed with dissociative identity disorder (Schreiber, 1973).
The eclipse attack consists of controlling the network communication of a target node so that it
only receives data from a malicious node, effectively isolating it from the rest of the network (Yves-
Christian et al., 2018). Eclipse attacks are possible in blockchain networks because they rely on a peer-
to-peer (P2P) communication protocol to propagate information and transactions between nodes. The
P2P protocol allows any node to connect to any other node in the network, and there are no built-in
mechanisms to verify the identity or reputation of connected nodes. In addition, many blockchain net-
works, especially those using proof-of-work consensus, rely on a large number of peer-to-peer connec-
tions to validate transactions and achieve consensus. This makes them vulnerable to eclipse attacks,
as an attacker can control a small portion of the nodes in the network and manipulate the flow of
information, making it difficult for target nodes to receive correct information and participate in the
consensus process.
Attackers can also exploit vulnerabilities or programming errors in smart contracts. As discussed
in Sect. 5 below, smart contracts are programs stored on the blockchain that can be executed auto-
matically when certain conditions are met. If a smart contract contains vulnerabilities, attackers can
exploit them to execute malicious code.
The timestamp hijacking attack or timejacking involves manipulating the timestamp of a block,
which would allow an attacker to manipulate the order of transactions or create fraudulent transac-
tions (Ma, Ge, & Zhou, 2020).
Denial-of-service (DoS) attacks aim to overload the network with a large number of invalid trans-
actions, making it difficult or impossible to process legitimate transactions (Carl et al., 2006). Another
generic attack against distributed systems is the routing attack, which occurs when an attacker ma-
nipulates network routing tables to redirect traffic to a malicious node, which in case of a blockchain
would facilitate transaction manipulation or cryptocurrency theft (Aggarwal & Kumar, 2021).
To mitigate these attacks, blockchain networks use various security measures, such as consensus
algorithms, cryptography and network monitoring. In addition, regular software updates, code audits
and penetration testing can help identify and address network vulnerabilities. Ultimately, it is critical
to continuously monitor and improve the security of a blockchain network, through measures such as
periodic audits, the establishment of rewards for errors and vulnerabilities found, and through frequent
updates to the software and protocols used.

5 Smart Contracts and dApps

Smart contracts are defined as self-executing digital contracts in which the terms of the agreement
between the parties are expressed directly in lines of software code. In other words, a smart contract
is an automatically triggerable piece of software that enforces the rules and terms of an agreement
between two or more parties. In the blockchain realm, it takes the form of a computer program stored
on a node in a blockchain network, which can be programmed to automatically trigger actions, trans-
actions or other events based on preset conditions.
Smart contracts can be used for a wide range of applications, such as financial transactions, sup-
ply chain management, digital asset creation and transfer, or voting systems. They are designed to

18
be transparent and secure, and can help reduce transaction costs, improve efficiency, and increase
transparency and trust among the different actors involved in a blockchain.
A dApp (decentralized Application) is an application that runs on a blockchain network and is de-
signed to operate in a decentralized and autonomous manner, without the need for intermediaries or
central servers, which reduces the risk of fraud or manipulation. In a dApp, the application’s server
logic is implemented as a smart contract or a set of smart contracts deployed on a blockchain net-
work. Users interact with the dApp through a user interface, typically a web application or mobile app
(cf. Fig. 2).

Figure 2: Typical structure of a dApp. Static content and application code (e.g., mobile app or browser’s JavaScript code) is
taken from a content server, while logic is implemented by orchestrating a series of smart contracts on a blockchain.

dApps represent a new paradigm for building and deploying decentralized applications, which ex-
ploits the advantages of blockchain networks for greater security, transparency and reliability, com-
pared to traditional centralized applications or even distributed. dApps are typically open source,
meaning that the code is publicly available for anyone to view, use and modify. In addition, dApps
are not controlled by any central authority, which makes them resistant to censorship and manipula-
tion. According to their nature, the requirements of dApps are materialized through smart contracts,
which are visible and transparent. dApps are protected by the underlying blockchain technology, which
uses cryptography to protect data integrity and prevent unauthorized access.
As an example of a dApp, a social networking platform can be designed that is completely decen-
tralized and uses a blockchain as a support for managing user data. This social network would take
advantage of blockchain technology to provide a secure, transparent and decentralized platform for
users to interact and share content. The platform would allow users to create profiles, post content
and interact with other users, just like any other social network. However, instead of being controlled
by a central authority, the platform would operate by storing information on a blockchain, which in turn
would ensure security, transparency and immutability. When a user creates a profile on this decentral-
ized social networking platform, their information is stored on the blockchain, which ensures that user
data is secure and cannot be manipulated by anyone. When a user creates a post or interacts with
another user, this information is also stored on the blockchain, providing a transparent and immutable
record of all activity on the platform. Since the platform is decentralized, there is no central author-
ity that controls it or can censor content. Instead, the platform would operate through a consensus

19
mechanism, where users collectively decide what content is valid and what is not. As a consequence,
the platform is truly open and accessible to all users, regardless of their geographic location or political
views.
Applications in the field of decentralized finance (DeFi) are also good examples of dApps. This
is a fast-growing sector that leverages blockchain technology to offer financial services without the
need for traditional intermediaries such as banks. A dApp-based lending platform built on a blockchain
network would operate in a decentralized manner without the control of financial institutions. The plat-
form would allow users to lend and borrow digital assets such as cryptocurrencies, stablecoins, non-
fungible tokens (cf. Sect. 5.4), . . . . When users wish to lend digital assets on the platform, they would
deposit their assets in a smart contract on the blockchain network. The smart contract automatically
matches lenders with borrowers based on the desired interest rates and lending terms. Once a loan
is granted, the borrower receives the digital assets and the lender receives interest on their deposit.
Since the lending platform is based on a blockchain network, it is transparent and secure. All trans-
actions and lending activities are recorded on the blockchain, providing a transparent and immutable
ledger collecting all lending activities. This ensures that the lending platform is reliable and operates
in a secure and transparent manner. In addition, the lending platform would operate without the need
for intermediaries, which can reduce transaction costs and provide greater accessibility to financial
services. This can be especially beneficial for individuals and businesses in developing countries or
for those not having access to traditional banking services.
The following section outlines how to approach the development of smart contracts and dApps.
Then, the most relevant security aspects of smart contract development are identified. Later on, a
very popular use case in the world of smart contracts and dApps is introduced: non-fungible tokens
or NFT.

5.1 Smart Contract and dApp Programming

Smart contracts are built using specific programming languages such as Solidity, Vyper or Scilla, or
general purpose languages such as Rust, Go or JavaScript. Each blockchain that supports smart con-
tracts promotes its own preferred languages and even its own deployment models. Solidity (Chittoda,
2019a) is by far the most widely used programming language for developing smart contracts on the
Ethereum blockchain. It is similar to JavaScript and is designed to be easy to learn and use. Vyper
(Mahmoodi, 2020) is a newer language, also from Ethereum, designed to be more secure and easier to
audit than Solidity. Rust (Klabnik & Nichols, 2019) is an established systems programming language
that is gaining popularity for developing smart contracts on the Polkadot blockchain. A modified ver-
sion of the Go language is Hyperledger Fabric’s language for developing its smart contracts, called
chaincodes (Abdelhady, 2019). Scilla is the language of the Zilliqa blockchain for its smart contracts
(Zilliqa Team, 2019). It is a language designed to be more secure and easier to audit than Solidity, and
includes features such as static analysis and formal verification.
Smart contracts, once programmed and compiled, are stored in a blockchain network using a
specific transaction, making them immutable and tamper-proof. Smart contract code allows for au-
tomated and unattended transactions between parties, eliminating the need for intermediaries, such
as financial institutions or regulators.
In general, creating a smart contract involves identifying the problem, choosing a blockchain plat-
form, writing the contract’s code, testing and deploying the contract, and interacting with it on the
blockchain network.
The first task involves identifying and characterizing the problem or use case that the smart con-
tract is intended to address, that is, determining the rules and conditions that will govern the execution
of the contract. For example, in the context of supply chain management, our challenge might be to

20
automate the tracking and verification of goods as they move through the supply chain. A smart con-
tract could be programmed to automatically release payment to a supplier once a shipment is received
and verified by the buyer. Once the contract knows that the delivery of the goods is verified, the con-
tract can perform the necessary transactions to transfer cryptocurrencies from the buyer’s wallet to
the seller.
Once problem characterization and requirements capture is completed, a blockchain platform that
supports smart contracts would be selected, trying to identify the most suitable for the specificities of
a given use case. Selecting the right blockchain to deploy our smart contracts can be a complex deci-
sion, as different blockchains have different characteristics and capabilities that may be more suitable
for certain applications. Besides, the blockchain chosen must have a certain reputation for reliability
and security to ensure the integrity of smart contracts and prevent unauthorized access or modifi-
cation. It should also have a clear governance structure and comply with all applicable regulations
and industry standards. Moreover, it must be able to handle the amount of transactions and smart
contract executions sufficient for our application. Interoperability is another important criterion, as the
blockchain must be able to integrate with the systems and platforms required by the target use case
(e.g., the existing logistics system in a supply chain or certain oracles (cf. Sect. 7). Finally, the cost
of deploying and executing smart contracts on the blockchain must be reasonable and competitive
compared to other options.
There are several ways to interact with a blockchain. Most commonly, developers will not operate
their own blockchain network nodes, so they will have to use a platform that offers a programmer’s
interface (API) that allows to communicate with the selected chain. These platforms typically provide
development tools for monitoring and analyzing smart contracts.
The next step is to set up a development environment. This usually involves installing the neces-
sary software and setting up a wallet for testing and deployment. As just indicated, there are platforms
that provide robust development tools and an active community to support the development and de-
ployment of smart contracts. For example, Remix (Towaha, 2019) is a web-based IDE (Integrated De-
velopment Environment) for writing, testing and deploying smart contracts on the Ethereum network.
It provides an easy-to-use interface for compiling and deploying smart contracts, and also includes an
integrated testing framework. Truffle Suite (Chittoda, 2019b) is another development framework for
Ethereum that includes tools for compiling, testing and deploying smart contracts. It includes Truf-
fle CLI, which allows developers to manage their smart contracts from the command line. Ganache
(Singh, 2020) is a personal blockchain for Ethereum development that allows developers to test their
smart contracts in a local environment. Hardhat (Infante, 2021) is a development environment for
building and deploying smart contracts on Ethereum, Binance Smart Chain and other blockchain plat-
forms. It includes a command-line interface for managing contracts, as well as an integrated testing
framework and support for deployment.
Once the development environment is chosen, the actual code for our smart contract would be writ-
ten using one of the programming languages supported by the blockchain. This will involve defining
the functions, interfaces, data structures and logic governing the behavior of the contract, according
to the requirements identified in the analysis phase. To test and validate the developed contract, it is
most common to use a test blockchain or testnet to ensure that it works as intended. This usually
involves using a tool such as Remix or Truffle to deploy and interact with the contract. Testing on a
testnet ensures that the smart contract is secure and free of vulnerabilities before deploying it to the
main network or mainnet. This helps minimize the risk of financial loss or exposing sensitive data due
to security issues.
Testing on a testnet also allows developers to verify that the smart contract works properly and
meets the requirements of the intended use case, and to receive feedback from the community and
identify potential problems or areas for improvement before deploying the contract on the mainnet.

21
This helps ensure that the contract will work as expected. Moreover, testing on a testnet can save
costs by avoiding the fees associated with deploying and running smart contracts on a mainnet.
As a matter of example, the Solidity code below illustrates how to program a simple smart contract
on the Sepolia testnet using Hardhat. This is a smart contract that simply returns a stored message
when queried, and provides a method to update that message.

1 // SPDX-License-Identifier: MIT
2 //
3 // Simple smart contract that disseminates a message and allows for its
4 // update.
5 //
6 // Specifies the version of Solidity, using semantic versioning.
7 // More information:
8 // https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
9 pragma solidity ^0.8.18;
10
11 // Define a contract called ‘BroadcastMessage‘.
12 // A contract is a collection of functions and data (its state).
13 // Once deployed, the contract will reside at a specific address
14 // of a blockchain. In our case, on an Ethereum testnet
15 // called Solidity.
16 // Learn more:
17 // https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
18 contract BroadcastMessage {
19
20 // Declares a ‘message‘ state variable of type string.
21 // State variables are attributes whose values are stored
22 // permanently in the contract storage.
23 // The ‘public‘ keyword makes variables accessible
24 // from outside a contract and creates a function that other contracts or
25 // clients can call to access the value.
26 string public message;
27
28 // Similar to many class-based object-oriented languages,
29 // a constructor is a special function that is only executed when
30 // the contract is created.
31 // Constructors are used to initialize contract data,
32 // in our case the initial value of the message.
33 // More information:
34 // https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
35 constructor(string memory initMessage) {
36
37 // Accepts an ‘initMessage‘ argument that is used for the
38 // initial value of the ‘message‘ attribute of the contract.
39 message = initMessage;
40 }
41
42 // Finally, the smart contract provides a public function that
43 // takes a string as parameter
44 // and updates the ‘message‘ attribute.
45 function update(string memory newMessage) public {
46 message = newMessage;
47 }
48 }

To deploy the smart contract on the Sepolia testnet, Hardhat would be configured with the net-
work details necessary for such deployment. That information is collected in a JavaScript file called
hardhat.config.js.

1 //

22
2 // Hardhat configuration file for our simple smart contract project.
3 //
4 // To deploy a smart contract written in Solidity, we need
5 // this file and the source file (.sol) of the smart contract.
6 //
7 // Node.js modules used:
8 // - dotenv to dispose of the .env file to provide
9 // configuration variables (VARIABLE = "value" lines).
10 // - hardhat-toolbox is a plugin that bundles
11 // commonly used Hardhat plugins and packages.
12 // Highly recommended to start developing with Hardhat.
13 // Among other things, it supports to deploy and interact with
14 // smart contracts using the ethers.js library and
15 // the hardhat-ethers plugin.
16 require(’dotenv’).config();
17 require("@nomicfoundation/hardhat-toolbox");
18
19 // URL of the Alchemy API used to access the Sepolia network
20 // and private key of the cryptocurrency wallet used to
21 // cover the costs of the deployment. This information is in the
22 // .env configuration file, i.e., the .env file contains two
23 // lines:
24 //
25 // API_URL = "https://XXXXXXX"
26 // PRIVATE_KEY = "XXXXXXXXXX"
27 const { API_URL, PRIVATE_KEY } = process.env;
28
29 /**
30 * @type import(’hardhat/config’).HardhatUserConfig
31 */
32
33 module.exports = {
34 solidity: "0.8.18", // Solidity version
35 defaultNetwork: "sepolia", // network used (Sepolia testnet)
36 networks: {
37 hardhat: {},
38 sepolia: { // Sepolia access data:
39 url: API_URL, // API’s URL & wallet’s private key
40 accounts: [‘0x${PRIVATE_KEY}‘]
41 }
42 }
43 };

Previously, as developers will not have their own nodes in the Sepolia network, an access point
to this network has to be obtained through a blockchain development platform, in this example the
Alchemy platform. This procedure requires registration with Alchemy, but it is free of charge. The
access point is a URL that can be used from the contract’s deployment code to interact with Sepolia.
The JavaScript code snippet below can be used to deploy the contract:

1 //
2 // Deployment script for the example smart contract
3 //
4 // Deployment command:
5 //
6 // npx hardhat run scripts/deploy.js --network sepolia
7 //
8
9 const { ethers } = require("hardhat");
10
11 async function main() {
12 // A ContractFactory is an abstraction used for deploying

23
13 // new smart contracts, so broadcastMessage
14 // is a factory for instances of our BroadcastMessage contract.
15 // When using ContractFactory and Contract
16 // from Hardhat’s plugin toolbox, the instances are connected
17 // by default to the first signer (i.e., the owner).
18 // ethers.js (which provides the ethers object) is a library that
19 // is loaded with the Hardhat toolbox.
20 const broadcastMessage = await ethers.getContractFactory("BroadcastMessage");
21
22 // Deployment initiated. deploy returns a promise that
23 // resolves to a Contract object (bcm). This object will have
24 // a method for each of the visible functions and attributes
25 // of our smart contract (in our case, a method to fetch
26 // the message attribute and the update() method).
27 // deploy receives the arguments of the constructor used
28 // (in our case, the initial message).
29 const bcm = await broadcastMessage.deploy("Initial message");
30 console.log("Contract deployed at address:", bcm.target);
31 }
32 // main() invokation to deploy. If all goes well, just exit. If not,
33 // display the error message via console.
34 main()
35 .then(() => process.exit(0))
36 .catch(error => {
37 console.error(error);
38 process.exit(1);
39 });

To conclude this example, a simple JavaScript program to interact with our contract is presented
below.

1 // Interaction with the previously deployed smart contract


2 //
3 // Requests the user to enter a message and updates it
4 // in the BroadcastMessage smart contract. Finally,
5 // fetches the (new) message from the smart contract
6 // and displays it.
7 //
8 // The environment variables are obtained from the .env file.
9 //
10
11 // Address of our smart contract. It is obtained by deploying it.
12 const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;
13
14 // load the ABI of our contact (Application Binary Interface)
15 // to interact with it. The ABI is also created when the contract is deployed.
16 const contract =
17 require("../artifacts/contracts/BroadcastMessage.sol/BroadcastMessage.json");
18
19 // Signer
20 // An account that has the ability to sign transactions
21 // In our case, a wallet created with MetaMask
22 // with funds from the Sepolia testnet sufficient to
23 // cover the costs of the interaction.
24 const ownerAddress = process.env.PUBLIC_KEY;
25 const signer = ethers.provider.getSigner(ownerAddress);
26
27 // Contract
28 // an ethers.js object representing the specific contract
29 // deployed on the Sepolia blockchain (i.e., BroadcastMessage).
30 // To create the object, we need the contract address, ABI and signer’s wallet.
31 const bcContract = new ethers.Contract(CONTRACT_ADDRESS, contract.abi, signer);

24
32
33 // Read the message stored in our smart contract
34 // and display it on the console. Also update it. In JavaScript,
35 // asynchronous functions are used to interact with blockchains.
36 console.log("");
37
38 async function main() {
39
40 // First, get the value of attribute ’message’.
41
42 const message = await bcContract.message();
43 console.log("Present message is: " + message);
44
45 // Now update the message using the method provided
46 // by the smart contract (i.e., update).
47 // We use the Node.js prompt-sync module to request text via console.
48 var prompt = require(’prompt-sync’)();
49
50 // Request a new message and
51 // update it in the smart contract
52 var newMessage = prompt(’New message: ’);
53 console.log(’Message updated to ’ + newMessage + ’...’);
54 const tx = await bcContract.update(newMessage);
55
56 // wait() on the returned transaction object ensures
57 // that our program waits for the transaction to be
58 // forged on the blockchain before continuing.
59 // If we were to omit this line, the new
60 // value may not yet be available upon requesting it (it may take
61 // a few seconds).
62
63 await tx.wait();
64
65 // Get the new value of the ’message’ attribute
66
67 const updatedMessage = await bcContract.message();
68 console.log("New message is: " + updatedMessage);
69 }
70
71 // Let’s roll!
72
73 main();

Once the smart contract works as expected on the testnet, ii would be deployed on a mainnet
like Ethereum’s or Hyperledger Fabric’s, using a tool such as Remix or Truffle. This usually involves
paying a cryptocurrency transaction fee. Once the smart contract is deployed, it can be interacted
with by sending transactions to it from a wallet or dApp. The contract will be executed according to
its programmed logic, and the outcomes will be recorded on the blockchain.
A dApp can be viewed as the orchestration of a set of smart contracts to obtain complex function-
ality. After choosing the blockchain platform and development environment, our first goal would be to
design the architecture of the dApp. This involves defining the data model, creating or identifying the
required smart contracts, and deciding on the interface design and user experience (UI/UX).
Once the dApp’s smart contracts are deployed, a user interface or front-end for the dApp has to be
developed. This involves creating a user-friendly UI/UX design that allows users to interact with the
dApp. There are several popular technologies that developers use to build front-ends for decentral-
ized applications. JavaScript is by far the most common choice for this. For example, React (Chin-
nathambi, 2018) is a popular JavaScript library for building user interfaces. It allows developers to
create reusable UI components and provides a simple and efficient way to manage application state.

25
Material UI (Schwarzmüller, 2018) is a set of React components that implement Google’s Material De-
sign guidelines. It provides broad portfolio of UI components, such as buttons, forms, dialog boxes,
etc., that can be easily customized and personalized.
Vue.js (Passaglia, 2017) is another popular JavaScript framework for building user interfaces. It
provides a simple and intuitive syntax and offers features such as bidirectional data binding and re-
active components. Angular (Schwarzmüller, 2021) is a comprehensive JavaScript framework widely
used for building complex web applications. It offers a wide range of features, such as templates, data
binding, dependency injection, etc. Web3.js (Adaś, 2021) is a JavaScript library that allows developers
to interact with Ethereum-based smart contracts and build decentralized applications. It provides a
simple and efficient way to interact with the Ethereum network and manage transactions and events.
Bootstrap (Spurlock, 2021) is a popular CSS framework that provides preconfigured UI components
and styles. It can be combined with the above technologies to create responsive, mobile-friendly UI
designs for digital applications.
Testing is a critical part of the dApp development process to verify that they work as intended.
This involves testing the smart contracts for bugs, testing the user interface to validate its usability,
and testing the overall performance of the dApp.
After testing the dApp, the final step is to deploy it on the chosen blockchain. This involves deploy-
ing the smart contracts on the blockchain network, deploying the front-end to the server or app stores,
and making the dApp available to users. As with smart contracts, there are platforms that help simplify
the dApp development process by allowing developers to focus on creating the core functionality of
their decentralized applications rather than worrying about the underlying blockchain infrastructure.
They also provide advanced analytics and monitoring tools to help developers optimize the perfor-
mance of their dApps. For example, OpenZeppelin is a reusable smart contract library for Ethereum
that provides a secure and proven foundation for building decentralized applications. It includes a CLI
for deploying contracts on Ethereum networks, as well as an online IDE for testing and deploying con-
tracts. Another example is Alchemy, perhaps the most popular blockchain development platform right
now. It is a platform that provides developers with the tools and infrastructure needed to create dApps
on various blockchain networks. It offers a set of developer tools, such as an API, debugging and an-
alytics tools to create, test and scale applications. It supports various networks, such as Ethereum,
Binance Smart Chain or Polygon, among others.

5.2 Smart Contracts and Cryptocurrency

As discussed at the beginning of these notes, the first killer application of blockchains was to support
a decentralized cryptocurrency system. In fact, many blockchains have only that function. In the case
of Ethereum, in addition to supporting smart contracts and DApps, it offers its own cryptocurrency,
named Ether (ETH). Apart of supporting money transfers and the purchase of goods or services using
an e-wallet, it is also possible to use smart contracts to make such transfers or purchases. Just like a
cryptocurrency account on the Ethereum network, smart contracts on that network are also identified
with an address. Just as we can make cryptocurrency transfers to or from a cryptocurrency account,
we can also transfer to or from a smart contract using its public address.
The example proposed below illustrates how to make these transfers. It implements a smart
contract that allows access to a service upon payment of a fee in cryptocurrency. The contract,
ServicePaymentContract, is initialized with a service fee when it is deployed. The address that de-
ployed the contract becomes the owner of the contract, and will be the only address able to retrieve the
funds stored in the contract. Users can send Ether to the contract at any time, representing payment
for a service. In this example, they can do so in two ways:

26
• By sending cryptocurrency directly. The receive function is a special function (i.e., a fallback
function) that handles incoming Ether transactions when sending Ether directly to the contract
without invoking any of its public or external functions. That is, if we transfer funds to the contract
directly from a wallet, putting as the address of the recipient the address of the contract, this
function will be executed. In our case, it checks whether the Ether sent is enough to cover the
cost of the service, and any overpayment is returned to the sender.
• By invoking a contract’s external or public function declared as payable. In our example, we
define function payForService as a payable function. This keyword in the function declaration
allows the function to receive Ether. Users invoking this function must send at least the cost of
the specified service upon contract’s invokation to pay for the service. In this example, we keep
whatever the address that invoked the function sent, without returning any excess.

Variable totalCollected keeps track of the total Ether collected from users. To retrieve the funds
stored in the contract, function redeemCollectedFunds allows the contract owner to redeem all the
funds collected by transferring those funds to their address. The contract uses events to record pay-
ments and fund redemptions.

1 //
2 // SPDX-License-Identifier: MIT
3 //
4 // Example contract to illustrate how a smart contract
5 // can implement a service for a fee (to be payed in
6 // Ether), and how the service provider (i.e., the contract’s
7 // owner), can redeem the fees collected.
8 //
9 // Please note that this is a simplified example. In a real-world
10 // scenario, more complex payment and redemption logic would be
11 // implemented, additional security and access control measures would.
12 // be considered. Additionally, it’s important to keep in mind the security
13 // considerations and best practices when handling Ether in smart contracts.
14 pragma solidity ^0.8.18;
15
16 contract ServicePaymentContract {
17
18 // Global variables to collect info about the contract’s owner
19 // service fees and amount collected so far.
20 address public owner;
21 uint256 public serviceCost;
22 uint256 public totalCollected;
23
24 // The contract uses events to log payments and fund redemptions.
25 // Event to indicate that some address payed the service fee.
26 event ServicePaid(address indexed payer, uint256 amount);
27
28 // Event to indicate that the owner collected the contract’s
29 // balance.
30 event EtherRedeemed(uint256 amount);
31
32 //
33 // When the contract is created, its owner is initialized.
34 // The creator/owner also establishes the service fee in Wei.
35 constructor(uint256 cost) {
36 owner = msg.sender;
37 serviceCost = cost;
38 }
39
40 // For actions available only to the contract’s owner.
41 modifier onlyOwner() {
42 require(msg.sender == owner, "Only the owner can call this function");
43 _;

27
44 }
45
46 // Users can send Ether to the contract, representing payment for
47 // a service. The receive function is a special fallback function that handles
48 // incoming Ether transactions not corresponding to the
49 // invocation of a contract’s payable function (i.e., by
50 // sending Ether to the contract using "transfer", "send" or "call").
51 // msg.data has to be empty, otherwise fallback() would be invoked
52 // instead.
53 // Note that both receive() and fallback() are defined without the
54 // function keyword.
55 // In our case, it checks whether the sent Ether is sufficient
56 // to cover the service cost.
57 // Any excess payment is refunded to the sender.
58 receive() external payable {
59 require(msg.value >= serviceCost,
60 "Insufficient payment for the service");
61 uint256 excessPayment = msg.value - serviceCost;
62 totalCollected += serviceCost;
63
64 // Emit an event to log the payment.
65 emit ServicePaid(msg.sender, serviceCost);
66
67 // Return any excess payment to the sender.
68 // function msg.sender.call sends excessPayment Wei to
69 // to the address accessing the service and checks whether
70 // the transaction was successful.
71 if (excessPayment > 0) {
72 (bool success, ) = msg.sender.call{value: excessPayment}("");
73 require(success, "Failed to refund excess payment");
74 }
75 }
76
77 // This function encapsulates the service as a payable function,
78 // making it more intuitive for users to pay for the service by simply
79 // sending Ether to the contract’s address.
80 // The owner can still redeem the collected funds.
81 //
82 // The payable keyword in the function declaration allows
83 // the function to receive Ether. Users must send at least the specified
84 // serviceCost as Ether to pay for the service.
85 // The totalCollected variable keeps track of the total
86 // Ether collected from users.
87 function offerServiceForAFee() public payable {
88 require(msg.value >= serviceCost,
89 "Insufficient payment for the service");
90 totalCollected += msg.value;
91
92 // Emit an event to log the payment.
93 emit ServicePaid(msg.sender, msg.value);
94
95 // Do your service thing here!
96 }
97
98 // Function that allows the contract owner to redeem the funds
99 // collected. The contract owner can call this function to withdraw
100 // the contract’s Ether balance.
101 function redeemCollectedFunds() public onlyOwner {
102 require(totalCollected > 0, "No funds to redeem");
103 uint256 amountToRedeem = totalCollected;
104 totalCollected = 0;
105
106 // Transfer the collected Wei to the owner.

28
107 (bool success, ) = owner.call{value: amountToRedeem}("");
108 require(success, "Failed to redeem funds");
109
110 // Emit an event to log the redemption.
111 emit EtherRedeemed(amountToRedeem);
112 }
113 }

In general, Ethereum smart contracts have two fallback functions. Function receive discussed
above and another one directly named fallback. Which of them is executed depends on how the
user interacts with the smart contract (see Fig. 3):
• Function receive() is executed when the contract receives Ether without any additional data
or call to one of its public or external functions. This function can be used to handle simple Ether
transfers associated with simple actions, such as just storing the incoming Ether or updating
the contract status.
• Function fallback() is run when someone sends Ether to the contract address along with
some data that does not match the invocation of any contract function. It serves as a fallback
or alternate function for transactions with invalid or unrecognized data, or even to implement
custom behavior when an unknown function is called.

.
Figure 3: invocation of fallback() or receive().

In practice, developers typically use receive to handle Ether sent directly to the contract address,
which is a common use case for receiving payments or donations. Function fallback is utilized less
frequently and is usually used for more advanced or specific purposes. Still, since fallback accepts
Ether, it essentially extends the behavior of receive, handling both Ether transfers and unrecognized
data transactions.
The Ethereum Virtual Machine (EVM) provides three objects to interact with the blockchain, called
block, msg, and tx, which respectively provide information about the blockchain, the information sent
to the smart contract in the active transaction, and the active transaction itself. The most relevant
attributes of these objects are listed in Table 2. The following functions are also available:
• blockhash(uint blockNumber) returns (bytes32): returns the hash of the block passed
as parameter, if the block is one of the 256 most recent blocks. Otherwise it returns 0.
• gasleft() returns (uint256): returns the amount of gas remaining in the contract.

29
.
Table 2: Properties of objects block, msg and tx.

block.basefee (uint) Base fee of the current block.


block.chainid (uint) Identifier of the current chain.
block.coinbase (address payable) Address of current blocks’ validator.
block.difficulty (uint) Difficulty of the current block (ob-
solete, deprecated). It behaves like
block.prevrandao.
block.gaslimit (uint) Current block’s gas limit.
block.number (uint) Number of the current block.
block.prevrandao (uint) Random number provided by the Beacon
Chain (cf. Appendix D).
block.timestamp (uint) Timestamp of the current block in sec-
onds since unix epoch (i.e., 00:00:00 UTC
on Jan. 1st, 1970).
msg.data (bytes calldata) Full calldata of the current message.
msg.sender (address) Calling address of the current message.
msg.sig (bytes4) First four bytes of the message (i.e. iden-
tification of the called function).
msg.value (uint) Amount of crypto sent with message, in
Wei.
tx.gasprice (uint) Price of the transaction, in gas.
tx.origin (address) Origin of the current transaction.

5.3 Security Issues

Smart contracts are a popular target for attackers because they can have high-value items associated
with them and are often complex, making them vulnerable to various types of threats. Smart contract
code can be complex and difficult to analyze, and attackers may find programming flaws that allow
them to manipulate the state of the contract or bypass security measures. In this section, the most
relevant attacks on smart contracts are identified.
The re-entry attack is one of the most common and dangerous attacks against smart contracts.
In this type of attack, the attacker exploits a flaw in the contract code that allows to repeatedly call the
same function before the previous call is completed. This may trigger, for example, the repetition of
an asset transfer several times in a row before the first (and supposedly only) of them is consolidated
in the ledger.
Another typical attack is a common attack in software engineering, namely integer overflow and
underflow. This attack occur when the contract code does not correctly validate input values, resulting
in errors that can be exploited by attackers to manipulate the contract state and achieve illicit trans-
actions.
A blockchain-specific attack is the so-called front running attack. It occurs when attackers use their
knowledge of pending transactions to place their own transaction ahead of others in the transaction
pool, allowing them to manipulate the state of the smart contract and potentially get it to behave in an
unintended way.
Like any distributed system, smart contracts are also exposed to denial-of-service (DoS) attacks, in
which an attacker floods the contract with transactions or input data in order to overload it and cause
it to stop working properly.

30
Smart contracts often rely on third-party libraries to implement the desired functionality, as dis-
cussed in the smart contract examples provided. Attackers could create and distribute malicious
libraries designed to exploit vulnerabilities in the contract code.
To mitigate these and other potential attacks, it is critical that developers carefully review and
test their smart contract code and apply security and risk management best practices, such as code
audits, testing for vulnerabilities, and using secure coding practices like input validation and access
control. It is also desirable to use secure integer arithmetic to avoid integer overflow and underflow
vulnerabilities. Obsolete functions and versions, in libraries or external contracts, are more vulnerable
to attacks. Then, developers should avoid using them and always use the latest version.
To avoid attacks based on malicious libraries, developers should use well audited open source li-
braries whenever possible. Smart contracts can be complex, and it is often safer to use well-tested,
audited and widely used libraries for basic functions such as cryptography and data serialization. Sim-
ilarly, smart contracts that rely on external contracts are more vulnerable to attack. A good practice
would be to minimize their use and rely only on trusted, audited external contracts. It is also good
practice to include access controls in the code to prevent unauthorized users from accessing sensi-
tive functions or data, such as role-based access control and the use of appropriate authentication
mechanisms.
Smart contract developers should test their code thoroughly before deploying it on a live mainnet,
including unit testing and integration testing, as well as testing under various load conditions using a
trusted testnet. Robust error management and logging mechanisms should also be implemented to
help identify and fix problems.
Simplicity is key when it comes to smart contract development. Complex code may introduce
unnecessary risks and potential vulnerabilities. In addition, thoroughly documenting code is essential
to ensure that it can be properly understood and maintained over time.

5.4 Non-fungible Tokens: NFT

A non-fungible token (NFT) is a digital asset that represents a unique item or content, such as a work
of art, a collectible item or virtual real estate in the metaverse. Unlike fungible tokens, such as cryp-
tocurrencies, which are interchangeable and always have the same intrinsic value (e.g., all bitcoins are
worth the same), each NFT is unique and has a distinct value. NFT are a characteristic phenomenon
of blockchain technology that enables the creation and ownership of unique digital assets that were
previously difficult to verify and monetize.
NFT based on blockchain technology facilitate secure and transparent ownership of digital assets.
Each NFT is stored on a blockchain network, which provides a public record of ownership and transac-
tions thereof, enabling the authenticity and ownership of the NFT to be verified. NFT gained popularity
in the art and pop culture worlds as an opportunity to monetize digital works as unique items, so that
collectors can own and exchange these digital assets. They are also used in games, in trading cards,
or in the virtual real estate market, facilitating owning and exchanging unique objects and properties
in the metaverse.
To create an NFT, the first step would be to select a blockchain platform that supports the creation
and ownership of digital assets. The most popular platforms for creating NFT are currently Ethereum,
Binance Smart Chain and Flow. Next, the digital asset to be turned into into an NFT has to be identified
or created. It can be a piece of artwork, a music or video clip, a virtual trading card or any other digital
content. Once the digital asset is selected, an NFT will be minted for it. This involves creating a unique
token that represents the digital asset on the chosen blockchain. In addition to the unique identification
of the asset itself, the NFT will have information about the asset, such as its name, description, creator,
location, etc. This information would configure the NFT’s metadata. The price and conditions for its

31
transferability have also to be defined. The price can be a set amount or fixed through an auction.
Royalties as a percentage of future sales of the NFT may also be defined.
Once the NFT is created and minted, it would be offered for sale on a marketplace that supports
NFT. Some popular marketplaces for NFT are OpenSea, Nifty Gateway and SuperRare. Once a buyer
acquires an NFT, ownership of the NFT will be transferred to them. This is done through a transaction
that updates the ownership records on the blockchain where the NFT is deposited. When a buyer
acquires an NFT, a smart contract can be programmed to automatically transfer ownership to the
buyer and update the ownership records on the blockchain.
Indeed, smart contracts are the instrument typically used to automate the purchase, sale and trans-
fer of ownership of NFT and digital assets in general. They can be used to automate sales, as a smart
contract can be programmed to automatically sell an NFT to the highest bidder in an auction, or to sell
an NFT at a fixed price. Smart contracts can also be used to automatically distribute royalties to the
creators of an NFT. The contract can be programmed to automatically transfer a percentage of the
sale price to the creator when the NFT is resold on a secondary market. Finally, smart contracts can
be used to define conditions and rules for NFT. For example, a smart contract can be programmed to
restrict the resale of an NFT for a certain period of time, or to require that certain conditions be met
before an NFT can be transferred.
A simple example of minting an NFT and uploading it to the Sepolia testnet is discussed below.
The digital asset in this case is the one depicted in Fig. 4. The metadata associated with it would be
as collected in this JSON record:

1 {
2 "attributes": [
3 {
4 "trait_type": "Location",
5 "value": "New York"
6 },
7 {
8 "trait_type": "Style",
9 "value": "Andy Warhol"
10 }
11 ],
12 "description": "My first NFT: A really cooooool hydrant.",
13 "image": "ipfs://QmfBhAcyKQSZJep6qYYcuDQP8hrFLo8yJYQN39UPuDVraQ",
14 "name": "CoolHydrant"
15 }

The reference to the asset in the metadata is a content ID (CID) in IPFS, stored in the image field
(cf. Sect. 8). In turn, The CID of this JSON record is what will be stored in the blockchain when minting
the NFT.
The smart contract code to mint our NFT, written in Solidity, is as follows:

1 // SPDX-License-Identifier: MIT
2 //
3 // Creating an NFT on the Sepolia testnet, according to Ethereum’s
4 // "How to write and deploy an NFT" tutorial.
5 //
6 // Based on [https://docs.openzeppelin.com/contracts/3.x/erc721]
7 // (https://docs.openzeppelin.com/contracts/3.x/erc721)
8 //
9 // Solidity version, using semantic versioning.
10 pragma solidity ^0.8.20;
11
12 // ERC721.sol contains the implementation of the ERC-721 standard, which
13 // our NFT contract will inherit. To be a valid NFT, the smart contract

32
Figure 4: Digital asset to create an NFT.

14 // must implement all methods of the ERC-721 standard.


15 import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
16
17 // Ownable.sol sets access control to our smart contract,
18 // so that only the owner of the smart contract can mint
19 // NFTs. Access control is optional. If anyone can mint an NFT
20 // using a given smart contract, omit the word Ownable
21 // on line 46 and onlyOwner on line 73).
22 import "@openzeppelin/contracts/access/Ownable.sol";
23
24 // The ERC721URIStorage contract is an implementation of ERC721 that includes
25 // the standard metadata (IERC721Metadata), as well as a mechanism for defining
26 // metadata for each NFT. This is where the _setTokenURI method comes from:
27 // to store NFT metadata offchain, more specifically in IPFS.
28 import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
29
30 // Thus, the contract will use external storage for the NFT metadata
31 // and for the NFT itself. Note that it can only be invoked by its owner
32 // and we use a counter to keep track of the NFTs generated and to ensure
33 // that the generated NFTs all have unique IDs.
34 // Omit the reference to the Ownable interface if you want anyone to be able to
35 // mint NFTs with this contract.
36 contract MyNFT is ERC721URIStorage, Ownable {
37 using Counters for Counters.Counter;
38
39 // Our smart contract uses one counter (_tokenIds)
40 // to keep track of the total number of NFTs minted and
41 // establish the unique ID of our new NFT.
42 // Each NFT minted with a smart contract must be assigned a
43 // unique ID. In this case, the unique ID is determined by the total number
44 // of NFTs created with the contract. For example, the first NFT minted with
45 // our smart contract has an ID of "1", the second "2", etc.).
46
47 uint256 private _tokenIds;
48
49 // The first argument of the ER721 constructor is the name of the smart
50 // contract, and the second is its symbol. The constructor of our
51 // contract does not require arguments. It simply calls the constructor of

33
52 // ERC721 with two default values.
53 constructor() ERC721("MyNFT", "NFT") {_tokenIds = 0;}
54
55 // This is the actual (and only) feature offered by our smart contract:
56 // the ability to mint NFTs. For the rest of the
57 // methods defined in the ERC721 standard we use the
58 // default implementations provided by ERC721.sol.
59 // It can only be invoked by the smart contract owner.
60 // Omit onlyOwner if you want anyone to be able to use it.
61 //
62 // The function receives as parameters:
63 // (1) The wallet of the receiver of the NFT (the creator of the contract
64 // in our case).
65 // (2) The URI of the token’s metadata. This string must resolve
66 // to a JSON document describing the NFT’s metadata.
67 // The metadata of an NFT is really what brings it to life,
68 // allowing it to have configurable properties, such as a name,
69 // description, image, and other attributes.
70 // Returns a number representing the ID of the newly minted NFT.
71 function mintNFT(address recipient, string memory tokenURI)
72 public onlyOwner
73 returns (uint256)
74 {
75 // Increments the NFT’s ID by one to guarantee unique IDs
76 // and gets the ID of this NFT.
77 _tokenIds++;
78 uint256 newItemId = _tokenIds;
79
80 // Mint the NFT. _mint() calls certain methods of the
81 // inherited ERC-721 library, and finally
82 // returns a number representing the ID of the newly minted NFT.
83 _mint(recipient, newItemId);
84
85 // Persistently store the tokenURI that references
86 // the metadata of this NFT.
87 _setTokenURI(newItemId, tokenURI);
88
89 return newItemId;
90 }
91 }

Since the Sepolia testnet is used, which is an Ethereum testnet, this NFT will comply with the ERC-
721 standard. This is a standard interface for NFT on the Ethereum blockchain defined in 2018 to
standardize how NFT are created, transferred and managed on that blockchain. ERC-721 tokens are
unique and each token has its own identifier and metadata that provides additional information about
the asset it represents. The ERC-721 standard is widely adopted by the Ethereum community, and
many popular NFT marketplaces, such as OpenSea and Rarible, support ERC-721 tokens.
Like all transactions, the transaction to mint an NFT carries an associated cost called gas. When re-
questing the transaction, the gas limit has to be indicated, i.e., the maximum price accepted expressed
in wei (1 ETH = 1018 wei), in our case 500,000 wei or 0.0000005 ETH.
The following Node.js code snippet would be used to mint the NFT and send it to the Sepolia
testnet.

1 // Script to mint an NFT using the smart contract


2 // previously deployed with the mintNFT function.
3 //
4 // Usage: node scripts/mint-nft.js
5 //
6 // Environment variables are obtained from the .env file.

34
7
8 require("dotenv").config()
9 // URL of the API of the Alchemy application
10 // created to deploy our contract. Alchemy
11 // provides an access to the Sepolia testnet, where
12 // our smart contract is deployed.
13 const API_URL = process.env.API_URL;
14
15 // Address of the wallet authorized to mint NFTs with the contract
16 // (we designed it so that only the authorized wallet may create them)
17 const PUBLIC_KEY = process.env.PUBLIC_KEY;
18
19 // Private key of the wallet. It is used to charge
20 // gas expenses incurred in the NFT minting.
21 const PRIVATE_KEY = process.env.PRIVATE_KEY;
22
23 // Alchemy Web3 is a wrapper around Web3.js,
24 // the most popular, practically the standard library for accessing
25 // Web3, which provides enhanced API methods and other
26 // interesting features. It is designed to require minimal configuration.
27 const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
28
29 // We create a Web3 object (web3) to access Sepolia via
30 // Alchemy.
31 const web3 = createAlchemyWeb3(API_URL);
32
33 // Let’s take the ABI (Application Binary Interface) from our contract
34 // to interact with it.
35 const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
36
37 // Address of the NFT contract
38 const contractAddress = process.env.CONTRACT_ADDRESS;
39
40 // Create a Contract object (nftContract) using ABI and address.
41 const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
42
43 // Define a function to invoke our contract’s minting function.
44 async function mintNFT(tokenURI) {
45 // Get a nonce.
46 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, ’latest’);
47
48 // Create the minting transaction to be sent to Sepolia
49 const tx = {
50 ’from’: PUBLIC_KEY, // Creator: our wallet.
51 ’to’: contractAddress, // the NFT minting contract
52 ’nonce’: nonce, // transaction nonce
53 ’gas’: 500000, // Offer 500.000 wei (0,0000005 ETH)
54 ’data’: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
55 }
56
57 // Now that we have created our transaction, we need to sign it
58 // so we can send it to web3. This is where we will use our private key.
59 // web3.eth.sendSignedTransaction returns the hash of the transaction,
60 // which we can use to make sure that our transaction was
61 // forged and was not discarded by the Sepolia network.
62 // The code below includes an error check to find out
63 // if our transaction was forged correctly.
64 const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
65 signPromise
66 .then((signedTx) => {
67 web3.eth.sendSignedTransaction(
68 signedTx.rawTransaction,
69 function (err, hash) {

35
70 if (!err) {
71 console.log(
72 "Transaction hash is: ",
73 hash,
74 "\nTransaction status at Alchemy’s mempool."
75 )
76 } else {
77 console.log(
78 "Something went wrong whem forging the transaction:",
79 err
80 )
81 }
82 }
83 )
84 })
85 .catch((err) => {
86 console.log(" signPromise failed:", err)
87 })
88 }
89
90 // Mint using the IPFS CID of the JSON with the NFT metadata.
91
92 mintNFT("ipfs://QmfJQ4xLorVNXLQ3S8cSGKtpBVYs44WD63C4Bi7yoWKtR2")

The code above uses the Alchemy Web3 library, a wrapper around Web3.js, a popular library for
accessing the Web3, which provides enhanced API methods and other interesting features. Another
common option is to use the ethers.js library. The following snippet uses this library through the Hard-
hat Toolbox.

1 // Script to mint an NFT using the smart contract


2 // previously deployed with the mintNFT function.
3 //
4 // Usage: node scripts/mint-nft.js
5 //
6 // Environment variables are obtained from the .env file.
7
8 require(’dotenv’).config()
9 // Address of the wallet authorized to mint NFTs with the contract
10 // (we designed it so that only the authorized wallet may create them)
11 const PUBLIC_KEY = process.env.PUBLIC_KEY;
12
13 // Private key of the wallet. It is used to charge
14 // gas expenses incurred in the NFT minting.
15 const PRIVATE_KEY = process.env.PRIVATE_KEY;
16
17 /// API key of the Alchemy application
18 // created to deploy our contract. Alchemy
19 // provides an access to the Sepolia testnet, where
20 // our smart contract is deployed.
21 const API_KEY = process.env.API_KEY;
22
23 // Creare a Hardhat Runtime Envirnoment (hre) object to access
24 // Sepolia through Alchemy.
25 const hre = require("hardhat");
26 const provider = new hre.ethers.AlchemyProvider("sepolia", API_KEY);
27
28 // ABI (Application Binary Interface) from our contract
29 // to interact with it.
30 const abiJSON = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
31
32 // Address of the NFT contract
33 const contractAddress = process.env.CONTRACT_ADDRESS;

36
34
35 // Create a Contract object (nftContract) using ABI,
36 // address and provider (Alchemy).
37 const nftContract = new hre.ethers.Contract(contractAddress, abiJSON.abi, provider);
38
39 // Wallet object (wallet) to sign and pay for the mining transaction.
40 const wallet = new hre.ethers.Wallet(PRIVATE_KEY, provider);
41
42 // URI of NFT’s JSON registry in IPFS
43 const tokenURI = process.env.NFT_URI;
44
45 // Define a function to invoke our contract’s minting function.
46 async function main() {
47
48 //
49 // This is a transaction that makes changes to the
50 // smart contract, so it has to be signed.
51 // Use the wallet for this purpose, which has information
52 // about the private key (for signing & paying gas).
53 const contractSigned = nftContract.connect(wallet);
54
55 // call the smart contract’s mining function.
56 // Pass as parameters the address of the creator of the contract
57 // (the only one that can mine) and the URI of the NFT.
58 const tx = await contractSigned.mintNFT(PUBLIC_KEY, tokenURI);
59
60 // Print the transacion hash
61 console.log(tx.hash);
62
63 await tx.wait();
64 console.log ("Minting: success");
65 }
66
67 main()
68 .then(result => {
69 console.log(’OK: Minted.’);
70 })
71 .catch(error => {
72 console.error(’Error:’, error);
73 });

After running this program, either with web3.js or ethers.js, the freshly minted NFT will be deposited
on the Sepolia network. It will appear at the NFT tab of the owner’s wallet as illustrated in Fig. 5.

6 Decentralized Finance (DeFi)

Decentralized finance (DeFi) refers to the financial ecosystem that operates on a decentralized network
using blockchain technology. It allows users to access financial services, such as lending, borrowing,
financial markets and investments, without the need for intermediaries such as banks and other tra-
ditional financial institutions.
DeFi is based on three fundamental principles that differentiate it from traditional financial sys-
tems: decentralization, transparency and public access. DeFi operates on a blockchain network, so
there is no central authority or intermediary controlling or overseeing the system. Instead, users inter-
act directly with each other through smart contracts (cf. Sect. 5) to automate financial transactions.
As contracts and transactions are materialized directly through programmed logic, there is no need for
other agents to process such contracts and transactions. Moreover, as such transactions are stored
persistently and immutably on the blockchain, there is also no need for agents to store and maintain

37
Figure 5: NFT in a crypto wallet, in the section where the NFT in the Sepolia network are listed.

such information. This eliminates the need for banks or other traditional financial institutions, and
promotes a more democratic and inclusive financial system.
In terms of transparency, DeFi is fundamentally so because all transactions are recorded in the
public ledger of the blockchain (cf. Sect. 1), making it easy to track and verify their authenticity. Users
can see exactly how their funds are being used and ensure that the system is operating fairly and
impartially. This level of transparency fosters accountability and builds trust among users.
DeFi also ensures public access because it is open to anyone with an Internet connection, regard-
less of location or financial situation. By eliminating intermediaries, the costs associated with such
intermediation are eliminated, costs that can be high to the point of constituting an entry barrier and
excluding certain social groups from accessing financial services. By offering a more inclusive and
accessible platform, DeFi promotes greater equity and equality of opportunities in the financial sector.
In a nutshell, DeFi’s impact on traditional financial systems is very significant because it challenges
the status quo by offering a more transparent, secure and accessible alternative. By eliminating in-
termediaries, DeFi enables lower operational costs while improving the efficiency of financial transac-
tions. In addition, DeFi platforms offer greater flexibility and liquidity, allowing users to access financial
services anytime, anywhere.
However, DeFi also poses different challenges than traditional financial systems, as it does not
easily adapt to the same regulatory frameworks and supervisory mechanisms that govern conven-
tional financial institutions, which can create risks for investors and raise concerns about the security
and stability of the financial sector. Overall, while DeFi offers exciting opportunities for innovation and
can be seen as a disruptive option for financial operations, its impact on traditional financial systems
will depend on how it evolves and adapts to regulatory frameworks and market demands.
In the following sections we will succinctly present the most relevant aspects of the DeFi ecosys-
tem, starting with decentralized financial markets. Later we will introduce decentralized lending plat-
forms and the concept of liquidity mining as a tool to provide liquidity to both types of platforms. We

38
will then briefly review other derivative products and asset management strategies in the DeFi envi-
ronment. We will complete this presentation by identifying some relevant challenges and regulatory
considerations.

6.1 Decentralized Exchanges

Decentralized exchanges (DEX) are digital markets that allow users to trade cryptocurrencies or other
digital assets on a peer-to-peer basis, without the need for intermediaries or brokers operating on
centralized exchanges and markets. By operating on a blockchain, they inherit the characteristics of
security, transparency and autonomy for users of this technology.
In a DEX, orders are matched directly between buyers and sellers through smart contracts, which
automate the trading process and ensure that all transactions are executed fairly and impartially with-
out intermediaries or brokers. As a result, transaction costs are dramatically reduced and many of
the requirements and limitations that exist in traditional markets are eliminated. The DEX maintains a
publicly accessible decentralized order book on the blockchain where all these intentions to buy and
sell assets are recorded. Users create (trading pairs) by linking two different assets (e.g., a trading
pair could consist of a popular cryptoasset, such as Ethereum or Bitcoin, and a different cryptoasset).
When a user places a buy or sell order, a smart contract in the DEX automatically attempts to match
that order with other orders registered in the order book. If there is a match, the exchange is automat-
ically executed. Users can interact with a DEX through their cryptocurrency wallets, and DEXs often
provide user-friendly interfaces and integrations with different wallets to enhance the user experience.
DEXs offer several advantages over centralized marketplaces, such as lower fees, higher liquidity,
more user control over their assets, and greater privacy as users are not required to register with any
entity. In addition, by not relying on single points of failure, the risk of hacking or fraud is reduced.
However, they also have some drawbacks, such as limiting the assets that can be traded to the es-
tablished trading pairs, slow transactions and vulnerabilities in the code of the smart contracts that im-
plement trade operations. Moreover, some DEXs may have a steeper learning curve for non-technical
users compared to centralized platforms, which tend to be conceptually simpler. In addition, relying
on an entity to operate them ensures minimal support and consulting services.
One of the most popular and widely used DEX is Uniswap. Uniswap operates on the Ethereum
network and has pioneered the concept of (automated market maker, AMM), which allows users to
exchange cryptocurrencies in a decentralized manner without the need for a traditional order book.
Instead, smart contracts and liquidity provided by the users themselves are utilized to materialize
exchanges through pools. A pool in Uniswap refers to a wallet containing different token trading pairs
created by users, who choose to deposit their tokens in the pool and share them with other users of the
system. Token pairs may contain any ERC-20 cryptoasset pair from the Ethereum network, either an
established token (such as Ethereum itself) or one new to the cryptocurrency scene, and are created
automatically when users deposit their tokens into the pool and are executed according to the rules of
the Uniswap system. This means that the prices of token pairs are determined according to the rules
of supply and demand, without intermediaries.
Users may withdraw their tokens from a pool at any time and receive corresponding amounts of
the other token in the pair. This allows users to trade with flexibility and control over their digital assets.
In addition, token pairs become more liquid when there is increased supply and demand in the system.
Uniswap has a decentralized governance model based on a proprietary token called UNI, which
allows its holders to participate in relevant decisions about the protocol. Actually, this token serves
multiple purposes within the ecosystem in addition to governance, such as paying commissions and
incentivizing user participation. As a governance token, UNI holders can participate in decision-making
processes related to the development and evolution of the Uniswap platform by voting on proposals

39
and updating parameters, such as commission amounts or the creation of liquidity pools. In addition,
users who provide liquidity to Uniswap pools are rewarded with UNI tokens, which creates an incentive
for participation and helps increase the overall liquidity of the platform.
Other relevant DEX platforms would be SushiSwap, a DEX built on Uniswap with added features
such as liquidity provisioning rewards and NFT-based governance; Balancer, another automated mar-
ket maker (AMM) that supports multiple pools, customizable token weightings and flexible fee struc-
tures for liquidity providers; or Curve Finance, a DEX focused on stablecoin trading with highly efficient
liquidity pools and integrated pricing oracles to maintain stability.

6.2 Decentralized Lending

In the DeFi ecosystem, decentralized lending is a way to lend and receive money without the need for
financial intermediaries such as banks or credit institutions. As with DEX, these loans use blockchain
technology to ensure security, transparency and autonomy for lenders and borrowers.
Decentralized loans can take the same forms as traditional loans, including variable or fixed in-
terest loans, loans in cryptocurrencies or conventional currency, instant loans, secured or unsecured
loans, and loans for different purposes (investment, consumer, mortgage, etc.). Lenders can earn
profitability by lending their money to other users, while borrowers can access cheaper financing with
less paperwork and requirements than through traditional sources.
Lending and borrowing protocols are also implemented through smart contracts that automati-
cally execute transactions and ensure the security of the process. These protocols can take various
forms, depending on the type of loan, and there are specific smart contracts for each type of loan.
These contracts reflect the specific conditions of the loan, such as the time to maturity, the interest to
be paid, the type and amount of collateral required, and the penalties for late payment.
Users can access lending and borrowing services through specific platforms. A popular platform in
this area is Compound, a DeFi platform that allows users to lend and borrow cryptocurrencies without
the need for intermediaries, based on an algorithm for calculating dynamic interest rates according
to the laws of supply and demand, where these rates are automatically adjusted according to the
supply and demand of each asset. Compound operates on the Ethereum blockchain, where loans are
carried out through smart contracts that ensure transparency of transactions. Users become lenders
by depositing cryptocurrency on Compound (Ethereum, BAT, DAI, ESDC, etc.), for which they receive
amounts of a specific token in return, called COMP. These tokens represent their stake and earn interest
in real time. Borrowers borrow in exchange for interest, also calculated in real time.
Compound is a DeFi platform for anonymous lending, i.e., with no know your customer (KYC) re-
quirements, meaning that users can participate without having to go through an identity verification
process. Governance in Compound is carried out through a decentralized voting system in which
COMP token holders can propose changes to protocol parameters, such as interest rates, lending
limits or collateral rates. These proposals are put to a community vote and, if they receive sufficient
support from other COMP holders, they are implemented on the platform.
Other relevant platforms in the DeFi lending world are the already discussed Uniswap, and Aave,
MakerDAO or Yearn Finance, each with their specific features. All these platforms offer a user-friendly
experience and allow users to lend or receive money without the need for advanced technical knowl-
edge about blockchain or cryptocurrencies.

40
6.3 Liquidity Mining

Liquidity mining or yield farming refers to the practice of providing liquidity to a DEX or lending platform
such as those discussed previously, in exchange for rewards in the form of tokens, such as transaction
fees, interest payments or new tokens that are created through the mining process. It consists of con-
tributing digital assets to a pool (e.g., cryptocurrencies), which are then used to facilitate transactions
between buyers and sellers on the platform. As we have seen in the previous sections, liquidity miners
can also receive governance tokens from the relevant platform as a reward, representing a stake in its
governance. Liquidity mining incentivizes users to contribute their assets to the platform, which helps
to increase its liquidity and overall value.
This is an important component of DeFi ecosystems because it encourages user participation
and engagement. By offering rewards for contributing liquidity, platforms can attract more users and
create a broader community around their offerings. In addition, liquidity mining helps ensure that there
are always enough assets available on the platform, which is essential to maintain its functionality and
stability. Still, rates of return in liquidity mining can be highly variable and depend on factors such as
the demand for liquidity in the protocol and the rewards offered. Miners seek to maximize their returns
by choosing the pools that offer the best rates.
In addition to rewards and governance participation, some DeFi platforms offer the option of lock-
ing tokens received as rewards in a process called (staking). By locking these tokens into staking
contracts, users can still earn additional returns, and in some cases even more elaborate strategies
are allowed, such as the creation of compound liquidity mining strategies, where the returns earned
are automatically reinvested to maximize revenue.
Although liquidity mining can become a lucrative activity, it also carries risks. DeFi protocols can be
prone to bugs or attacks, and rates of return can change rapidly, volatility that directly affects expected
returns.

6.4 DeFi Derivatives and Asset Management

In the DeFI context, synthetic assets and complex financial products are often created by taking advan-
tage of the flexibility provided by the programmed logic in smart contracts. These derivative financial
instruments are characterized by the fact that their value is associated with the value of an underlying
asset or assets, in many cases in a very elaborated way. Among the most representative are synthetic
assets, options, futures, synthetic indices, and leveraged and inverse tokens.
Synthetic assets are representations or digital twins of real-world assets. In any case, these assets
are not directly backed by the underlying asset, but are created synthetically through smart contracts.
An example of a synthetic asset could be a token indexed to the price of gold or a commodity. Through
smart contracts, users can own a token that reflects the value of gold without physically owning any
of the precious metal.
Options are derivative contracts that give the holder the right (but not the obligation) to buy or sell
an underlying asset at a specific price on a specific date. Options are not unique to the DeFi world, but
in this context option contracts, actually software programs rather than contracts per se, can be used
to create complex strategies, such as strangles or strategy spreads, which are applied automatically
and allow users to manage risk and seek returns in different market scenarios.
Futures contracts, which are also not specific to the DeFi world, are agreements to buy or sell an
underlying asset at a future date at an agreed price. Futures allow participants to bet on the future
price of an asset, and at DeFi they are often used to create products that allow users to bet on the
future price of cryptocurrencies, indices or other assets.

41
Synthetic indices are often created by combining multiple underlying assets or exposure to mul-
tiple assets. These indexes do not necessarily replicate traditional indexes, but are synthetically con-
structed using smart contract logic. For example, a synthetic index might track the combined perfor-
mance of several cryptocurrencies. Participants can gain diversified exposure through a token repre-
senting this synthetic index.
Leveraged and inverse tokens provide leveraged or inverse exposure to an underlying asset. They
can be used for leveraged or hedging strategies. A leveraged strategy involves the use of borrowed
capital to make investments, while a hedging strategy involves protecting an existing position or an-
ticipating potential losses by taking an offsetting position in another asset or financial instrument. For
example, a 3x leveraged token can achieve three times the daily return of an underlying asset. On the
other hand, an inverse token might seek to obtain the inverse of the daily return to offset potential
losses. Interest rate swaps are derivative contracts that allow the exchange of cash flows associated
with interest rates. At DeFi, interest rate swaps can be implemented to manage risks associated with
variable interest rates in lending and liquidity protocols.
In any case, note that derivatives and complex financial products pose significant risks, both in
the physical world and in the DeFi world, so their use requires a thorough knowledge of them and
in general of the financial operation of complex products. The decentralized nature of DeFi by no
means eliminates the risks associated with these financial instruments. Users should fully understand
the products in which they participate and carefully weigh the risks and rewards before engaging in
complex DeFi strategies.
A relevant example in DeFi asset management is Yearn Finance, a DeFi protocol and platform that
operates on the Ethereum blockchain that became one of the most well-known DeFi projects. Yearn
Finance’s primary mission is to optimize and automate investment returns in the DeFi space, using
advanced strategies to maximize returns for its users by optimizing the placement of funds on different
DeFi protocols. Yearn Finance seeks to provide a simple and efficient investment experience for users,
allowing them to deposit funds into the protocol and let the algorithms automatically manage timely
investments for the best possible returns.
Yearn Finance operates vaults, which are proactively managed pools of liquidity. Users can deposit
funds into these vaults, and the protocol uses automated strategies to maximize returns. To this end,
it provides two key functions: earn and zap. The earn function allows users to deposit stablecoins and
other assets into Yearn Finance to earn interest, while zap allows users to make more efficient and
optimized transactions by combining multiple trades into a single transaction, seeking the best return
opportunities in each case. In addition, Yearn Finance enables the participation of external strategists
who can propose and manage investment strategies in the protocol.
Yearn Finance’s native token is YFI, which was initially distributed fairly to the community and al-
lows holders to participate in the governance of the protocol, propose and vote on changes.

6.5 Challenges and Policy Considerations

DeFi has emerged as one of the most promising applications of blockchain technology, as DeFi plat-
forms allow users to conduct financial activities of any kind without intermediaries. However, these
platforms also present unique challenges in terms of scalability, security vulnerabilities and associated
risks related to smart contract exploits.
One of the main issues with DeFi platforms is their inability to handle large volumes of transactions
simultaneously, which can lead to network congestion and slow processing and response times for
users, something that can be critical in the finance world. In addition, as more complex smart con-
tracts are developed, the risk of introducing vulnerabilities that can be exploited by malicious actors
increases. Note that the computer code of smart contracts is public and can be analyzed by anyone.

42
Another concern related to DeFi platforms is their susceptibility to security breaches due to their
reliance on public blockchains and open source code. In fact, hackers have successfully attacked
these systems in the past, causing significant losses for users. Finally, smart contract exploits pose a
significant risk to DeFi platforms, as they can lead to unexpected outcomes or even total loss of user
funds if not designed and implemented correctly. Despite these challenges, DeFi continues to grow
rapidly with the ongoing launch of new projects. As the industry matures, developers are expected to
continue to address these issues through better coding practices, improved security measures and
more robust testing protocols.
However, this rapid expansion has also raised concerns among regulators, who are debating how
to oversee these platforms and protect consumers from potential risks. One of the main challenges
facing the DeFi regulation is the decentralized nature of the underlying blockchain platforms, which
makes it difficult to enforce traditional regulatory frameworks, as there is no central authority control-
ling the network or its participants. In addition, many DeFi projects are formally located in jurisdictions
with lax or unclear regulations surrounding cryptocurrencies and digital assets, making it difficult to
enforce compliance rules.
Another problem related to the regulation of DeFi is the lack of transparency surrounding these
platforms. Due to their decentralized structure, it can be difficult for regulators to obtain information
about users’ activities or identify potential risks, which has led some countries to consider implement-
ing stricter know-your-customer (KYC) and anti-money laundering requirements in order to increase
oversight of these platforms.
Finally, jurisdictional issues arise in relation to the regulation of the financing of the DeFi projects
themselves, as many of them operate in several countries and would fall under the jurisdiction of
various regulatory bodies, depending on where users or service providers are located, which in turn
creates confusion and potential conflicts among different legal frameworks.
Despite these challenges, there has been some progress in developing a more consistent approach
to the regulation of DeFi, with initiatives such as the Financial Action Task Force (FATF), which has is-
sued guidance on digital assets (FATF, 2012-2023), and regulators such as the U.S. Securities and
Exchange Commission (SEC), which has taken action against certain projects for alleged securities
law violations. As the industry continues to evolve, more clarity is likely to emerge on how DeFi plat-
forms should be regulated to balance innovation with investor protection.

7 Oracles

In blockchain technology, an oracle is a third-party service that provides external data or events to a
smart contract on a blockchain. Oracles allow smart contracts to interact with the outside world and
execute actions based on real-world events.
Oracles (cf. Fig. 6) are materialized as smart contracts that act as intermediaries between other
smart contracts and external data sources, providing data such as prices, weather reports or sports
scores to the smart contract. They can also provide data about events on other blockchains or data
that is not natively available on the blockchain, such as off-chain financial data or data from Internet
of Things’s (IoT) sensors.
Oracle systems can be broadly classified according to two criteria based on their architecture and
functionality: software-based or hardware-based oracles, depending on the origin of the data man-
aged; and centralized or decentralized oracles, depending on whether the oracle monitors a single
entity or seeks to obtain data from multiple independent sources. Each type has its own characteris-
tics, use cases and differences.

43
Figure 6: Example of a blockchain network to which oracles are connected to some of its nodes. Such nodes provide
programmer application interfaces (API) to access information. Access to information is provided by smart contracts.

Software-based oracles are software implementations that provide data to smart contracts. They
can extract information from online sources, APIs, databases, etc. They are flexible and can be easily
adapted to different use cases. However, their main challenge is to ensure the integrity and reliability
of the data they provide. Typically they are used to make financial market predictions, provide weather
information, exchange rates, etc. For example, if a smart contract needs to know the current price
of Bitcoin to execute a trade, it can make use of a software-based oracle that pulls that information
from multiple cryptocurrency platforms and provides it to the contract. These are typically accessed
through a programmer interface (API) from any application. Examples would be CoinGecko API (cryp-
tocurrency price, volume and capitalization information), Alpha Vantage API (financial data, including
exchange rates, stock prices, and technical indicator data) or OpenWeatherMap API (real-time weather
data and climate information).
Hardware-based oracles use physical sensors or hardware devices to provide real-world data on
variables such as temperature, humidity, geographic location, and so on. They provide a more direct
and reliable source of data than software oracles, but can be more expensive to implement and main-
tain compared to software-based oracles. Part of the Internet of Things (IoT) ecosystem, they are
common in environmental monitoring, cold chain control, or security and surveillance applications.
For example, in an environmental monitoring system for a perishable goods supply chain, a tempera-
ture sensor connected to the blockchain through a hardware-based oracle could be used. The sensor
could generate real-time information about the temperature of a cargo container and send that data to
the blockchain, where a smart contract would implement logic based on this data, such as to trigger
an alert if the temperature exceeds a certain threshold.
Centralized oracles get data from a single central source, which can be a company, a centralized
interface, or any entity that provides information. They are simpler to implement but can be vulnerable
to attacks and manipulations, as they rely on a single entity. We can find them providing asset prices,
centralized financial information, specific events from a trusted source, etc.
In turn, decentralized oracles obtain data from multiple independent sources, thereby reducing de-
pendence on a single entity and improving resistance to manipulation. They therefore offer greater
robustness and resistance to censorship than centralized ones, as they do not depend on a single
source. They are common in the monitoring of electoral process data, monitoring of sports results in
betting systems, or in the provision of decentralized information in financial markets. Within decen-
tralized oracles, we can find consensus-based oracles, which obtain data from various sources and
use consensus algorithms to determine the correct value and ensure data integrity in environments
where information can change rapidly or unexpectedly.

44
An example of a decentralized oracle is Chainlink (cf. Sect. 7.2), a platform that facilitates the con-
nection between smart contracts and external data sources in a decentralized manner. Chainlink uses
a network of oracle nodes to provide real-world information to smart contracts on various blockchains.
These nodes share and validate information using smart contracts on the Chainlink network itself, en-
suring decentralized consensus. When a smart contract needs to know a piece of data monitored
by Chainlink (e.g., the exchange rate of a certain cryptocurrency), it sends a request to the Chainlink
network to which several oracle nodes respond with the requested information. The response is com-
pared and an algorithm or a consensus function is used (e.g., calculation of the median of the returned
values) to determine the final value to be provided to the smart contract.
Oracles are most relevant in blockchain applications that require external data to trigger smart
contract execution, such as in many DeFi applications (cf. Sect. 6), prediction markets, and supply
chain management systems. By providing an avenue for smart contracts to access external data,
oracles enable the development of more complex and sophisticated blockchain applications.

7.1 Oracle Architectures

The two main models of oracle architectures are the request-response model (pull model) and the
publish-subscribe model (push model). Each has its own characteristics and suits different use cases
in the context of blockchains and smart contracts.
In the request-response model, also known as pull, the smart contract actively makes a request
to obtain data from the oracle when it needs it, that is, when a specific condition in the contract is
triggered. The oracle responds to the request by providing the requested data.
With this model, the smart contract has greater control over when and what data to request, en-
hancing efficiency since oracle resources are used only when data is needed. However, there may be
some delay between activating the contract and obtaining data, since the request is made only when
it is deemed necessary without knowing the status of the data source.
In the publish-subscribe model, also known as push, the oracle actively provides data to the smart
contract when predefined events occur. The smart contract pre-subscribes to certain events or types
of data provided by the oracle. Thereafter, the oracle automatically sends data to the contract when the
events of interest occur, without the contract actively requesting it, using a callback function defined
during the subscription process.
In this model, data can immediately reach the contract as soon as it becomes available, while
reducing complexity by not requiring the smart contract to actively initiate data requests. However,
oracles based on this model can consume more resources, as they are continuously sending data,
even if it is not needed.
The choice between pull and push models will depend on the specific use case and smart con-
tract requirements (e.g., update frequency required by the use case, importance of data immediacy, or
resource efficiency requirements on the blockchain network). Some use cases may benefit from the
immediacy of the subscription-based model, while others may prefer the control and efficiency of the
request/response-based model. For example, use of the pull model is common in obtaining rates of
change or weather information, while the push model is more appropriate for continuous monitoring
of IoT sensors or when real-time updates of specific events are needed. d

7.2 Oracles and DeFi

An oracle can provide stock prices to a smart contract in a DeFi application that enables users to
create and trade synthetic assets that track stock prices. In this example, an oracle service would be

45
responsible for providing the smart contract with real-time stock price data from a trusted data source,
such as a stock exchange. The smart contract would use this data to calculate the synthetic asset
price and execute trades between users. Imagine that a user wants to create a synthetic asset that
tracks ACME’s stock price. To do so, they would send a request to the smart contract, which in turn
would send a request to the oracle for the current price of ACME stock. The oracle would provide the
smart contract with the current stock price, and the smart contract would use this data to calculate
the value of the synthetic asset. If another user wishes to trade this synthetic asset, the smart contract
would again request the current stock price from the oracle to ensure that the trade is executed at the
current market price. Once the trade is executed, the smart contract will update the ownership of the
synthetic asset and transfer the funds involved in the trade.
In this example, the oracle acts as a reliable source of real-time stock price data that allows the
smart contract to accurately price and execute trades on synthetic assets that track ACME’s stock
price. This allows users to trade synthetic assets that represent real-world assets, without relying on
centralized brokers or traditional financial institutions.
A simple example is provided below of a smart contract that contacts an oracle to obtain the
conversion rate between Bitcoin (BTC) and the US dollar (USD). For this, the Chainlink, platform is
used, which among other services offers oracles (data feeds) for DeFi applications. To access these
data feeds, Chainlink makes available smart contracts in various popular blockchains.

1 // SPDX-License-Identifier: MIT
2 //
3 // Smart contract to test an oracle (data feed) from Chainlink.
4 // The oracle provides the BTC/USD conversion rate.
5 //
6 // Version of Solidity used
7 pragma solidity ^0.8.18;
8
9 // Import a Chainlink interface named AggregatorV3Interface.
10 // Interfaces define functions without their implementation, which
11 // leaves the contracts implementing the interface to define
12 // the implementation themselves.
13 // In this case, AggregatorV3Interface defines, among other functions,
14 // the signature of the latestRoundData function that we are going to use.
15 import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
16
17 // Use the toString function of the Hardhat toolkit to
18 // convert the data returned by the oracle (via its
19 // smart contract) into strings,
20 // to construct the JSON record returned as a result by
21 // our smart contract.
22 import "@openzeppelin/contracts/utils/Strings.sol";
23
24 // Define the smart contract
25 contract BTCUSDRateJSON {
26
27 // Declare a variable to store the address of the
28 // oracle Chainlink
29 AggregatorV3Interface internal priceFeed;
30
31 // The smart contract’s constructor simply invokes the
32 // oracle constructor. This, in turn, simply sets
33 // the address of the Chainlink oracle in the Sepolia network.
34 //
35 // An interface object called priceFeed is initialized,
36 // which uses the AggregatorV3Interface to connect to the
37 // oracle that provides the BTC/USD conversion rate,
38 // already deployed at address
39 // 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43

46
40 // of the Sepolia network.
41 //
42 // The interface allows our contract to execute functions
43 // on that already deployed proxy contract.
44 constructor() {
45 // You may replace the address with the address of any
46 // other proxy of any other Chainlink data feed.
47 // This is the address of the oracle contract on .
48 // the Sepolia testnet that provides BTC / USD rates.
49 priceFeed = AggregatorV3Interface(
50 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
51 );
52 }
53
54 // Function to return the BTC/USD exchange rate.
55 // This function uses the priceFeed object
56 // to execute the oracle’s latestRoundData() function.
57 // The priceFeed object is initialized to point to
58 // the smart contract at
59 // 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 via
60 // the constructor (see above).
61 //
62 // The function returns a JSON record with all the information.
63 function getConversionRateBTCUSD() public view returns (string memory) {
64 // Get the latest conversion rate through the oracle
65 // by calling preceFeed’s latestRoundData function.
66 // This function returns the conversion information set on the
67 // last available round.
68 (
69 uint80 roundID,
70 int256 price,
71 uint256 startedAt,
72 uint256 timeStamp,
73 uint80 answeredInRound
74 ) = priceFeed.latestRoundData();
75
76 // The aggregator’s response includes several variables: round ID
77 // where the value was set; conversion rate; timestamp from
78 // when the round started; completion timestamp,
79 // ID of the round where the rate was computed.
80 // We use these to build a JSON record and return it.
81 string memory JsonString =
82 string.concat(’{"RoundID":"’,
83 Strings.toString(roundID),
84 ’","Price":"’,
85 Strings.toString(uint256(price)),
86 ’","startedAt":"’,
87 Strings.toString(startedAt),
88 ’","TimeStamp":"’,
89 Strings.toString(timeStamp),
90 ’","answeredInRound":"’,
91 Strings.toString(answeredInRound),
92 ’"}’);
93
94 return JsonString;
95 }
96 }

This contract provides a function getConversionRateBTCUSD that returns a JSON string with all
the relevant information about the conversion rate, namely its value, and when and how the conversion
rate was set. The next JavaSCript program interacts with this contract and displays the conversion
rate information.

47
1
2 //
3 // Interaction with exchange rate conversion’s smart contract
4 // discussed above.
5 //
6 // Returns the BTC/USD conversion rate, along with other information.
7 //
8 // To run this: npx hardhat run scripts/interacct.js
9
10 // Address of our smart contract, obtained after deployment
11 // and stored in the .env file
12 const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS_JSON;
13
14 // Get the ABI (Application Binary Interface) of our contract
15 // to interact with it.
16 const contract =
17 require("../artifacts/contracts/test-oracle.sol/StockMarketValueJSON.json");
18
19 // Signer
20 // A wallet that has the ability to sign transactions.
21 // In our case, created with MetaMask.
22 // To identify it, we need the wallet’s public key (from .env).
23 // To be able to pay with this wallet, the file hardhat.config.js
24 // has information about the private key
25 // and the network used (Sepolia testnet in our case).
26 const ownerAddress = process.env.PUBLIC_KEY;
27 const signer = ethers.provider.getSigner(ownerAddress);
28
29 // Contract
30 // An ethers.js library object representing a
31 // specific smart contract deployed on the chain,
32 // in our case, our BTCUSDRateJSON contract.
33 // To identify it, we need the contract address, the ABI and the signer’s wallet.
34 const financeContract = new ethers.Contract(CONTRACT_ADDRESS, contract.abi, signer);
35
36 // Contact our smart contract to obtain
37 // the BTC/USD conversion rate along with the additional information
38 // provided by the oracle.
39 // As discussed in another example, asynchronous functions are used
40 // to interact with blockchain networks.
41 async function main() {
42
43 try {
44 // Get the last value of the BTC/USD conversion rate.
45 // The method returns a JSON string.
46 const presentValue = await financeContract.getConversionRateBTCUSD();
47
48 // Parse (i.e., convert) the JSON string to an object
49 const valObj = JSON.parse(presentValue);
50
51 // Display the information using the object just created.
52 // Returned values are conditioned to
53 // make them more human-readable: we convert the
54 // rate to dollars and the timestamps to dates and times.
55 console.log("Round ID: " + valObj.RoundID);
56 console.log("Conversion rate: " + valObj.Price / 10**8 + " USD/BTC");
57 console.log("Start: " + new Date(valObj.startedAt * 1000));
58 console.log("End: " + new Date(valObj.TimeStamp * 1000));
59 console.log("Final round: " + valObj.answeredInRound);
60 } catch (error) {
61 // We should not get here
62 console.log("ERROR FOUND");
63 console.error(error);

48
64 }
65
66 }
67
68 // Let’s roll!
69
70 main();

If the program is run with:


npx hardhat run scripts/interact.js -network sepolia

a typical outcome could be:


Round ID: 18446744073709553674
Conversion rate: 28399.39341 USD/BTC
Start: Sun Apr 02 2023 12:18:00 GMT+0200
End: Sun Apr 02 2023 12:18:00 GMT+0200
Final round: 18446744073709553674

7.3 Random number generation

Generating truly random numbers in a smart contract is not a simple task, as smart contracts in
blockchain networks operate in a deterministic environment, meaning that given the same inputs
and conditions, the same results will always occur. This determinism is a fundamental aspect of
blockchain technology, as it ensures that all nodes in the network can reach a consensus on the state
of the blockchain. However, true randomness is, by definition, unpredictable, which conflicts with the
deterministic nature of blockchains and thus of smart contracts. To complicate matters further, smart
contracts have limited access to external information, and cannot directly interact with off-chain data
sources or the physical world. In fact, this feature is the very raison d’être of oracles.
Consequently, pseudorandom number generators that use the information available in a smart
contract as a seed, may be predictable if an attacker knows the value of the seed or the internal state of
the blockchain, and thus could be vulnerable to manipulation. In addition, pseudorandom number gen-
eration is comparatively computationally expensive. The cost of running complex computations on a
blockchain will have to be covered by the creator or users of the contract, so implementing complex
and expensive pseudorandom number generation can make smart contracts prohibitively expensive
to use.
A common method for generating random numbers on a blockchain is to generate a hash of a
sequence of bytes composed of certain values extracted from the blockchain, which are in principle
difficult to predict, such as the block number, the block timestamp, the mining’s difficulty value in proof-
of-work consensus, the Randao value (cf. Appendix D) generated by block validators in Ethereum’s
proof-of-participation (Kalinin & Ryan, 2021), the amount of gas remaining in the contract, or the ad-
dress that invoked the contract.
The following code generates a pseudo-random number between 1 and 100 using three of the
above values in an Ethereum chain:

1 pragma solidity ^0.8.18;


2
3 contract RandomNumberGenerator {
4 function generateRandomNumber() public view returns (uint) {
5 // Fetch the timestamp of this block and prevrandao.
6 // prevrandao is the Randao value of the last update.
7 // of Randao, i.e., the last slot in which someone
8 // actually updated the Randao and produced a new block.

49
9 // We also use the address that invoked this contract.
10 uint seed = uint(keccak256(abi.encodePacked(
11 block.timestamp,
12 block.prevrandao,
13 msg.sender)));
14
15 // Generate a pseudorandom number between 1 y 100.
16 uint randomNum = (seed % 100) + 1;
17
18 return randomNum;
19 }
20 }

In the above example, the use of block.timestamp can be controlled by validators to some extent,
since although the timestamp of the current block must be strictly greater than the timestamp of the
last block, the only guarantee is that its value will be somewhere between the timestamps of two con-
secutive blocks in the canonical chain. A malicious validator could make it take any value as long as
the above condition is met. Similarly, block.prevrandao is manipulable to some extent since a mali-
cious validator could omit a block if the resulting value is not favorable. However block.prevrandao
can be an interesting randomness solution in many applications, because it is generated by a crypto-
graphically secure algorithm and is unique for each block.
Because of these bias and cost issues, many blockchain developers and projects turn to external
oracle services, such as Chainlink’s Verifiable Random Function (VRF) (Blaut, Ma, & Wolter, 2023). VRF
relies on a cryptographic process to generate a number that can be guaranteed to be random. The
process starts with a seed value, provided by the user, the smart contract, or the application requesting
the random number. Upon making the request, the Chainlink node generates a random number off
the blockchain and commits to that number by performing a calculation known as a cryptographic
commitment. This commitment remains hidden and no one knows the actual value of the random
number at this stage beyond the node that generated it.
After a waiting period indicated by the contract that requested the random number (e.g., after the
mining of a certain number of blocks is completed or after a certain event occurs), the Chainlink node
publicly discloses the committed random number along with a cryptographic proof that serves to
ensure that the number was generated correctly. The smart contract or application that requested the
random number checks the cryptographic proof to verify that the disclosed number was generated
fairly and securely, and that the number is unpredictable and was not tampered with. Cryptographic
techniques used for compromise and proof generation typically involve algorithms such as elliptic
curve cryptography (ECC) and the use of zero-knowledge proofs. These cryptographic methods are
well established and widely recognized for their security and reliability.
In practice, to generate a random number a contract wrapper of the VRF generator is instantiated.
For example, to generate random numbers without subscribing to Chainlink but paying for them up-
front, contract VRFV2WrapperConsumerBase would be instantiated. After funding our contract and
initializing some variables (e.g., how many numbers we want to generate, the maximum gas that we
are willing to pay VRF to return the numbers, the number of block commits VRF has to wait for, or
certain addresses used by VRF), we would launch an asynchronous procedure to complete the gen-
eration:
1. We would call VRF function requestRandomness to request random numbers. This function
immediately returns a request identifier.
2. When the VRF generator completes its task, it will invoke function fulfillRandomWords, pass-
ing as parameters to it the request identifier of the previous phase and a string in memory with
the generated random numbers. The code of this function would be overriden to utilize the cal-
culated numbers in any desired way. The most usual approach would be to save those values
or pass them to other functions, and/or emit an event indicating that the numbers are available.

50
An example of this process is collected in the sample contract CardDeks discussed ahead:

1 function resetRandomSeed() external {


2 // Requests the wrapper to generate a random word. Parameters:
3 // - callbackGasLimit: The maximum amount of gas to pay
4 // to complete the VRF callback function. If it is not enough,
5 // it will be reverted.
6 // - requestConfirmations: The number of block confirmations
7 // that the VRF service will wait to respond.
8 // - numwords: The number of random numbers to request.
9 // The function returns a requestId.
10 // This contract pays the wrapper the calculated price of the request.
11 uint256 requestId = requestRandomness(
12 callbackGasLimit,
13 requestConfirmations,
14 1
15 );
16
17 // Call to wrapper function calculateRequestPrice
18 // to estimate the total cost of the transaction
19 // and initialize the request ID.
20 // The rest of the RequestStatus fields were initialized
21 // when creating the contract.
22 _request.request = requestId;
23 _request.paid = VRF_V2_WRAPPER.calculateRequestPrice(callbackGasLimit);
24 }
25
26 // Callback function. The wrapper calls it when it finished, passing
27 // as parameters the corresponding _requestId and the list
28 // of random words generated (a single word in our case).
29 // In this example, it receives a random number and stores it in _nonce.
30 // In general, it would be overriden to implement the logic to
31 // handle the random values after they are returned to the contract.
32 function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords)
33 internal override {
34 require(_request.paid > 0, "Solicitud VRF no encontrada.");
35 _request.fulfilled = true;
36 _request.randomSeed = _randomWords[0];
37 _nonce = _randomWords[0];
38
39 emit randomSeedAvailable(_requestId, _request.randomSeed, _request.paid);
40 }

The generation of non-predictable or reproducible random numbers is crucial for situations where
fairness and unpredictability are essential, such as in gaming, betting and other applications like sup-
ply chain management, statistical applications or certain decentralized finance applications. In the
following example, we present a smart contract to provide a card deck management service. In this
example, we use VRF to obtain a nonce for card generation, specifically, VRF numbers are used to ini-
tialize a pseudorandom card generator (PCG). Anyone can invoke Chainlink’s VRF generator through
this contract (function resetRandomSeed if the contract has enough LINK to cover the cost of gener-
ating VRF random numbers. LINK is Chainlink’s proprietary cryptocurrency used to pay for its services.
Initially, the PCG nonce is initialized with the contract’s gas, but can be reset at any time with a verifiable
random number.
In other words, the PCG is based on the classic method of generating pseudorandom numbers
in smart contracts on an Ethereum blockchain (i.e., from the SHA-256 hash of the last Randao value
of proof-of-stake, the block timestamp, the address invoking the function, and a nonce). The nonce
is updated at each generation to pseudo-randomize the generation of the next card. However, at any

51
time anyone can fund the LINK contract and updte the nonce with a VRF number (e.g., when creating
a new deck, starting a new game with an existing deck, etc.).
As can be seen in the contract, this example also illustrates the setting of a fee for the address
offering the deck management service. For this purpose, functions createDeck and addPlayer are
declared as payable, and it is set as a requirement that the value of msg.value has to be greater than
or equal to the defined deck fee (originally 10,000 wei in this example). The contract owner can update
this value at any time using function updateFee. In addition to the fee, the contract allows the contract
owner to recover LINK remnants from VRF number generation, via function withdraw. This would be
a second source of revenue.

1 // SPDX-License-Identifier: MIT
2 //
3 // Contract to implement a collection of card decks. It uses Chainlink’s
4 // Verified Random Function (VRF) to obtain a nonce for card generation.
5 //
6 // - To get a new deck of cards, invoke the createDeck() function. Returns a deck ID.
7 // - To get a new card from a deck, invoke the dealCard(deckId) function.
8 // It is also possible to get a card and its symbolic name according to the
9 // standard for cards (see below). There are also public functions to get
10 // n cards or to get all remaining cards in the deck (see below, indices only,
11 // without symbolic names).
12 // - To get the list of all cards dealt so far, invoke
13 // cardsDealt(deckId).
14 // - To reset the deck (i.e., to return all dealt cards to the deck)
15 // invoke resetDeck(deckId).
16 // - To get the list of cards dealt so far from a deck:
17 // cardsDealt(deckID).
18 //
19 // The functions to reset a deck, see all dealt cards, or
20 // deal all remaining cards can only be invoked by the deck creator.
21 //
22 // The cost of creating a deck or adding a player to an existing deck/match
23 // is indicated by the _PRICE constant.
24 //
25 // The owner of the contract has a function to withdraw the collected ETH
26 // payed for the creation of decks and players. Unused LINK to pay for VRF
27 // generation will also be collected.
28 //
29 // VRF numbers are used to initialize the pseudo-random card generator (PCG).
30 // Anybody can invoke Chainlink’s VRF generator if the contract has
31 // enough LINK to cover the cost of generating VRF random numbers.
32 // To do so, anyone can invoke the resetRandomSeed() function.
33 //
34 // Initially, the PCG is initialized with the contract’s gas stock, but it
35 // can be reset at any time with a VRF number.
36 //
37
38 pragma solidity ^0.8.20;
39
40 // Imports required in this example:
41 // - ConfirmedOwner: A contract with helpers for basic contract property.
42 // - VRFV2WrapperConsumerBase: Creates VRF V2 requests without the need for
43 // subscription management. Instead of creating and funding a VRF V2 subscription,
44 // it is possible to use this wrapper to create a request,
45 // paying in advance. This option allows anyone to
46 // initialize the PCG.
47
48 import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
49 import "@chainlink/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol";
50
51 //

52
52 // To request LINK and ETH for a testnet: https://faucets.chain.link/
53 // Find information about LINK Token Contracts and get the latest ETH and
54 // LINK here: https://docs.chain.link/docs/link-token-contracts/
55 //
56
57 // Once this contract is deployed, you have to fund it with LINK to
58 // be able to get random numbers. To do this, you have to:
59 //
60 // 1. Buy Chainlink LINK for the network where you deployed your contract.
61 // 2. Get the address of your contract (you can get it once it is deployed).
62 // 3. Transfer LINK from your wallet to the contract address.
63 //
64 // Since the price is determined using the gas price of the transaction,
65 // wrapper charges an additional premium to the callback gas, plus
66 // some additional overhead associated with the VRF contract.
67 //
68 // To estimate costs: https://docs.chain.link/vrf/v2/estimating-costs
69
70 // Client contracts must inherit from VRFV2WrapperConsumerBase and
71 // must be funded with sufficient LINK to perform the request,
72 // otherwise the requests will be reverted.
73 //
74 // The ’requestRandomness’ function is invoked with the parameters
75 // desired. This function is in charge of paying for the request
76 // according to its price, deducting the price of the request, by
77 // drawing funds from the contract (LINK / gas).
78
79 contract CardDeks is ConfirmedOwner, VRFV2WrapperConsumerBase {
80
81 // VRF STRUCTURES
82
83 // Structure to track the status of a VRF request:
84 // Request ID, amount paid, if already paid, whether it has been completed
85 // and generated numberswhen completed.
86 struct RequestStatus {
87 uint256 request; // requestId
88 uint256 paid; // amount paid in LINK, 0 if not requested
89 bool fulfilled; // if the request has been fulfilled successfully.
90 uint256 randomSeed; // when request is fulfilled, number generated.
91 }
92
93 RequestStatus internal _request;
94
95 // Maximum gas we are willing to pay to the VRF.
96 // Depends on the number of values requested to send to the
97 // fulfillRandomWords() function. We adjust this limit
98 // depending on the network, the amount of numbers requested,
99 // and the cost of the callback call in fulfillRandomWords().
100 // If the callbackGasLimit is not sufficient, the callback will fail and
101 // the contract will be charged for the work done so far to generate
102 // the requested random values.
103 uint32 callbackGasLimit = 400000;
104
105 // How many block confirmations to wait for before responding.
106 // The longer the node waits, the more secure the random value will be.
107 // The default value is 3. The minimum and maximum number
108 // of acknowledgements for each network can be found here:
109 // https://docs.chain.link/vrf/v2/direct-funding/supported-networks/#configurations
110 uint16 requestConfirmations = 3;
111
112 // LINK address for Sepolia. Updatable by the contract owner.
113 address internal _linkAddress = 0x779877A7B0D9E8603169DdbD7836e478b4624789;
114

53
115 // WRAPPER address for Sepolia. Updatable by the contract owner.
116 address internal _wrapperAddress = 0xab18414CD93297B0d12ac29E63Ca20f515b3DB46;
117
118 // Fee to create a deck or add players to a deck.
119 uint256 private _deckFee;
120
121 // Maximum number of players per deck
122 uint256 private constant _MAX_PLAYERS = 16;
123
124 // Number of cards in a deck
125 uint32 private constant _N_CARDS = 52;
126
127 // Nonce for pseudorandom number generation
128 uint256 private _nonce;
129
130 // Structure of the deck. Gathers the basic elements of a deck of cards.
131 struct Deck {
132 address creator; // Deck creator
133 bool[] generatedCards; // Cards generated so far for this deck
134 uint32 cardCount; // Number of cards generated for this deck
135 address[] players; // Players that can play with this deck
136 uint32 nplayers; // Number of active players
137 }
138
139 // DECK STRUCTURE
140
141 // List of decks created
142 Deck[] private _decks;
143
144 // Number of decks created
145 uint256 private _ndecks;
146
147 // Modifier for operations requiring a dealer.
148 modifier onlyDealer(uint256 deckid) {
149 require(msg.sender == _decks[deckid].creator,
150 "Only the creator of this deck can do this."
151 );
152 _;
153 }
154
155 // Modifier for operations requiring a player.
156 modifier onlyPlayer(uint256 deckid) {
157 require(isPlayer(deckid, msg.sender),
158 "Only a registered player for this deck can do this."
159 );
160 _;
161 }
162
163 // Event to signal that the VRF requestId request has been completed.
164 // The generated random wordis stored in the _request structure,
165 // and payment informs about the cost of the process.
166 event randomSeedAvailable (
167 uint256 requestId,
168 uint256 randomWord,
169 uint256 payment
170 );
171
172 // Initializes the owner of the contract, the deck rate,
173 // the number of decks created so far and the
174 // number of decks of cards created so far and the nonce to
175 // calculate pseudo-random numbers to the amount of gas in this contract.
176 // In addition, it invokes the constructors of ConfirmedOwner.
177 // and RFV2WrapperConsumerBase.

54
178 constructor() ConfirmedOwner(msg.sender)
179 VRFV2WrapperConsumerBase(_linkAddress, _wrapperAddress) {
180 _deckFee = 10000 wei;
181 _ndecks = 0;
182 _nonce = gasleft(); // Use the available gas as initial nonce.
183 }
184
185 // Generates a pseudo-random number from the last Randao,
186 // the timestamp of the contract and a nonce, which in turn
187 // is initialized to the remaining gas for this contract.
188 // The nonce can also be initialized to a VRF number upon request.
189 function _computeSeed() internal returns (uint256) {
190 uint256 randomSeed = uint256(keccak256(abi.encodePacked(
191 block.prevrandao,
192 block.timestamp, msg.sender,
193 _nonce))
194 );
195 _nonce++;
196 return randomSeed;
197 }
198
199 // VRF FUNCTIONS
200
201 // Function to obtain a VRF number to reset the nonce,
202 // used for card generation, to a VRF number. It
203 // requests random number generation by the VRF V2
204 // Chainlink wrapper contract. A single number will be requested.
205 //
206 // To execute this function, the contract has to have LINK
207 // enough to generate the VRF number. WARNING: the excess LINK
208 // can only be redeemed by the owner of the contract.
209 function resetRandomSeed() external {
210 // Requests the wrapper to generate a random word. Parameters:
211 // - callbackGasLimit: The maximum amount of gas to pay
212 // to complete the VRF callback function. If it is not enough,
213 // the call will be reverted.
214 // - requestConfirmations: The number of block confirmations
215 // that the VRF service will wait to respond.
216 // - numwords: The number of random numbers to request.
217 // The function returns a requestId.
218 // This contract pays the wrapper the calculated price of the request.
219 uint256 requestId = requestRandomness(
220 callbackGasLimit,
221 requestConfirmations,
222 1
223 );
224
225 // Call to the wrapper function calculateRequestPrice
226 // to estimate the total cost of the transaction
227 // and initialize the request ID.
228 // The rest of the RequestStatus fields were initialized
229 // when creating the contract.
230 _request.request = requestId;
231 _request.paid = VRF_V2_WRAPPER.calculateRequestPrice(callbackGasLimit);
232 }
233
234 // Callback function. The wrapper calls it when finished, passing
235 // as parameters the corresponding _requestId and the list
236 // of random words generated (a single word in our case).
237 //
238 // In this example, it receives a random number and stores it in _nonce.
239 // In general, it would be overriden to implement the logic to
240 // handle the random values after they are returned to the contract.

55
241 function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords)
242 internal override {
243 require(_request.paid > 0, "VRF request not found.");
244 _request.fulfilled = true;
245 _request.randomSeed = _randomWords[0];
246 _nonce = _randomWords[0];
247
248 emit randomSeedAvailable(_requestId, _request.randomSeed, _request.paid);
249 }
250
251 // Gets the initialization status of the nonce.
252 function getRandomSeedStatus() external view returns (bool) {
253 require(_request.paid > 0, "VRF request not found.");
254 return (_request.fulfilled);
255 }
256
257 // Update the Chainlink wrapper address.
258 function updateVRFWrapper(address newAddress) external onlyOwner {
259 _wrapperAddress = newAddress;
260 }
261
262 // Update the Chainlink LINK address.
263 function updateVRFLinkaddress(address newAddress) external onlyOwner {
264 _linkAddress = newAddress;
265 }
266
267 // DECK FUNCTIONS
268
269 // Returns a new random card index between 1 and _N_CARDS.
270 // It is generated from a nonce,
271 // the timestap and the address of the sender.
272 function _getCardIndex() internal returns (uint32) {
273 // Generate a random number between 1 and _N_CARDS
274 uint32 carIndex = uint32((_computeSeed() % _N_CARDS) + 1);
275
276 return carIndex;
277 }
278
279 // Safe decrement function for 32-bit positive integers.
280 function _dec(uint32 a) internal pure returns (uint32) {
281 assert(a > 0);
282 return a - 1;
283 }
284
285 // Deal a new card from a deck of cards. The cards will be different,
286 // and it is possible to get cards as long as the deck is not exhausted.
287 function dealCard(uint256 deckid) public onlyPlayer(deckid) returns (uint32) {
288 require(deckid < _ndecks, "Deck not found.");
289 require(_decks[deckid].cardCount < _N_CARDS, "Deck depleted. Reset deck.");
290 uint32 card;
291
292 // Keep generating cards until a card not already dealt is generated.
293 do {
294 card = _getCardIndex();
295 } while(_decks[deckid].generatedCards[_dec(card)]);
296
297 // We have a fresh card. Increase the number of cards and
298 // store the card.
299 _decks[deckid].cardCount++;
300 _decks[deckid].generatedCards[_dec(card)] = true;
301
302 return card;
303 }

56
304
305 // Same as above, only it returns the symbolic name of the card.
306 function dealCardSym(uint256 deckid) external onlyPlayer(deckid)
307 returns (string memory) {
308 require(deckid < _ndecks, "Deck not found.");
309 return uintToCard(dealCard(deckid));
310 }
311
312 // Deal n cards from a deck of cards. The cards dealt will be different,
313 // and cards can be drawn as long as the deck is not exhausted.
314 function dealCards(uint256 deckid, uint32 n) external onlyPlayer(deckid)
315 returns(uint32[] memory) {
316 require(deckid < _ndecks, "Deck not found.");
317 require(_decks[deckid].cardCount <= (_N_CARDS - n),
318 "Not enough cards in deck.");
319
320 uint32[] memory cards = new uint32[](n);
321 for (uint32 i=0; i < n; i++)
322 cards[i] = dealCard(deckid);
323
324 return cards;
325 }
326
327 // Deal all remaining cards from a deck. Only for the creator
328 // of this deck.
329 function depleteDeck(uint deckid) external onlyDealer(deckid)
330 returns(uint32[] memory) {
331 require(deckid < _ndecks, "Deck not found.");
332 require(_decks[deckid].cardCount<_N_CARDS,
333 "Deck depleted.");
334
335 uint32 cardsToDeal = _N_CARDS - _decks[deckid].cardCount;
336 uint32[] memory cards = new uint32[](cardsToDeal);
337
338 for (uint32 i=0; i < cardsToDeal; i++)
339 cards[i] = dealCard(deckid);
340
341 return cards;
342 }
343
344 // Returns an array with all the cards dealt from a deck.
345 function cardsDealt(uint256 deckid) external view onlyDealer(deckid)
346 returns(uint32[] memory) {
347 require(deckid < _ndecks, "Deck not found.");
348 uint32[] memory cards = new uint32[](_decks[deckid].cardCount);
349 uint32 j = 0;
350
351 for (uint32 i=0; i < _N_CARDS; i++)
352 if (_decks[deckid].generatedCards[i]) cards[j++] = i + 1;
353
354 return cards;
355 }
356
357 // Resetsa deck.
358 function resetDeck(uint deckid) external onlyDealer(deckid) {
359 require(deckid < _ndecks, "Deck not found.");
360 for (uint32 i = 0; i < _N_CARDS; i++)
361 _decks[deckid].generatedCards[i] = false;
362 _decks[deckid].cardCount = 0;
363 }
364
365 // Function to convert a card number from a 52-card deck
366 // to a card, according to the standard

57
367 // poker ordering. Ranks are typically numbered in ascending order as follows:
368 //
369 // Hearts:
370 // 2, 3, 4, 5, 6, 7, 8, 9, 10, J (Jack), Q (Queen), K (King), A (Ace)
371 //
372 // Diamonds:
373 // 2, 3, 4, 5, 6, 7, 8, 9, 10, J (Jack), Q (Queen), K (King), A (Ace)
374 //
375 // Clubs:
376 // 2, 3, 4, 5, 6, 7, 8, 9, 10, J (Jack), Q (Queen), K (King), A (Ace)
377 //
378 // Spades:
379 // 2, 3, 4, 5, 6, 7, 8, 9, 10, J (Jack), Q (Queen), K (King), A (Ace)
380 //
381 function uintToCard(uint32 cardNumber) public pure returns (string memory) {
382 require(cardNumber >= 1 && cardNumber <= 52,
383 "Card number must be between 1 and 52.");
384
385 string[13] memory ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10",
386 "J", "Q", "K", "A"];
387 string[4] memory suits = ["Hearts", "Diamonds", "Clubs", "Spades"];
388
389 uint32 suitIndex = (cardNumber - 1) / 13;
390 uint32 rankIndex = (cardNumber - 1) % 13;
391
392 string memory card = string(abi.encodePacked(ranks[rankIndex],
393 " of ", suits[suitIndex]));
394
395 return card;
396 }
397
398 // Function to add a deck to the list of _decks, with nPlayers players.
399 // Returns the ID of the new deck.
400 // In addition, it initializes the properties of the deck.
401 function createDeck(uint32 nPlayers) external payable returns (uint) {
402 require(msg.value >= _deckFee, "Not enough crypto for this purchase.");
403 require(nPlayers <= _MAX_PLAYERS, "Too many players for this deck." );
404
405 // Creates a new deck object with 0 cards dealt,
406 // and it is added to the _decks array.
407 _decks.push(Deck(
408 msg.sender,
409 new bool[](_N_CARDS),
410 0,
411 new address[](nPlayers),
412 1));
413 uint256 newId = _decks.length - 1;
414 // Add the creator of the deck as its first player.
415 _decks[newId].players[0] = msg.sender;
416 // Increment the number of decks created.
417 _ndecks++;
418
419 // Return the new ID.
420 return newId;
421 }
422
423 // Add a new player to a deck.
424 function addPlayer(uint256 deckid, address newPlayer) external payable
425 onlyDealer(deckid) {
426 require(deckid < _ndecks, "Deck not found.");
427 require(_decks[deckid].nplayers < _MAX_PLAYERS, "Table already full.");
428 require(msg.value >= _deckFee, "Not enough crypto for this purchase.");
429

58
430 // Añade el nuevo jugador a la lista de jugadores de esta baraja.
431 _decks[deckid].players[_decks[deckid].nplayers++] = newPlayer;
432 }
433
434 // Get the list of players of a deck.
435 function getPlayersList(uint256 deckid) external view onlyPlayer(deckid)
436 returns (address[] memory) {
437 require(deckid < _ndecks, "Deck not found.");
438
439 uint32 np = _decks[deckid].nplayers;
440 address[] memory plist = new address[](np);
441
442 for (uint i= 0; i < np; i++)
443 plist[i] = _decks[deckid].players[i];
444
445 return plist;
446 }
447
448 // Check if an address is a registered player for a deck.
449 function isPlayer(uint256 deckid, address player) public view returns (bool) {
450 require(deckid < _ndecks, "Deck not found.");
451 address[] memory plist = _decks[deckid].players;
452 uint32 np = _decks[deckid].nplayers;
453
454 for (uint i= 0; i < np; i++)
455 if (plist[i] == player) return true;
456
457 return false;
458 }
459
460 // Function to update the deck/new player creation fee.
461 function updateFee(uint256 newFee) external onlyOwner {
462 _deckFee = newFee;
463 }
464
465 // Contract revenue collection function, both for the
466 // for the deck’s fee as well as for LINK remnants.
467 // Only the owner of the contract can redeem the remaining
468 // LINK from VRF number generation. This is
469 // an additional income for the contract creator.
470 function withdraw() external onlyOwner {
471 payable(owner()).transfer(address(this).balance);
472 }
473
474
475 }

This deck service is intended to serve 52-card Franch decks (cf. Fig. 7). It could easily be updated to
serve other types of decks by just redefining constant _N_CARDS to take a different value and defining a
new function uintToCard. For example, for Spanish desks we would define _N_CARDS=40 and provide
the function below:

1 // Función para convertir un número de carta en una carta, según el


2 // estándar de la baraja española de 40 cartas.
3 // Las cartas se ordenan normalmente en orden ascendente como sigue:
4 //
5 // Oros
6 // 1, 2, 3, 4, 5, 6, 7, 10 (Sota), 11 (Caballo), 12 (Rey).
7 //
8 // Copas:
9 // 1, 2, 3, 4, 5, 6, 7, 10 (Sota), 11 (Caballo), 12 (Rey).
10 //

59
Figure 7: Our deck generation service works with decks like this one (Author: Belbury, CC BY-SA 4.0).

11 // Espadas:
12 // 1, 2, 3, 4, 5, 6, 7, 10 (Sota), 11 (Caballo), 12 (Rey).
13 //
14 // Bastos:
15 // 1, 2, 3, 4, 5, 6, 7, 10 (Sota), 11 (Caballo), 12 (Rey).
16 //
17 function uintToCard(uint32 cardNumber) public pure returns (string memory) {
18 require(cardNumber >= 1 && cardNumber <= _N_CARDS,
19 "El valor de la carta tiene que estar entre 1 y 40.");
20
21 string[10] memory ranks = ["1", "2", "3", "4", "5", "6", "7",
22 "10", "11", "12"];
23 string[4] memory suits = ["Oros", "Copas", "Espadas", "Bastos"];
24
25 uint32 suitIndex = (cardNumber - 1) / 10;
26 uint32 rankIndex = (cardNumber - 1) % 10;
27
28 string memory card = string(abi.encodePacked(ranks[rankIndex],
29 " de ", suits[suitIndex]));
30
31 return card;
32 }

7.4 Oracle Networks and Cross-chain Oracles

An oracle network is a decentralized system that provides smart contracts on a blockchain with access
to external data sources and services. As discussed (cf. Sect. 5), smart contracts are self-executing
programs designed to execute automatically when certain conditions are met. Smart contracts are
typically limited to data and events that are available within the blockchain network itself. Oracle net-
works are decentralized networks, typically P2P, that provide smart contracts with access to external
data sources through oracles, such as price feeds, weather data and other off-chain information, act-
ing as intermediaries between the blockchain and the outside world. Oracle networks utilize a decen-
tralized architecture that ensures the security and reliability of the data that they provide. This means

60
that data obtained by the oracle network is validated and verified by multiple nodes in the network,
reducing the risk of fraudulent or inaccurate data.
The use of oracle networks allows smart contracts to interact with the real world in a secure and
reliable way, making them more powerful and versatile. In fact, there are already a significant number
of oracle networks associated with the most popular blockchain networks. For example, Chainlink is
a decentralized oracle network that offers an API to allows smart contracts to access off-chain data
and other resources. It is the most widely used oracle infrastructure on Ethereum and supports a wide
range of data sources and protocols. Band Protocol is another decentralized oracle network that al-
lows smart contracts to access off-chain data. It uses a delegated proof-of-stake (DPoS) consensus
mechanism and supports a range of data sources, such as cryptocurrency prices, weather data and
sports scores. Binance Smart Chain Oracle is an oracle network that provides secure and reliable ac-
cess to off-chain data for smart contracts on Binance Smart Chain. Other popular oracle networks
include TRON Oracle on the TRON network; Provable and Tellor for various blockchain platforms; Au-
gur as a decentralized prediction platform that uses oracles to solve and report event outcomes, such
as elections or sporting events; or MakerDAO and Uniswap in cryptocurrency markets.
Cross-chain oracles, also known as inter-chain oracles, are systems designed to provide informa-
tion and facilitate interoperability between different blockchains. In essence, in a fragmented context
with multiple blockchains where each operates independently of the others, these oracles allow these
blockchains to communicate with each other and share real-world data or information about specific
events, such as information about assets, contract statuses, events, etc.
Cross-chain oracles provide a layer of interoperability between blockchains, allowing one blockchain
to obtain and use information from another blockchain in a secure and reliable manner. This commu-
nication can be bidirectional, that is, information flows in both directions between blockchains, which
is essential for applications that require coordination among multiple blockchains and where security
and trust are critical. Cross-chain oracles must ensure that data transferred between blockchains is
accurate and not manipulated.
These oracles can be used, for example, for the secure transfer of digital assets between different
blockchains or to deploy interoperable smart contracts operating on different blockchains. To achieve
effective interoperability, specific bridging standards and protocols are often used to enable interop-
erability between blockchains, such as Polkadot or Cosmos.
Successful implementation of cross-chain oracles is essential for the development of broader, con-
nected blockchain ecosystems, allowing applications and digital assets to move seamlessly across
different blockchains in a secure and reliable manner.

7.5 Security Issues

While oracles play an important role in enabling decentralized applications to interact with real-world
data, they also introduce several security challenges and potential vulnerabilities. Oracles can be vul-
nerable to data manipulation, either through a compromised node or a malicious actor providing fake
data. This can result in inaccurate data being provided to a smart contract, leading to incorrect contract
execution. Centralized oracles can also become a single point of failure, meaning that if the oracle fails,
the entire blockchain application can be compromised. This can result in significant financial losses
or other negative consequences.
Oracles can be vulnerable to unauthorized access, either through a faulty node or through an in-
secure connection. This can result in sensitive data being exposed or manipulated by unauthorized
parties. Moreover, oracles can be used as an attack vector to exploit vulnerabilities in smart contracts.
For example, a malicious actor could use an oracle to provide false data that triggers an exploit in the
smart contract, allowing it to steal funds or execute unauthorized actions. Oracles can also be vulner-

61
able to network attacks such as distributed denial-of-service (DDoS), which can disrupt the oracle’s
ability to provide accurate data.
To mitigate these security issues, appropriate security measures have to be implemented when
working with oracles, such as multiple oracles for redundancy, using decentralized oracles, encrypting
data and connections, performing regular audits, and using secure authentication and authorization
mechanisms. It is also important to carefully consider the risks and potential vulnerabilities associated
with oracles when designing and implementing decentralized applications.
In other words, working with oracles in a blockchain requires following certain best practices to
ensure the reliability, security and integrity of the data fed to the smart contract. When selecting an
oracle provider, one with a proven track record of offering reliable and accurate data should be chosen.
It should also have transparent mechanisms in place to verify data authenticity and accuracy. For this,
it is also recommended to use multiple oracles that provide redundant data. This can help prevent any
single point of failure or manipulation by a single oracle. Error management and rollback mechanisms
should also be considered to handle situations where data is inaccurate or unavailable.
Decentralized oracles or oracle networks that rely on a network of independent nodes provide
greater security and tamper resistance than centralized oracles. Decentralized oracles also guarantee
a higher level of transparency and accountability, as data is verified by multiple independent sources.
To avoid manipulation and ensure data authenticity, it is recommended to use cryptographic meth-
ods such as digital signatures or hash functions to verify oracle’s data. In addition, regular audits of
oracles and smart contracts can help ensure data reliability and security. Audits can also help identify
any potential vulnerabilities or weaknesses in the oracle or smart contract.

8 Peer-to-peer File Systems

Peer-to-peer (P2P) file systems are distributed file systems that allow users to share files directly with
each other without relying on a centralized storage server. They are built on a P2P network (cf. Ap-
pendix E) where each user contributes a portion of their storage space and network bandwidth to the
system. Files are typically hosted on multiple nodes in the network. These storage systems use cryp-
tographic algorithms to protect and encrypt data, dispersion algorithms to maintain data integrity and
availability, consensus algorithms to ensure consistency among nodes, and decentralized authenti-
cation to verify users. As a result, a more robust and efficient storage solution than traditional file
systems is obtained, allowing data to be shared and accessed securely, quickly and reliably without
relying on a centralized provider.
Like the networks on which they are built, P2P file systems use a distributed hash table (DHT) to
index and locate files on the network. When a user wants to access a file, they can look it up in the
DHT and download it directly from the node that is currently hosting it.
P2P file systems have several advantages over traditional client-server file systems, due to its P2P
nature. They are more resilient to failures and can continue to operate even if some nodes in the
network go offline. They also provide faster download speeds, as files can be retrieved from multiple
sources simultaneously. In addition, P2P file systems are often more private and secure, as files are
not stored on a centralized server that could be vulnerable to attack. Some popular examples of P2P
file systems are BitTorrent, eDonkey and Gnutella. These systems are commonly used to share large
files, such as movies, music and software, but can also be used to share other types of data, such as
scientific datasets or backups.
In the next paragraphs we will briefly discuss the fundamentals and key principles of these file
systems, as well as their architecture and operation. We will focus on the IPFS (Interplanetary File
System) file system, a decentralized storage system that has become a benchmark for providing per-

62
sistent storage in the blockchain arena. First of all, we will briefly discuss the limitations of traditional
file systems in the blockchain context.

8.1 Limitations of Traditional File Systems

Traditional file systems have key differences from P2P file systems in terms of their architecture and
operation. In centralized systems, data is stored in a single location controlled by a service provider
(e.g., a set of servers or a cloud storage service), which implies dependence on that entity for manage-
ment and access to that data. These solutions are often proprietary and vulnerable to cyber-attacks
or loss of information due to human error or hardware failure. Conceptually, a traditional cloud stor-
age system is still a centralized file system, since the management of the stored information depends
exclusively on the cloud service provider.
Traditional file systems have several limitations in terms of security, accessibility and points of
failure compared to decentralized file systems. For example, in centralized file systems, access to
resources is managed through permissions and user groups. This system of permissions by user
type is vulnerable to impersonation or phishing attacks because, if unauthorized access to a user’s
credentials occurs, access is available to all information accessible to that user, which would allow
an attacker to delete, modify, encrypt, or store new unauthorized information. In contrast, decentral-
ized file systems have mechanisms in place to ensure the immutability of stored information and use
cryptographic techniques natively to protect and encrypt data, which drastically reduces the risk of
information theft or alteration.
In addition, traditional file systems are typically proprietary and centralized, meaning that a single
entity controls all access to stored data, usually the entity that operates the servers where the data
is stored or the cloud storage service. This can limit the ability of individual users to freely share or
collaborate on projects, especially if they are global organizations with geographically dispersed users.
On the other hand, decentralized file systems, due to the underlying P2P architecture, allow users to
share and access data while avoiding centralized control.
On the other hand, in traditional file systems there are several critical failure points that can catas-
trophically compromise the integrity of information, such as data loss due to human error, hardware
failure, or errors in the operating system or information management applications. In addition, these
systems are often prone to cyber-attacks and information theft due to security vulnerabilities. Decen-
tralized file systems drastically reduce the probability of data loss, since they are distributed among
the nodes of the P2P network.

8.2 Fundamentals of Decentralized File Systems

A decentralized file system is based on three fundamental principles: content addressing, decentral-
ization and fault tolerance. In a traditional file system we can locate a content from a file identifier
and the path to that file, while in decentralized systems we locate a content from a unique key that is
calculated from the content itself, so that two different contents cannot share the same key. When we
want to obtain a stored content, instead of indicating where it is located (i.e., path and file name) we
directly indicate what content we want to obtain.
Decentralization implies that data is chunked into small fragments that are stored in a distributed
manner among multiple nodes in the P2P network, reducing dependency on the centralized provider
and increasing resilience to points of failure. This distribution of data among nodes allows easy re-
covery of any lost or damaged fragments to reconstruct the original file. Fault tolerance is achieved
through dispersion and consensus algorithms that maintain coherence and consistency in a decen-

63
tralized network, avoiding conflict between different versions of the same file and preserving data
integrity.
These systems also often use encryption algorithms to protect and guarantee the security of
stored data, reducing the risk of information theft or alteration. Moreover, user authentication is per-
formed through decentralized protocols, such as public key cryptography or digital signatures, which
avoids relying on a centralized provider for user verification.
Ultimately, decentralized file systems, by relying on a P2P network where data is stored and dis-
tributed among multiple nodes, eliminate dependency on the centralized provider and improve their
robustness against points of failure, while supporting automatic and transparent replication to the user
to ensure content availability even if some nodes fail. Data distribution ensures that files are split into
small fragments for storage between nodes, allowing any lost or damaged fragments to be easily re-
covered to reconstruct the original file, and dispersion and consensus algorithms maintain coherence
and consistency in a decentralized network, avoiding conflicts between different versions of the same
file and preserving data integrity. In summary, a decentralized file system is a more secure, efficient
and resilient solution based on principles such as decentralization, data distribution and fault.

8.3 Architecture and Operation

A decentralized file system architecture is based on a set of nodes connected to a P2P network. These
nodes are divided into several types, depending on their role within the network, although a particular
node can assume several roles. For example, storage nodes provide physical storage to store frag-
ments of content or provide persistent storage; lookup nodes maintain copies of DHT tables to identify
the location of content from its identifiers; and routing nodes support the routing of content requests
and their delivery from storage nodes to users.
As indicated earlier, a fundamental characteristic of P2P storage systems is that stored information
is identified by its content and not by its location, as is the case in traditional storage systems. Content-
addressing is a process by which specific content stored on the network is located and accessed
rather than specific files, using the P2P protocol to find optimal routes for transferring data. The keys
to identify specific content are actually hash keys generated from the content of a file or block of data
to be stored, which are used to identify and verify the integrity of the data stored on the network, thus
avoiding potential problems such as data theft or improper alteration of the content.
In the event of data loss, decentralized algorithms will automatically identify and recover content
from existing copies in the network. Communication among nodes is done using unique hashes to
verify the integrity of the content before transferring it, which avoids potential problems such as data
theft or improper content alteration. In short, data replication and recovery are based on collaboration
among network nodes to ensure greater resilience to failures, security and fast access to previously
stored content. Moreover, decentralized algorithms do not allow changes to the content of a file once
it has been stored, ensuring immutability and integrity.

8.4 InterPlanetary File System

The Interplanetary File System (IPFS) is a protocol and network designed to create a peer-to-peer
method for storing and sharing hypermedia in a distributed file system. It was initially designed by
Juan Benet (Benet, 2014), and is now an open source project developed with the help of the community.
IPFS is designed to replace the traditional client-server architecture of the World Wide Web, creating
a distributed and decentralized file sharing solution. Instead of retrieving content from a single server,
IPFS retrieves content from a network of peers storing the same content. This creates a more robust
and censorship-resistant system, as content is not tied to a single point of failure. IPFS supports

64
any file type and allows fast access to content previously stored on the network, regardless of its
geographic location or the capacity of the local node. This system offers a decentralized and efficient
alternative to traditional centralized systems such as FTP, HTTP or SMB.
Instead of retrieving content from a single server, IPFS retrieves content from a network of peers
that store the same content. This creates a more robust and censorship-resistant system, as content
is not tied to a single point of failure.To do this, IPFS uses a unique addressing system, called content-
addressable storage (CAS). In IPFS, each piece of content is given a unique hash key that is used as
an address on the network. When a user requests a piece of content, IPFS looks for other nodes that
have the same content and retrieves it from them. This also means that if a piece of content is already
on the network, it will not be duplicated, which saves space and reduces bandwidth usage.
When a file is submitted to an IPFS node, the node stores a copy of the file in its local storage and
creates a hash key for the content, called the content identifier (CID), which represents the content of
the file. This hash key can be used to retrieve the file from any other IPFS node on the network. The
following code fragment illustrates the storage of a file on an IPFS node.

1 // Function storeIPFSFile takes two arguments: the address of the IPFS


2 // node (e.g. ’’) and the name of the file (e.g., ’example.txt’).
3 //
4 // The function creates an IPFS client instance using the
5 // node address passed as a parameter. It then uses the ipfs.add method
6 // to add the file to IPFS. The CID (identifying hash) of the
7 // stored file is displayed on the console if the operation succeeds.
8 //
9 // An example call would be:
10 //
11 // storeIPFSfile(’http://localhost:5001’, ’example.txt’);
12 //
13 // We use the ipfs-http-client module and the fs module to manage
14 // files. To install ipfs-http-client:
15 //
16 // npm install --save ipfs-http-client
17 //
18 const IPFSClient = require(’ipfs-http-client’);
19 const fs = require(’fs’);
20
21 async function storeIPFSFile(IPFSNodeAddress, file) {
22 // create an IPFS client instance. The constructor receives
23 // the URI of the node used.
24 const ipfs = IPFSClient(IPFSNodeAddress);
25
26 try {
27 // add file to IPFS
28 const result = await ipfs.add({
29 path: file,
30 content: fs.createReadStream(file)
31 });
32
33 // display CID obtained
34 console.log(’File stored at IPFS. CID: ${result.cid.toString()}’);
35 } catch (error) {
36 console.error(’Error when storing file: ${error}’);
37 }
38 }

The IPFS node also divides the file into smaller chunks, called blocks, and creates a Merkle directed
acyclic graph (DAG) that represents the structure of the file. Each block in the Merkle DAG is identified
by its own hash, and the hashes of the blocks are used to create the hash of the root of the graph,
which in turn is the file’s unique identifier or CID (cf. Appendix C). The IPFS node then transmits the file

65
CID to other nodes, allowing them to discover and retrieve the file when requested. The file is stored in
a distributed fashion on the IPFS network, which means that multiple copies of the file may be stored
on multiple nodes, thus increasing redundancy and fault tolerance. When a user requests a file by
its hash key (i.e., its CID), the IPFS client sends a request for the file to the IPFS network. The IPFS
network then uses the CID to locate a node that has a copy of the file and returns it to the user’s IPFS
client. The client then reassembles the file from the blocks returned by the network and presents it to
the user.
In short, submitting a file to an IPFS node creates a unique content identifier for the file and stores
it in a distributed fashion on the IPFS network, allowing it to be easily retrieved from any other node on
the network. However, in IPFS it is also possible to pin content, that is, to ensure that specific content,
usually a file or a set of files, is permanently or semi-permanently stored and available on a specific
IPFS network node. When a content is pinned, it means that the node retains a copy of that content,
preventing the IPFS garbage collector from deleting it. IPFS has a garbage collection mechanism to
reclaim storage space by removing content that is not used or referenced. Pinning content ensures
that it will not be sent to the trash, making it reliably and permanently accessible. Users can manually
pin and unpin content according to their preferences, and some IPFS nodes also support automatic
or dynamic pinning based on usage patterns or policies. Because pinning has associated storage
and bandwidth costs, some pinning services may charge a fee for providing such persistent storage
services.
IPFS is a powerful tool for Web3 development, as it facilitates the creation of a distributed and
decentralized web that is more resilient, faster and more secure than traditional client-server archi-
tectures. It has many potential uses, such as creating a more efficient and secure method of sharing
large files or even a censorship-resistant version of the Internet.

8.5 IPFS and Blockchain: Use Cases

Blockchains are primarily designed to handle fast and efficient transactions rather than store large vol-
umes of data persistently, so if they are used as file systems, processing capacity and performance will
decrease significantly. Consequently, storing large amounts of persistent information on a blockchain
is not considered a good practice due to the computational costs, decreased efficiency and scala-
bility issues involved. Instead, it is preferable to use decentralized systems such as IPFS, which are
specifically designed to store and manage large files in a decentralized, efficient and scalable manner.
Furthermore, because they are based on content-based addressing, it is possible to guarantee data
immutability if required.
As a consequence, IPFS and blockchain are often used together to create decentralized applica-
tions that leverage the strengths of both technologies. It can be used to store large amounts of data,
including immutable files, and provides a way to address this data using a unique hash key that can
be used to retrieve the data from any node on the network. Blockchain, meanwhile, enables the cre-
ation of a distributed ledger that can be used to store and verify data in a secure and immutable way.
By combining these technologies, developers can create decentralized applications capable of stor-
ing and sharing data in a secure and censorship-resistant manner. For example, a blockchain-based
Web3 social networking platform could use IPFS to store user-generated content, such as photos and
videos, while using the blockchain to verify the authenticity of content and provide a decentralized
method of verifying user identity.
Another use case is the creation of a decentralized file sharing platform of any type (e.g., images,
multimedia clips, computer applications, medical records, etc.), where IPFS can be used to store the
files, while the blockchain is used to manage transactions between users, ensuring full traceability of
these transactions, and in general all the properties associated with blockchain technology.

66
IPFS is often used in conjunction with NFT as a way to store the digital asset or metadata associ-
ated with it. By storing the asset or metadata in IPFS, the NFT becomes decentralized, immutable and
more secure. A common way to use IPFS with NFT is to store the metadata in IPFS and then create
an NFT that references the IPFS CID. In this way, anyone who owns that NFT can use its CID to retrieve
the underlying metadata from IPFS, and then retrieve the asset from the metadata, even if the original
creator of the NFT is no longer available. The digital asset may also be stored in IPFS. For example,
as pointed out in Sect. 5.4, a digital artist could create a unique work of art and store it in IPFS, along
with metadata about the work such as its title, artist’s name, and creation date. They could then create
an NFT that references the metadata’s CID, which in turn would include the artwork’s CID. This would
allow buyers to verify the authenticity and ownership of the artwork.
Filecoin is a decentralized storage network based on the IPFS protocol that offers storage services
and data access in the cloud without relying on a centralized provider. Filecoin has its own blockchain
to ensure the integrity, security and transparency of the process of storing and reimbursing resources
by the nodes participating in the network. On Filecoin, users can store files on the system using pay-
ment tokens (FIL) to compensate storage providers that offer space on their devices. These providers
are responsible for maintaining data availability and persistence, ensuring fast and secure access for
all users. The Filecoin network is efficient, resilient to failures and offers a decentralized alternative to
the centralized model of cloud storage services such as Amazon S3 or Google Cloud Storage. Thanks
to its open source foundation and globally dispersed community, Filecoin promotes universal data ac-
cess and the creation of decentralized applications for a variety of scenarios, from multimedia content
to digital property records.
Sia (Simplified Internet Access) is a decentralized cloud storage platform that uses blockchain and
smart contracts to create a marketplace for storage providers and users. Users can rent storage space
to network hosts using Siacoin (SC) as the native cryptocurrency.

8.6 Other Decentralized File Systems

In addition to IPFS and the decentralized storage systems discussed in the previous section, there
are several commercial initiatives to exploit the concept of decentralized storage, each with its own
business model and approach to distributed storage and data retrieval. Swarm, Storj and Maidsafe
would be among the most prominent commercial decentralized file systems.
Swarm is a decentralized content storage and distribution platform developed as part of the Ethereum
ecosystem. It enables decentralized website hosting and distributed file storage. Swarm is designed
to integrate with Ethereum, allowing it to manage content driven by Ethereum-based applications.
Storj is a decentralized storage system based on the IPFS protocol that seeks to provide an efficient
and secure solution for data storage, access and sharing. It uses a different approach to Filecoin, as
they do not require dedicated storage space providers; instead, any user with an Internet connection
can become a storage provider and receive rewards for doing so. Data is divided into blocks or shards
that are distributed among nodes in the network, ensuring greater resilience to failures and security
against cyber attacks or loss of information. Communication between users and storage providers is
encrypted to protect privacy and file content.
The Maidsafe Network aims to create a decentralized, autonomous Internet by combining a de-
centralized file storage system with a peer-to-peer communication network. It is designed to be self-
managing, self-healing and resistant to censorship.
These solutions offer a decentralized alternative to services such as Dropbox or Google Drive,
allowing fast and secure access to data previously stored on the network without relying on centralized
providers. Both have a community of users dedicated to developing decentralized tools and solutions
for a variety of scenarios, from web hosting to multimedia file sharing.

67
9 Blockchain as a Service

Blockchain as a Service (BaaS) is a cloud-based service that provides customers with a platform to de-
velop, deploy and manage their blockchain applications, without the need to set up and maintain their
own blockchain infrastructure. BaaS providers offer a pre-built blockchain environment that customers
can use to create, test and deploy their own decentralized applications, often through an easy-to-use
web interface.
BaaS providers typically offer a range of blockchain protocols to choose from, including permis-
sionless blockchains such as Ethereum or Bitcoin, as well as permissioned blockchains such as Hy-
perledger Fabric or R3 Corda. They also provide functions such as node management, consensus
algorithms, identity management and data storage, making it easier for customers to focus on devel-
oping their own dApps rather than spending resources and time on infrastructure management.
BaaS is becoming increasingly popular as it offers several benefits to companies and organiza-
tions looking to adopt blockchain technology and generally enter the Web 3.0. These benefits include
reduced costs, faster time to production, increased scalability and enhanced security. BaaS also al-
lows companies to experiment with blockchain technology before making significant investments in
their own blockchain infrastructure.
In a nutshell, BaaS is an attractive option for companies that want to take advantage of the bene-
fits of blockchain technology without having to make large investments in developing and managing
their own blockchain infrastructure. Among the most relevant players in the BaaS market is Microsoft
with its Azure platform. Microsoft Azure offers a range of blockchain solutions, including BaaS plat-
forms for Ethereum, Hyperledger Fabric and Corda. The platform offers a range of tools and services
for developers, making it easy to create, test and deploy blockchain applications. Amazon, with its
AWS platform, also offers a variety of blockchain services, including BaaS platforms for Ethereum
and Hyperledger Fabric. IBM offers its own range of blockchain solutions, including BaaS platforms
for Hyperledger Fabric and Corda, while Oracle offers a BaaS platform called Oracle Blockchain for
Hyperledger Fabric. SAP also joined this trend with SAP Blockchain for Hyperledger Fabric.
Other relevant players in the BaaS market are Huawei, Baidu, Alibaba Cloud and Tencent Cloud,
which offer their own BaaS platforms for various blockchains.

10 Conclusion

Blockchain technology, smart contracts and decentralized applications are rapidly transforming the
way in which people interact with each other, work, do business and even have fun. Blockchain tech-
nology offers a secure and transparent way to store and share data without the need for intermediaries,
while smart contracts allow complex business processes to be automated. dApps are also changing
the way in which applications and services are deployed, allowing individuals and entities to interact
with each other in a more decentralized and democratic way.
For many, the widespread use of decentralized applications and blockchain technology represents
the dawn of the third generation of the World Wide Web, called Web3 or Web 3.0. This new web is
characterized by being based on a set of technologies and protocols that allow the creation of de-
centralized applications that can run over blockchain networks. These applications are typically built
using smart contracts, which are self-executing computer programs that automate the exchange of
value and information among different parties.
In addition to smart contracts, Web3 also includes other technologies such as decentralized stor-
age, identity management and decentralized communication protocols such as P2P protocols. These

68
technologies enable the creation of decentralized applications that are more secure, transparent and
reliable than traditional centralized applications.
Web3 is considered by many to be the next evolution of the Internet, offering a new, more demo-
cratic, decentralized and open way of creating and interacting with applications. The goal of Web3
is to create a more transparent and equitable digital world, where users have more control over their
online data and interactions.
In any case, the technologies on which Web3 is based are still relatively new and, as discussed,
there are several risks associated with their use. Web3 applications are built on top of blockchain
networks, which are generally considered secure. However, the smart contracts that power these
applications may still be vulnerable to hacking or other security threats, which could result in the loss
of funds or other assets. Besides, decentralized Web3 applications can be complex and difficult to
build and maintain, which can increase the risk of vulnerabilities or code failures. Web3 applications
are still in the early stages of development and adoption, and there is a risk that they may not achieve
widespread use.
Furthermore, the regulatory landscape for Web3 applications is still evolving, and there is a risk
that regulations or laws may emerge that may restrict the use or development of these applications.
There are also concerns about the interoperability of the various, many times competing, approaches.
There are many different blockchain networks and protocols, which can make it difficult for Web3
applications to interact with each other.
While there are still many challenges to overcome, such as scalability, interoperability and regula-
tory uncertainty, the potential benefits of these technologies are clear. From reducing fraud and in-
creasing transparency to enabling new business models and empowering people, blockchain, smart
contracts and decentralized applications have the potential to revolutionize the way people live and
work.
As these technologies continue to evolve and mature, it is important for developers, businesses
and governments to stay informed and engaged with the latest developments. Working together, the
full potential of blockchain, smart contracts and decentralized applications can be unlocked to create
a more equitable, secure and decentralized future.

10.1 To Learn More

Due to the popularity that blockchain technology is reaching and the rapid advances in its development,
we can find in the literature a significant number of publications on the subject. Below we list some
of them that we consider relevant. These books provide a good introduction to blockchain technology
and its applications in various sectors, as well as a critical analysis of its advantages and limitations.
• Mastering Blockchain: Unlocking the Power of Cryptocurrencies, Smart Contracts, and Decentral-
ized Applications, by Lorne Lantz and Daniel Cawrey (2020), provides a comprehensive introduc-
tion to blockchain technology and its applications, covering topics such as Bitcoin, Ethereum,
smart contracts and decentralized applications.
• The Internet of Money, by Andreas M. Antonopoulos (2016), is a compilation of talks given by
the author on Bitcoin and blockchain technology. It provides an accessible introduction to the
subject and explores the possible implications of this technology on our financial systems.
• Blockchain Basics: A Non-Technical Introduction in 25 Steps, by Daniel Drescher (2017), provides a
non-technical introduction to blockchain technology, exploring the fundamentals of how it works
and its potential applications in various industries.
• Blockchain Revolution: How the Technology Behind Bitcoin is Changing Money, Business, and the
World, by Don Tapscott and Alex Tapscott (2018), explores the potential impact of blockchain
technology in various sectors, from finance to healthcare to public administration.

69
• The Truth Machine: The Blockchain and the Future of Everything, de Paul Vigna y Michael J. Casey
(2019), explores the potential implications of blockchain technology on various aspects of so-
ciety, such as finance, identity and governance, and provides a critical analysis of its potential
benefits and limitations.
Obviously, countless online tutorials on the subject are also at our disposal, with resources for
anyone to acquire a deeper understanding of blockchain technology and how to develop applications
using blockchain platforms. Among the most relevant and settled ones are:
• The Solidity Tutorials on the Ethereum Website. Ethereum is one of the most popular blockchain
platforms, and Solidity is the programming language used to write smart contracts on the Ethereum
network. The Solidity tutorials on the Ethereum website provide a step-by-step guide to learning
Solidity and developing smart contracts.
• IBM Blockchain 101. This IBM tutorial provides an introduction to blockchain technology, cover-
ing topics such as decentralized networks, smart contracts and consensus mechanisms. The
tutorial also includes a hands-on exercise that allows students to create a simple blockchain
network using Hyperledger Fabric.
• Coursera: Blockchain Basics. This course, offered by the University at Buffalo and State Univer-
sity of New York, provides an introduction to blockchain technology, covering topics such as the
history of blockchain, Bitcoin, Ethereum and smart contracts. The course includes video lectures
and hands-on programming exercises.
• Hyperledger Fabric Documentation. Hyperledger Fabric is a blockchain platform that is widely
used in enterprise applications. Hyperledger Fabric Documentation provides a comprehensive
guide for developers to learn how to implement and deploy blockchain applications using this
platform.
• ConsenSys Academy offers a series of online courses on blockchain technology, covering top-
ics such as Ethereum, Solidity and decentralized application development. The courses are
designed for both beginners and experienced developers, and include both video lectures and
hands-on exercises.

70
References
Abdelhady, Mohamed Ahmed (2019). Hands-On Smart Contract Development with Hyperledger Fabric.
Packt Publishing.
Adaś, Patryk (2021). Mastering Web3.js. Packt Publishing.
Aggarwal, Shubhani and Neeraj Kumar (2021). “Chapter Twenty - Attacks on blockchain”. In: The Blockchain
Technology for Secure and Smart Applications across Industry Verticals. Edited by Shubhani Aggar-
wal, Neeraj Kumar, and Pethuru Raj. Volume 121. Advances in Computers. Elsevier, pages 399–410.
DOI: https://doi.org/10.1016/bs.adcom.2020.08.020. URL: https://www.sciencedirect.
com/science/article/pii/S0065245820300759.
Antonopoulos, Andreas M. (2016). The Internet of Money. CreateSpace Independent Publishing Plat-
form.
Barger, Artem et al. (2021). “A Byzantine Fault-Tolerant Consensus Library for Hyperledger Fabric”.
In: 2021 IEEE International Conference on Blockchain and Cryptocurrency (ICBC), pages 1–9. DOI:
10.1109/ICBC51069.2021.9461099.
Benet, Juan (2014). “IPFS - Content Addressed, Versioned, P2P File System”. In: arXiv preprint arXiv:1407.3561.
Blaut, Gabriel, Xuyang Ma, and Katinka Wolter (2023). “Exploring Randomness in Blockchains”. In: 2023
IEEE International Conference on Blockchain and Cryptocurrency (ICBC), pages 1–5. DOI: 10.1109/
ICBC56567.2023.10174962.
Buterin, Vitalik (2014). Ethereum: A Next-Generation Smart Contract and Decentralized Application Plat-
form. ethereum.org.
Buterin, Vitalik and Nathan Schneider (2022). Proof of Stake: The Making of Ethereum and the Philoso-
phy of Blockchains. Seven Stories Press.
Carl, G. et al. (2006). “Denial-of-service attack-detection techniques”. In: IEEE Internet Computing 10.1,
pages 82–89. DOI: 10.1109/MIC.2006.5.
Castro, Miguel and Barbara Liskov (Nov. 2002). “Practical Byzantine Fault Tolerance and Proactive
Recovery”. In: ACM Trans. Comput. Syst. 20.4, pages 398–461. ISSN: 0734-2071. DOI: 10 . 1145 /
571637.571640. URL: https://doi.org/10.1145/571637.571640.
Chain, Binance (2020). Binance Smart Chain: A Parallel Binance Chain to Enable Smart Contracts. Bi-
nance Chain.
Chinnathambi, Kirupa (2018). Learning React: A Hands-On Guide to Building Web Applications Using
React and Redux. Addison-Wesley Professional.
Chittoda, J. (2019a). Mastering Blockchain Programming with Solidity: Write production-ready smart
contracts for Ethereum blockchain with Solidity. Packt Publishing. ISBN: 9781839218637. URL: https:
//books.google.es/books?id=wWOnDwAAQBAJ.
Chittoda, Jitendra (2019b). Mastering Blockchain Development with Solidity and Truffle. Packt Publish-
ing.
Deirmentzoglou, Evangelos, Georgios Papakyriakopoulos, and Constantinos Patsakis (2019). “A Sur-
vey on Long-Range Attacks for Proof of Stake Protocols”. In: IEEE Access 7, pages 28712–28725.
DOI: 10.1109/ACCESS.2019.2901858.
Delgado-von-Eitzen, Christian, Luis Anido-Rifón, and Manuel J. Fernández-Iglesias (2021a). “Applica-
tion of Blockchain in Education: GDPR-Compliant and Scalable Certification and Verification of
Academic Information”. In: Applied Sciences 11.10. ISSN: 2076-3417. DOI: 10.3390/app11104537.
URL: https://www.mdpi.com/2076-3417/11/10/4537.
— (2021b). “Blockchain Applications in Education: A Systematic Literature Review”. In: Applied Sci-
ences 11.24. ISSN: 2076-3417. DOI: 10.3390/app112411811. URL: https://www.mdpi.com/2076-
3417/11/24/11811.
Drescher, Daniel (2017). Blockchain Basics: A Non-Technical Introduction in 25 Steps. Apress.
FATF (2012-2023). International Standards on Combating Money Laundering and the Financing of Ter-
rorism & Proliferation. Paris, France: FATF.
Hoskinson, Charles (2017). Why we are Building Cardano. INPUT | OUTPUT.

71
Infante, Roberto (2021). Building Ethereum DApps: Decentralized Applications on the Ethereum Blockchain
with Solidity and Hardhat. Apress.
Islam, Nazrul et al. (2023). “Is BlockChain Mining Profitable in the Long Run?” In: IEEE Transactions on
Engineering Management 70.2, pages 386–399. DOI: 10.1109/TEM.2020.3045774.
Kalinin, Mikhail and Danny Ryan (2021). Supplant DIFFICULTY opcode with PREVRANDAO Expose bea-
con chain randomness in the EVM by supplanting DIFFICULTY opcode semantics. Ethereum Im-
provement Proposals EIP-4399. Ethereum.
Klabnik, Steve and Carol Nichols (2019). The Rust Programming Language. No Starch Press.
Lamport, Leslie, Robert Shostak, and Marshall Pease (July 1982). “The Byzantine Generals Problem”.
In: ACM Trans. Program. Lang. Syst. 4.3, pages 382–401. ISSN: 0164-0925. DOI: 10.1145/357172.
357176. URL: https://doi.org/10.1145/357172.357176.
Lantz, Lorne and Daniel Cawrey (2020). Mastering Blockchain: Unlocking the Power of Cryptocurrencies,
Smart Contracts, and Decentralized Applications. O’Reilly Media.
Ma, Guangkai, Chunpeng Ge, and Lu Zhou (2020). “Achieving reliable timestamp in the bitcoin plat-
form”. In: Peer-to-Peer Networking and Applications 13.6, pages 2251–2259. DOI: 10.1007/s12083-
020-00905-6.
Mahmoodi, Sina (2020). Vyper Smart Contract Programming. Packt Publishing.
Merkle, Ralph C. (1990). “A Certified Digital Signature”. In: Advances in Cryptology — CRYPTO’ 89 Pro-
ceedings. Edited by Gilles Brassard. New York, NY: Springer New York, pages 218–238. ISBN: 978-
0-387-34805-6.
Miller, Andrew (2019). “Permissioned and permissionless blockchains”. In: Blockchain for distributed
systems security. Edited by Sachin Shetty, Charles A. Kamhoua, and Laurent L. Njilla. IEEE Press,
pages 193–204.
Nakamoto, Satoshi (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. www.bitcoin.org.
Passaglia, Andrea (2017). Vue.js 2 Cookbook. Packt Publishing.
Schreiber, Flora Rheta (1973). Sybil: The Classic True Story of a Woman Possessed by Sixteen Separate
Personalities. Grand Central Publishing.
Schwarzmüller, Maximilian (2018). Material-UI: React components for faster and easier web develop-
ment. Packt Publishing Ltd.
— (2021). Angular 12: The Complete Guide. Packt Publishing.
Singh, Niharika (2020). Ganache: Personal Blockchain for Ethereum Development. Packt Publishing.
Snider, Myles, Kyle Samani, and Tushar Jain (2018). “Delegated Proof of Stake: Features and Tradeoffs”.
In: Multicoin Capital March 2, 2018.
Spurlock, Jake (2021). Bootstrap 5: Building Responsive Layouts with HTML and CSS. Packt Publishing.
Tapscott, Don and Alex Tapscott (2018). Blockchain Revolution: How the Technology Behind Bitcoin is
Changing Money, Business, and the World. Portfolio.
Towaha, Syed Omar Faruk (2019). Learn Ethereum DApp Development with Remix. Packt Publishing.
Vigna, Paul and Michael J. Casey (2019). The Truth Machine: The Blockchain and the Future of Every-
thing. Picador.
Wang, Wenbo et al. (2019). “A Survey on Consensus Mechanisms and Mining Strategy Management
in Blockchain Networks”. In: IEEE Access 7, pages 22328–22370. DOI: 10.1109/ACCESS.2019.
2896108.
Wood, Gavin (2016). Polkadot: Vision for a Heterogeneous Multi-chain Framework. Polkadot.
Yakovenko, Anatoly (2017). Solana: A new architecture for a high performance blockchain. Solana.
Yves-Christian, Adja Elloh et al. (2018). “Total Eclipse: How To Completely Isolate a Bitcoin Peer”. In:
2018 Third International Conference on Security of Smart Cities, Industrial Control System and Com-
munications (SSIC), pages 1–7. DOI: 10.1109/SSIC.2018.8556790.
Zilliqa Team (2019). Scilla: A Smart Contract Intermediate Level Language. Zilliqa Research Pte. Ltd.

72
Apéndices

A Public Key Cryptography

Public key cryptography, also known as asymmetric cryptography, is a cryptographic technique that
uses a pair of keys, one public and one private, to encrypt and decrypt data. The public key is used
to encrypt data, while the private key is used to decrypt data. The public key can be freely distributed,
while the owner keeps the private key secret. When a user wants to send encrypted data to another
person, they use the recipient’s public key to encrypt the data. The recipient then uses their private key
to decrypt it.
Public-key cryptography is considered more secure than symmetric cryptography, where the same
key is used for encryption and decryption, because even if the public key is intercepted, the data cannot
be decrypted without the private key.
Public key cryptography is used in a wide range of applications, such as secure communication,
digital signatures and secure access to websites and online services. It is a fundamental component of
many modern technologies, such as SSL/TLS, PGP and SSH. All common programming environments,
including those used to develop blockchain technology, have cryptographic libraries that among many
other functions provide elements for signing, encrypting and decrypting messages using public-class
cryptography. For example, the JavaScript code below illustrates the use of such a library.

1 // Example of encryption and decryption using


2 // public key cryptography (PKI).
3 //
4 // Use Node,js’s crypto module.
5 //
6 const crypto = require(’crypto’);
7
8 // Function for encrypting a message using a public key
9 function encrypt(message, publicKey) {
10
11 // create a buffer from the message to pass it
12 // to the crypto library’s encryption function.
13 const buffer = Buffer.from(message, ’utf8’);
14
15 // Encrypt the message. The publicEncrypt method encrypts
16 // a byte buffer with the public key passed as a
17 // parameter. It returns a buffer with the original content
18 // encrypted.
19 const encrypted = crypto.publicEncrypt(publicKey, buffer);
20
21 // Convert the buffer returned by the function into a
22 // string and return it
23 return encrypted.toString(’base64’);
24 }
25
26 // Function for decrypting a message using a public key
27 function decrypt(encryptedMessage, privateKey) {
28
29 // Create a buffer from the message to pass it
30 // to the crypto library’s decryption function.
31 const buffer = Buffer.from(encryptedMessage, ’base64’);
32

73
33 // Decrypt the message
34 const decrypted = crypto.privateDecrypt(privateKey, buffer);
35
36 // convert the buffer returned by the function into a
37 // string and return it
38 return decrypted.toString(’utf8’);
39 }

The following code segment illustrates the use of the above functions encrypt and decrypt.

1 // Usage example of the encrypt and decrypt functions defined


2 // previously.
3 //
4 // Generate a new public/private key pair with the
5 // crypto library.Use the RSA algorithm, with 2048-bit keys.
6 const { publicKey, privateKey } = crypto.generateKeyPairSync(’rsa’, {
7 modulusLength: 2048,
8 });
9
10 // Encrypt a message using the generated public key
11 const message = ’Este es mi mensaje secreto’;
12 const encryptedMessage = encrypt(message, publicKey);
13 console.log(‘Encrypted message: ${encryptedMessage}‘);
14
15 // Decrypts the encrypted message using the generated private key.
16 // The final message will be the same as the original one.
17 const decryptedMessage = decrypt(encryptedMessage, privateKey);
18 console.log(‘Decrypted message: ${decryptedMessage}‘);

Public key cryptography can also be used to sign digital content to ensure ownership and non-
repudiation. Basically, to sign a digital content, a hash key is calculated for it (cf. Appendix B) and that
key is encrypted with the private key. The result can be used as a signature, that is, as a guarantee
that the original content was signed by the owner of the private key. To verify this, a recipient of the
original document can calculate its hash key and decrypt the signature with the signer’s public key. If
both values match, we can ensure that the original document was signed by the owner of the private
key, since they are the only person who knows it.
The following example presents a JavaScript function to sign a file’s content.

1 // Example of a signature using


2 // public key cryptography (PKI). Definition of a signature function.
3 //
4 // We use Node.js’s crypto and fs modules
5 //
6 const fs = require(’fs’);
7 const crypto = require(’crypto’);
8
9 // The function takes two parameters: the reference to a file that
10 // stores the private key and the reference to the file that
11 // we want to sign. As a result, it returns the signature.
12 function signFileWithPKI(privateKeyPath, dataPath) {
13 // read private key from file
14 const privateKey = fs.readFileSync(privateKeyPath, ’utf8’);
15 // read content to be signed from file
16 const data = fs.readFileSync(dataPath, ’utf8’);
17
18 // Create a signature object using a SHA-256 hash.
19 const sign = crypto.createSign(’SHA256’);
20 // Add the data to be signed to the object.
21 sign.write(data);

74
22 // Close the object.
23 sign.end();
24
25 // Sign the object with the private key
26 // and return a base64-encoded record
27 const signature = sign.sign(privateKey, ’base64’);
28 return signature;
29 }

The code snippet below illustrates the process of signing a file and verifying that signature.

1 // Example of signing a file and checking


2 // the signature using PKI.
3 //
4 // We use Node.js’s crypto and fs modules
5 //
6 const fs = require(’fs’);
7 const crypto = require(’crypto’);
8
9 // Generate a public-private key pair suitable for signing
10 const { privateKey, publicKey } = crypto.generateKeyPairSync(’rsa’, {
11 modulusLength: 2048,
12 publicKeyEncoding: { type: ’spki’, format: ’pem’ },
13 privateKeyEncoding: { type: ’pkcs8’, format: ’pem’ },
14 });
15
16 // store the public and private keys in separate files
17 fs.writeFileSync(’private_key.pem’, privateKey);
18 fs.writeFileSync(’public_key.pem’, publicKey);
19
20 // call the signing function to sign a file
21 // named ’data.txt
22 const signature = signFileWithPKI(’private_key.pem’, ’data.txt’);
23
24 // verify the signature.
25 // We create a SHA-256 verification object (the same
26 // protocol used for the signature)
27 const verify = crypto.createVerify(’SHA256’);
28 // store file in object
29 verify.write(fs.readFileSync(’data.txt’, ’utf8’));
30 // and close.
31 verify.end();
32
33 // Use the public key to verify the signature.
34 // The encoding used is the same as the one used to encode
35 // the signature.
36 const isVerified = verify.verify(publicKey, signature, ’base64’);
37
38 // Display the verification outcome (true o false)
39 console.log(’Signature verified:’, isVerified);

B Hash Functions

A hash function is a mathematical function that takes input data of any size and produces output
of a fixed size called a hash key. The hash function generates a unique fingerprint of the input data,
which is typically a byte sequence. Hash functions are commonly used in cryptography to ensure data
integrity and security. By comparing the hash of the original data to the hash of the received data, it
can be determined whether the data was tampered with in transit.

75
Hash functions are designed to be one-way functions, which means that it is computationally in-
feasible to determine the original input data from the hashed output. This property of hash functions
makes them useful in many applications, such as digital signatures, password storage, and data val-
idation. Hash functions are also used in blockchain technology to create a secure and tamper-proof
transaction ledger. Each block in the blockchain contains a hash of the previous block, creating a
blockchain that cannot be altered without invalidating the entire chain.
Some common hash functions are SHA-256 and MD5, although the choice of a specific hash al-
gorithm depends on the actual application and the level of security required. The following JavaScript
code segment illustrates calculating a SHA-256 hash key using the Node.js Crypto module.

1 //
2 // Example of generating an SHA-256 hash of a
3 // character string
4 //
5 // Use Node.js’s crypto library.
6 //
7 const crypto = require(’crypto’);
8 //
9 // The sha256 function takes a text string as argument
10 // and returns the SHA-256 value of that string as a
11 // hexadecimal value.
12 //
13 // The function uses the built-in crypto module in Node.js,
14 // which provides a variety of cryptographic functions,
15 // including the SHA-256 hash function.
16 function sha256(text) {
17
18 // Create an instance of a SHA-256 hash object
19 const hash = crypto.createHash(’sha256’);
20
21 // Update the hash stored in the hash object
22 // with the string passed as parameter
23 hash.update(text);
24
25 // Return the value of the hash key (digest) stored
26 // in the object as a result.
27 return hash.digest(’hex’);
28 }

To compute a SHA-256 key for an image stored in a file, the following code snippet can be used:

1 const fs = require(’fs’);
2
3 const nomFichero = ’Imagen.png’;
4
5 // Read file
6 const fileContents = fs.readFileSync(nomFichero);
7
8 // Call our sha256 function
9 const sha256Value = sha256(fileContents);
10
11 console.log(‘SHA-256 hash key of file ${nomFichero} is: ${sha256Value}‘);

76
C Merkle Trees

A Merkle tree, also known as a hash tree, is a data structure used in computing and cryptography to
effectively verify the integrity of large data sets. It owes its name to its inventor, Ralph Merkle (Merkle,
1990).
A Merkle tree is a binary tree in which each non-leaf node is labeled with the hash of the labels
of its child nodes. Each leaf node in the tree represents a single piece of data, and the hash value of
each leaf node is computed using a cryptographic hash function, such as SHA-256. The tree is built
by recursively hashing pairs of child nodes until a single root hash is produced.
The root hash of a Merkle tree is also known as Merkle root and serves as a summary of the entire
data set. By comparing the Merkle root of a received data set to a previously agreed Merkle root, a
recipient can verify that the data set was not tampered with or modified. To do this, hashes of a subset
of leaf nodes and their corresponding parent nodes are requested from the sender, and these hashes
are used to verify the authenticity of the Merkle root.

Figure 8: Example of a Merkle tree of four transactions. The root of the tree is what would be stored in a block to validate
these transactions.

Merkle trees are commonly used in blockchain technology to effectively verify the integrity of the
transactions in a block. Using a Merkle tree, blockchain network nodes can quickly verify that a block
of transactions was not modified. Additionally, Merkle trees can help reduce the amount of data that
needs to be transmitted and stored on the blockchain, making it more efficient and scalable.
The following code snippet illustrates calculating a Merkle tree from a list of transactions.

1 //
2 // This script uses the Node.js’s builtin crypto module to compute
3 // SHA-256 hashes for each transaction. It then builds the
4 // Merkle tree from the bottom up by combining adjacent hashes and
5 // combining them until a single root hash is obtained. The function
6 // computeMerkleRoot() takes an array of transactions, represented as
7 // strings, and returns the hash of the root node of the Merkle tree.
8 //
9 // To test the script, we define an example transaction array.
10 // and call computeMerkleRoot() with them. The Merkle root hash
11 // is displayed on the console.
12 //
13 const crypto = require(’crypto’);
14

77
15 function computeMerkleRoot(transactions) {
16 // Maps each transaction string to its SHA-256 hash key
17 const transactionHashes = transactions.map((transaction) => {
18 return crypto.createHash(’sha256’).update(transaction).digest(’hex’);
19 });
20
21 // Build the Merkle tree from the bottom up
22 let level = transactionHashes;
23 while (level.length > 1) {
24 const nextLevel = [];
25 for (let i = 0; i < level.length; i += 2) {
26 const left = level[i];
27 const right = i + 1 < level.length ? level[i + 1] : ’’;
28 const combined =
29 crypto.createHash(’sha256’).update(left + right).digest(’hex’);
30 nextLevel.push(combined);
31 }
32 level = nextLevel;
33 }
34
35 // Returns the Merkle root
36 return level[0];
37 }
38
39 // Usage example
40 const transactions =
41 [’transaction 1’, ’transaction 2’, ’transaction 3’, ’transaction 4’];
42 const MerkleRoot = computeMerkleRoot(transactions);
43 console.log(’Merkle root:’, MerkleRoot);

A Merkle directed acyclic graph (DAG) is a more general data structure in which each node can
have multiple child nodes, which in turn represents the hash of its child nodes. The structure is directed
acyclic, which means that there are no cycles in the graph. Merkle DAG are used in IPFS to represent
the content address data structure used to store and retrieve data.
A key difference between the two structures is that Merkle trees are typically binary trees, where
each node has two child nodes, while Merkle DAG can have any number of child nodes. Also, Merkle
DAG are more flexible and can be used to represent more complex data structures than Merkle trees.
Besides, in a Merkle tree all the leaf nodes are at the same level and are usually arranged in a balanced
binary tree. In a Merkle DAG, leaf nodes can be at any level and the structure can be more complex.
In general, both Merkle trees and Merkle DAGs are data structures used to verify the integrity of
large data sets by creating a hash-based summary of the data. The choice between the two depends
on the specific use case and the complexity of the data structure being represented.

D Ethereum’s Proof-of-stake

Validators implement proof-of-stake in Ethereum according to the following steps:


1. Ether stake. Validators must stake at least 32 ETH to participate in the consensus process. This
Ether is locked into a deposit contract, and is used to incentivize validators to act honestly.
2. Block Proposal. Validators are randomly selected to propose new blocks to the network. A pro-
posed block contains a list of transactions that the validator has verified.
3. Block validation. Other validators verify the proposed block and vote on whether to accept it. If
more than 50% of the validators vote in favor, the block is added to the blockchain.
4. Reward payment. Validators are rewarded with Ether for proposing and validating blocks. They
are also penalized for proposing or validating invalid blocks.

78
This process repeats continuously, with new blocks being added to the blockchain every 12 sec-
onds (as of October 2023).
Validators are selected to propose blocks through a process called Randao (Random Number Au-
thority Oracle), which consists of a cryptographically secure process of random number generation
that ensures that all validators have an equal chance of being selected. Randao works by collecting
contributions from multiple participants who stake an amount of ether in a smart contract. Then,
these participants send hash values of their contributions and finally reveal the original information.
The aggregated hash value of all contributions is used to generate a random number. Each valida-
tor generates a random number using its secret key and then publishes a hash of that number. All
hashes are then combined to create a single value. Consequently, the Randao value thus computed is
characteristic of the validated block.
Randao is designed to be resistant to manipulation by individual validators. This is because even
if a small number of validators attempt to manipulate the Randao value, their efforts will be countered
by the random numbers generated by the other validators.
One of the key uses of the Randao number in Ethereum PoS is to randomly select validators who
are eligible to create new blocks. Randao is used to assign validators specific responsibilities, such as
proposing blocks or attesting to the validity of blocks. The randomization provided by Randao helps
ensure that validator selection is unpredictable and reduces the risk of collusion or centralization, as
well as fairness and security in the network.
In addition to selecting validators to propose and validate blocks, it is also used to generate block
rewards. The more Ether a validator staked, the more likely they are to be selected to propose and
validate blocks, and the greater their share of the block reward. When a validator proposes a block, it
also includes a signature to demonstrate that the validator staked the required amount of Ether and
verified the block. Other validators verify the proposed block by checking the signature and ensuring
that all transactions in the block are valid. Once a block was verified and accepted by the majority of
validators, it is added to the blockchain.
Validators are rewarded with Ether for proposing and validating blocks with an amount of Ether
proportional to the validator’s stake, and similarly validators are penalized if they propose or validate
invalid blocks, with a penalty proportional to the severity of the infraction. Randao is also used to
determine penalties, helping to ensure that penalty conditions are not predictable in advance.
This process takes place in a parallel chain to the main chain called the Beacon Chain. This chain is
responsible for implementing proof-of-stake consensus, coordinating validators, and improving scal-
ability and efficiency on the Ethereum blockchain, as the Beacon Chain is the basis for shard chains,
which will split the Ethereum network into smaller, more manageable blocks. The Beacon Chain was
launched in December 2020, and merged with the original Ethereum proof-of-work chain in September
2022.
Randao on Ethereum is an attempt to ensure randomness in an environment where transactions
and smart contract execution are deterministic and transparent. However, it is important to note that,
in some cases, the randomness of Randao could be compromised if the majority of participants act
maliciously. Therefore, it is always essential to consider security and implications when using Randao-
based random number generation systems in decentralized applications.

E Peer-to-peer Networks

A peer-to-peer (P2P) network is a decentralized network in which all participants have the same priv-
ileges and responsibilities. In a P2P network, each node (i.e., peer) in the network can act as both a
client and a server, and can communicate and exchange data directly with other nodes without the

79
need for intermediaries. In other words, there is no central authority or server that controls the net-
work, instead each node contributes to the functionality of the network by sharing its resources, such
as its computing power, storage capacity or bandwidth. This allows P2P networks to be more fault
tolerant, since they do not depend on a single point of failure and can continue to function even if some
nodes in the network fail or go offline.
Peer-to-peer networks typically implement some form of virtual network overlay on top of the In-
ternet topology, where the nodes in the overlay correspond to a subset of the nodes in the physical
network. Data is still exchanged directly over the underlying Internet, but at the application layer the
peers can communicate with each other directly, via logical overlay links, each of which corresponds
to a path through the underlying physical network. Overlay links are used for indexing and peer discov-
ery, and make the P2P system independent of the physical network topology. Based on how nodes
are linked to each other within the overlay network, and how resources are indexed and located, P2P
networks can be classified as unstructured or structured.
Unstructured P2P networks do not impose a particular structure on the overlay network, but in-
stead are made up of nodes that form random connections with each other. Since there is no globally
imposed structure, unstructured networks are easy to build and allow resources to be optimized lo-
cally in different regions of the overlay. Also, since the role of all peers in the network is the same,
unstructured networks are very robust when large numbers of peers join and leave the network fre-
quently.

Figure 9: Peer-to-peer (P2P) network. When a node joins the network, it establishes connections with some of the existing
nodes. The network protocol ensures that all participating nodes can share information with each other.

However, the main limitations of unstructured networks arise precisely from this lack of structure.
When a user wants to find a specific piece of information in the peer network, the search query must
be spread across the entire network to find as many peers as possible that share that information.
This causes a high amount of signaling traffic on the network, uses more computational resources
by requiring each peer to process all search queries, and does not guarantee that data will always be
retrieved. Besides, since there is no correlation between a peer and the content that that peer handles,
there is no guarantee that search dissemination will find a peer that has the desired data. Popular
content is likely to be available in multiple peers, and any peer that searches for it will eventually find
it, but if a user is looking for infrequent data, shared by only a few users, the search is highly unlikely
to be successful.
In structured peer-to-peer networks, the peer overlay is arranged in a specific topology, and the pro-
tocol ensures that any node can efficiently search for a certain file on the network, even if the resource
is extremely rare. The most common type of structured P2P networks implements a distributed hash
table in which each file or resource is assigned to a specific peer. This allows users to search for
resources on the network using such a table. In other words, the relation between peers and avail-

80
able resources is stored in a shared table, and any user on the P2P network can efficiently retrieve the
resource associated with a given peer.
However, to route traffic efficiently through the network, nodes in a structured overlay must main-
tain lists of neighbors that satisfy specific criteria. This makes them less robust in networks with a
high turnover rate, that is, with a large number of peers joining and leaving the network frequently.
P2P networks can be used for various applications, such as file sharing, messaging, or voice and
video calls. A popular example of a P2P network is BitTorrent, a file-sharing network in which users
share files directly with each other, rather than downloading them from a central server. P2P networks
also solve many problems faced by various sectors such as public entities, financial institutions, cap-
ital markets, insurance companies, supply chains, instant messaging, voice communication, media
transmission, collaboration, science and research, and high-performance computing, to name just a
few.
Lately, P2P networks experienced a resurgence beyond the sharing of multimedia resources with
the advent of blockchain-based cryptocurrencies. For example, the Bitcoin cryptocurrency is ultimately
a P2P network built on top of the Internet. It is managed and controlled by all peers that agree to par-
ticipate. All nodes are connected in a flat topology, which means that there is no hierarchy, centralized
services, or anything that implies a central authority thanks to the decentralized P2P model. A decen-
tralized network presents valuable aspects that were essential for the consolidation of cryptocurren-
cies. They are generally robust, free and open access technologies that anyone can adopt to develop
new content and applications. They are also secure and immutable, and are open and transparent
while providing anonymity.

81
82
Glossary
51% attack
A type of attack on a blockchain network where a single entity or group of entities controls more
than 50% of the network’s resources (e.g., computing power, nodes, cryptocurrency. . . ). With this
majority control, the attacker can potentially manipulate the network by preventing transaction
confirmations, double-spending coins, or rewriting the transaction history.

address
A unique identifier on a blockchain that represents the location of a wallet, NFT or smart contract.
altcoin
Any cryptocurrency other than Bitcoin.
application-specific integrated circuit (ASIC)
A specialized computer chip designed specifically for mining cryptocurrencies.

Bitcoin
The first and most well-known cryptocurrency, created in 2009. Its symbol is BTC.
block
A set of verified transactions added to the blockchain.
blockchain
A decentralized, distributed ledger technology that enables secure and transparent peer-to-peer
transactions.
byzantine fault tolerance (BFT)
A system’s ability to continue functioning even if some of its components fail or behave in un-
expected ways. Also, a consensus algorithm that is fault-tolerant and secure against a certain
number of Byzantine (i.e., malicious) nodes.
byzantine general
A term used to describe a scenario in which a group of generals must coordinate an attack, but
some of them may be traitors who will send false messages.

canonical block
The most recent block that all nodes in the network agree is the current valid block.
certificate authority
A trusted third party that issues and verifies digital certificates used for secure communication.
coin
A unit of cryptocurrency.
coinbase
The first transaction in a block that creates new cryptocurrency and rewards the miner who
solved the block.
cold storage
The practice of keeping cryptocurrency offline in a secure, offline environment to protect against
hacking or theft.
confirmation
The process of verifying a transaction on the blockchain to ensure it is valid and recorded on the
ledger.
consensus
The general agreement among all nodes on the blockchain about the state of the ledger and the
validity of transactions.

83
consortium
A group of organizations or individuals that come together to share resources and collaborate
on a blockchain network.
cryptocurrency
A digital or virtual currency that uses cryptography for security and operates independently of a
central bank.
cryptography
The practice of using mathematical algorithms and protocols to secure and verify transactions
on the blockchain.

decentralization
The principle of distributing control and authority over a blockchain network among many differ-
ent nodes, rather than relying on a central authority.
decentralized application (dApp)
An application that runs on a blockchain network and is not controlled by any central authority.
decentralized autonomous organization (DAO)
An organization that is run by computer code on a blockchain network, rather than by human
managers or leaders.
decentralized finance (DeFi)
The use of blockchain technology to create open, transparent, and accessible to everyone de-
centralized financial applications.
DeFi
Financial systems built on blockchain technology that operate in a decentralized manner without
traditional intermediaries.
delegated proof-of-stake (DPoS)
A consensus algorithm used in some blockchain networks, where token holders can vote to
select a set of delegates who are responsible for verifying transactions and adding new blocks
to the chain.
denial of service (DoS)
A type of attack in which an attacker floods a network or server with traffic, making it unavailable
for legitimate users.
depth
The number of blocks that were added to the blockchain after a particular transaction, used to
measure the level of transactions’ confirmation or security.
DEX
Decentralized exchange. An exchange platform that operates without a central entity and allows
users to trade directly with each other.
difficulty
A measure of how hard it is to mine a new block on the blockchain, determined by the total
computational power required. It is adjusted periodically to maintain a consistent rate of block
production.
digital signature
A mathematical scheme used to verify the authenticity and integrity of a message, transaction,
or document on the blockchain.
directed acyclic graph (DAG)
A data structure used in blockchain technology and decentralized filesystems to organize and
summarize sets of data.
distributed hash table (DHT)
A decentralized system for storing and retrieving key-value pairs. In a DHT, nodes are organized
in a P2P network, and each node is responsible for storing and serving a subset of the keys.
When a node needs to retrieve a value for a given key, it uses a hash function to determine which
node is responsible for that key and then sends a request to that node.

84
double spend
The act of trying to spend the same cryptocurrency more than once, which is prevented on the
blockchain through consensus and cryptographic protocols.

eclipse attack
A type of attack in which an attacker takes control of a victim’s connection to the network, allow-
ing them to manipulate the victim’s view of the network.
Ether
The native cryptocurrency of the Ethereum blockchain, used to pay for transaction fees and
smart contract execution. Its symbol is ETH.
Ethereum
A decentralized blockchain platform that enables the creation of smart contracts and decentral-
ized applications (dApps).
exchange
A platform where users can buy, sell, and trade cryptocurrencies with other users or with the
platform itself.

fork
A split in the blockchain network that creates two separate versions of the ledger. This may be
caused by race conditions in block creation, differences in consensus rules or protocol upgrades.
front-running attack
A type of attack in which an attacker has advanced knowledge of a pending transaction and can
manipulate the transactions’ order to their advantage.
full node
A type of node on the blockchain network that stores a complete copy of the ledger and partici-
pates in verifying and validating transactions.

gas
The unit of measurement used to calculate the cost of executing a transaction or smart contract
on the Ethereum blockchain.
gas price
The amount of Ether required to pay for each unit of gas used in a transaction or smart contract
execution on the Ethereum blockchain.
genesis block
The first block in the blockchain, created by the network’s founder(s) and containing a special
transaction that generates the initial supply of the cryptocurrency.
governance
Process by which token holders participate in decision making about protocol development and
changes.
graphic processing unit (GPU)
A specialized computer chip designed for efficient and high-speed processing of graphics and
other complex data, often used in cryptocurrency mining.

halving
A programmed reduction in the reward for mining a new block on the blockchain, which occurs
periodically to maintain a finite and deflationary supply of the cryptocurrency.
hard fork
A permanent split in the blockchain network that creates a new version of the ledger, often
caused by fundamental changes in consensus rules or protocol upgrades.
hash
A mathematical function that takes an input (data) and produces a fixed-size output (hash value
or key), used to uniquely identify data on the blockchain.

85
hash collision
A situation where two different inputs produce the same hash value, which is very rare and con-
sidered a security risk on the blockchain.
hash rate
The speed at which a miner can perform hash computations in the process of mining cryptocur-
rency on the blockchain.
height
The position of a block in the blockchain network, determined by the number of blocks that were
added to the blockchain since the genesis block.
hold
A strategy of holding onto a cryptocurrency for a long period of time, typically in the hopes of
realizing significant gains in value over time.
Hyperledger
An open-source blockchain platform hosted by the Linux Foundation, designed for enterprise
use and focused on privacy, scalability, and interoperability.

immutability
The property of the blockchain that once a transaction or data was added to the blockchain, it
cannot be modified or deleted, ensuring the integrity and authenticity of the ledger.
impermanent loss
The loss of value that liquidity providers may experience due to volatility in asset prices.
instantaneous lending
A type of DeFi loan that allows users to borrow and repay an amount of funds in a single trans-
action.
integer overflow
A condition that occurs when the result of an arithmetic operation exceeds the maximum size
that can be represented by an integer type.
integer underflow
A condition that occurs when the result of an arithmetic operation is smaller than the minimum
size that can be represented by an integer type.
integrated development environment (IDE)
A software application that provides comprehensive facilities to computer programmers for soft-
ware development.

ledger
A record-keeping system that tracks transactions and data on the blockchain, maintained by
nodes in the network.
light node
A type of node on the blockchain network that stores only a partial copy of the ledger, relying on
full nodes for transaction verification and validation.
liquidity
Ease with which a DeFi asset can be bought or sold in the market without significantly affecting
its price.
liquidity mining
In the DeFi context, refers to obtaining tokens by participating in protocols that distribute re-
wards.
long range attack
A type of attack in which an attacker gains control of the complete or a large portion of a
blockchain’s history, allowing them to rewrite transactions.

mainnet
The live and operational version of the blockchain network that is open to the public and used
for actual transactions and data storage.

86
Merkle directed acyclic graph (DAG)
A DAG used in IPFS in which each node is labeled with the hash of its data and the hash of its
children, forming a Merkle tree-like structure.
Merkle proof
A cryptographic proof that allows a node on the blockchain network to verify the inclusion of a
transaction or data in a block without having to download and validate the entire block.
Merkle root
The topmost hash in a Merkle tree, which summarizes all the transactions or data in a block and
is included in the block header.
Merkle tree
A data structure used in the blockchain to organize and summarize transactions or data in a
block, based on a series of hash computations.
MetaMask
A browser extension and mobile app that allows users to interact with decentralized applications
(dApps) on the Ethereum blockchain and other compatible networks. It also serves as a wallet
for those networks.
metaverse
A virtual universe or world, usually created and managed by a blockchain-based platform. The
metaverse is a shared virtual space where users can interact with each other, explore digital
environments, and engage in various activities such as gaming, socializing, and commerce. The
metaverse is often envisioned as an immersive and decentralized version of the internet, with
its own economy and governance systems.
miner
A participant in the blockchain network who uses computational power to validate transactions,
create new blocks, and earn rewards in the form of cryptocurrency.
mining
The process of using computational power to validate transactions, create new blocks, and earn
rewards in the form of cryptocurrency on the blockchain network.
mint
The process of creating new tokens, specially non-fungible tokens (NFT). The term is also used
to refer to the process of creating new units of a cryptocurrency.
multisignature
A type of digital signature that requires multiple parties to sign a transaction or authorize a trans-
fer of funds on the blockchain, used for security and risk management purposes.

network
The collection of nodes and participants connected to the blockchain, which together validate
transactions, maintain the ledger, and ensure the security and integrity of the network.
node
A participant in the blockchain network that validates transactions, maintains a copy of the
ledger, and communicates with other nodes to ensure the security and integrity of the network.
non-fungible token (NFT)
A type of digital asset on the blockchain that is unique and cannot be exchanged for other tokens
or assets on a one-to-one basis, often used for collectibles, gaming, and art.
nonce
An incremental or random number generated by a miner during the process of mining a block
on the blockchain, used to create a unique hash value that meets the difficulty target.

open source
A type of software that is freely available and can be modified and distributed by anyone, often
used for blockchain projects to foster collaboration and innovation.

87
oracle
A third-party service or mechanism that provides real-world data to the blockchain, often used
to facilitate smart contract execution and decision-making on the blockchain.

peer-to-peer (P2P)
A type of network architecture where nodes communicate and transact directly with each other,
without the need for intermediaries or central authorities, often used in blockchain networks.
permissioned
A type of blockchain network where access and participation are restricted to approved partici-
pants or entities, often used for enterprise and government applications.
permissionless
A type of blockchain network where access and participation are open to anyone, without the
need for approval or authentication, often used for public applications and decentralized finance.
practical byzantine fault tolerance (PBFT)
A consensus algorithm that allows a distributed network of nodes to agree on the state of a
system, even if some nodes fail or behave maliciously. A more efficient variation of byzantine
fault tolerance where nodes take turns to create and validate blocks.
proof-of-authority (PoA)
A consensus mechanism where validators are approved and authorized to validate transactions
based on their identity or reputation, often used in private or enterprise blockchains.
proof-of-coverage (PoC)
A consensus mechanism where validators prove that they have the necessary insurance cover-
age to back up their transactions or activities on the blockchain, used in insurance and financial
industries.
proof-of-importance (PoI)
A consensus mechanism where validators prove their importance and contribution to the net-
work based on their transaction history and other factors, used in the NEM blockchain.
proof-of-liquidity (PoL)
A consensus mechanism where validators prove their liquidity and ability to provide sufficient
funds or assets to the network, used in decentralized exchanges and liquidity pools.
proof-of-space-and-time (PoSaT)
A consensus mechanism where validators prove their commitment of disk space and time to
the network, used in the Chia blockchain.
proof-of-stake (PoS)
A consensus mechanism where validators prove their ownership or stake in the network’s cryp-
tocurrency to validate transactions and earn rewards, often in Ethereum 2.0 and other blockchains.
proof-of-weight (PoW)
A consensus mechanism where validators prove their reputation and importance in the network
based on their contribution and activity, used in the Algorand blockchain.
proof-of-work (PoW)
A consensus mechanism where validators prove their computational work by solving complex
mathematical problems to validate transactions and earn rewards, used in Bitcoin and other
early blockchains.
public key
A cryptographic key used to encrypt data and verify digital signatures on the blockchain, often
associated with a specific wallet or address.
public key infrastructure (PKI)
A system that uses private and public keys to secure and authenticate transactions and data on
the blockchain, often used for digital identity and access management.

88
re-entry attack
A type of attack in which an attacker exploits a smart contract that makes multiple calls to other
contracts, allowing them to execute their own code multiple times and drain the contract’s funds.
replay protection
A mechanism to prevent malicious actors from replaying or duplicating valid transactions on the
blockchain, often used in hard forks and network upgrades.
reward
The incentive or compensation earned by validators for their contribution to the network, often
in the form of cryptocurrency or tokens.
rollback
The reversal of one or more blocks in the chain. This can happen due to a software bug, a
network attack, or other unexpected events that cause a divergence between the actual state of
the blockchain and what the majority of nodes believe to be true. Rollbacks can have serious
implications for the integrity and reliability of the blockchain.

scalability
The ability of the blockchain network to handle increasing transaction volume and user adoption
without compromising performance or security. A key challenge for blockchain developers.
secure hash algorithm (SHA)
A cryptographic algorithm used to generate unique hash values and ensure the integrity and
authenticity of data on the blockchain.
security token
A type of crypto token that represents an asset, such as shares in a company, and is subject to
securities regulations.
smart contract
Self-executing code that automatically enforces the terms of a contract between parties on a
blockchain network.
Solidity
A programming language used to write smart contracts on the Ethereum blockchain.
stablecoin
Stable token. A type of cryptocurrency that is designed to maintain a stable value against a fiat
currency or other asset (e.g., Euro or US dollar).
state machine
A mathematical model used to describe the behavior of a system, such as a blockchain network.
Sybil attack
A type of attack in which an attacker creates multiple fake identities in a network in order to gain
control over it.

tamper evident
A property of a system that makes it clear when an attempt was made to modify or tamper with
it.
tamperproof
A property of a system that prevents unauthorized modification or tampering.
Tangle
A distributed ledger technology used by the IOTA network that uses a Directed Acyclic Graph
(DAG) instead of a blockchain.
testnet
A blockchain network used for testing and development purposes, separate from the main blockchain
network.
token
A unit of value that is created and managed on a blockchain network.

89
tokenization
The process of converting a physical or digital asset into a token on a blockchain network.
transaction
A transfer of value between two parties on a blockchain network.
transaction fee
A fee paid by the sender of a transaction to incentivize network participants to process and
validate the transaction.
transaction pool
A collection of unconfirmed transactions waiting to be processed and added to a blockchain
network.
trustless
A property of a blockchain network that allows parties to transact with each other without relying
on trust in a central authority or intermediary.

virtual machine
A software environment that emulates a computer system and allows for the execution of smart
contracts on a blockchain network.

wallet
A software application that allows users to store, manage, and transfer crypto tokens on a
blockchain network.
web3
Short for web 3.0, web3 refers to the next generation of the internet, which is envisioned as a de-
centralized and distributed network of applications and services that use blockchain technology
and other decentralized protocols.
wei
The smallest unit of Ether (ETH), the cryptocurrency used on the Ethereum blockchain. 1 Ether
is equal to 1018 wei. This unit is used to represent very small amounts of Ether. For example, if
the gas price for a transaction is 20 gwei, it means that the cost of executing that transaction is
20 × 106 wei or 0.00000002 ETH.

yield farming
Liquidity mining. A strategy that involves providing liquidity to DeFi protocols in exchange for
rewards, such as tokens or interest.

90

View publication stats

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy