diff --git a/404.html b/404.html index 5141ad4..048f0cf 100644 --- a/404.html +++ b/404.html @@ -4,13 +4,13 @@ Page Not Found | Blockchain Protocols and Distributed Applications - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/Assignments/assignment1/index.html b/Assignments/assignment1/index.html index dafe76c..4eb4312 100644 --- a/Assignments/assignment1/index.html +++ b/Assignments/assignment1/index.html @@ -4,13 +4,13 @@ assignment1 | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Assignments/assignment2/index.html b/Assignments/assignment2/index.html index dd04652..ef4bdcd 100644 --- a/Assignments/assignment2/index.html +++ b/Assignments/assignment2/index.html @@ -4,13 +4,13 @@ assignment2 | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Assignments/index.html b/Assignments/index.html index 214e467..40cbba6 100644 --- a/Assignments/index.html +++ b/Assignments/index.html @@ -4,13 +4,13 @@ Assignments | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Assignments/project/index.html b/Assignments/project/index.html index a77694b..779340c 100644 --- a/Assignments/project/index.html +++ b/Assignments/project/index.html @@ -4,7 +4,7 @@ Semester Project | Blockchain Protocols and Distributed Applications - + @@ -15,7 +15,7 @@ Deadline: Wednesday, 17 January 2024, 11:59 PM

List of ideas

You can choose one of the idea below or you can create one of your own.

Infrastructure & Developers Tooling

Idea nameDescription
Cross chain Bridgebuild a cross-chain bridge that enables the secure and seamless transfer of assets between different blockchain networks, enhancing interoperability and expanding the utility of blockchain ecosystems.
Wallet as a servicecreate a solution so that companies can seamlessly integrate wallet functionalities directly into their applications, simplifying user onboarding to the ease of a username and password. Whether facilitating in-game asset trading for gamers or pioneering innovative token-based loyalty programs, WaaS represents a potent resource for enterprises seeking to unlock the full potential of the web3 ecosystem.
Data analyticscreate data analytics tools and platforms tailored for blockchain and DeFI data, offering insights, visualization, and predictive analytics to empower developers and users.
Decentralized storage solutiondesign a decentralized storage solution that leverages blockchain technology for secure and distributed data storage, catering to the needs of decentralized applications and services.
Gas profiling tooldeveloping a gas profiling tool that helps Multiversx developers optimize gas usage in their smart contracts, reducing transaction costs and enhancing overall efficiency.
Digital identity solutioncreate a decentralized digital identity solution that allows users to manage and control their identities securely, offering privacy and data ownership in the digital realm.
Smart contract simulatorbuild a smart contract simulator that enables developers to test and analyze the behavior of their smart contracts in various scenarios before deploying them on the blockchain, enhancing code reliability.
EVM compatible sharddevelop an Ethereum Virtual Machine (EVM)-compatible shard
Blockchains for everybodyNot everybody owns a smart phone or a laptop. How can they interact with the blockchain?

Mobile Apps

Idea nameDescription
Multi-chain WalletDevelop a cross chain user-friendly mobile wallet app that allows users to store, manage, and transact with cryptocurrencies securely. The app should also support decentralized applications (DApps) and DeFi services.
Tokenized Digital Collectiblescreate a mobile app that specializes in collecting, trading, and showcasing blockchain-based digital collectibles and NFTs. Users would be able to explore, discover, and interact with a wide range of digital art, assets, and unique collectibles, all securely stored on the blockchain. The app would offer features such as buying, selling, and trading NFTs, creating an engaging platform for collectors and enthusiasts to connect and showcase their prized digital possessions.
Fitness companionutilizes blockchain for secure data storage, tokenized rewards, and decentralized fitness challenges, creating a motivating and privacy-focused ecosystem for users to achieve their fitness goals. Users can also make seamless cryptocurrency payments to fitness professionals and collect fitness-related NFTs to celebrate their accomplishments within the community.
NFT Ticket mastermobile app that disrupts traditional ticketing by using blockchain and NFTs. It empowers event organizers to issue verifiable and tradable NFT-based tickets, enhancing security and ownership, while attendees enjoy the convenience of secure mobile ticketing and a resale marketplace for tickets.
Quest Mastermobile app that lets groups of three or more users create and join challenges, with each participant contributing tokens to a prize pool. To claim the prize, all participants must reach a consensus that a task has been successfully completed, creating a fun and interactive way to collaborate and compete while using blockchain for transparency and rewards
Tokenized Real Estate Investment PlatformAn app that democratizes real estate investment by allowing users to invest in fractional ownership of properties using blockchain tokens. Users can buy, sell, and trade real estate tokens, making property investment more accessible.
Crypto Savings and Investment AppA user-friendly mobile app that simplifies cryptocurrency savings and investments. It could offer features like automated recurring investments, yield farming, and tracking portfolios, all while utilizing blockchain for transparency and security.
Blockchain-Backed Supply Chain TrackerAn app that allows consumers to trace the journey of products from the source to their hands. Users can scan QR codes to access information about the product's origin, quality, and authenticity, all recorded on the blockchain.
Blockchain-Powered Voting AppA mobile app for secure and transparent voting in elections, referendums, or decision-making processes. Blockchain technology ensures the integrity of votes and provides accessible and verifiable election results.
Blockchain-Powered Voting AppAn app that connects freelancers and clients on a blockchain platform. Smart contracts ensure secure and automatic payment upon project completion, and reputation systems build trust within the freelance community.

Artificial Intelligence

Idea nameDescription
Smart IDE'sIDE that incorporates advanced AI capabilities to enhance the coding experience. This intelligent IDE provides real-time code assistance, predictive suggestions, bug detection, code optimization, and even supports real-time collaboration, significantly improving developer productivity and code quality. It's a powerful tool that leverages AI to make coding more efficient, intuitive, and collaborative.
AI-Powered documentationThe IDE generates documentation and comments based on code, making it easier to maintain and understand codebases.
Security AnalysisAI algorithms continuously analyze code for potential vulnerabilities and provide security recommendations.
Code GenerationThe IDE can generate boilerplate code, common functions, and even entire code segments based on high-level descriptions or user requirements, speeding up the development process.
Generative AI in gamesintegrate advanced AI algorithms that dynamically generate game content, such as levels, characters, and narratives. This innovation creates ever-changing and immersive gaming experiences, providing players with endless challenges and adventures, all driven by the power of AI.
AI agents interactionsa product where AI-powered agents autonomously handle and optimize various types of blockchain transactions, including transfers of assets, smart contract executions, and consensus participation. These AI agents enhance the efficiency, security, and reliability of blockchain interactions, enabling a new and innovative way to study blockchains interactions and why not testing principles.
Chain behavior predictionsBuild an AI-driven platform that predicts the behavior of various blockchain networks based on historical data and current trends. Users can leverage these predictions to make informed decisions when participating in cross-chain transactions or asset swaps.
3D Generated worldsThe integration of blockchain technology ensures secure ownership of digital assets, including virtual land, creatures, and resources, empowering users to explore, interact, trade, and collaborate within this vibrant and blockchain-enhanced 3D universe.

Payments

Idea nameDescription
MicropaymentsExplore groundbreaking solutions that leverage blockchain technology to enable microtransactions. You will delve into the possibilities of frictionless, low-cost micropayments for various use cases, such as content monetization, pay-as-you-go services, and micro-donations
Scheduled paymentsDevelop blockchain-based solutions that enable automated and scheduled transactions. You will explore innovative ways to leverage blockchain technology for seamless and secure scheduled payments, benefiting a wide range of applications, from recurring bills and salary payments to subscription services.
Fund raising platformsDesign blockchain-powered fundraising platforms that redefine how funds are raised, tracked, and allocated for various causes. By leveraging blockchain's transparency and security, you can create efficient, decentralized solutions that enhance the fundraising process and foster trust among donors and fundraisers, ultimately driving social impact and positive change
Cross-Chain paymentsThis idea aims to bridge the gap between different blockchain networks, allowing users to seamlessly transfer and transact digital assets across multiple blockchains. This idea seeks to simplify the process of conducting cross-chain transactions, enhancing interoperability and accessibility in the blockchain ecosystem. It holds the potential to revolutionize the way we move and use cryptocurrencies and tokens across various blockchain platforms, ultimately making blockchain technology more versatile and user-friendly.
No-Code solution for grandmas and grandpasThis idea challenges you to create a no-code blockchain interaction solution that is so user-friendly it can be effortlessly used by individuals of all ages and backgrounds. The primary focus is to streamline the onboarding process for merchants, enabling them to accept MVX tokens with ease through features like simplified wallet setup, integrated point-of-sale systems, and user-friendly interfaces. By fostering inclusivity and accessibility, you can envision a future where blockchain technology is as accessible as everyday mobile devices, revolutionizing the way we engage with digital assets.
Fast pay solutionsThis idea challenges you to revolutionize digital payments by seamlessly integrating QR code scanning with blockchain technology, offering innovative solutions that prioritize user-friendliness and security. This track empowers you to shape the future of financial transactions, bridging the gap between traditional payment methods and the decentralized world of blockchain, ultimately enhancing accessibility and usability for users worldwide.
Payments for all tokensWhat if you have USDC and the merchants accepts only BUSD? Come up with a solution without the need to go through the additional step of converting their tokens on a swapping platform before finalizing their payment for the intended purchase.
NFT Payments solutionsExplore ways to integrate non-fungible tokens (NFTs) into payment systems. You should devise a payment solution that incorporates NFTs for unique, valuable, or collectible transactions.
Programmable money"Although money itself isn't inherently programmable, its full potential can be unlocked through automation and purpose-built tools. This presents an opportunity to create open-source, fee-free, and publicly accessible programs that can harness the power of money and on-chain tokens more effectively.

For example: Facilitating the seamless processing of invoices within a smart contract filled with funds. Person A submits an invoice, and person B can sign an approval transaction to release the funds to the appropriate recipient." | | Loyalty and Rewards Programs | Create a blockchain-based loyalty and rewards program that allows businesses to issue and manage loyalty points or tokens on a blockchain. You should focus on enhancing customer engagement and retention. |

Gaming and Metaverse

Idea nameDescription
Blockchain Gaming EconomyDescription: Develop a comprehensive blockchain-based gaming economy that integrates cryptocurrencies, non-fungible tokens (NFTs), and decentralized exchanges. This challenge involves designing in-game assets, marketplaces, and economic systems that empower players to buy, sell, and trade virtual items and currency securely on the blockchain.
Decentralized Game DevelopmentDescription: Create a decentralized game development platform that allows game creators to collaborate transparently while utilizing blockchain technology for asset ownership and revenue sharing. This challenge encourages teams to design tools and frameworks that foster a community-driven approach to game creation.
Blockchain-Based Game VerificationDescription: Build a system or tool that verifies the authenticity of in-game assets by utilizing blockchain technology. This verification system should ensure that assets, such as characters, weapons, or collectibles, are legitimate and cannot be tampered with, enhancing player trust and security.
In-game advertising platformDescription: Construct an innovative in-game advertising platform that seamlessly integrates advertisements into gaming experiences. This platform should offer targeted and non-disruptive advertising solutions that benefit both advertisers and players while ensuring transparency and fair compensation for developers.
Generative AI in a gameDescription: Integrate generative artificial intelligence (AI) techniques into a game to dynamically generate content such as levels, quests, or narratives. You should leverage AI algorithms to create engaging and ever-evolving gaming experiences that adapt to player behavior.
Generative AI in trailers/videos/tutorialsDescription: Utilize generative AI to automate the creation of game trailers, promotional videos, or tutorial content. This challenge encourages You to develop AI systems that can efficiently generate high-quality multimedia content for games and user guidance purposes.
Game PluginsDescription: Design and develop a set of plugins or extensions for existing game engines or platforms. These plugins should enhance game development workflows, improve performance, or add new features, making it easier for developers to create games across various genres.
Sample gamesDescription: Create sample games that serve as templates or starting points for aspiring game developers. These games should cover different genres and showcase best practices in game design, coding, and user experience.
Game templatesDescription: Develop a library of game templates that provide pre-designed frameworks for specific game types or mechanics. These templates should include customizable assets, code templates, and documentation, enabling developers to kickstart their game projects more efficiently.
- + \ No newline at end of file diff --git a/Lectures/Introduction/index.html b/Lectures/Introduction/index.html index f9312d4..fa43271 100644 --- a/Lectures/Introduction/index.html +++ b/Lectures/Introduction/index.html @@ -4,13 +4,13 @@ Introduction | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Lectures/index.html b/Lectures/index.html index 86a2572..398f1d4 100644 --- a/Lectures/index.html +++ b/Lectures/index.html @@ -4,13 +4,13 @@ Lectures | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html index 1d42d96..d40124b 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/basic_wallet/index.html @@ -4,14 +4,14 @@ Basic Wallet | Blockchain Protocols and Distributed Applications - +
Skip to main content

Basic Wallet

To create a public key with which we can display our financial gain in the internet we need first to generate a private key using an algorithm, the private key will generate the public key and…from now on we can apply a hash on it and remove some character from behind and add 0x in front to know that this is a public address.

/function to create a public and private key
func CreateKeyPair() (crypto.PrivKey, crypto.PubKey, error) {
// Create a private and public key pair
priv, pub, err := crypto.GenerateKeyPair(crypto.RSA, 2048)
if err != nil {
return nil, nil, err
}

return priv, pub, nil
}

func CreatePairPublicPrivateKey() ([]byte, []byte) {

//create a private and public key
priv, pub, err := CreateKeyPair()
if err != nil {
panic(err)
}

//convert private key to bytes
privBytes, err := crypto.MarshalPrivateKey(priv)
if err != nil {
panic(err)
}

//convert public key to bytes
pubBytes, err := crypto.MarshalPublicKey(pub)
if err != nil {
panic(err)
}

//list of bytes to string
privString := hex.EncodeToString(privBytes)
pubString := hex.EncodeToString(pubBytes)

//create a wallet variable
wallet := types.Wallet{
PrivateKey: []byte(privString),
PublicKey: []byte(pubString),
}
//convert wallet to bytes marshal
walletBytes, _ := json.Marshal(wallet)

//put wallet in the db
fileop.PutInDB("db/usr", []byte("wallet1"), walletBytes)

return []byte(pubString), []byte(privString)

}

For generating privateKey and publicKey we will use RSA because is very common and is easy to understand then we store the data into a wallet struct and the struct will be stored on our local storage.

So well we will mine a block we will get the first transaction from coinbase

{"BlockNumber":0,
"Time":1668970059,
"Hash":"06c6836e73c1676d58f938fd17a91224b50e5de97623dcc80c4f48d6eb96e052",
"Inputs":[{"Txid":0,"Value":1,"Signature":"","PubKey":"coinbase"}],
"Outputs":[{"Txid":0,"Value":1,"PubKeyHash":"0x2432\n","Signature":""}]
}

Every input and output transactions will be signed, so this will be saw by everyone from the blockchain, we will cache this on our wallet because we will be easy when we want to create a transaction.

In bitcoin there isn’t the idea of a balance like having 200 bitcoin, when you send a transaction you also send how you get that money.(we can see how the money where spent.

Our wallet when is creating transaction 3 will say the input from transaction1 and transaction2 and the the outputs like in the json above.

Here is an example of a real bitcoin transaction. Also you signed with your private key what you send to the other peers.


{
"txid": "1b3cb78e7d6cad2cc2050e6dccc2bd5845e98f598062d19fbda8e0a3b5b4b0e6",
"hash": "9d046215268a1d8031c6b4835a68c9c8c6984b576dc82ec37f859e636ec6e660",
"version": 1,
"size": 368,
"vsize": 341,
"weight": 1364,
"locktime": 1064830807,
"vin": [
{
"coinbase": "039ea80b2cfabe6d6df2adbfb95872a2c4bf41bd0af61255f06bc31f0aa11d1c2b11fe673f0a94af3e10000000f09f909f092f4632506f6f6c2f73000000000000000000000000000000000000000000000000000000000000000000000005001d000000",
"txinwitness": [
"0000000000000000000000000000000000000000000000000000000000000000"
],
"sequence": 0
}
],
"vout": [
{
"value": 6.28864092,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 c825a1ecf2a6830c4401620c3a16f1995057c2ab OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914c825a1ecf2a6830c4401620c3a16f1995057c2ab88ac",
"address": "1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY",
"type": "pubkeyhash"
}
},
{
"value": 0,
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN aa21a9ed7c2862196195aa9d4d8b947653d3548ffe4c111d5669a6ec2c96f12f91672884",
"hex": "6a24aa21a9ed7c2862196195aa9d4d8b947653d3548ffe4c111d5669a6ec2c96f12f91672884",
"type": "nulldata"
}
},
{
"value": 0,
"n": 2,
"scriptPubKey": {
"asm": "OP_RETURN 48617468cd302e8d060f04304c01afa1fd1a73a8538f6eee545aa1c0a97e54fa4db86856",
"hex": "6a2448617468cd302e8d060f04304c01afa1fd1a73a8538f6eee545aa1c0a97e54fa4db86856",
"type": "nulldata"
}
},
{
"value": 0,
"n": 3,
"scriptPubKey": {
"asm": "OP_RETURN 52534b424c4f434b3a8350e01a86adc281c624fc5e9e1ba740ac5c1a38c0413a51b5ab342800498b80",
"hex": "6a4c2952534b424c4f434b3a8350e01a86adc281c624fc5e9e1ba740ac5c1a38c0413a51b5ab342800498b80",
"type": "nulldata"
}
}
]
}

This is our code for the signing of the transactions.

func SingUsingKey(privateKey []byte, publicKey []byte, data []byte) []byte {
if GetPrivateKeyAndValidatePublicKey(publicKey) {
//decode private key
privKeyBytes, _ := hex.DecodeString(string(privateKey))
//unmarshal private key
privKey, err := crypto.UnmarshalPrivateKey(privKeyBytes)
if err != nil {
log.Printf("Error unmarshalling private key: %s", err)
return nil
}

//sign data
signature, err := privKey.Sign(data)
if err != nil {
log.Printf("Error signing data: %s", err)
return nil
}

return signature

} else {
fmt.Println("Public key does not match private key")
return nil
}

}

func VerifySign(signature []byte, publicKey []byte, data []byte) bool {

pubKey, err := crypto.UnmarshalPublicKey(publicKey)
if err != nil {
log.Printf("Error unmarshalling public key: %s", err)
return false
}

//verify signature
verify, err := pubKey.Verify(data, signature)
if err != nil {
return false
}

return verify
}

- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html index b243ae3..d506a4a 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/discovery_node/index.html @@ -4,7 +4,7 @@ What is a discovery node? | Blockchain Protocols and Distributed Applications - + @@ -13,7 +13,7 @@

Bootstrap Nodes: These are well-known nodes that act as initial points of contact for new nodes entering the network. New nodes can connect to these bootstrap nodes to discover other peers in the network.

DHT (Distributed Hash Table): Libp2p uses a DHT to store and retrieve information about peers in a decentralized manner. Nodes in the network can query the DHT to discover the addresses of other peers.

The role of a discovery node is to participate in one or more of these mechanisms, helping peers find each other and establish connections in a decentralized way. This is crucial for the robustness and scalability of decentralized systems, as it enables nodes to adapt to changes in the network's topology dynamically.

- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html index 247119a..da1950d 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/index.html @@ -4,13 +4,13 @@ Basic Peer-to-Peer Blockchain | Blockchain Protocols and Distributed Applications - +
Skip to main content

Basic Peer-to-Peer Blockchain

- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html index b849493..b7ec469 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/mining/index.html @@ -4,13 +4,13 @@ Mining a block | Blockchain Protocols and Distributed Applications - +
Skip to main content

Mining a block

In this tutorial we will use the most simple and basic way to mine a block.We will use proof of work.

sha256("0xs2rgi3p4jfbt43hrjweafwefwff"+0)="t09q3pfoewjaiougt80u9ropijdd"
sha256("0dnoirihp32u823u42o324rwfadsq"+1)="981r03q2ipfout8403qrp2ojiht"
sha256("8q349pjrofioh83409prjfdsfaeoi"+2)="802394qrpjiu58u93q4ropjohir"
sha256("9q0fwei0923rupi0u439rp034u9rr"+3)="fo9432ropeif43092oekr3op32r"
sha256("9r01fhewogr9u3jfeopijot0q49ru"+4)="f43epkfoij5t43pwelmfijwerk3"
sha256("t4280fhpibtqgh0w9pitq4ghgpit4"+5)="p9340ropjiot80932orit43jt09"
----------------------------------------------------------------------
//after a lot of iteration we will get to a hash that looks like this
----------------------------------------------------------------------
sha256("t4280fhpibtqgh0w9pitq4ghgpit4"+123)="000p9340ropjiot80932orit43jt09"
//we have some zeros in the front(we chose the number of zeros
//so this hash is valid

 Nonce is the solution to our problem

Proof of work is a computational method employed to arrive at a valid solution by repeatedly hashing data until a hash with a specific number of leading zeros is obtained. Achieving multiple leading zeros in a hash is a challenging and low-probability task.

Alt text

The idea that is present in the code above can expand more, what if we link the transactions with the block? — we concatenate all the content together and apply a hash function on all of them so we will get to a specific number of zeros and that block becomes valid.

In the bottom image we see what is our end goal…so the blocks need to be linked together ( to create a blockchain ). From the bottom image we see that the blocks are linked by the prev hash. And all the transaction are put in a Merkle tree then the root node is added to blockchain.

Alt text

This is the structure of a block.

//block struct
type Block struct {
//is the index of the block ex:0 ,1,2,3
Index int `json:"index"`
//time of the block when is mined
Timestamp int64 `json:"timestamp"`
//list of transaction, we will get here later
Tx [][]byte `json:"tx"`
//merkle root a byte of the merkle transaction tree
MerkleRoot []byte `json:merkle`
//hash of the prevblock
PrevHash string `json:"prevHash"`
//current hash of this block
Hash string `json:"hash"`
//nonce the number that we try to guess when we mine a block
Nonce int `json:"nonce"`
//this is the reward per block
Reward int `json:"reward"`
//this is the current coinbase of the network we grow as the network grows
Coinbase int `json:"coinbase"`
//the miner how mined the block
Miner string `json:"miner"`
}

func ProofOfWork(address string) types.Block {
getLastBlockKey := fileop.GetLastKey("db/blocks/blockchain")
if len(getLastBlockKey) == 0 {
if getLastBlockKey == nil {
//fmt.Println("Genesis:", string(getLastBlockKey))
//create genesis block
return CreateGenesisBlock(address)
}
}
newBlock := CreateBlock()
//get private and public key
_, privateKey := cryptogeneration.GetPublicPrivateKeys()
//create list of transaction
var tx []merkletree.Content
//get all transaction in levelDB
transaction := fileop.GetAllKeys("db/mempool/valide")
if len(transaction) != 0 {
//unmarshall transaction
for _, v := range transaction {
data := fileop.GetFromDB("db/mempool/valide", v)
transactionDB := types.Transaction{}
json.Unmarshal(data, &transactionDB)
transactionDB.BlockNumber = newBlock.Index
//add to list of transaction
tx = append(tx, transactionDB)
}
}

tx = append(tx, CreateTransaction(privateKey, address, nil, 100, 0, 0))

//create merkle tree
merkleTree, _ := merkle.BuildTree(tx)
listOfTransaction, RootNode := merkle.ExportLeafs(merkleTree)

newBlock.Tx = listOfTransaction
newBlock.MerkleRoot = RootNode
//reconstruct merkle tree from string
//merkleTree, _ := merkle.ReconstructTree(newBlock.Tx)
//get merkle tree from string

iterator := 0
for {
newBlock.Nonce = iterator
storeHash := CalculateHash(newBlock)
if storeHash[:2] == "00" {
//fmt.Println("Hash:", storeHash)
newBlock.Hash = storeHash
//clear db//mempool/valide
fileop.EraseAllKeys("db/mempool/valide")
//fmt.Println("proof_of_work_func:", newBlock)
return newBlock
break
}
iterator += 1
}

return types.Block{}
}

Well now we have this block mined so how we will send to other peers(because a blockchain is decentralized( not always)) ?

Up we speak about the channel that we will open to listen to data transfered in the network so… we will have a function that will send that to all the peers that we have stored in our local database.

func SendToAllPeers(node host.Host, data []byte, type_to_send int) {
//read from db all keys
number := fileop.GetNumberOfKeys("db/peers")
if number == 0 {
fmt.Println()
} else {

//get all keys from db/peers
//here we read all the data from the peers table and
//we send the block to every one of this peer
keys := fileop.GetAllKeys("db/peers")
fmt.Println("=================")
//for each key send message
for i := 0; i < len(keys); i++ {
fmt.Println(string(keys[i]))
}
fmt.Println("================")
//for each key convert to string
for i := 0; i < number; i++ {
peer_addres := string(keys[i])
//remove \n from string
//we need \n to read the characters to know where the row of data will end
peer_addres = peer_addres[:len(peer_addres)-1]
fmt.Println("Sending to peer: ", peer_addres)
if type_to_send == 0 {
//send to blocks channel
OpenConnectionMine(peer_addres, node, data)
} else if type_to_send == 1 {
//send to transaction channel
OpenConnectionTransaction(peer_addres, node, data)
}
}
}
}

Here is the the openConnectionMine function:


func OpenConnectionMine(peer_addres string, node host.Host, data []byte) {
//here we will get the address
addr, err := multiaddr.NewMultiaddr(peer_addres)
if err != nil {
println("Error: address format wrong1")
return
}
peer, err := peerstore.AddrInfoFromP2pAddr(addr)
if err != nil {
println("Error: address format wrong2")
return
}

if err := node.Connect(context.Background(), *peer); err != nil {
println("Error: connection failed")
return
}
//we send a block in this section that was mined
//we open a stream to that peer
stream, err := node.NewStream(context.Background(), peer.ID, "/mine/1.0.0")
if err != nil {
//print err
log.Fatal(err)
println("Error: stream creation failed")
return
}
fmt.Print("Sending message...")

//send string to stream
_, err = stream.Write(data)

if err != nil {
println("Error: message sending failed")
return
}
}
- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html index b276a72..48b79f2 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/p2p_network/index.html @@ -4,13 +4,13 @@ Peer to peer network | Blockchain Protocols and Distributed Applications - +
Skip to main content

Peer to peer network

For this part we will use libp2p was used by the guys that build IPFS and Filecoin.

First we need to spawn a p2p node

func RunSourceNode() {
// start a libp2p node that listens on a random local TCP port,
// but without running the built-in ping protocol
node := CreateNode("/ip4/127.0.0.1/tcp/0")

// configure our own ping protocol
pingService := &ping.PingService{Host: node}
node.SetStreamHandler(ping.ID, pingService.PingHandler)

// print the node's PeerInfo in multiaddr format
peerInfo := peerstore.AddrInfo{
ID: node.ID(),
Addrs: node.Addrs(),
}
addrs, err := peerstore.AddrInfoToP2pAddrs(&peerInfo)
if err != nil {
panic(err)
}
fmt.Println("libp2p node address:", addrs[0])
//we need paralel interaction for this
go LogicNodeInteraction(node)

for {
//here will be our local terminal to interact with the blockchain
terminalview.TerminalView(node)
}

}

Here we spawn a basic peer to peer Node now we need a way to interact with the node and some logic to be able to communicate with the other blockchains.

Syncronise peers inside the network

So we have LogicNodeInteraction which will run in parallel with the terminal.

func LogicNodeInteraction(node host.Host) {
//Set stream handler for the "/hello/1.0.0" protocol
go node.SetStreamHandler("/transaction/1.0.0", func(s network.Stream) {
log.Printf("/transaction/1.0.0 stream created")
err := ReadTransactionProtocol(s)
if err != nil {
s.Reset()
} else {
s.Close()
}
})

go node.SetStreamHandler("/mine/1.0.0", func(s network.Stream) {
log.Printf("/mine/1.0.0 stream created")
err := ReadMineProtocol(s)
if err != nil {
log.Printf("Error: %s", err)
s.Reset()
} else {
log.Printf("Closing stream")
s.Close()
}
})

go node.SetStreamHandler("/messages/1.0.0", func(s network.Stream) {
log.Printf("/messages/1.0.0 stream created")
err := ReadMessagesProtocol(s)
if err != nil {
log.Printf("Error: %s", err)
s.Reset()
} else {
log.Printf("Closing stream")
s.Close()
}
})

}

Here we spawn 3 channels to listen for other peers(they need to send messages on one of this channels)

So what are they doing?

This will be out channel of communication between our nodes.

"/transaction/1.0.0" - is responsible for transaction, here is the way our transaction will be send

”/mine/1.0.0" — is responsible for the blocks that are mined, they will come from other nodes to this one ( here will come blocks that are valid and invalid form the other peers)

”/messages/1.0.0" — here will come diffrent messages about the network(transaction that are not valid…etc) (we will not enter into this)```
- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html index f635130..0e4b2b2 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/sources/index.html @@ -4,7 +4,7 @@ Sources | Blockchain Protocols and Distributed Applications - + @@ -13,7 +13,7 @@ https://github.com/kyuupichan/bitcoin-0.01
https://bitcoin.org/bitcoin.pdf
https://learnmeabitcoin.com/

- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html index cc87f39..a50db2c 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/terminal/index.html @@ -4,13 +4,13 @@ The terminal | Blockchain Protocols and Distributed Applications - +
Skip to main content

The terminal

This terminal will be a way to interact with other nodes.l(“complete code will be available on github”)

func TerminalView(node host.Host) {
//print a menu with 8 options
//1. Create a new wallet
//2. View your wallet
//3. Send coins
//4. View your transactions
//5. Mine
//6. Options
//7. Exit

theEntireMenu()

//read data from keyboard
reader := bufio.NewReader(os.Stdin)
fmt.Print(">")
text, _ := reader.ReadString('\n')
fmt.Println(text)
//remove \n from text
text = text[:len(text)-1]
//verify the input
switch text {
case "1":
createWallet()
case "2":
viewWallet()
case "3":
sendCoins(node)
case "4":
viewTransactions()
case "5":
mine(node)
case "6":
options()
case "7":
exit()
case "8":
addPeers(node)
}

}

func theEntireMenu() {
fmt.Println("+--------------------+")
fmt.Println("|1.)Create new wallet|")
fmt.Println("+--------------------+")
fmt.Println("|2.)View your wallet |")
fmt.Println("+--------------------+")
fmt.Println("|3).Send coins |")
fmt.Println("+--------------------+")
fmt.Println("|4.)View transactions|")
fmt.Println("+--------------------+")
fmt.Println("|5.)Mine |")
fmt.Println("+--------------------+")
fmt.Println("|6.)Options |")
fmt.Println("+--------------------+")
fmt.Println("|7.)Exit |")
fmt.Println("+--------------------+")
fmt.Println("|8.)Add peers |")
fmt.Println("+--------------------+")
}

How will look:

Alt text

At the top of the terminal, you'll find our P2P address. This address makes it easy to share with other nodes for sending requests.

- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html index c023809..293a76f 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/transactions/index.html @@ -4,13 +4,13 @@ Transactions | Blockchain Protocols and Distributed Applications - +
Skip to main content

Transactions

So we have a wallet we know how a transaction looks lets send a transaction to another address in the blockchain.

First we need to know the address where we want to send the coins.

This is the format of a transaction.


//transaction struct
type Transaction struct {
BlockNumber int
Time int64
Hash string
Inputs []TxInput
Outputs []TxOutput
}

type TxInput struct {
Txid int64
Value int64
Signature string
PubKey string
}

type TxOutput struct {
Txid int64
Value int64
PubKeyHash string
Signature string
}

After we send the transaction from our node, the data will be sent across the network to all the nodes, now the nodes will start to validate the transaction(what means to validate the transaction? — first to check that input money are valid by verify the signature of the one that send money to the person that is sending towards you.

If a transaction is invalid the node will not send the transaction further in the network and will send a message to the node that send the invalid transaction that the transaction is invalid.

But if the transaction is valid will be send further to the other nodes and stored in a mempool until…a node will chose to mine a block and to add the transaction into the blockchain.

- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html index 7ffea53..654112d 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/what_we_build/index.html @@ -4,13 +4,13 @@ What we will build? | Blockchain Protocols and Distributed Applications - +
Skip to main content

What we will build?

  • Peer to peer network
  • Syncronise peers inside the network
  • Mine a block and send it to the other peers
  • Have a basic wallet and add money to it when we mine a block
  • Send transactions and approve them into blockchain

You can git clone the repo from here.

- + \ No newline at end of file diff --git a/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html b/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html index 862eec5..8d5a7b2 100644 --- a/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html +++ b/Practical Sessions/Basic Peer-to-Peer Blockchain/why_golang/index.html @@ -4,13 +4,13 @@ Why golang? | Blockchain Protocols and Distributed Applications - +
Skip to main content

Why golang?

Golang is an excellent choice for building a blockchain due to its readability and widespread use in the field. Its popularity stems from the simplicity of its syntax and the prevalence of libraries commonly employed in blockchain development.

One of Golang's standout features is its speed, a crucial factor when dealing with the intricate operations of a blockchain. This language's efficiency ensures that the blockchain can handle tasks swiftly and responsively.

Moreover, Golang provides the libp2p library, a valuable tool for simplifying the creation of a peer-to-peer network. This library streamlines the process of connecting nodes in a decentralized system, making it easier for developers to establish and maintain a robust network.

Golang's support for parallelism is another asset. Using the 'go' keyword before a function enables easy implementation of parallel and asynchronous operations. This feature enhances the performance of the blockchain by allowing it to execute multiple tasks simultaneously, contributing to a more efficient and responsive system.

  • You can go and install golang from here
  • You can install libp2p from here
- + \ No newline at end of file diff --git a/Practical Sessions/Env Setup/index.html b/Practical Sessions/Env Setup/index.html index ad0d814..4fdc893 100644 --- a/Practical Sessions/Env Setup/index.html +++ b/Practical Sessions/Env Setup/index.html @@ -4,13 +4,13 @@ Env Setup | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Env Setup/setup/index.html b/Practical Sessions/Env Setup/setup/index.html index d0807c8..c613fd7 100644 --- a/Practical Sessions/Env Setup/setup/index.html +++ b/Practical Sessions/Env Setup/setup/index.html @@ -4,7 +4,7 @@ Setting up your environment | Blockchain Protocols and Distributed Applications - + @@ -14,7 +14,7 @@ If you've installed rustup in the past, you can update your installation by running rustup update.

For more informantion, please check rustup documentation.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Configuring the PATH environment variable

In the Rust development environment, all tools are installed to the ~/.cargo/bin directory, and this is where you will find the Rust toolchain, including rustc, cargo, and rustup.

During installation rustup will attempt to configure the PATH. Because of differences between platforms, command shells, and bugs in rustup, the modifications to PATH may not take effect until the console is restarted, or the user is logged out, or it may not succeed at all.

Please make sure you have included ~/.cargo/bin directory in your PATH environment variable.

Please verify that rustup was succesffully install with rustup --version.

Uninstall Rust

If at any point you would like to uninstall Rust, you can run rustup self uninstall.

MultiversX prerequisites

mxpy

Mxpy is a tool for interaction with the blockchain:

----------------------
COMMAND GROUPS summary
----------------------
contract Build, deploy, upgrade and interact with Smart Contracts
tx Create and broadcast Transactions
validator Stake, UnStake, UnBond, Unjail and other actions useful for Validators
account Get Account data (nonce, balance) from the Network
ledger Get Ledger App addresses and version
wallet Create wallet, derive secret key from mnemonic, bech32 address helpers etc.
deps Manage dependencies or multiversx-sdk modules
config Configure multiversx-sdk (default values etc.)
localnet Set up, start and control localnets
data Data manipulation omnitool
staking-provider Staking provider omnitool
dns Operations related to the Domain Name Service

Before installing mxpy, please make sure you have a working Python 3 environment. You'll need Python 3.8 or later on Linux or MacOS.

The recommended way to install mxpy is by using pipx. If you'd like to use mxpy on Windows, we recommend installing it within the Windows Subsystem for Linux (WSL).

In order to install mxpy using pipx, run the following command:

pipx install multiversx-sdk-cli --force

To check that mxpy installed successfully you can run the following command:

mxpy --version

wasm32-unknown-unknown

This is WebAssembly target which uses 32-bit memories. It is used to compile MultiversX smart contracts to WebAssembly.

To add it, please use:

rustup target add wasm32-unknown-unknown

sc-meta

This tool is used to compile smart contracts.

To install it, run:

cargo install multiversx-sc-meta --locked

To verify that it's correctly installed, run:

sc-meta --version

Ethereum prerequisites

MetaMask

MetaMask is a web browser extension and mobile app that allows you to manage your Ethereum private keys. By doing so, it serves as a wallet for Ether and other tokens, and allows you to interact with decentralized applications, or dapps.

Please visit this to install MetaMask as a browser extension (Safari is not supported) or as a mobile app.

Hardhat

Hardhat is a development environment for Ethereum software. It consists of different components for editing, compiling, debugging and deploying your smart contracts and dApps, all of which work together to create a complete development environment.

To install Hardhat, use:

npm install --save-dev hardhat

To verify that hardhat is install, run:

$ npx hardhat
888 888 888 888 888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888

👷 Welcome to Hardhat v2.22.12 👷‍

? What do you want to do? …
Create a JavaScript project
Create a TypeScript project
Create a TypeScript project (with Viem)
Create an empty hardhat.config.js
❯ Quit

For the ones that prefer, there is a Hardhat for Visual Studio Code.

- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Block Leader/leader/index.html b/Practical Sessions/Explorer/Block Leader/leader/index.html index 2fdd851..8d0a251 100644 --- a/Practical Sessions/Explorer/Block Leader/leader/index.html +++ b/Practical Sessions/Explorer/Block Leader/leader/index.html @@ -4,7 +4,7 @@ Blockchain Leader | Blockchain Protocols and Distributed Applications - + @@ -12,7 +12,7 @@
Skip to main content

Blockchain Leader

We will continue with the same block from the previous section (Block Height: 16826695).

Leader

We can observe that the Leader (also called the proposer) is Istari Vision. The leader, also known as the block producer or validator, is responsible for performing several critical tasks within a consensus round:

  1. Block Proposal: The leader is tasked with proposing a new block containing a set of transactions. This block proposal is the first step in the process of reaching consensus. The leader selects transactions to include in the proposed block and creates a cryptographic hash of the block's contents.

  2. Signature and Verification: After proposing a block, the leader signs it with their private key to prove its authenticity. Other network participants can verify the leader's signature using their public key. This verification ensures that the proposed block is indeed from the authorized leader.

  3. Broadcasting the Proposal: Once the block is signed, the leader broadcasts it to the network. Other nodes in the network receive and validate the proposed block to ensure its compliance with the consensus rules.

  4. Agreement and Confirmation: If the proposed block meets the consensus criteria, it is accepted by the network. The leader's proposed block becomes part of the blockchain, and consensus is achieved for that round.

Let's see some details about this proposer:

Istari Vision

We can see his public key, version of the software for the blockchain node and other information we will further discuss.

Practice

  • Open 3 different blocks in 3 different tabs. Observe that every time there is another leader. Why do you think the system is designed this way?
  • Open 3 different blocks in 3 different tabs on Ethereum Explorer. Observe that every time there is another leader.
- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Blockchain Observers/observers/index.html b/Practical Sessions/Explorer/Blockchain Observers/observers/index.html index 1a082ff..f48fb06 100644 --- a/Practical Sessions/Explorer/Blockchain Observers/observers/index.html +++ b/Practical Sessions/Explorer/Blockchain Observers/observers/index.html @@ -4,14 +4,14 @@ Blockchain Observers | Blockchain Protocols and Distributed Applications - +
Skip to main content

Blockchain Observers

Observers are a type of nodes that don't participate in the consensus but keep a peer-to-peer communication with the rest of the blockchain. They are usually used to see the communication between nodes (ex: debugging).

Let's filter the nodes to see only the observers. There is an Observers tab below the Nodes section.

Observers

We can observer the same fields as the nodes, but there is no Rating. Why is that?

Note that each Observer is only on a Shard.

What should we do if we want to listen to the communication on every shard?

Observer that there are other types of nodes

- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Blockchain Validators/validators/index.html b/Practical Sessions/Explorer/Blockchain Validators/validators/index.html index bfea2e1..aeaae85 100644 --- a/Practical Sessions/Explorer/Blockchain Validators/validators/index.html +++ b/Practical Sessions/Explorer/Blockchain Validators/validators/index.html @@ -4,7 +4,7 @@ Blockchain Validators | Blockchain Protocols and Distributed Applications - + @@ -12,7 +12,7 @@
Skip to main content

Blockchain Validators

Every validators/node is publicly displayed on the explorer:

You can check on the explorer the nodes of every blockchain.


NOTE

We call nodes or validators the computers who participate in the blockchain to execute transactions. The more available nodes, the more decentralized the blockchain is.


Let's stick to the MultiversX. Go to the Nodes Section.

Nodes

Observe the nodes public information:

  • Public Key
  • Name
  • Shard
  • Node Software Version
  • Status
  • Rating
  • Nonce

We recall that the Nonce is the number of transaction that user transmited on the blockchain.

Rating

Each individual validator has a Rating score, which expresses its overall reliability, performance and responsiveness. When validators join the network immediately after staking, they start with an initial score of 50 points.

Validators gain or lose rating points in a round depending on their role in that round (consensus proposer vs. consensus validator) and on their behavior within that role.

For the overall health of the network, if the rating of a validator drops below 10 points, it will be jailed. Being jailed means that the validator will be taken out of the shards, it will not participate in consensus, and thus it will not earn any rewards.

Rating affects the probability of a validator to be selected in the consensus group of a round. This is done by applying rating modifiers on the probability of selection for each validator.

You can read more on rating shard validators here.

Node details

The explorer offers details on each node participant to the blockchain.

Node Details

Practice

- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Blocks/index.html b/Practical Sessions/Explorer/Blocks/index.html index d21547c..7af8209 100644 --- a/Practical Sessions/Explorer/Blocks/index.html +++ b/Practical Sessions/Explorer/Blocks/index.html @@ -4,7 +4,7 @@ Blocks in Blockchain | Blockchain Protocols and Distributed Applications - + @@ -13,7 +13,7 @@ Blocks on MultiversX

We can observe 4 blocks from 1 second ago for 4 different shards: Shard0, Shard1, Shard2, Metachain. These shard a sub-blockchains and enables MultiversX to scale. You can read more about shard here.

We can observe 4 more blocks from 7 seconds ago. That's because each shard outputs a block every 6 seconds.


NOTE

We previously saw that every 6 seconds starts new round, but not necessarly a new block gets notarized. In this case all the blocks successfully passed the consensus round and got notarized.


Block details

Here is the link for one of the blocks in the previous image (Block Height: 16826695).

Block 16826695

Observe the block details:

Based on a simple calculus, the epoch is 1168 which means this blockchain started 3 years and 73 days ago.

We will talk about the other fields in the next section.

Practice

  1. Go to the MultiversX Explorer and check more blocks from different shard;
  2. Go to the Ethereum Explorer and check some blocks details.
- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Consensus Grup/consensus/index.html b/Practical Sessions/Explorer/Consensus Grup/consensus/index.html index f79ce0c..21347a2 100644 --- a/Practical Sessions/Explorer/Consensus Grup/consensus/index.html +++ b/Practical Sessions/Explorer/Consensus Grup/consensus/index.html @@ -4,7 +4,7 @@ Consensus Group | Blockchain Protocols and Distributed Applications - + @@ -13,7 +13,7 @@ Leader

There are 63 validators which execute every transaction in this block. If you click on the 63 validators (See all) button you will see 63 public keys, which are links to all the 63 nodes that participated in consensus.

Practice

- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html b/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html index 4a4936f..2a0c58a 100644 --- a/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html +++ b/Practical Sessions/Explorer/Devnet Blockchains/devnet_testnet/index.html @@ -4,14 +4,14 @@ Devnet & Testnet Blockchain | Blockchain Protocols and Distributed Applications - +
Skip to main content

Devnet & Testnet Blockchain

While developing applications, there is a need for a development/testing blockchain.

Inspect:

What differences can you observe?

These blockchains offer the Faucet option where you can mint blockchain tokens (eGLD, ETH, etc.). This way the development is easier for the community.


NOTE

All the tokens are "fake" tokens. They are only used to mock the real tokens on the Mainnet.


- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Time in Blockchain/time/index.html b/Practical Sessions/Explorer/Time in Blockchain/time/index.html index f2b3455..76cdcc4 100644 --- a/Practical Sessions/Explorer/Time in Blockchain/time/index.html +++ b/Practical Sessions/Explorer/Time in Blockchain/time/index.html @@ -4,7 +4,7 @@ Understanding Time in Blockchains | Blockchain Protocols and Distributed Applications - + @@ -16,7 +16,7 @@ Each blockchain has it's own length of rounds:

A round is a time limit to execute a batch of transactions.

Blocks

Every round a new block is being proposed. That proposal can succeed or not. In case of success, a block is added to the blockchain history. The missed blocks are due to not reaching consensus and are usually under 5%.


NOTE

For MultiversX case, every 6 seconds starts new round, but not necessarly a new block gets notarized.


Epochs

This is another time measurement and it's used for larger periods of time (just like minutes, hours, years, decades, etc.).

Each blockchain has it's own length of epochs:

Block Timestamps

Blockchains organize transactions into blocks, and each block has a timestamp. This timestamp is crucial for several reasons:

  1. Order of Transactions: The timestamp helps order transactions within a block. Transactions are grouped together and processed in the order in which they are added to a block. This ensures that everyone has a consistent view of the transaction history.

  2. Difficulty Adjustment: Some blockchains, like Bitcoin, use the block timestamp to adjust the difficulty of the proof-of-work (PoW) algorithm. This keeps the block generation rate relatively constant, regardless of the total network hash rate.

  3. Block Validity: Block timestamps are used to determine whether a block is valid. If the timestamp of a new block is too far in the future or past, it can be considered invalid.

Practice

Check MultiversX Explorer and Ethereum Explorer and see how (almost) at every 6, respectively 12 seconds a new block appears.

- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/Transactions/index.html b/Practical Sessions/Explorer/Transactions/index.html index 98f02a3..e0aad3c 100644 --- a/Practical Sessions/Explorer/Transactions/index.html +++ b/Practical Sessions/Explorer/Transactions/index.html @@ -4,7 +4,7 @@ Transactions | Blockchain Protocols and Distributed Applications - + @@ -14,7 +14,7 @@ We can see that there are 6 transactions in this group.

Miniblocks

Transactions are grouped in miniblocks. Each miniblock is a category with Shard_source - Shard_destionation.

So, for the first miniblock we have 3 transactions from Shard1 to Shard2: Block 16826695

Transaction details

We will use the first transaction from the first miniblock as an example:

Transaction

Observe the fields:

There are more fields in this transaction, but we will discuss about it in a further section.

Practice

- + \ No newline at end of file diff --git a/Practical Sessions/Explorer/index.html b/Practical Sessions/Explorer/index.html index c9e35c4..635f5d7 100644 --- a/Practical Sessions/Explorer/index.html +++ b/Practical Sessions/Explorer/index.html @@ -4,13 +4,13 @@ Explorer | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Money/index.html b/Practical Sessions/Money/index.html index 4b7951c..9afa402 100644 --- a/Practical Sessions/Money/index.html +++ b/Practical Sessions/Money/index.html @@ -4,13 +4,13 @@ Money | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Money/mint_tokens/index.html b/Practical Sessions/Money/mint_tokens/index.html index 0bec3c6..45ee3af 100644 --- a/Practical Sessions/Money/mint_tokens/index.html +++ b/Practical Sessions/Money/mint_tokens/index.html @@ -4,13 +4,13 @@ Mint tokens | Blockchain Protocols and Distributed Applications - +
Skip to main content

Mint tokens

In this section you will learn how to mint tokens on MultiversX.

There are 2 types of tokens on MultiversX:

  • Native tokens - EGLD;
  • ESDT - eStandard Digital Token.

In the previous section you learnt how to mint xEGLD on MultiversX Testnet using Faucet option.

Testnet Wallet

Mint ESDT

This time we use the Create Token option.

Token Name:

  • length between 3 and 20 characters
  • alphanumeric characters only

Token Ticker:

  • length between 3 and 10 characters
  • alphanumeric UPPERCASE only

Number of decimals:

  • should be a numerical value between 0 and 18;
  • there are no floats on the blockchain;
  • a token with 3 decimals and value 1000 would be equal with value 1;
  • EGLD has 18 decimals and the value of 1000000000000000000 is 1 EGLD.

Let's create a token new token:

Issue Token

and inspect the transaction

Explorer Token Created

Observe Token Operations field. We received 321.00 BPDA-208994 tokens. BPDA-208994 is the token ID. The token ID is formed by appending to the token ticker the character - and 6 random hexadecimals characters. This is done because there might be mutiple tokens with the same ticker; the token ID is always unique.

We can click on the token ID and see the details of the token:

Token Details

Observe the fields TOKEN, Supply, Holders, Transactions, Owner, Decimals.

Let create another token with the same input:

Issue Token2

Observe that the token ID is different.

Practice

  • Create your own ESDT token;
  • Inspect the transaction;
  • Send some of your tokens to erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd;
  • Create another token with the same ticker. Observer that the token ID is different and unique.
- + \ No newline at end of file diff --git a/Practical Sessions/Money/swap/index.html b/Practical Sessions/Money/swap/index.html index e70f35d..ab97911 100644 --- a/Practical Sessions/Money/swap/index.html +++ b/Practical Sessions/Money/swap/index.html @@ -4,14 +4,14 @@ Swap tokens on xExchange | Blockchain Protocols and Distributed Applications - +
Skip to main content

Swap tokens on xExchange

In this section, you will learn how to swap a token with another on MultiversX. For this, we will use the Devnet xExchange, a MultiversX Decentralized Exchange.

Keep in mind that Devnet and Testnet chains are different! First go to Devnet Wallet and use Faucet functionality to get xEGLD.

DEX

Use Connect button and connect with your wallet via your preferred method. After connection go to the Swap tab (it's located on the top of the page).

DEX

Select USDC and click Swap. Check the transaction on the Explorer. Check your balance on your Wallet.

- + \ No newline at end of file diff --git a/Practical Sessions/Observer/index.html b/Practical Sessions/Observer/index.html index 22b742b..976fd9b 100644 --- a/Practical Sessions/Observer/index.html +++ b/Practical Sessions/Observer/index.html @@ -4,14 +4,14 @@ Setting up an Observer | Blockchain Protocols and Distributed Applications - +
Skip to main content

Setting up an Observer

In this section we will be setting up an Observer on the MultiversX Testnet.

Clone the installer repository:

git clone https://github.com/multiversx/mx-chain-scripts

Edit ENVIRONMENT and CUSTOM_HOME in config/variables.cfg config file:

ENVIRONMENT="testnet"

CUSTOM_HOME="/home/costin"
CUSTOM_USER="costin

Don't forget to put your Github Token in the GITHUBTOKEN field. Please check that the `CUSTOM_HOME`` directory exists.

Run the installation script as follows:

./script.sh observing_squad

Start the nodes and the Proxy using the command:

./script.sh start

If you encounter any issue please check the MultiversX Observing Squad Documentation.

Monitoring and trivial checks

One can monitor the running Observers using the termui utility (installed during the setup process itself in the CUSTOM_HOME="/home/ubuntu" folder), as follows:

~/elrond-utils/termui --address localhost:8080    # Shard 0
~/elrond-utils/termui --address localhost:8081 # Shard 1
~/elrond-utils/termui --address localhost:8082 # Shard 2
~/elrond-utils/termui --address localhost:8083 # Metachain

Observer Output

- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contract Events/events/index.html b/Practical Sessions/Smart Contract Events/events/index.html index 974dc0f..cc1d296 100644 --- a/Practical Sessions/Smart Contract Events/events/index.html +++ b/Practical Sessions/Smart Contract Events/events/index.html @@ -4,7 +4,7 @@ Events | Blockchain Protocols and Distributed Applications - + @@ -16,7 +16,7 @@ Let's inspect the logs:

Swap Event1

The first transaction is an ESDTTransfer for the token USDC-c76f1f which has 6 decimals; therefore 580345261 is equal to 580,345261$. You can match the events to the Token Operations from the Transacton Details.

You can check the deposit_swap_fees_event code here.

Notice the burn event below. Keep in mind that MEX-455c57 has 18 decimals. Swap Event2

Here is the code for the swap_no_fee_and_forward event.

Writing your own event in the Smart Contract

The structure of an event is:

    #[event("your_event_name")]
fn the_function_you_call_when_you_want_to_emit_en_event(
&self,
#[indexed] field1: &TokenIdentifier,
#[indexed] field2: &ManagedAddress,
#[indexed] field3: u64,
#[indexed] field4: BigUint,
);

And when you want to emit an event, just call the function:

    self.the_function_you_call_when_you_want_to_emit_en_event(field1, field2, field3, field4);
- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contract Events/index.html b/Practical Sessions/Smart Contract Events/index.html index 60be32f..bd802b8 100644 --- a/Practical Sessions/Smart Contract Events/index.html +++ b/Practical Sessions/Smart Contract Events/index.html @@ -4,13 +4,13 @@ Smart Contract Events | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/adder/index.html b/Practical Sessions/Smart Contracts/adder/index.html index 691613c..aa9e76c 100644 --- a/Practical Sessions/Smart Contracts/adder/index.html +++ b/Practical Sessions/Smart Contracts/adder/index.html @@ -4,13 +4,13 @@ The Adder SC | Blockchain Protocols and Distributed Applications - +
Skip to main content

The Adder SC

The Adder smart contract is a simple smart contract with an add functionality and a global variable that can be incremented.

/// One of the simplest smart contracts possible,
/// it holds a single variable in storage, which anyone can increment.
#[multiversx_sc::contract]
pub trait Adder {
#[view(getSum)]
#[storage_mapper("sum")]
fn sum(&self) -> SingleValueMapper<BigUint>;

#[init]
fn init(&self, initial_value: BigUint) {
self.sum().set(initial_value);
}

/// Add desired amount to the storage variable.
#[payable("*")]
#[endpoint]
fn add(&self, value: BigUint) {
self.sum().update(|sum| *sum += value);
}
}

We notice 3 functions:

  • sum - this is a global variable, a SingleValueMapper (a single value) of type BigUint (unsigned integer);
  • init - the constructor;
  • add - function that increments the global variable (sum) with the value parameter;

We notice 5 types of adnotations:

  • #[view(getSum)] - this is a function that allows you to read the variable by calling the paramter(getSum);
  • #[storage_mapper("sum")] - this is a global variable (also called a storage) stored in the contract
  • #[init] - the constructor function
  • #[endpoint] - An endpoint is a function callable directly by the user.

Here is the smart contract code listed above and here are all the files needed for compilation.

Let's compile the contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder$ sc-meta all build
/home/costin/mvx/mx-contracts-rs/contracts/adder

Found 1 contract crates.

(1/1)
In /home/costin/mvx/mx-contracts-rs/contracts/adder/meta
Calling `cargo run build`
Finished dev [unoptimized + debuginfo] target(s) in 0.08s
Running `/home/costin/mvx/mx-contracts-rs/target/debug/adder-meta build`
Building adder.wasm in /home/costin/mvx/mx-contracts-rs/contracts/adder/wasm ...
RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release
Compiling proc-macro2 v1.0.69
Compiling unicode-ident v1.0.12
Compiling syn v1.0.109
Compiling version_check v0.9.4
Compiling hex v0.4.3
Compiling smallvec v1.11.1
Compiling autocfg v1.1.0
Compiling cfg-if v1.0.0
Compiling zerocopy v0.7.25
Compiling endian-type v0.1.2
Compiling nibble_vec v0.1.0
Compiling once_cell v1.18.0
Compiling radix_trie v0.2.1
Compiling arrayvec v0.7.4
Compiling bitflags v1.3.2
Compiling hex-literal v0.3.4
Compiling num-traits v0.2.17
Compiling ahash v0.8.6
Compiling hashbrown v0.13.2
Compiling quote v1.0.33
Compiling multiversx-sc-codec-derive v0.18.1
Compiling multiversx-sc-derive v0.44.0
Compiling multiversx-sc-codec v0.18.1
Compiling multiversx-sc v0.44.0
Compiling multiversx-sc-wasm-adapter v0.44.0
Compiling adder v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/adder)
Compiling adder-wasm v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/adder/wasm)
Finished release [optimized] target(s) in 5.31s
Copying ../wasm/target/wasm32-unknown-unknown/release/adder_wasm.wasm to ../output/adder.wasm ...
Calling wasm-opt on ../output/adder.wasm ...
Extracting imports to ../output/adder.imports.json ...
Checking EI version: 1.2 ... OK
Packing ../output/adder.mxsc.json ...
Contract size: 685 bytes.

Let's check the contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder$ ls -l output/
total 16
-rw-rw-r-- 1 costin costin 1639 dec 6 17:02 adder.abi.json
-rw-rw-r-- 1 costin costin 262 dec 6 17:02 adder.imports.json
-rw-rw-r-- 1 costin costin 3249 dec 6 17:02 adder.mxsc.json
-rwxrwxr-x 1 costin costin 685 dec 6 17:02 adder.wasm

We notice that the resulted contract (adder.wasm) has 685 bytes.

- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/deploy/index.html b/Practical Sessions/Smart Contracts/deploy/index.html index 6519ff0..5c80eb4 100644 --- a/Practical Sessions/Smart Contracts/deploy/index.html +++ b/Practical Sessions/Smart Contracts/deploy/index.html @@ -4,7 +4,7 @@ Smart Contract deployment | Blockchain Protocols and Distributed Applications - + @@ -14,7 +14,7 @@ Now we can call the deploy function:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ deploy
DEBUG:cli.contracts:deploy
DEBUG:accounts:AccountBase.sync_nonce()
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443
DEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 "GET /address/erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd HTTP/1.1" 200 363
DEBUG:accounts:AccountBase.sync_nonce() done: 1
INFO:cli.contracts:Contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4
INFO:utils:View this contract address in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/accounts/erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4
INFO:transactions:Transaction.send: nonce=1
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443
DEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 "POST /transaction/send HTTP/1.1" 201 106
INFO:transactions:Hash: 09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1
INFO:utils:View this transaction in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1
WARNING:cli.data:Always review --expression parameters before executing this command!
WARNING:cli.data:Always review --expression parameters before executing this command!
WARNING:cli.data:Never use this command to store sensitive information! Data is unencrypted.
INFO:cli.data:Data has been stored at key = 'address-testnet', in partition = '*'.
WARNING:cli.data:Never use this command to store sensitive information! Data is unencrypted.
INFO:cli.data:Data has been stored at key = 'deployTransaction-testnet', in partition = '*'.

Smart contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4

Now we have performed a deployment of the wasm binary (our adder contract) in the blockchain.

Notice the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1. Click on the link to see your transaction.

Notice the Smart contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4. Go to the Testnet Explorer and search for your SC address.

Notice the contract deployed on testnet:

Contract deployed on Testnet

Observe the fields Owner, Deployed (timestamp).

- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/empty/index.html b/Practical Sessions/Smart Contracts/empty/index.html index 31a8af1..95ce895 100644 --- a/Practical Sessions/Smart Contracts/empty/index.html +++ b/Practical Sessions/Smart Contracts/empty/index.html @@ -4,13 +4,13 @@ The Empty SC | Blockchain Protocols and Distributed Applications - +
Skip to main content

The Empty SC

The smallest smart contract is an empty smart contract with no functionalities. Compiled, it is a binary that is accepted by the blockchain.

/// An empty contract. To be used as a template when starting a new contract from scratch.
#[multiversx_sc::contract]
pub trait EmptyContract {
#[init]
fn init(&self) {}
}

Here is the smart contract code listed above and here are all the files needed for compilation.

We have the addnotation #[init] where we specify the constructor function. Only one constructor is allowed per smart contract.

Let's build the smart contract:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/empty$ sc-meta all build
/home/costin/mvx/mx-contracts-rs/contracts/empty

Found 1 contract crates.

(1/1)
In /home/costin/mvx/mx-contracts-rs/contracts/empty/meta
Calling `cargo run build`
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/costin/mvx/mx-contracts-rs/target/debug/empty-meta build`
Building empty.wasm in /home/costin/mvx/mx-contracts-rs/contracts/empty/wasm ...
RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release
Compiling proc-macro2 v1.0.69
Compiling unicode-ident v1.0.12
Compiling syn v1.0.109
Compiling version_check v0.9.4
Compiling hex v0.4.3
Compiling autocfg v1.1.0
Compiling smallvec v1.11.1
Compiling cfg-if v1.0.0
Compiling once_cell v1.18.0
Compiling endian-type v0.1.2
Compiling nibble_vec v0.1.0
Compiling zerocopy v0.7.25
Compiling arrayvec v0.7.4
Compiling radix_trie v0.2.1
Compiling hex-literal v0.3.4
Compiling ahash v0.8.6
Compiling bitflags v1.3.2
Compiling num-traits v0.2.17
Compiling quote v1.0.33
Compiling hashbrown v0.13.2
Compiling multiversx-sc-codec-derive v0.18.1
Compiling multiversx-sc-derive v0.44.0
Compiling multiversx-sc-codec v0.18.1
Compiling multiversx-sc v0.44.0
Compiling empty v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/empty)
Compiling multiversx-sc-wasm-adapter v0.44.0
Compiling empty-wasm v0.0.0 (/home/costin/mvx/mx-contracts-rs/contracts/empty/wasm)
Finished release [optimized] target(s) in 5.28s
Copying ../wasm/target/wasm32-unknown-unknown/release/empty_wasm.wasm to ../output/empty.wasm ...
Calling wasm-opt on ../output/empty.wasm ...
Extracting imports to ../output/empty.imports.json ...
Checking EI version: 1.2 ... OK
Packing ../output/empty.mxsc.json ...
Contract size: 232 bytes.

The resulted contract is output/empty.wasm, a WebAseembly binary module that is only 232 bytes:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/empty$ ls -l output/
total 16
-rw-rw-r-- 1 costin costin 838 dec 6 16:48 empty.abi.json
-rw-rw-r-- 1 costin costin 60 dec 6 16:48 empty.imports.json
-rw-rw-r-- 1 costin costin 1406 dec 6 16:48 empty.mxsc.json
-rwxrwxr-x 1 costin costin 232 dec 6 16:48 empty.wasm

Practice

  • Clone the Empty SC repo;
  • Compile the contract.
- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/index.html b/Practical Sessions/Smart Contracts/index.html index 1c8992a..ff5f5d1 100644 --- a/Practical Sessions/Smart Contracts/index.html +++ b/Practical Sessions/Smart Contracts/index.html @@ -4,13 +4,13 @@ Smart Contracts | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/neversea/index.html b/Practical Sessions/Smart Contracts/neversea/index.html index e72f72b..05eb872 100644 --- a/Practical Sessions/Smart Contracts/neversea/index.html +++ b/Practical Sessions/Smart Contracts/neversea/index.html @@ -4,7 +4,7 @@ Never Sea Festival Smart Contract | Blockchain Protocols and Distributed Applications - + @@ -12,7 +12,7 @@
Skip to main content

Never Sea Festival Smart Contract

You are the Never Sea Festival 2024 organizers and you decide to create the registration via blockchain. Starting from Smart Contract template you have to add more features to coordinate the event.

Clone the Neversea project.

Compile and deploy the Smart Contract template

To check that the contract was successfully built, verify that there was a wasm (WebAssembly) file generate: output/neversea.wasm. This is the compiled code of your contract.

To check that the contract was successfully deployed, check the devnet/testnet.


NOTE

Check the deployment on the explorer. Do not assume that the contract was successfully deployed if there are no command line errors.

Any modification of the contract must be succeeded by a compilation and deployment!


Practice

  • Make a contract call to register a user;
  • Make a contract call to view the registered users;
  • Modify the registration endpoint to enable VIP access;
  • Create a new storage mapper registration_fee_vip;
  • Create a new storage mapper vip_participants to save the VIP participants;
  • In the registration endpoint, make a verification of the tokens received. If the tokens received is registration_fee_vip, add the user to vip_participants, if the amount is registration_fee, add them to participants, else, deny registration;
  • Modify the registration fee to enable Early Bird and Full price access;
  • Create a new endpoint that modifies the registration_fee and registration_fee_vip storage mapper. This endpoint should be call only by the owner.
  • BONUS: Create a feature to enable 50% discount vouchers for friends and partners. Create a list of hardcoded discount codes. Create a new endpoint that receives a discount code as a parameter and registers a user with 50% discount.

Hint Use #[only_owner] endpoint annotation.


- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/prerequisites/index.html b/Practical Sessions/Smart Contracts/prerequisites/index.html index 493810a..a84a514 100644 --- a/Practical Sessions/Smart Contracts/prerequisites/index.html +++ b/Practical Sessions/Smart Contracts/prerequisites/index.html @@ -4,13 +4,13 @@ Prerequisites | Blockchain Protocols and Distributed Applications - +
Skip to main content

Prerequisites

Install mxpy - blockchain interaction

We use mxpy to interact with the blockchain.

To install mxpy run:

wget -O mxpy-up.py https://raw.githubusercontent.com/multiversx/mx-sdk-py-cli/main/mxpy-up.py
python3 mxpy-up.py

To check the successful installation:

$ mxpy --version
MultiversX Python CLI (mxpy) 6.1.3

If you encounter any errors, follow the guide here.

Install sc-meta - contract interaction

We use sc-meta to compile the contracts and to upgrade the dependencies.

To install sc-meta, simply call:

$ cargo install multiversx-sc-meta

To check for successful installation:

$ sc-meta --version
multiversx-sc-meta 0.45.1

If you encounter any errors, follow the guide here.

Contracts examples

Here is a list of Smart Contract examples. We will use part of them to understand smart contracts on MultiversX.

- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/sc_call/index.html b/Practical Sessions/Smart Contracts/sc_call/index.html index e037353..49665f6 100644 --- a/Practical Sessions/Smart Contracts/sc_call/index.html +++ b/Practical Sessions/Smart Contracts/sc_call/index.html @@ -4,14 +4,14 @@ Smart Contract call | Blockchain Protocols and Distributed Applications - +
Skip to main content

Smart Contract call

Now let's call our previous adder smart contract.

Inspect the deploy function in our testnet.snippets.sh. Observer that we provided the arguments: --arguments 0. In our init function, we provided the argument and saved it in our sum global variable (storage):

      #[init]
fn init(&self, initial_value: BigUint) {
self.sum().set(initial_value);
}

Therefore in the SC there is a sum storage initialized with 0.

Let's call the add endpoint to add a value to our storage:

/mvx/mx-contracts-rs/contracts/adder/interaction$ add 
Enter number: 2
DEBUG:cli.contracts:call
DEBUG:accounts:AccountBase.sync_nonce()
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443
DEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 "GET /address/erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd HTTP/1.1" 200 363
DEBUG:accounts:AccountBase.sync_nonce() done: 2
INFO:transactions:Transaction.send: nonce=2
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443
DEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 "POST /transaction/send HTTP/1.1" 201 106
INFO:transactions:Hash: 260ca64134d2d14781493959bf5b4c5046b1b4bb6aa46b76d075aa6ec170fa7b
INFO:utils:View this transaction in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/260ca64134d2d14781493959bf5b4c5046b1b4bb6aa46b76d075aa6ec170fa7b
{
"emittedTransaction": {
"nonce": 2,
"value": "0",
"receiver": "erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4",
"sender": "erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd",
"gasPrice": 1000000000,
"gasLimit": 5000000,
"data": "YWRkQDAy",
"chainID": "T",
"version": 1,
"signature": "d67b1da6c9151aec3950c16b37df91a7789b49edc53574152c29db12339662eaef8896566e88684b8b547f8856ee0f4afd97031ea32e49a0ea3519ca3b3e600e"
},
"emittedTransactionData": "add@02",
"emittedTransactionHash": "260ca64134d2d14781493959bf5b4c5046b1b4bb6aa46b76d075aa6ec170fa7b",
"contractAddress": "erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4"
}

Inspect the MultiversX Testnet Explorer to see the transaction.

Let's call the getSum view function to read from the storage:

costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ getSum 
DEBUG:cli.contracts:query
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443
DEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 "POST /vm-values/query HTTP/1.1" 201 525
[
{
"base64": "Ag==",
"hex": "02",
"number": 2
}
]

Notice that the view functions (the queries) are not transactions on blockchain. We didn't pay any gas for this. We didn't create any transaction.

- + \ No newline at end of file diff --git a/Practical Sessions/Smart Contracts/wallet_cmdline/index.html b/Practical Sessions/Smart Contracts/wallet_cmdline/index.html index 03b365d..2e0cdbb 100644 --- a/Practical Sessions/Smart Contracts/wallet_cmdline/index.html +++ b/Practical Sessions/Smart Contracts/wallet_cmdline/index.html @@ -4,7 +4,7 @@ Create Wallet from command line | Blockchain Protocols and Distributed Applications - + @@ -12,7 +12,7 @@
Skip to main content

Create Wallet from command line

In this section you will learn how to create a wallet from the command line. We will use mxpy tools installed in the previous section.

You can create a new wallet by using the mxpy wallet new command:

$ mxpy wallet new --help
usage: mxpy wallet new [-h] ...

Create a new wallet and print its mnemonic; optionally save as password-protected JSON (recommended) or PEM (not recommended)

options:
-h, --help show this help message and exit
--format {raw-mnemonic,keystore-mnemonic,keystore-secret-key,pem}
the format of the generated wallet file (default: None)
--outfile OUTFILE the output path and base file name for the generated wallet files
(default: None)
--address-hrp ADDRESS_HRP the human-readable part of the address, when format is keystore-
secret-key or pem (default: erd)

Create a wallet with pem format

Notice: Pem format is recommended only for development! The advantage is that you don't require any other input (password for example). This is why it's also really dangerous to use pem format for personal wallets.

$ mxpy wallet new --format pem --outfile private_key.pem
Mnemonic: glide place surround pupil gold razor member shove detail love tray prefer fire marriage undo capital play runway injury emotion attitude spike goddess lion
INFO cli.wallet: Wallet (pem) saved: /home/costin/mvx/mx-contracts-rs/contracts/adder/interaction/private_key.pem

In blockchain, Mnemonics refers to a 12, 18 or 24-word phrase created for new cryptocurency wallet holders. Mnemonics are used to make cryptocurrency wallets more secure and easy to store.

Mnemonics aim to ensure that the cryptocurrency wallet can be accessed when the cryptocurrency wallet password is lost or forgotten. Given the decentralized and secure nature of cryptocurrency wallets, it is difficult to access the details of a cryptocurrency wallet. The details of decentralized and secure cryptocurrency wallets can be accessed through mnemonics. If the mnemonic is lost, access to the cryptocurrency wallet is completely lost.

Notice: In order to use this addres to deploy contracts or make transactions you must go to the tesnet wallet or devnet wallet and use the Faucet option to request xEGLD. The tokens are required to pay the fees.

Notice: Same private key can be used for devnet, testnet or mainnet, but the storage is completly different. For example if you have 1 EGLD on Testnet, you don't necessarly have 1 EGLD on Devnet.

- + \ No newline at end of file diff --git a/Practical Sessions/Tokens/fungible/index.html b/Practical Sessions/Tokens/fungible/index.html index 20d5295..10f53d2 100644 --- a/Practical Sessions/Tokens/fungible/index.html +++ b/Practical Sessions/Tokens/fungible/index.html @@ -4,7 +4,7 @@ Fungible Tokens | Blockchain Protocols and Distributed Applications - + @@ -13,7 +13,7 @@ After this transaction, he will receive in his wallet the minted tokens.

Practice

Setting ESDT Roles

Notice the Properties section in a Token page. UTK tokens

There are several roles assigned to a token. To change those roles we need to make a blockchain transaction:

RolesAssigningTransaction {
Sender: <address of the ESDT manager>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 0
GasLimit: 60000000
Data: "setSpecialRole" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <address to assign the role(s) in a hexadecimal encoding> +
"@" + <role in hexadecimal encoding> +
"@" + <role in hexadecimal encoding> +
...
}

Practice

You can read more about roles in the documentation.

Burning ESDT Tokens

Anyone that holds an amount of ESDT tokens may burn it at their discretion, effectively losing them permanently. This operation reduces the total supply of tokens, and cannot be undone, unless the token manager mints more tokens.

Do you have roles for burning?

LocalBurnTransaction {
Sender: <address with ESDTRoleLocalBurn role>
Receiver: <same as sender>
Value: 0
GasLimit: 300000
Data: "ESDTLocalBurn" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <supply to burn in hexadecimal encoding>
}

Practice

Other actions for ESDTTokens

Pausing and Unpausing

The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

Freezing and Unfreezing

The manager of an ESDT token may freeze the tokens held by a specific Account. As a consequence, no tokens may be transferred to or from the frozen Account. Freezing and unfreezing the tokens of an Account are operations designed to help token managers to comply with regulations. The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

Wiping

The manager of an ESDT token may wipe out all the tokens held by a frozen Account. This operation is similar to burning the tokens, but the Account must have been frozen beforehand, and it must be done by the token manager. Wiping the tokens of an Account is an operation designed to help token managers to comply with regulations. The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

- + \ No newline at end of file diff --git a/Practical Sessions/Tokens/index.html b/Practical Sessions/Tokens/index.html index efda5ce..792ebe1 100644 --- a/Practical Sessions/Tokens/index.html +++ b/Practical Sessions/Tokens/index.html @@ -4,13 +4,13 @@ Tokens | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Tokens/nft/index.html b/Practical Sessions/Tokens/nft/index.html index 9689b02..4da57f6 100644 --- a/Practical Sessions/Tokens/nft/index.html +++ b/Practical Sessions/Tokens/nft/index.html @@ -4,7 +4,7 @@ Non-Fungible Tokens (NFTs) | Blockchain Protocols and Distributed Applications - + @@ -21,7 +21,7 @@ For example, ESDTRoleNFTCreate = 0x45534454526f6c654e4654437265617465.

NFT fields

Below you can find the fields involved when creating an NFT:

{
"description": "This is a sample description",
"attributes": [
{
"trait_type": "Background",
"value": "Yellow",
"{key}": "{value}",
"{...}": "{...}",
"{key}": "{value}"
},
{
"trait_type": "Headwear",
"value": "BlackBeanie"
},
{
"trait_type": "SampleTrait3",
"value": "SampleValue3"
}
],
"collection": "ipfsCID/fileName.json"
}


NOTE

Please note that each argument must be encoded in hexadecimal format with an even number of characters.


Creation of an NFT

A single address can own the role of creating an NFT for an ESDT token. This role can be transferred by using the ESDTNFTCreateRoleTransfer function.

An NFT can be created on top of an existing ESDT by sending a transaction to self that contains the function call that triggers the creation. Any number of URIs can be assigned (minimum 1).

NFTCreationTransaction {
Sender: <address with ESDTRoleNFTCreate role>
Receiver: <same as sender>
Value: 0
GasLimit: 3000000 + Additional gas (see below)
Data: "ESDTNFTCreate" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <initial quantity in hexadecimal encoding> +
"@" + <NFT name in hexadecimal encoding> +
"@" + <Royalties in hexadecimal encoding> +
"@" + <Hash in hexadecimal encoding> +
"@" + <Attributes in hexadecimal encoding> +
"@" + <URI in hexadecimal encoding> +
"@" + <URI in hexadecimal encoding> +
...
}

Additional gas refers to:

Transfer NFT Creation Role

The role of creating an NFT can be transferred by a Transaction like this:

TransferCreationRoleTransaction {
Sender: <address of the current creation role owner>
Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
Value: 0
GasLimit: 60000000 + length of Data field in bytes * 1500
Data: "transferNFTCreateRole" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <the address to transfer the role from in hexadecimal encoding> +
"@" + <the address to transfer the role to in hexadecimal encoding>
}

Change NFT Attributes

An user that has the `ESDTRoleNFTUpdateAttributes`` role set for a given ESDT, can change the attributes of a given NFT/SFT.


NOTE

ESDTNFTUpdateAttributes will remove the old attributes and add the new ones. Therefore, if you want to keep the old attributes you will have to pass them along with the new ones.


This is done by performing a transaction like this:

ESDTNFTUpdateAttributesTransaction {
Sender: <address of an address that has ESDTRoleNFTUpdateAttributes role>
Receiver: <same as sender>
Value: 0
GasLimit: 10000000
Data: "ESDTNFTUpdateAttributes" +
"@" + <token identifier in hexadecimal encoding> +
"@" + <NFT or SFT nonce in hexadecimal encoding> +
"@" + <Attributes in hexadecimal encoding>
}

Transfers

Performing an ESDT NFT transfer is done by specifying the receiver's address inside the Data field, alongside other details. An ESDT NFT transfer transaction has the following form:

TransferTransaction {
Sender: <account address of the sender>
Receiver: <same as sender>
Value: 0
GasLimit: 1000000 + length of Data field in bytes * 1500
Data: "ESDTNFTTransfer" +
"@" + <collection identifier in hexadecimal encoding> +
"@" + <the NFT nonce in hexadecimal encoding> +
"@" + <quantity to transfer in hexadecimal encoding> +
"@" + <destination address in hexadecimal encoding>
}

Branding

Here is SubcarpatiOGs NFT Collection. Stramosi NFT

Observe that there are Social links, a Description and you can even see a Logo.

For branding you NFT collection please read the instructions.

- + \ No newline at end of file diff --git a/Practical Sessions/Tokens/standards/index.html b/Practical Sessions/Tokens/standards/index.html index ffc865b..e227cc0 100644 --- a/Practical Sessions/Tokens/standards/index.html +++ b/Practical Sessions/Tokens/standards/index.html @@ -4,7 +4,7 @@ Token Standards | Blockchain Protocols and Distributed Applications - + @@ -13,7 +13,7 @@ ERCs are a set of technical standards that are used to create and manage tokens on the Ethereum blockchain. ERC standards define a set of rules and protocols that tokens must follow in order to be compatible with the Ethereum network. These rules cover a variety of aspects, such as token transfer functions, token ownership, and smart contract security. By following these standards, developers can ensure that their tokens are interoperable with other tokens and can be easily exchanged on the Ethereum network.

There are currently several ERC standards, including ERC-20, ERC-721, ERC-777, and ERC-1155, each of which has a specific set of features and functions. ERC-20 is the most widely used token standard and is used to create fungible tokens, while ERC-721 is used to create non-fungible tokens (NFTs). Other ERC standards, such as ERC-777 and ERC-1155, provide additional features and functions for creating more complex tokens.

You can read more about ERC-20 and ERC-721.

Here are the top Ethereum tokens.

ESDT - eStandard Digital Token

The MultiversX network natively supports the issuance of custom tokens, without the need for contracts such as ERC20, but addressing the same use-cases. And due to the native in-protocol support, transactions with custom tokens do not require the VM at all.

Technically, the balances of ESDT tokens held by an Account are stored directly under the data trie of that Account. It also implies that an Account can hold balances of any number of custom tokens, in addition to the native EGLD balance. The protocol guarantees that no Account can modify the storage of ESDT tokens, neither its own nor of other Accounts.

ESDT tokens can be issued, owned and held by any Account on the MultiversX network, which means that both users and smart contracts have the same functionality available to them.

Diferences between ERC and ESDT

The first difference we observe is that ERC standards are smart contracts deployed on blockchain while ESDTs are tokens assigned to users. In ERC user balances are stored in the Smart Contract while in ESDT balances are stored in users' wallets.

Here are the top MultiversX tokens.

- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html b/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html index 1ca61ba..59d8241 100644 --- a/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html +++ b/Practical Sessions/Wallet/Cmd line wallet/cmdline_wallet/index.html @@ -4,7 +4,7 @@ First Blockchain transaction | Blockchain Protocols and Distributed Applications - + @@ -13,7 +13,7 @@ We will do this on MultiversX blockchain.

First, we need a wallet. Every access, read, write, execute, etc to the blockchain needs to be sign by you with a private key (a wallet).

To create a wallet simply run:

$ mxpy wallet new --format pem --outfile new_wallet.pem

Let's interpret the output:

$ mxpy wallet new --format pem --outfile new_wallet.pem
Mnemonic: bid blind field captain bar produce brush salute luggage double hole wonder meadow glass destroy giraffe auction square crush catalog knee lizard century nasty
Wallet address: erd1pfhel08mq6ucua005qgyvwq0el78ap3ytpcugy35yvqfdeq7afqsydkj3d

First, there is a mnemonic: 24 random words. These words are used to create your private key (wallet) at any time, so you must store them carefully. For now, this is only a test wallet, so just store them in a text file on your computer.

Second, we have a wallet address. This is our blockchain address.

Third, we have a new file new_wallet.pem that contains our private key (wallet):

$ cat new_wallet.pem 
-----BEGIN PRIVATE KEY for erd1pfhel08mq6ucua005qgyvwq0el78ap3ytpcugy35yvqfdeq7afqsydkj3d-----
NjM1N2UxOGQxYjBjMDk5ZjY1MzM2OWUxZGFiZGM3Mzg1Yjc5ZmY0ZWNlZTBiNWY5
NWFmNjE1MzZjZDMwODNhOTBhNmY5ZmJjZmIwNmI5OGU3NWVmYTAxMDQ2MzgwZmNm
ZmM3ZTg2MjQ1ODcxYzQxMjM0MjMwMDk2ZTQxZWVhNDE=
-----END PRIVATE KEY for erd1pfhel08mq6ucua005qgyvwq0el78ap3ytpcugy35yvqfdeq7afqsydkj3d-----
- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/Keystore/index.html b/Practical Sessions/Wallet/Keystore/index.html index 19e541c..fd16af4 100644 --- a/Practical Sessions/Wallet/Keystore/index.html +++ b/Practical Sessions/Wallet/Keystore/index.html @@ -4,7 +4,7 @@ Keystore files | Blockchain Protocols and Distributed Applications - + @@ -17,7 +17,7 @@ kdfparams - The parameters required for the kdf algorithm above; mac - A code used to verify your password. Keystore files created with the first major version of the web wallet (available prior February 14th, 2023) hold the encrypted secret key, instead of the encrypted mnemonic (as the new keystore files do). Though the older files are still compatible with the new web wallet - compatibility is achieved through the aforementioned "kind" field.

When kind is set (or not set at all) to secretKey, the ciphertext field will contain the encrypted secret key, as it did before. However, when kind is set to mnemonic, the ciphertext field will contain the encrypted mnemonic instead.

Auxiliary reference: ERC-2335: BLS12-381 Keystore.

- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/Wallet/index.html b/Practical Sessions/Wallet/Wallet/index.html index 4916390..38ff48e 100644 --- a/Practical Sessions/Wallet/Wallet/index.html +++ b/Practical Sessions/Wallet/Wallet/index.html @@ -4,13 +4,13 @@ Setting up a Wallet via Browser | Blockchain Protocols and Distributed Applications - +
Skip to main content

Setting up a Wallet via Browser

We will use MultiversX Testnet Wallet to participate in the blockchain as a user.

If you already have a wallet, there is no need to create another one.

Go to MultiversX Testnet Wallet and create a new wallet by clicking Create new one.

Testnet Wallet

Carefully read and acknowledge the information, then click "Continue".

Create Wallet

Save your secret phrase! This is very important

Each wallet will have 24 secret words that can be used for recovery.

The words, numbered in order, are your Secret Phrase. They are just displayed on your screen once and not saved on a server or anywhere in the world. You only get one chance to save them - please do so now.

Click the “copy” (two rectangles) button and then paste them into a text file. If your pets don’t usually find important pieces of paper to be delicious, you could even write the words down.

Create Wallet

The next page is a test to see if you actually have saved the Secret Phrase. Enter the random words as indicated there and press "Continue".

You are one step away from getting your Keystore File. First, encrypt it with a password.

Wallet Password

In case you forget this password, you can get a new Keystore File with your secret phrase. Remembering it is always better.

Congratulations, you have a new wallet! The associated Keystore File was downloaded to wherever your browser saves files by default. The file has the actual address of the wallet as default name, something like “erd….json”. You can rename it to “something.json” so it’s easier to manage, if you want.)

- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/browser_wallet/index.html b/Practical Sessions/Wallet/browser_wallet/index.html index f0e49b7..266b1b0 100644 --- a/Practical Sessions/Wallet/browser_wallet/index.html +++ b/Practical Sessions/Wallet/browser_wallet/index.html @@ -4,13 +4,13 @@ Browser Wallet Extension | Blockchain Protocols and Distributed Applications - +
Skip to main content

Browser Wallet Extension

The MultiversX DeFi Wallet can be installed on Firefox, Chrome, Brave, and other chromium-based browsers. This extension is free and secure, with compelling features that allow you to create a new wallet or import existing wallets, manage multiple wallets on the MultiversX mainnet, and store MultiversX tokens such as EGLD, ESDT, or NFTs on the MultiversX Network with easy accessibility.

Follow the tutorial here to install a Browser extension.

- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/faucet/index.html b/Practical Sessions/Wallet/faucet/index.html index 5799e3b..9cc9892 100644 --- a/Practical Sessions/Wallet/faucet/index.html +++ b/Practical Sessions/Wallet/faucet/index.html @@ -4,13 +4,13 @@ Access a wallet | Blockchain Protocols and Distributed Applications - +
Skip to main content

Access a wallet

Go to Testnet Wallet and click on "PEM" (bottom of the screen); click "Select a file" and locate your wallet new_wallet.pem.

Testnet Wallet

And you’re in! Your EGLD address is on top, you can use the “copy” button (the two rectangles) to copy it to the clipboard.

Faucet

You can request test tokens from the Faucet tab.

Faucet

Practice

Request tokens via Faucet functionality.

- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/index.html b/Practical Sessions/Wallet/index.html index f467062..3c69392 100644 --- a/Practical Sessions/Wallet/index.html +++ b/Practical Sessions/Wallet/index.html @@ -4,13 +4,13 @@ Wallet | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/observer/index.html b/Practical Sessions/Wallet/observer/index.html index 3070034..d84a817 100644 --- a/Practical Sessions/Wallet/observer/index.html +++ b/Practical Sessions/Wallet/observer/index.html @@ -4,13 +4,13 @@ Observe transaction via Observers | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/Practical Sessions/Wallet/send_tx/index.html b/Practical Sessions/Wallet/send_tx/index.html index 6687764..1ca0e18 100644 --- a/Practical Sessions/Wallet/send_tx/index.html +++ b/Practical Sessions/Wallet/send_tx/index.html @@ -4,13 +4,13 @@ Send a transaction | Blockchain Protocols and Distributed Applications - +
Skip to main content

Send a transaction

Click "Send" on the right-hand section of the wallet:

Transaction

Input the destination address & amount, and then click "Send".

Send tokens

After confirming the transaction you can see the progress and completion of the transaction.

Practice

Check transaction history in the "Transactions" menu on the left-hand side of the wallet.

Transaction History

Click on the last transaction (Send Transaction) and check the details.

Open that transaction in the Explorer. At the right hand side of the Hash field, click on the magnifier.

Go to Explorer

- + \ No newline at end of file diff --git a/Practical Sessions/index.html b/Practical Sessions/index.html index ba53695..7158c8e 100644 --- a/Practical Sessions/index.html +++ b/Practical Sessions/index.html @@ -4,13 +4,13 @@ Practical Sessions | Blockchain Protocols and Distributed Applications - +
Skip to main content
- + \ No newline at end of file diff --git a/assets/js/d12b36cf.82dd544f.js b/assets/js/d12b36cf.867bd869.js similarity index 64% rename from assets/js/d12b36cf.82dd544f.js rename to assets/js/d12b36cf.867bd869.js index 350af22..c6335d1 100644 --- a/assets/js/d12b36cf.82dd544f.js +++ b/assets/js/d12b36cf.867bd869.js @@ -1 +1 @@ -"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[554],{5680:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>m});var a=n(6540);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=l(n),u=r,m=d["".concat(c,".").concat(u)]||d[u]||g[u]||i;return n?a.createElement(m,s(s({ref:t},p),{},{components:n})):a.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,s=new Array(i);s[0]=u;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[d]="string"==typeof e?e:r,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>g,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var a=n(8168),r=(n(6540),n(5680));const i={},s="Events",o={unversionedId:"Practical Sessions/Smart Contract Events/events",id:"Practical Sessions/Smart Contract Events/events",title:"Events",description:"Key Takeaways:",source:"@site/docs/Practical Sessions/Smart Contract Events/events.md",sourceDirName:"Practical Sessions/Smart Contract Events",slug:"/Practical Sessions/Smart Contract Events/events",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/events",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Smart Contract Events",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/"},next:{title:"Assignments",permalink:"/blockchain-protocols-and-distributed-applications/Assignments/"}},c={},l=[{value:"Example of events",id:"example-of-events",level:2},{value:"Writing your own event in the Smart Contract",id:"writing-your-own-event-in-the-smart-contract",level:2}],p={toc:l},d="wrapper";function g(e){let{components:t,...i}=e;return(0,r.yg)(d,(0,a.A)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"events"},"Events"),(0,r.yg)("p",null,"Key Takeaways:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Events in smart contracts serve as a communication mechanism between the contract and user interfaces;"),(0,r.yg)("li",{parentName:"ul"},"By emitting events, smart contracts can notify external applications or listeners about specific actions or changes;"),(0,r.yg)("li",{parentName:"ul"},"Events play a key role in facilitating effective interaction with user interfaces while ensuring secure automated execution of code-based agreements.")),(0,r.yg)("h2",{id:"example-of-events"},"Example of events"),(0,r.yg)("p",null,"Notice the ",(0,r.yg)("strong",{parentName:"p"},"Logs")," section near the ",(0,r.yg)("strong",{parentName:"p"},"Transaction Details"),".\n",(0,r.yg)("img",{alt:"ESDTNFTCreate",src:n(7096).A,width:"1290",height:"687"})),(0,r.yg)("p",null,"This section shows all the events this transaction emitted.\nNotice that most transactions have this ",(0,r.yg)("strong",{parentName:"p"},"Logs")," section."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"ESDTNFTTransfer",src:n(509).A,width:"1359",height:"920"})),(0,r.yg)("p",null,"Let's open this tab and inspect the Events"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"ESDTNFTTransfer Event",src:n(4132).A,width:"1317",height:"406"})),(0,r.yg)("p",null,"Notice there are 4 data fields:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"SBPT-774fbd")," - the token ID;"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"1")," - the nonce;"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"1")," - the value (the ",(0,r.yg)("em",{parentName:"li"},"Smart")," display feature doesn't know how to interpret that but the ",(0,r.yg)("em",{parentName:"li"},"Decimal")," option does);"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd")," - the destination address.")),(0,r.yg)("p",null,"Let's inspect a more complex operation and check all the log events.\n",(0,r.yg)("a",{parentName:"p",href:"https://explorer.multiversx.com/transactions/4f85a8ca33fb5d7ca336d61e6014d96c57048ffb7ee2d9f290bb0a7c1c7c87ff"},"Here")," is the link to the transaction."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Swap Transaction",src:n(8207).A,width:"1284",height:"864"})),(0,r.yg)("p",null,"Notice that the transaction has 4 transfers and 1 burn operations.\nLet's inspect the logs:"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Swap Event1",src:n(617).A,width:"1284",height:"864"})),(0,r.yg)("p",null,"The first transaction is an ",(0,r.yg)("inlineCode",{parentName:"p"},"ESDTTransfer")," for the token ",(0,r.yg)("inlineCode",{parentName:"p"},"USDC-c76f1f")," which has 6 decimals; therefore ",(0,r.yg)("em",{parentName:"p"},"580345261")," is equal to ",(0,r.yg)("em",{parentName:"p"},"580,345261$"),".\nYou can match the events to the ",(0,r.yg)("strong",{parentName:"p"},"Token Operations")," from the Transacton Details."),(0,r.yg)("p",null,"You can check the ",(0,r.yg)("inlineCode",{parentName:"p"},"deposit_swap_fees_event")," code ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-exchange-sc/blob/e4b95afa68273bab34b4124b711f28af9677e029/energy-integration/fees-collector/src/events.rs#L16"},"here"),"."),(0,r.yg)("p",null,"Notice the burn event below. Keep in mind that ",(0,r.yg)("inlineCode",{parentName:"p"},"MEX-455c57")," has 18 decimals.\n",(0,r.yg)("img",{alt:"Swap Event2",src:n(2434).A,width:"1284",height:"864"})),(0,r.yg)("p",null,(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-exchange-sc/blob/e4b95afa68273bab34b4124b711f28af9677e029/dex/pair/src/events.rs#L202"},"Here")," is the code for the ",(0,r.yg)("inlineCode",{parentName:"p"},"swap_no_fee_and_forward")," event."),(0,r.yg)("h2",{id:"writing-your-own-event-in-the-smart-contract"},"Writing your own event in the Smart Contract"),(0,r.yg)("p",null,"The structure of an event is:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-rust"},' #[event("your_event_name")]\n fn the_function_you_call_when_you_want_to_emit_en_event(\n &self,\n #[indexed] field1: &TokenIdentifier,\n #[indexed] field2: &ManagedAddress,\n #[indexed] field3: u64,\n #[indexed] field4: BigUint,\n );\n')),(0,r.yg)("p",null,"And when you want to emit an event, just call the function:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-rust"}," self.the_function_you_call_when_you_want_to_emit_en_event(field1, field2, field3, field4);\n")))}g.isMDXComponent=!0},7096:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/nft_create-be681b473566e9bc24c351fdbacc607e.png"},509:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/nft_transfer-2319daed87e2152baf71999044f2b81f.png"},4132:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/nft_transfer_event-74d222d148831423cc8228608aef406c.png"},617:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/swap_logs1-8c23d9df87f15dcc8585249c02c9e8b7.png"},2434:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/swap_logs2-304037efc689473f50b9ea4bc560b53d.png"},8207:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/swap_tx-a11141af8c1daf6d3422d1f9621e62dc.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[554],{5680:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>m});var a=n(6540);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=l(n),u=r,m=d["".concat(c,".").concat(u)]||d[u]||g[u]||i;return n?a.createElement(m,s(s({ref:t},p),{},{components:n})):a.createElement(m,s({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,s=new Array(i);s[0]=u;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[d]="string"==typeof e?e:r,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>g,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var a=n(8168),r=(n(6540),n(5680));const i={},s="Events",o={unversionedId:"Practical Sessions/Smart Contract Events/events",id:"Practical Sessions/Smart Contract Events/events",title:"Events",description:"Key Takeaways:",source:"@site/docs/Practical Sessions/Smart Contract Events/events.md",sourceDirName:"Practical Sessions/Smart Contract Events",slug:"/Practical Sessions/Smart Contract Events/events",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/events",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Smart Contract Events",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contract Events/"},next:{title:"Assignments",permalink:"/blockchain-protocols-and-distributed-applications/Assignments/"}},c={},l=[{value:"Example of events",id:"example-of-events",level:2},{value:"Writing your own event in the Smart Contract",id:"writing-your-own-event-in-the-smart-contract",level:2}],p={toc:l},d="wrapper";function g(e){let{components:t,...i}=e;return(0,r.yg)(d,(0,a.A)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"events"},"Events"),(0,r.yg)("p",null,"Key Takeaways:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Events in smart contracts serve as a communication mechanism between the contract and user interfaces;"),(0,r.yg)("li",{parentName:"ul"},"By emitting events, smart contracts can notify external applications or listeners about specific actions or changes;"),(0,r.yg)("li",{parentName:"ul"},"Events play a key role in facilitating effective interaction with user interfaces while ensuring secure automated execution of code-based agreements.")),(0,r.yg)("h2",{id:"example-of-events"},"Example of events"),(0,r.yg)("p",null,"Notice the ",(0,r.yg)("strong",{parentName:"p"},"Logs")," section near the ",(0,r.yg)("strong",{parentName:"p"},"Transaction Details"),".\n",(0,r.yg)("img",{alt:"ESDTNFTCreate",src:n(3648).A,width:"1290",height:"687"})),(0,r.yg)("p",null,"This section shows all the events this transaction emitted.\nNotice that most transactions have this ",(0,r.yg)("strong",{parentName:"p"},"Logs")," section."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"ESDTNFTTransfer",src:n(7029).A,width:"1359",height:"920"})),(0,r.yg)("p",null,"Let's open this tab and inspect the Events"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"ESDTNFTTransfer Event",src:n(684).A,width:"1317",height:"406"})),(0,r.yg)("p",null,"Notice there are 4 data fields:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"SBPT-774fbd")," - the token ID;"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"1")," - the nonce;"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"1")," - the value (the ",(0,r.yg)("em",{parentName:"li"},"Smart")," display feature doesn't know how to interpret that but the ",(0,r.yg)("em",{parentName:"li"},"Decimal")," option does);"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd")," - the destination address.")),(0,r.yg)("p",null,"Let's inspect a more complex operation and check all the log events.\n",(0,r.yg)("a",{parentName:"p",href:"https://explorer.multiversx.com/transactions/4f85a8ca33fb5d7ca336d61e6014d96c57048ffb7ee2d9f290bb0a7c1c7c87ff"},"Here")," is the link to the transaction."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Swap Transaction",src:n(4663).A,width:"1284",height:"864"})),(0,r.yg)("p",null,"Notice that the transaction has 4 transfers and 1 burn operations.\nLet's inspect the logs:"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Swap Event1",src:n(1345).A,width:"1284",height:"864"})),(0,r.yg)("p",null,"The first transaction is an ",(0,r.yg)("inlineCode",{parentName:"p"},"ESDTTransfer")," for the token ",(0,r.yg)("inlineCode",{parentName:"p"},"USDC-c76f1f")," which has 6 decimals; therefore ",(0,r.yg)("em",{parentName:"p"},"580345261")," is equal to ",(0,r.yg)("em",{parentName:"p"},"580,345261$"),".\nYou can match the events to the ",(0,r.yg)("strong",{parentName:"p"},"Token Operations")," from the Transacton Details."),(0,r.yg)("p",null,"You can check the ",(0,r.yg)("inlineCode",{parentName:"p"},"deposit_swap_fees_event")," code ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-exchange-sc/blob/e4b95afa68273bab34b4124b711f28af9677e029/energy-integration/fees-collector/src/events.rs#L16"},"here"),"."),(0,r.yg)("p",null,"Notice the burn event below. Keep in mind that ",(0,r.yg)("inlineCode",{parentName:"p"},"MEX-455c57")," has 18 decimals.\n",(0,r.yg)("img",{alt:"Swap Event2",src:n(1450).A,width:"1284",height:"864"})),(0,r.yg)("p",null,(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-exchange-sc/blob/e4b95afa68273bab34b4124b711f28af9677e029/dex/pair/src/events.rs#L202"},"Here")," is the code for the ",(0,r.yg)("inlineCode",{parentName:"p"},"swap_no_fee_and_forward")," event."),(0,r.yg)("h2",{id:"writing-your-own-event-in-the-smart-contract"},"Writing your own event in the Smart Contract"),(0,r.yg)("p",null,"The structure of an event is:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-rust"},' #[event("your_event_name")]\n fn the_function_you_call_when_you_want_to_emit_en_event(\n &self,\n #[indexed] field1: &TokenIdentifier,\n #[indexed] field2: &ManagedAddress,\n #[indexed] field3: u64,\n #[indexed] field4: BigUint,\n );\n')),(0,r.yg)("p",null,"And when you want to emit an event, just call the function:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-rust"}," self.the_function_you_call_when_you_want_to_emit_en_event(field1, field2, field3, field4);\n")))}g.isMDXComponent=!0},3648:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/nft_create-be681b473566e9bc24c351fdbacc607e.png"},7029:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/nft_transfer-2319daed87e2152baf71999044f2b81f.png"},684:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/nft_transfer_event-74d222d148831423cc8228608aef406c.png"},1345:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/swap_logs1-8c23d9df87f15dcc8585249c02c9e8b7.png"},1450:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/swap_logs2-304037efc689473f50b9ea4bc560b53d.png"},4663:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/swap_tx-a11141af8c1daf6d3422d1f9621e62dc.png"}}]); \ No newline at end of file diff --git a/assets/js/d92a3c43.73052009.js b/assets/js/d92a3c43.337d04a0.js similarity index 52% rename from assets/js/d92a3c43.73052009.js rename to assets/js/d92a3c43.337d04a0.js index 2de593b..b88ef02 100644 --- a/assets/js/d92a3c43.73052009.js +++ b/assets/js/d92a3c43.337d04a0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[8864],{5680:(e,t,n)=>{n.d(t,{xA:()=>u,yg:()=>g});var r=n(6540);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=a,g=c["".concat(s,".").concat(d)]||c[d]||m[d]||i;return n?r.createElement(g,o(o({ref:t},u),{},{components:n})):r.createElement(g,o({ref:t},u))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var r=n(8168),a=(n(6540),n(5680));const i={},o="Resources and Useful Links",l={unversionedId:"resources",id:"resources",title:"Resources and Useful Links",description:"List of Resources:",source:"@site/docs/resources.md",sourceDirName:".",slug:"/resources",permalink:"/blockchain-protocols-and-distributed-applications/resources",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Grading",permalink:"/blockchain-protocols-and-distributed-applications/grading"}},s={},p=[{value:"List of Resources:",id:"list-of-resources",level:2},{value:"Books and interesting reading materials",id:"books-and-interesting-reading-materials",level:2},{value:"Virtual Machine",id:"virtual-machine",level:2},{value:"VirtualBox / VMware",id:"virtualbox--vmware",level:3},{value:"UTM (macOS >= 11)",id:"utm-macos--11",level:3}],u={toc:p},c="wrapper";function m(e){let{components:t,...n}=e;return(0,a.yg)(c,(0,r.A)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.yg)("h1",{id:"resources-and-useful-links"},"Resources and Useful Links"),(0,a.yg)("h2",{id:"list-of-resources"},"List of Resources:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://github.com/CostinCarabas/blockchain-protocols-and-distributed-applications"},"GitHub Repository")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://curs.upb.ro/2024/course/view.php?id=1947"},"Moodle Class")," (used for homework submissions, quizzes, announcements, etc.)")),(0,a.yg)("h2",{id:"books-and-interesting-reading-materials"},"Books and interesting reading materials"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"http://elaineshi.com/docs/blockchain-book.pdf"},"Foundations of Distributed Consensus and Blockchains")," - must read book for blockchain protocol enthusiasts;"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://www.lynalden.com/open-networks/"},"Implications of Open Monetary and Information Networks")," - read to form an intuition about the need for blockchain and decentralized solutions;"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://bitcoin.org/bitcoin.pdf"},"Bitcoin Whitepaper"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://ethereum.org/en/whitepaper/"},"Ethereum Whitepaper"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://files.multiversx.com/multiversx-whitepaper.pdf"},"MultiversX Whitepaper"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"docs/state-of-crypto.pdf"},"State of Crypto")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://roadmap.sh/blockchain"},"Step by step guide to becoming a blockchain developer in 2024"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/workflow.md#secure-development-workflow"},"Secure Development Workflow for Smart Contracts"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"docs/defi.pdf"},"DeFi Handbook \u2014 Introduction to Decentralized Finance")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://cryptozombies.io/en/multiversx"},"Cryptozombies learning game"))),(0,a.yg)("h2",{id:"virtual-machine"},"Virtual Machine"),(0,a.yg)("p",null,"You can use any Linux environment (native install, ",(0,a.yg)("inlineCode",{parentName:"p"},"WSL"),", virtual machine, docker environment, etc.) for the OS class.\nWe provide Linux virtual machines with all the setup ready."),(0,a.yg)("h3",{id:"virtualbox--vmware"},"VirtualBox / VMware"),(0,a.yg)("p",null,"You can download the Linux virtual machine from ",(0,a.yg)("a",{parentName:"p",href:"https://repository.grid.pub.ro/cs/so/linux-2024/so-vm.ova"},"this link"),".\nYou will need to log in using your ",(0,a.yg)("inlineCode",{parentName:"p"},"UPB")," account."),(0,a.yg)("p",null,"You can import the ",(0,a.yg)("inlineCode",{parentName:"p"},".ova")," file in ",(0,a.yg)("a",{parentName:"p",href:"https://www.virtualbox.org/"},"VirtualBox")," or ",(0,a.yg)("a",{parentName:"p",href:"https://www.vmware.com/"},"VMware"),".\nFollow the instructions on the official websites for installation."),(0,a.yg)("h3",{id:"utm-macos--11"},"UTM (macOS >= 11)"),(0,a.yg)("p",null,"If you are using an ",(0,a.yg)("inlineCode",{parentName:"p"},"M1")," Apple system, you will not be able to run the virtual machine using VirtualBox or VMware.\nYou will need to use ",(0,a.yg)("a",{parentName:"p",href:"https://mac.getutm.app/"},(0,a.yg)("inlineCode",{parentName:"a"},"UTM")),", along with a ",(0,a.yg)("a",{parentName:"p",href:"https://repository.grid.pub.ro/cs/so/linux-2024/SO-Ubuntu-22-04-03-LTS.utm.zip"},(0,a.yg)("inlineCode",{parentName:"a"},".qcow2"))," image.\nYou will need to log in using your ",(0,a.yg)("inlineCode",{parentName:"p"},"UPB")," account."),(0,a.yg)("p",null,"After you install ",(0,a.yg)("inlineCode",{parentName:"p"},"UTM")," and download and unzip the archive, you can import it using the ",(0,a.yg)("inlineCode",{parentName:"p"},"Open existing VM")," option in ",(0,a.yg)("inlineCode",{parentName:"p"},"UTM"),"."),(0,a.yg)("p",null,"You can also follow the instructions for ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/cs-pub-ro/operating-systems/blob/main/util/macos-vm/README.md"},"running the VM using ",(0,a.yg)("inlineCode",{parentName:"a"},"qemu")),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[8864],{5680:(e,t,r)=>{r.d(t,{xA:()=>u,yg:()=>g});var n=r(6540);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(r),d=a,g=c["".concat(s,".").concat(d)]||c[d]||m[d]||i;return r?n.createElement(g,o(o({ref:t},u),{},{components:r})):n.createElement(g,o({ref:t},u))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=r(8168),a=(r(6540),r(5680));const i={},o="Resources and Useful Links",l={unversionedId:"resources",id:"resources",title:"Resources and Useful Links",description:"List of Resources:",source:"@site/docs/resources.md",sourceDirName:".",slug:"/resources",permalink:"/blockchain-protocols-and-distributed-applications/resources",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Grading",permalink:"/blockchain-protocols-and-distributed-applications/grading"}},s={},p=[{value:"List of Resources:",id:"list-of-resources",level:2},{value:"Books and interesting reading materials",id:"books-and-interesting-reading-materials",level:2},{value:"Virtual Machine",id:"virtual-machine",level:2},{value:"VirtualBox / VMware",id:"virtualbox--vmware",level:3},{value:"UTM (macOS >= 11)",id:"utm-macos--11",level:3}],u={toc:p},c="wrapper";function m(e){let{components:t,...r}=e;return(0,a.yg)(c,(0,n.A)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.yg)("h1",{id:"resources-and-useful-links"},"Resources and Useful Links"),(0,a.yg)("h2",{id:"list-of-resources"},"List of Resources:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://github.com/CostinCarabas/blockchain-protocols-and-distributed-applications"},"GitHub Repository")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://curs.upb.ro/2024/course/view.php?id=1947"},"Moodle Class")," (used for homework submissions, quizzes, announcements, etc.)")),(0,a.yg)("h2",{id:"books-and-interesting-reading-materials"},"Books and interesting reading materials"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"http://elaineshi.com/docs/blockchain-book.pdf"},"Foundations of Distributed Consensus and Blockchains")," - must read book for blockchain protocol enthusiasts;"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://www.lynalden.com/open-networks/"},"Implications of Open Monetary and Information Networks")," - read to form an intuition about the need for blockchain and decentralized solutions;"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://bitcoin.org/bitcoin.pdf"},"Bitcoin Whitepaper"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://ethereum.org/en/whitepaper/"},"Ethereum Whitepaper"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://files.multiversx.com/multiversx-whitepaper.pdf"},"MultiversX Whitepaper"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"docs/state-of-crypto.pdf"},"State of Crypto")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://roadmap.sh/blockchain"},"Step by step guide to becoming a blockchain developer in 2024"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/workflow.md#secure-development-workflow"},"Secure Development Workflow for Smart Contracts"),";"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"docs/defi.pdf"},"DeFi Handbook \u2014 Introduction to Decentralized Finance")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"https://cryptozombies.io/en/multiversx"},"Cryptozombies learning game"))),(0,a.yg)("h2",{id:"virtual-machine"},"Virtual Machine"),(0,a.yg)("p",null,"You can use any Linux environment (native install, ",(0,a.yg)("inlineCode",{parentName:"p"},"WSL"),", virtual machine, docker environment, etc.) for the OS class.\nWe provide Linux virtual machines with all the setup ready."),(0,a.yg)("h3",{id:"virtualbox--vmware"},"VirtualBox / VMware"),(0,a.yg)("p",null,"You can download the Linux virtual machine from ",(0,a.yg)("a",{parentName:"p",href:"https://repository.grid.pub.ro/cs/so/linux-2024-2025/so-vm-gui-2024.ova"},"this link"),"."),(0,a.yg)("p",null,"You can import the ",(0,a.yg)("inlineCode",{parentName:"p"},".ova")," file in ",(0,a.yg)("a",{parentName:"p",href:"https://www.virtualbox.org/"},"VirtualBox")," or ",(0,a.yg)("a",{parentName:"p",href:"https://www.vmware.com/"},"VMware"),".\nFollow the instructions on the official websites for installation."),(0,a.yg)("h3",{id:"utm-macos--11"},"UTM (macOS >= 11)"),(0,a.yg)("p",null,"If you are using an ",(0,a.yg)("inlineCode",{parentName:"p"},"M1")," Apple system, you will not be able to run the virtual machine using VirtualBox or VMware.\nYou will need to use ",(0,a.yg)("a",{parentName:"p",href:"https://mac.getutm.app/"},(0,a.yg)("inlineCode",{parentName:"a"},"UTM")),", along with a ",(0,a.yg)("a",{parentName:"p",href:"https://repository.grid.pub.ro/cs/so/linux-2024/SO-Ubuntu-22-04-03-LTS.utm.zip"},(0,a.yg)("inlineCode",{parentName:"a"},".qcow2"))," image."),(0,a.yg)("p",null,"After you install ",(0,a.yg)("inlineCode",{parentName:"p"},"UTM")," and download and unzip the archive, you can import it using the ",(0,a.yg)("inlineCode",{parentName:"p"},"Open existing VM")," option in ",(0,a.yg)("inlineCode",{parentName:"p"},"UTM"),"."),(0,a.yg)("p",null,"You can also follow the instructions for ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/cs-pub-ro/operating-systems/blob/main/util/macos-vm/README.md"},"running the VM using ",(0,a.yg)("inlineCode",{parentName:"a"},"qemu")),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f3ef1ad2.f98e2f0b.js b/assets/js/f3ef1ad2.8b875d3f.js similarity index 98% rename from assets/js/f3ef1ad2.f98e2f0b.js rename to assets/js/f3ef1ad2.8b875d3f.js index 9f79c31..fdec282 100644 --- a/assets/js/f3ef1ad2.f98e2f0b.js +++ b/assets/js/f3ef1ad2.8b875d3f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[6419],{5680:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>u});var a=n(6540);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),l=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(i.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=l(n),y=r,u=d["".concat(i,".").concat(y)]||d[y]||m[y]||o;return n?a.createElement(u,s(s({ref:t},p),{},{components:n})):a.createElement(u,s({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=y;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[d]="string"==typeof e?e:r,s[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var a=n(8168),r=(n(6540),n(5680));const o={},s="Smart Contract deployment",c={unversionedId:"Practical Sessions/Smart Contracts/deploy",id:"Practical Sessions/Smart Contracts/deploy",title:"Smart Contract deployment",description:"Let's deploy our first smart contract on the blockchain. For this we will use mxpy tools previously installed.",source:"@site/docs/Practical Sessions/Smart Contracts/deploy.md",sourceDirName:"Practical Sessions/Smart Contracts",slug:"/Practical Sessions/Smart Contracts/deploy",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/deploy",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"The Adder SC",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/adder"},next:{title:"Smart Contract call",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/sc_call"}},i={},l=[],p={toc:l},d="wrapper";function m(e){let{components:t,...o}=e;return(0,r.yg)(d,(0,a.A)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"smart-contract-deployment"},"Smart Contract deployment"),(0,r.yg)("p",null,"Let's deploy our first smart contract on the blockchain. For this we will use ",(0,r.yg)("inlineCode",{parentName:"p"},"mxpy")," tools previously installed.\nWe will deploy the ",(0,r.yg)("inlineCode",{parentName:"p"},"adder")," contract from the previous section."),(0,r.yg)("p",null,"In the ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-contracts-rs/tree/main/contracts/adder/"},"repo")," there is a folder named ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-contracts-rs/tree/main/contracts/adder/interaction"},"interaction"),"."),(0,r.yg)("p",null,"Let's inspect the ",(0,r.yg)("inlineCode",{parentName:"p"},"testnet.snippets.sh")," file:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},'ALICE="${USERS}/alice.pem"\nADDRESS=$(mxpy data load --key=address-testnet)\nDEPLOY_TRANSACTION=$(mxpy data load --key=deployTransaction-testnet)\nPROXY=https://testnet-api.multiversx.com\n\ndeploy() {\n mxpy --verbose contract deploy --project=${PROJECT} --recall-nonce --pem=${ALICE} --gas-limit=50000000 --arguments 0 --send --outfile="deploy-testnet.interaction.json" --proxy=${PROXY} --chain=T || return\n\n TRANSACTION=$(mxpy data parse --file="deploy-testnet.interaction.json" --expression="data[\'emittedTransactionHash\']")\n ADDRESS=$(mxpy data parse --file="deploy-testnet.interaction.json" --expression="data[\'contractAddress\']")\n\n mxpy data store --key=address-testnet --value=${ADDRESS}\n mxpy data store --key=deployTransaction-testnet --value=${TRANSACTION}\n\n echo ""\n echo "Smart contract address: ${ADDRESS}"\n}\n\nadd() {\n read -p "Enter number: " NUMBER\n mxpy --verbose contract call ${ADDRESS} --recall-nonce --pem=${ALICE} --gas-limit=5000000 --function="add" --arguments ${NUMBER} --send --proxy=${PROXY} --chain=T\n}\n\ngetSum() {\n mxpy --verbose contract query ${ADDRESS} --function="getSum" --proxy=${PROXY}\n}\n')),(0,r.yg)("p",null,"This file helps us to easily make deployment and transactions on the blockchain."),(0,r.yg)("p",null,"First, let's modify the ",(0,r.yg)("inlineCode",{parentName:"p"},"ALICE")," variable and put our own ",(0,r.yg)("inlineCode",{parentName:"p"},"pem")," file."),(0,r.yg)("p",null,"After that use ",(0,r.yg)("inlineCode",{parentName:"p"},"source")," command or ",(0,r.yg)("inlineCode",{parentName:"p"},".")," in bash to interpret the file:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ . testnet.snippets.sh \n")),(0,r.yg)("p",null,"This will load all the variables and functions in the environment.\nNow we can call the ",(0,r.yg)("inlineCode",{parentName:"p"},"deploy")," function:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ deploy\nDEBUG:cli.contracts:deploy\nDEBUG:accounts:AccountBase.sync_nonce()\nDEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443\nDEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 \"GET /address/erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd HTTP/1.1\" 200 363\nDEBUG:accounts:AccountBase.sync_nonce() done: 1\nINFO:cli.contracts:Contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4\nINFO:utils:View this contract address in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/accounts/erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4\nINFO:transactions:Transaction.send: nonce=1\nDEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443\nDEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 \"POST /transaction/send HTTP/1.1\" 201 106\nINFO:transactions:Hash: 09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1\nINFO:utils:View this transaction in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1\nWARNING:cli.data:Always review --expression parameters before executing this command!\nWARNING:cli.data:Always review --expression parameters before executing this command!\nWARNING:cli.data:Never use this command to store sensitive information! Data is unencrypted.\nINFO:cli.data:Data has been stored at key = 'address-testnet', in partition = '*'.\nWARNING:cli.data:Never use this command to store sensitive information! Data is unencrypted.\nINFO:cli.data:Data has been stored at key = 'deployTransaction-testnet', in partition = '*'.\n\nSmart contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4\n")),(0,r.yg)("p",null,"Now we have performed a deployment of the wasm binary (our adder contract) in the blockchain."),(0,r.yg)("p",null,"Notice the ",(0,r.yg)("em",{parentName:"p"},"MultiversX Testnet Explorer: ",(0,r.yg)("a",{parentName:"em",href:"https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1"},"https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1")),".\nClick on the link to see your transaction. "),(0,r.yg)("p",null,"Notice the ",(0,r.yg)("em",{parentName:"p"},"Smart contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4"),".\nGo to the ",(0,r.yg)("a",{parentName:"p",href:"https://testnet-explorer.multiversx.com"},"Testnet Explorer")," and search for your SC address."),(0,r.yg)("p",null,"Notice the contract deployed on testnet:"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Contract deployed on Testnet",src:n(5425).A,width:"1425",height:"656"})),(0,r.yg)("p",null,"Observe the fields ",(0,r.yg)("strong",{parentName:"p"},"Owner"),", ",(0,r.yg)("strong",{parentName:"p"},"Deployed")," (timestamp)."))}m.isMDXComponent=!0},5425:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/contract-7f54c1dcbaef7ff56c843d1e668d5b86.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkblockchain_protocols_and_distributed_applications=self.webpackChunkblockchain_protocols_and_distributed_applications||[]).push([[6419],{5680:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>u});var a=n(6540);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),l=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(i.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=l(n),y=r,u=d["".concat(i,".").concat(y)]||d[y]||m[y]||o;return n?a.createElement(u,s(s({ref:t},p),{},{components:n})):a.createElement(u,s({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=y;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[d]="string"==typeof e?e:r,s[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var a=n(8168),r=(n(6540),n(5680));const o={},s="Smart Contract deployment",c={unversionedId:"Practical Sessions/Smart Contracts/deploy",id:"Practical Sessions/Smart Contracts/deploy",title:"Smart Contract deployment",description:"Let's deploy our first smart contract on the blockchain. For this we will use mxpy tools previously installed.",source:"@site/docs/Practical Sessions/Smart Contracts/deploy.md",sourceDirName:"Practical Sessions/Smart Contracts",slug:"/Practical Sessions/Smart Contracts/deploy",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/deploy",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"The Adder SC",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/adder"},next:{title:"Smart Contract call",permalink:"/blockchain-protocols-and-distributed-applications/Practical Sessions/Smart Contracts/sc_call"}},i={},l=[],p={toc:l},d="wrapper";function m(e){let{components:t,...o}=e;return(0,r.yg)(d,(0,a.A)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"smart-contract-deployment"},"Smart Contract deployment"),(0,r.yg)("p",null,"Let's deploy our first smart contract on the blockchain. For this we will use ",(0,r.yg)("inlineCode",{parentName:"p"},"mxpy")," tools previously installed.\nWe will deploy the ",(0,r.yg)("inlineCode",{parentName:"p"},"adder")," contract from the previous section."),(0,r.yg)("p",null,"In the ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-contracts-rs/tree/main/contracts/adder/"},"repo")," there is a folder named ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/multiversx/mx-contracts-rs/tree/main/contracts/adder/interaction"},"interaction"),"."),(0,r.yg)("p",null,"Let's inspect the ",(0,r.yg)("inlineCode",{parentName:"p"},"testnet.snippets.sh")," file:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},'ALICE="${USERS}/alice.pem"\nADDRESS=$(mxpy data load --key=address-testnet)\nDEPLOY_TRANSACTION=$(mxpy data load --key=deployTransaction-testnet)\nPROXY=https://testnet-api.multiversx.com\n\ndeploy() {\n mxpy --verbose contract deploy --project=${PROJECT} --recall-nonce --pem=${ALICE} --gas-limit=50000000 --arguments 0 --send --outfile="deploy-testnet.interaction.json" --proxy=${PROXY} --chain=T || return\n\n TRANSACTION=$(mxpy data parse --file="deploy-testnet.interaction.json" --expression="data[\'emittedTransactionHash\']")\n ADDRESS=$(mxpy data parse --file="deploy-testnet.interaction.json" --expression="data[\'contractAddress\']")\n\n mxpy data store --key=address-testnet --value=${ADDRESS}\n mxpy data store --key=deployTransaction-testnet --value=${TRANSACTION}\n\n echo ""\n echo "Smart contract address: ${ADDRESS}"\n}\n\nadd() {\n read -p "Enter number: " NUMBER\n mxpy --verbose contract call ${ADDRESS} --recall-nonce --pem=${ALICE} --gas-limit=5000000 --function="add" --arguments ${NUMBER} --send --proxy=${PROXY} --chain=T\n}\n\ngetSum() {\n mxpy --verbose contract query ${ADDRESS} --function="getSum" --proxy=${PROXY}\n}\n')),(0,r.yg)("p",null,"This file helps us to easily make deployment and transactions on the blockchain."),(0,r.yg)("p",null,"First, let's modify the ",(0,r.yg)("inlineCode",{parentName:"p"},"ALICE")," variable and put our own ",(0,r.yg)("inlineCode",{parentName:"p"},"pem")," file."),(0,r.yg)("p",null,"After that use ",(0,r.yg)("inlineCode",{parentName:"p"},"source")," command or ",(0,r.yg)("inlineCode",{parentName:"p"},".")," in bash to interpret the file:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ . testnet.snippets.sh \n")),(0,r.yg)("p",null,"This will load all the variables and functions in the environment.\nNow we can call the ",(0,r.yg)("inlineCode",{parentName:"p"},"deploy")," function:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-bash"},"costin@Byblos:~/mvx/mx-contracts-rs/contracts/adder/interaction$ deploy\nDEBUG:cli.contracts:deploy\nDEBUG:accounts:AccountBase.sync_nonce()\nDEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443\nDEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 \"GET /address/erd1ld6er5zpdze3cynzkapur9qhzh826jje6n87g7tvdfrtszs8jn2qv44nqd HTTP/1.1\" 200 363\nDEBUG:accounts:AccountBase.sync_nonce() done: 1\nINFO:cli.contracts:Contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4\nINFO:utils:View this contract address in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/accounts/erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4\nINFO:transactions:Transaction.send: nonce=1\nDEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): testnet-api.multiversx.com:443\nDEBUG:urllib3.connectionpool:https://testnet-api.multiversx.com:443 \"POST /transaction/send HTTP/1.1\" 201 106\nINFO:transactions:Hash: 09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1\nINFO:utils:View this transaction in the MultiversX Testnet Explorer: https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1\nWARNING:cli.data:Always review --expression parameters before executing this command!\nWARNING:cli.data:Always review --expression parameters before executing this command!\nWARNING:cli.data:Never use this command to store sensitive information! Data is unencrypted.\nINFO:cli.data:Data has been stored at key = 'address-testnet', in partition = '*'.\nWARNING:cli.data:Never use this command to store sensitive information! Data is unencrypted.\nINFO:cli.data:Data has been stored at key = 'deployTransaction-testnet', in partition = '*'.\n\nSmart contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4\n")),(0,r.yg)("p",null,"Now we have performed a deployment of the wasm binary (our adder contract) in the blockchain."),(0,r.yg)("p",null,"Notice the ",(0,r.yg)("em",{parentName:"p"},"MultiversX Testnet Explorer: ",(0,r.yg)("a",{parentName:"em",href:"https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1"},"https://testnet-explorer.multiversx.com/transactions/09756e622aea6682f8108661270eb0bfe4503fae9ebd1e0253e179daaabbcbe1")),".\nClick on the link to see your transaction. "),(0,r.yg)("p",null,"Notice the ",(0,r.yg)("em",{parentName:"p"},"Smart contract address: erd1qqqqqqqqqqqqqpgqgjdcmz3049s0g2zwm6dzfrnk5s3qwn8yjn2qltmga4"),".\nGo to the ",(0,r.yg)("a",{parentName:"p",href:"https://testnet-explorer.multiversx.com"},"Testnet Explorer")," and search for your SC address."),(0,r.yg)("p",null,"Notice the contract deployed on testnet:"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Contract deployed on Testnet",src:n(7241).A,width:"1425",height:"656"})),(0,r.yg)("p",null,"Observe the fields ",(0,r.yg)("strong",{parentName:"p"},"Owner"),", ",(0,r.yg)("strong",{parentName:"p"},"Deployed")," (timestamp)."))}m.isMDXComponent=!0},7241:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/contract-7f54c1dcbaef7ff56c843d1e668d5b86.png"}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.745a0bd2.js b/assets/js/runtime~main.5f9099f6.js similarity index 97% rename from assets/js/runtime~main.745a0bd2.js rename to assets/js/runtime~main.5f9099f6.js index 44502a8..b3a9619 100644 --- a/assets/js/runtime~main.745a0bd2.js +++ b/assets/js/runtime~main.5f9099f6.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,d,f,t,b={},c={};function r(e){var a=c[e];if(void 0!==a)return a.exports;var d=c[e]={id:e,loaded:!1,exports:{}};return b[e].call(d.exports,d,d.exports,r),d.loaded=!0,d.exports}r.m=b,r.c=c,e=[],r.O=(a,d,f,t)=>{if(!d){var b=1/0;for(i=0;i=t)&&Object.keys(r.O).every((e=>r.O[e](d[o])))?d.splice(o--,1):(c=!1,t0&&e[i-1][2]>t;i--)e[i]=e[i-1];e[i]=[d,f,t]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},d=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var t=Object.create(null);r.r(t);var b={};a=a||[null,d({}),d([]),d(d)];for(var c=2&f&&e;"object"==typeof c&&!~a.indexOf(c);c=d(c))Object.getOwnPropertyNames(c).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(t,b),t},r.d=(e,a)=>{for(var d in a)r.o(a,d)&&!r.o(e,d)&&Object.defineProperty(e,d,{enumerable:!0,get:a[d]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,d)=>(r.f[d](e,a),a)),[])),r.u=e=>"assets/js/"+({196:"9da79274",371:"ccf76c4f",551:"4f869f09",554:"d12b36cf",674:"f09f4349",733:"83609664",762:"7848bf17",775:"3ac942f0",1090:"143dbf3b",1932:"62717f00",1958:"bb46bb8c",2018:"061587e1",2200:"1128852d",2278:"23374ca6",2421:"1523e34e",2830:"3b260257",2848:"9fc7fbc1",2893:"85f8441f",3140:"053840e8",3316:"215797bb",3798:"e75b870c",3884:"e3ece220",4009:"2ee066bd",4134:"393be207",4292:"76ada497",4390:"5e99f083",4484:"51e4ea00",4503:"f4bc3419",4620:"f6a805cd",5020:"14403852",5047:"4e4a4c47",5193:"0de68a20",5205:"6d865e2f",5362:"ed4d6624",5637:"507276da",5673:"b9e8fd80",5688:"5712a78f",5758:"9912e575",5830:"d1095428",5978:"62ff5f97",6061:"1f391b9e",6314:"b080bbe4",6419:"f3ef1ad2",6927:"3f645037",6969:"14eb3368",7088:"9b4ccf33",7168:"56a89565",7202:"dcd0bb0b",7361:"bd1b2524",7927:"83258dd0",7960:"528d1b10",8387:"eb02a9a6",8401:"17896441",8581:"935f2afb",8678:"5536eb16",8714:"1be78505",8758:"5cd13e5c",8770:"f57012b0",8864:"d92a3c43",8878:"1cd07dfb",9095:"4a9b7d7d",9114:"706697ec",9143:"695c3a47",9218:"01497563",9793:"078b4cd8",9932:"85df453d"}[e]||e)+"."+{196:"4ea87710",371:"a033e710",551:"db28beba",554:"82dd544f",674:"a3987bcf",733:"828d0b42",762:"76051c0c",775:"77dda5be",1090:"c83d5873",1774:"98b7b215",1932:"259cc815",1958:"527798a0",2018:"1482aad8",2200:"1e0cb43b",2278:"f37f2bd5",2421:"4afb90b9",2830:"e995ffea",2848:"943e80cf",2893:"3f487fa6",3140:"5c5adf15",3316:"ac85eda9",3798:"d1f674a5",3884:"685cd67e",4009:"73bc3e6b",4134:"21a35a55",4292:"0f91b507",4390:"6ee33848",4484:"85657a69",4503:"bccc60ea",4567:"48a79152",4620:"0af55769",5020:"119d86fd",5047:"b54cd082",5193:"b4a3feb0",5205:"a70b1104",5362:"bccb49ad",5637:"3cd34f31",5673:"c464f199",5688:"fadd65f0",5758:"aeea487b",5830:"beb8b1b5",5978:"e6068bcd",6061:"3f5d37e4",6314:"61085227",6419:"f98e2f0b",6927:"e9e2c05b",6969:"143050e2",7088:"ec91dff8",7168:"9b15d354",7202:"b985e13c",7361:"26c63d43",7927:"ab6f80d1",7960:"714d4d67",8387:"4b1d571e",8401:"62e76f39",8581:"8bb20c07",8678:"4e6f64e6",8714:"6af14fa3",8758:"2e26f813",8770:"675901e5",8864:"73052009",8878:"147abf33",9095:"38740ee7",9114:"9af80d36",9143:"922438c1",9218:"a93fff41",9793:"b7281600",9932:"3fd5d4a8"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},t="blockchain-protocols-and-distributed-applications:",r.l=(e,a,d,b)=>{if(f[e])f[e].push(a);else{var c,o;if(void 0!==d)for(var n=document.getElementsByTagName("script"),i=0;i{c.onerror=c.onload=null,clearTimeout(s);var t=f[e];if(delete f[e],c.parentNode&&c.parentNode.removeChild(c),t&&t.forEach((e=>e(d))),a)return a(d)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:c}),12e4);c.onerror=u.bind(null,c.onerror),c.onload=u.bind(null,c.onload),o&&document.head.appendChild(c)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/blockchain-protocols-and-distributed-applications/",r.gca=function(e){return e={14403852:"5020",17896441:"8401",83609664:"733","9da79274":"196",ccf76c4f:"371","4f869f09":"551",d12b36cf:"554",f09f4349:"674","7848bf17":"762","3ac942f0":"775","143dbf3b":"1090","62717f00":"1932",bb46bb8c:"1958","061587e1":"2018","1128852d":"2200","23374ca6":"2278","1523e34e":"2421","3b260257":"2830","9fc7fbc1":"2848","85f8441f":"2893","053840e8":"3140","215797bb":"3316",e75b870c:"3798",e3ece220:"3884","2ee066bd":"4009","393be207":"4134","76ada497":"4292","5e99f083":"4390","51e4ea00":"4484",f4bc3419:"4503",f6a805cd:"4620","4e4a4c47":"5047","0de68a20":"5193","6d865e2f":"5205",ed4d6624:"5362","507276da":"5637",b9e8fd80:"5673","5712a78f":"5688","9912e575":"5758",d1095428:"5830","62ff5f97":"5978","1f391b9e":"6061",b080bbe4:"6314",f3ef1ad2:"6419","3f645037":"6927","14eb3368":"6969","9b4ccf33":"7088","56a89565":"7168",dcd0bb0b:"7202",bd1b2524:"7361","83258dd0":"7927","528d1b10":"7960",eb02a9a6:"8387","935f2afb":"8581","5536eb16":"8678","1be78505":"8714","5cd13e5c":"8758",f57012b0:"8770",d92a3c43:"8864","1cd07dfb":"8878","4a9b7d7d":"9095","706697ec":"9114","695c3a47":"9143","01497563":"9218","078b4cd8":"9793","85df453d":"9932"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,d)=>{var f=r.o(e,a)?e[a]:void 0;if(0!==f)if(f)d.push(f[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var t=new Promise(((d,t)=>f=e[a]=[d,t]));d.push(f[2]=t);var b=r.p+r.u(a),c=new Error;r.l(b,(d=>{if(r.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var t=d&&("load"===d.type?"missing":d.type),b=d&&d.target&&d.target.src;c.message="Loading chunk "+a+" failed.\n("+t+": "+b+")",c.name="ChunkLoadError",c.type=t,c.request=b,f[1](c)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,d)=>{var f,t,b=d[0],c=d[1],o=d[2],n=0;if(b.some((a=>0!==e[a]))){for(f in c)r.o(c,f)&&(r.m[f]=c[f]);if(o)var i=o(r)}for(a&&a(d);n{"use strict";var e,a,d,f,t,b={},c={};function r(e){var a=c[e];if(void 0!==a)return a.exports;var d=c[e]={id:e,loaded:!1,exports:{}};return b[e].call(d.exports,d,d.exports,r),d.loaded=!0,d.exports}r.m=b,r.c=c,e=[],r.O=(a,d,f,t)=>{if(!d){var b=1/0;for(i=0;i=t)&&Object.keys(r.O).every((e=>r.O[e](d[o])))?d.splice(o--,1):(c=!1,t0&&e[i-1][2]>t;i--)e[i]=e[i-1];e[i]=[d,f,t]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},d=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var t=Object.create(null);r.r(t);var b={};a=a||[null,d({}),d([]),d(d)];for(var c=2&f&&e;"object"==typeof c&&!~a.indexOf(c);c=d(c))Object.getOwnPropertyNames(c).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(t,b),t},r.d=(e,a)=>{for(var d in a)r.o(a,d)&&!r.o(e,d)&&Object.defineProperty(e,d,{enumerable:!0,get:a[d]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,d)=>(r.f[d](e,a),a)),[])),r.u=e=>"assets/js/"+({196:"9da79274",371:"ccf76c4f",551:"4f869f09",554:"d12b36cf",674:"f09f4349",733:"83609664",762:"7848bf17",775:"3ac942f0",1090:"143dbf3b",1932:"62717f00",1958:"bb46bb8c",2018:"061587e1",2200:"1128852d",2278:"23374ca6",2421:"1523e34e",2830:"3b260257",2848:"9fc7fbc1",2893:"85f8441f",3140:"053840e8",3316:"215797bb",3798:"e75b870c",3884:"e3ece220",4009:"2ee066bd",4134:"393be207",4292:"76ada497",4390:"5e99f083",4484:"51e4ea00",4503:"f4bc3419",4620:"f6a805cd",5020:"14403852",5047:"4e4a4c47",5193:"0de68a20",5205:"6d865e2f",5362:"ed4d6624",5637:"507276da",5673:"b9e8fd80",5688:"5712a78f",5758:"9912e575",5830:"d1095428",5978:"62ff5f97",6061:"1f391b9e",6314:"b080bbe4",6419:"f3ef1ad2",6927:"3f645037",6969:"14eb3368",7088:"9b4ccf33",7168:"56a89565",7202:"dcd0bb0b",7361:"bd1b2524",7927:"83258dd0",7960:"528d1b10",8387:"eb02a9a6",8401:"17896441",8581:"935f2afb",8678:"5536eb16",8714:"1be78505",8758:"5cd13e5c",8770:"f57012b0",8864:"d92a3c43",8878:"1cd07dfb",9095:"4a9b7d7d",9114:"706697ec",9143:"695c3a47",9218:"01497563",9793:"078b4cd8",9932:"85df453d"}[e]||e)+"."+{196:"4ea87710",371:"a033e710",551:"db28beba",554:"867bd869",674:"a3987bcf",733:"828d0b42",762:"76051c0c",775:"77dda5be",1090:"c83d5873",1774:"98b7b215",1932:"259cc815",1958:"527798a0",2018:"1482aad8",2200:"1e0cb43b",2278:"f37f2bd5",2421:"4afb90b9",2830:"e995ffea",2848:"943e80cf",2893:"3f487fa6",3140:"5c5adf15",3316:"ac85eda9",3798:"d1f674a5",3884:"685cd67e",4009:"73bc3e6b",4134:"21a35a55",4292:"0f91b507",4390:"6ee33848",4484:"85657a69",4503:"bccc60ea",4567:"48a79152",4620:"0af55769",5020:"119d86fd",5047:"b54cd082",5193:"b4a3feb0",5205:"a70b1104",5362:"bccb49ad",5637:"3cd34f31",5673:"c464f199",5688:"fadd65f0",5758:"aeea487b",5830:"beb8b1b5",5978:"e6068bcd",6061:"3f5d37e4",6314:"61085227",6419:"8b875d3f",6927:"e9e2c05b",6969:"143050e2",7088:"ec91dff8",7168:"9b15d354",7202:"b985e13c",7361:"26c63d43",7927:"ab6f80d1",7960:"714d4d67",8387:"4b1d571e",8401:"62e76f39",8581:"8bb20c07",8678:"4e6f64e6",8714:"6af14fa3",8758:"2e26f813",8770:"675901e5",8864:"337d04a0",8878:"147abf33",9095:"38740ee7",9114:"9af80d36",9143:"922438c1",9218:"a93fff41",9793:"b7281600",9932:"3fd5d4a8"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},t="blockchain-protocols-and-distributed-applications:",r.l=(e,a,d,b)=>{if(f[e])f[e].push(a);else{var c,o;if(void 0!==d)for(var n=document.getElementsByTagName("script"),i=0;i{c.onerror=c.onload=null,clearTimeout(s);var t=f[e];if(delete f[e],c.parentNode&&c.parentNode.removeChild(c),t&&t.forEach((e=>e(d))),a)return a(d)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:c}),12e4);c.onerror=u.bind(null,c.onerror),c.onload=u.bind(null,c.onload),o&&document.head.appendChild(c)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/blockchain-protocols-and-distributed-applications/",r.gca=function(e){return e={14403852:"5020",17896441:"8401",83609664:"733","9da79274":"196",ccf76c4f:"371","4f869f09":"551",d12b36cf:"554",f09f4349:"674","7848bf17":"762","3ac942f0":"775","143dbf3b":"1090","62717f00":"1932",bb46bb8c:"1958","061587e1":"2018","1128852d":"2200","23374ca6":"2278","1523e34e":"2421","3b260257":"2830","9fc7fbc1":"2848","85f8441f":"2893","053840e8":"3140","215797bb":"3316",e75b870c:"3798",e3ece220:"3884","2ee066bd":"4009","393be207":"4134","76ada497":"4292","5e99f083":"4390","51e4ea00":"4484",f4bc3419:"4503",f6a805cd:"4620","4e4a4c47":"5047","0de68a20":"5193","6d865e2f":"5205",ed4d6624:"5362","507276da":"5637",b9e8fd80:"5673","5712a78f":"5688","9912e575":"5758",d1095428:"5830","62ff5f97":"5978","1f391b9e":"6061",b080bbe4:"6314",f3ef1ad2:"6419","3f645037":"6927","14eb3368":"6969","9b4ccf33":"7088","56a89565":"7168",dcd0bb0b:"7202",bd1b2524:"7361","83258dd0":"7927","528d1b10":"7960",eb02a9a6:"8387","935f2afb":"8581","5536eb16":"8678","1be78505":"8714","5cd13e5c":"8758",f57012b0:"8770",d92a3c43:"8864","1cd07dfb":"8878","4a9b7d7d":"9095","706697ec":"9114","695c3a47":"9143","01497563":"9218","078b4cd8":"9793","85df453d":"9932"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,d)=>{var f=r.o(e,a)?e[a]:void 0;if(0!==f)if(f)d.push(f[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var t=new Promise(((d,t)=>f=e[a]=[d,t]));d.push(f[2]=t);var b=r.p+r.u(a),c=new Error;r.l(b,(d=>{if(r.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var t=d&&("load"===d.type?"missing":d.type),b=d&&d.target&&d.target.src;c.message="Loading chunk "+a+" failed.\n("+t+": "+b+")",c.name="ChunkLoadError",c.type=t,c.request=b,f[1](c)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,d)=>{var f,t,b=d[0],c=d[1],o=d[2],n=0;if(b.some((a=>0!==e[a]))){for(f in c)r.o(c,f)&&(r.m[f]=c[f]);if(o)var i=o(r)}for(a&&a(d);n Grading | Blockchain Protocols and Distributed Applications - +

Grading

SectionPercent of total grade
Lab involvement10p
Homework 115p
Homework 215p
Project20p
Lecture involvement10p (bonus)
Practical final exam30p points
Theoretical final exam10p points
Total110p

4.5 points are required to pass the class. There are no other requirements (such as a minimal grade for a given component).

In case you don't pass the exam you may choose to keep the lab and assignments grade or the final exam grade for the next year. You cannot keep some parts of these grades. If choosing not to keep any grade, everything will be reset for at the beginning of the 2025-2026 academic year.

Practical Exam

  • Open Book - you can access any online/offline resources as long as you don't collaborate;
  • 60 minutes;
  • Some of the tasks you will have to do: create a wallet, write a basic smart contract, build and deploy it, interact with it (make transactions on the blockchain with the SC you deployed), use events for SC, create fungible and non-fungible tokens;
  • You can prepare and use any scripts for interaction with the blockchain;
  • Can be solved on any blockchain you want;

Theoretical Exam

  • Closed Book - access to any online/offline resources is considered cheating;
  • 15 minutes;
  • The exam will take place on Moodle.
- + \ No newline at end of file diff --git a/index.html b/index.html index 9804b10..80440ba 100644 --- a/index.html +++ b/index.html @@ -4,14 +4,14 @@ Blockchain Protocols and Distributed Applications | Blockchain Protocols and Distributed Applications - +

Blockchain Protocols and Distributed Applications

Welcome to the course on Blockchain Protocols and Distributed Applications. This course will provide you with a comprehensive understanding of blockchain technology and its applications in various domains.

Course Overview

In this course, you will explore the following key topics:

  • Introduction to Blockchain Technology
  • Blockchain Protocols and Consensus Mechanisms
  • Virtual Machines in Blockchains
  • Wallets
  • Smart Contracts
  • DApps (Decentralized Applications)
  • Security in Blockchains
  • MultiversX and Rust Programming
  • Blockchain Use Cases in Finance and more

Prerequisites

While there are no strict prerequisites for this course, a basic understanding of computer science and programming concepts will be beneficial.

Who should take this course?

  • Students interested in blockchain technology and its applications.
  • Developers and professionals looking to enhance their skills in blockchain development.
  • Anyone curious about the future of decentralized and secure systems.
- + \ No newline at end of file diff --git a/markdown-page/index.html b/markdown-page/index.html index e5f9c48..9552aa7 100644 --- a/markdown-page/index.html +++ b/markdown-page/index.html @@ -4,13 +4,13 @@ Markdown page example | Blockchain Protocols and Distributed Applications - +

Markdown page example

You don't need React to write simple standalone pages.

- + \ No newline at end of file diff --git a/resources/index.html b/resources/index.html index 418657a..c441d6f 100644 --- a/resources/index.html +++ b/resources/index.html @@ -4,18 +4,16 @@ Resources and Useful Links | Blockchain Protocols and Distributed Applications - +

Resources and Useful Links

List of Resources:

Books and interesting reading materials

Virtual Machine

You can use any Linux environment (native install, WSL, virtual machine, docker environment, etc.) for the OS class. -We provide Linux virtual machines with all the setup ready.

VirtualBox / VMware

You can download the Linux virtual machine from this link. -You will need to log in using your UPB account.

You can import the .ova file in VirtualBox or VMware. +We provide Linux virtual machines with all the setup ready.

VirtualBox / VMware

You can download the Linux virtual machine from this link.

You can import the .ova file in VirtualBox or VMware. Follow the instructions on the official websites for installation.

UTM (macOS >= 11)

If you are using an M1 Apple system, you will not be able to run the virtual machine using VirtualBox or VMware. -You will need to use UTM, along with a .qcow2 image. -You will need to log in using your UPB account.

After you install UTM and download and unzip the archive, you can import it using the Open existing VM option in UTM.

You can also follow the instructions for running the VM using qemu.

- +You will need to use UTM, along with a .qcow2 image.

After you install UTM and download and unzip the archive, you can import it using the Open existing VM option in UTM.

You can also follow the instructions for running the VM using qemu.

+ \ No newline at end of file