<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Javier Acrich</title>
    <description>The latest articles on DEV Community by Javier Acrich (@javier1984).</description>
    <link>https://dev.to/javier1984</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F373854%2F1710b252-ae1d-44a4-a022-179e9dc43e46.jpg</url>
      <title>DEV Community: Javier Acrich</title>
      <link>https://dev.to/javier1984</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/javier1984"/>
    <language>en</language>
    <item>
      <title>Interacting with Compound.finance</title>
      <dc:creator>Javier Acrich</dc:creator>
      <pubDate>Wed, 30 Mar 2022 20:17:36 +0000</pubDate>
      <link>https://dev.to/javier1984/interacting-with-compoundfinance-20n7</link>
      <guid>https://dev.to/javier1984/interacting-with-compoundfinance-20n7</guid>
      <description>&lt;p&gt;Compound is one of the oldest protocols out there, it allows you to lend and borrow just like everybody else, but how can you do that with typescript, ethers.js and Angular ?&lt;/p&gt;

&lt;p&gt;That is what I am going to show you today with some code examples.&lt;br&gt;
in this occasion we are going to start up a new dapp using Angular to demonstrate how to do it.  &lt;/p&gt;

&lt;p&gt;First let's explain some of the fundamental concepts of Compound.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cTokens&lt;/strong&gt;&lt;br&gt;
Each asset supported by the Compound Protocol is integrated through a cToken contract, which is an EIP-20 compliant representation of balances supplied to the protocol. By minting cTokens, users (1) earn interest through the cToken's exchange rate, which increases in value relative to the underlying asset, and (2) gain the ability to use cTokens as collateral.&lt;/p&gt;

&lt;p&gt;cTokens are the primary means of interacting with the Compound Protocol; when a user mints, redeems, borrows, repays a borrow, liquidates a borrow, or transfers cTokens, she will do so using the cToken contract.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comptroller&lt;/strong&gt;&lt;br&gt;
The Comptroller is the risk management layer of the Compound protocol; it determines how much collateral a user is required to maintain, and whether (and by how much) a user can be liquidated. Each time a user interacts with a cToken, the Comptroller is asked to approve or deny the transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So let's see some code.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We are going to connect our metamask wallet to our page so that we are able to see our cDai balance. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then we are going to deposit DAI to the cDAI contract in the kovan network because we do not want to use real money. &lt;br&gt;
and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally we are going to listen to the Mint event that the cDAI contract raises when DAI is deposited.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First of all we have to request permission to the provider that Metamask injects in the global object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1lxsqhd5sciac6wc8rc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1lxsqhd5sciac6wc8rc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we are connected we are going to retrieve the current cDAI balance:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxzsmqt7u3td0a5xz8pl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxzsmqt7u3td0a5xz8pl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to deposit we need to get a handler of a signer, &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj43n6t0hkfqq18tqzfj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj43n6t0hkfqq18tqzfj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and finally here we can listen to the &lt;em&gt;Mint&lt;/em&gt; event raised by the cDai contract. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcji06bxhhm8ggz2ejbwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcji06bxhhm8ggz2ejbwc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good! you have reached the end of the article, if you want, you can take a look at the whole code here:&lt;a href="https://github.com/javieracrich/dapp" rel="noopener noreferrer"&gt;https://github.com/javieracrich/dapp&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>hardhat</category>
      <category>ethers</category>
      <category>angular</category>
    </item>
    <item>
      <title>Randomness in deterministic systems.</title>
      <dc:creator>Javier Acrich</dc:creator>
      <pubDate>Tue, 01 Feb 2022 17:56:06 +0000</pubDate>
      <link>https://dev.to/javier1984/randomness-in-deterministic-systems-2mld</link>
      <guid>https://dev.to/javier1984/randomness-in-deterministic-systems-2mld</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is the use case for randomness ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After defi, blockchain gaming  is probably the largest use case for blockchains right now. Blockchain gaming basically depends on users going to a smart contract that guarantees that a user will be fairly treated and whatever manipulation happens in a centralized version of that same game can't occur with the user. So for example the creator of the contract can't manipulate money away from users that deserve to get it according to the contract's condition, or if there is some kind of digital good generated by the contract, the contact creator can't simple take it away from a user. &lt;/p&gt;

&lt;p&gt;The most common design pattern for blockchain gaming is the use of randomness. Randomness often generates payouts to users in crypto currency or generates digital goods or any type of events that games rely on. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RfvLaryr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e46i9td81rlozi7q3ib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RfvLaryr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e46i9td81rlozi7q3ib.png" alt="Image description" width="752" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The design patterns we see in blockchain gaming so far, sometimes don't deliver the full potential and end to end security that defi is now seeking to deliver to its users through the use of highly reliable oracles.&lt;/p&gt;

&lt;p&gt;In certain scenarios the creator of the blockchain game also runs the random number generation service, so on the one hand the smart contract and the conditions of the game and possibly the owner of digital goods is on a blockchain and therefore not gameable, but the random number generation that determines the amount or the value of the relationship between that contract and the user and the currency they put into that contract is controller by the game's creator.&lt;/p&gt;

&lt;p&gt;This leads to not the certainty but the unfortunate possibility  that there is a chance that the game's creator could have the same problems either by having his service compromised by an adversary or by compromising it themselves or whatever collection of problems that might occur. &lt;/p&gt;

&lt;p&gt;This is why it is important to have a verifiable source of randomness that can't be gamed and that is outside the control of any interested party such as the player or even the creator of the game. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Randomness in deterministic systems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Getting truly random numbers in a deterministic system is impossible. You cannot create truly random numbers but you can pseudo-random numbers. Blockchain is a deterministic system so we have to make sure that each node must be given the same random number. Determinism is fundamental because it is vital that regardless of where the smart contract code executes, it produces the same result every time and everywhere.&lt;/p&gt;

&lt;p&gt;For example, Timestamp vulnerability is quite common. Usually, the timestamp of a block is accessed via &lt;code&gt;block.timestamp&lt;/code&gt; but this timestamp can be manipulated by miners, leading to influencing the outcome of some function that relies on timestamps. The timestamp is used as a source of randomness in lottery games to select the next winner. Thus, it might be possible for a miner to modify the timestamp in such a way that its chances of becoming the next winner increase.&lt;/p&gt;

&lt;p&gt;In order to get the true random number we have to look at outside the blockchain. We need to use oracle services to get the true random number. If you do not have your true random number in your smart contract, your smart contract can get hacked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is chainlink VRF ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chainlink VRF is an external source of randomness for smart contracts as a key input that is cryptographically proven to be unbiased and developers and users can safely rely on it. The benefit of Chainlink VRF is that it is built to use the unique capabilities of blockchains to verify that proof and signatures which no other randomness generator does. &lt;/p&gt;

&lt;p&gt;There are a number of applications that use randomness in very meaningful ways to be able to securely exist. It is of of those input that pulling that input from some other off chain source is sometimes problematic because it is not necessarily build for a blockchain or using all the capabilities of a blockchain to provide security to the application developer and the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Show me the code!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";

/**
 * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
 * PLEASE DO NOT USE THIS CODE IN PRODUCTION.
 */

/**
 * Request testnet LINK and ETH here: https://faucets.chain.link/
 * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
 */

contract RandomNumberConsumer is VRFConsumerBase {

    bytes32 internal keyHash;
    uint256 internal fee;
    uint256 public randomResult;

    /**
     * Constructor inherits VRFConsumerBase
     * 
     * Network: Kovan
     * Chainlink VRF Coordinator address: 0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9
     * LINK token address:                0xa36085F69e2889c224210F603D836748e7dC0088
     * Key Hash: 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4
     */
    constructor() 
        VRFConsumerBase(
            0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9, // VRF Coordinator
            0xa36085F69e2889c224210F603D836748e7dC0088  // LINK Token
        )
    {
        keyHash = 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4;
        fee = 0.1 * 10 ** 18; // 0.1 LINK (Varies by network)
    }

    /** 
     * Requests randomness 
     */
    function getRandomNumber() public returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) &amp;gt;= fee, "Not enough LINK - fill contract with faucet");
        return requestRandomness(keyHash, fee);
    }

    /**
     * Callback function used by VRF Coordinator
     */
    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
        randomResult = randomness;
    }

    // function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My name is Javier Acrich and you can find me at &lt;a href="https://www.linkedin.com/in/javieracrich/"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>chainlink</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Rock-Paper-Scissors Smart Contract with commit-reveal pattern</title>
      <dc:creator>Javier Acrich</dc:creator>
      <pubDate>Tue, 07 Sep 2021 18:56:30 +0000</pubDate>
      <link>https://dev.to/javier1984/rock-paper-scissors-smart-contract-with-commit-reveal-pattern-11jp</link>
      <guid>https://dev.to/javier1984/rock-paper-scissors-smart-contract-with-commit-reveal-pattern-11jp</guid>
      <description>&lt;p&gt;I wrote a smart contract in which you can bet DAI and play rock paper scissors taking turns with your opponent.&lt;/p&gt;

&lt;p&gt;Traditionally when you play rock paper scissors with a friend, you both play at the same time, and then you can cut her paper with your scissors, and that's how both of you know you have won.&lt;/p&gt;

&lt;p&gt;but in a decentralized app,  you can't play at the same time, you have to take turns. If you go first, since everything is public in the blockchain, she can see what you have chosen, for instance if you have chosen scissors, then she'll know she has to choose rock to win. &lt;/p&gt;

&lt;p&gt;To overcome this issue the &lt;em&gt;commit/reveal&lt;/em&gt; pattern exists. It consists of 2 phases. The first one, the commit phase in which you commit your choice, but it remains secret, and then the reveal phase where you reveal your choice and make it visible. &lt;/p&gt;

&lt;p&gt;In solidity you can accomplish the hiding part using the hashing function &lt;br&gt;
&lt;code&gt;keccak256(abi.encodePacked(...))&lt;/code&gt;&lt;br&gt;
which returns a hash of a group of data.&lt;/p&gt;

&lt;p&gt;but, if you hash, your choice, for instance scissors, nothing stops your opponent, from hashing the 3 choices (rock, paper, and scissors) and then compare the hashes with the one that is stored in the smart contact, and in that way check what you have chosen, in order to win the game. This is why you need to make things a little more complex and add a password, a string that you only know, and hash that along with your choice.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function hashChoice(Choice data) private view returns (bytes32) {&lt;br&gt;
        return keccak256(abi.encodePacked(address(this), playerPasswords[_msgSender()], data));&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in this way, you will have a unique hash, that your opponent won't be able to use against you.&lt;/p&gt;

&lt;p&gt;so before playing you have to login to the game providing your password&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function login(string memory password) external {&lt;br&gt;
        require(playerPasswords[_msgSender()] == bytes32(0), "you have already logged in");&lt;br&gt;
        playerPasswords[_msgSender()] = hashPassword(password);&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;after logging in, player1 can commit the choice using the previously registered password and adding an optional bet in DAI to spice things up.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function player1Commit(&lt;br&gt;
        Choice choice,&lt;br&gt;
        uint256 _amount,&lt;br&gt;
        string memory password&lt;br&gt;
    ) external onlyLoggedIn(password) {&lt;br&gt;
...&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;player 2 does the same afterwards. Once the 2 players have committed their choices, it is time for the reveal phase. &lt;/p&gt;

&lt;p&gt;Both players have to send new transactions to the contract to reveal what they have chosen. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;function player1Reveals(&lt;br&gt;
        Choice choice,&lt;br&gt;
        uint256 gameId,&lt;br&gt;
        string memory password&lt;br&gt;
    ) external onlyLoggedIn(password) {...}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function player2Reveals(&lt;br&gt;
        Choice choice,&lt;br&gt;
        uint256 gameId,&lt;br&gt;
        string memory password&lt;br&gt;
    ) external onlyLoggedIn(password) {...}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;At this time, we already know who the winner is, so the only step missing is the prize distribution. We can do that calling the distribute function. Any player can call it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function distribute(uint256 gameId) external&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the case that player 1 has committed, but player 2 is not cooperative and decides not to commit at all, a function has been added to retrieve the bet after 1 week.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;player1WithdrawBalance(uint256 gameId) external&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can check the source code for this exercise in my &lt;a href="https://github.com/javieracrich/RockPaperScissors/blob/main/contracts/RockPaperScissorsV2.sol"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My name is &lt;strong&gt;Javier Acrich&lt;/strong&gt;. I'm a software engineer and I work at Santex. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Techo, mi smart contract para alquiler de propiedades.</title>
      <dc:creator>Javier Acrich</dc:creator>
      <pubDate>Mon, 16 Aug 2021 13:17:54 +0000</pubDate>
      <link>https://dev.to/javier1984/techo-mi-smart-contract-para-alquiler-de-propiedades-4ae</link>
      <guid>https://dev.to/javier1984/techo-mi-smart-contract-para-alquiler-de-propiedades-4ae</guid>
      <description>&lt;p&gt;Escribí este smart contract en Solidity usando Ethers.js y Hardhat para practicar.&lt;br&gt;
Un contrato de alquiler de propiedad me pareció un buen caso de uso para implementar. &lt;/p&gt;

&lt;p&gt;Tenemos un propietario, un inquilino y una inmobiliaria.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--snTTgu4h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fi4mh0zqzu2g61vcrt20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--snTTgu4h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fi4mh0zqzu2g61vcrt20.png" alt="Interacciones"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Primero, la inmobiliaria desplega el contrato en mainnet con todas las configuración necesaria: el monto de dinero, la duración, la frecuencia de pago, el porcentaje de comisión inmobiliaria y las direcciones del inquilino y del propietario.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Una vez que el smart contract esta desplegado, el inquilino activa el contrato mandándole el 100% del monto acordado al contrato + la comisión inmobiliaria. Al hacer esto, la inmobiliaria recibe su comisión y el contrato queda preparado para que el propietario pueda empezar a cobrar la renta.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El propietario todos los meses (o semanas, o días, según haya sido configurado al inicio) retira la renta del contrato. El monto de la renta es calculado automáticamente por el contrato. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;La inmobiliaria puede rescindir anticipadamente el contrato en cualquier momento y el dinero remanente en el contrato regresa automáticamente al inquilino.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El smart contract tiene las validaciones necesarias para que solo el propietario pueda cobrar las rentas y que no pueda cobrar mas de una renta por ciclo. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Beneficios para el inquilino&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No hacen falta garantías para alquilar. el inquilino aporta el 100% del dinero al inicio del contrato.&lt;/li&gt;
&lt;li&gt;Poder usar su crypto ahorrada, sin tener que venderla.&lt;/li&gt;
&lt;li&gt;Al rescindir anticipadamente, el contrato le devuelve el dinero restante automáticamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Beneficios para el propietario&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se asegura el pago del alquiler ya que los pagos son manejados por el contrato, no según la voluntad del inquilino.&lt;/li&gt;
&lt;li&gt;Cobrar el alquiler en crypto.&lt;/li&gt;
&lt;li&gt;No necesita garantías propietarias del inquilino.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Beneficios para la inmobiliaria.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cobrar la comisión del alquiler en crypto.&lt;/li&gt;
&lt;li&gt;Ofrecer un nuevo servicio para sus clientes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Si quieres ver el Código de este smart contract junto con los unit tests lo puedes encontrar en mi &lt;a href="https://github.com/javieracrich/CryptoTecho"&gt;Github Profile&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aqui puedes ver el contrato desplegado y verificado en la red de &lt;a href="https://ropsten.etherscan.io/address/0xc43Bc74F20222c4e0975798B6e5B291B66A60605#code"&gt;Ropsten&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mi nombre es JAVIER ACRICH y trabajo en &lt;a href="https://santexgroup.com/"&gt;Santex&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Is it possible to upgrade a smart contract? no? think again.</title>
      <dc:creator>Javier Acrich</dc:creator>
      <pubDate>Fri, 09 Apr 2021 02:37:05 +0000</pubDate>
      <link>https://dev.to/javier1984/is-it-possible-to-upgrade-a-smart-contract-no-think-again-gil</link>
      <guid>https://dev.to/javier1984/is-it-possible-to-upgrade-a-smart-contract-no-think-again-gil</guid>
      <description>&lt;h2&gt;
  
  
  Are smart contracts really upgradable?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;"TL;DR" Not really. but...&lt;/em&gt;&lt;br&gt;
Smart Contracts are pieces of software that live in the blockchain. They can execute actions according to a series of parameters already programmed. All of this in an immutable, transparent, and completely secure way. The fact that these smart contracts are distributed in thousands of machines makes them censorship-resistant, transparent, efficient, secure, and inexpensive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Transparency&lt;/em&gt; - The data on the blockchain is available for everyone to see.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Efficiency&lt;/em&gt; - No room for (mis-) interpretations or lost documents. "code is law" is a popular expression that describes this behavior.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cost reduction&lt;/em&gt; - As middlemen are cut out, the costs are significantly reduced as well.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Security&lt;/em&gt; - Cryptography is used to secure transactions and prevents attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is OpenZeppelin?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://openzeppelin.org"&gt;OpenZeppelin&lt;/a&gt; is a company that offers a variety of services for developing distributed applications.&lt;br&gt;
It also offers some free standard base smart contracts that are audited for security reasons and they are one of the most used smart contracts among developers. When building a new smart contract often you have to follow standards like ERC20 or EC721. Instead of reinventing the wheel, you can just inherit your contract from one of the openZeppelin contracts to save time and start programming right away your specific business rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why upgrade a Contract?
&lt;/h2&gt;

&lt;p&gt;By design, smart contracts are immutable. On the other hand, software quality heavily depends on the ability to upgrade and patch source code in order to produce iterative releases. Even though blockchain-based software profits significantly from the technology’s immutability, still a certain degree of mutability is needed for bug fixing and potential product improvements. OpenZeppelin Upgrades solves this apparent contradiction by providing an easy-to-use, simple, robust, and opt-in upgrade mechanism for smart contracts that can be controlled by any type of governance, be it a multi-sig wallet, a simple address or a complex DAO.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I upgrade a Contract?
&lt;/h2&gt;

&lt;p&gt;The basic idea is to use a proxy for upgrades. The first contract is a simple wrapper or "proxy" with which users interact directly and is in charge of forwarding transactions to and from the second contract, which contains the logic. The key concept to understand is that the logic contract can be replaced while the proxy or the access point is never changed. Both contracts are still immutable in the sense that their code cannot be changed, but the logic contract can simply be swapped by another contract. The wrapper can thus point to different logic implementation and in doing so, the software is "upgraded".&lt;/p&gt;

&lt;p&gt;OpenZeppelin provides a &lt;a href="https://docs.openzeppelin.com/upgrades-plugins/1.x/"&gt;plugin&lt;/a&gt; that allows us to upgrade a contract easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DVXW2JmO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j4g7gkt6gr4bhoefoab6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DVXW2JmO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j4g7gkt6gr4bhoefoab6.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diagram 1: contracts relation and users&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When we deploy our implementation contract with the Upgrades plugin we are also deploying 2 more contracts. The Proxy Contract and the ProxyAdmin Contract.&lt;/p&gt;

&lt;p&gt;The Proxy Contract will be the contract that your clients will connect to. You won't have to update this contract since it doesn't hold any of the logic. Just the state.&lt;br&gt;
The Implementation Contract will hold the logic (that you can later upgrade if you find bugs or need to add features )&lt;br&gt;
But you won't actually “upgrade” it. We will just make the Proxy Contract point to a new V2 Contract with fixed bugs or more features than V1.  And since the client is connected to the Proxy Client, you won't have to ask them to switch to the V2 Contract. What a relief…&lt;/p&gt;

&lt;p&gt;You also deploy the ProxyAdmin Contract whose only responsibility is to change the Proxy Contract to point to a newer Implementation Contract. Only an admin owner can do this trick.&lt;/p&gt;

&lt;p&gt;There is a special function in Solidity called &lt;a href="https://docs.soliditylang.org/en/v0.8.3/introduction-to-smart-contracts.html?highlight=DELEGATECALL#delegatecall-callcode-and-libraries"&gt;DELEGATECALL&lt;/a&gt; that allows you to call another contract using the context of the caller. Not the callee. This allows the discrimination between state and logic which makes possible the “upgrade”&lt;/p&gt;

&lt;p&gt;My name is &lt;a href="https://www.linkedin.com/in/javieracrich/"&gt;&lt;strong&gt;Javier Acrich&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
And I work at &lt;a href="https://santexgroup.com/"&gt;Santex&lt;/a&gt; as a full-stack software developer.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>solidity</category>
      <category>openzeppelin</category>
      <category>smartcontracts</category>
    </item>
    <item>
      <title>How to build a performant SignalR chat SPA using Angular 10 and .Net Core 3.1</title>
      <dc:creator>Javier Acrich</dc:creator>
      <pubDate>Thu, 01 Oct 2020 15:04:32 +0000</pubDate>
      <link>https://dev.to/javier1984/how-to-build-a-performant-signalr-chat-spa-using-angular-10-and-net-core-3-1-4ghn</link>
      <guid>https://dev.to/javier1984/how-to-build-a-performant-signalr-chat-spa-using-angular-10-and-net-core-3-1-4ghn</guid>
      <description>&lt;p&gt;This article explores SignalR concepts and tries to explain with simplicity how to build a chat interface in a single page application. You can find the source code to this app at the end of this text.&lt;/p&gt;

&lt;p&gt;ASP.NET Core SignalR is an open-source library that simplifies adding real-time web functionality to apps. Real-time web functionality enables server-side code to push content to clients instantly.&lt;/p&gt;

&lt;p&gt;Let's see some of the most important concepts in SignalR: Hubs, Protocols, and Transports.&lt;/p&gt;

&lt;h1&gt;
  
  
  HUB
&lt;/h1&gt;

&lt;p&gt;A hub is the thing in the middle between the client and the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbwdjnjrcaktcawbo2qgr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbwdjnjrcaktcawbo2qgr.PNG" alt="A hub is the thing in the middle between the client and the server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SignalR uses hubs to communicate between clients and servers.&lt;br&gt;
A hub is a high-level pipeline that allows a client and server to call methods on each other. SignalR handles the dispatching across machine boundaries automatically, allowing clients to call methods on the server and vice versa. &lt;/p&gt;

&lt;h1&gt;
  
  
  PROTOCOLS
&lt;/h1&gt;

&lt;p&gt;There are 2 protocols you can use in SignalR&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0jlawe1e3c46xbknpdhj.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0jlawe1e3c46xbknpdhj.PNG" alt="Protocols"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are serialization formats you can use to send messages between server and client. Json is the default protocol, but we can also use MessagePack which is a fast and compact binary serialization format. It's useful when performance and bandwidth are a concern because it creates smaller messages compared to JSON. The binary messages are unreadable when looking at network traces and logs unless the bytes are passed through a MessagePack parser. SignalR has built-in support for the MessagePack format and provides APIs for the client and server to use.&lt;/p&gt;

&lt;h1&gt;
  
  
  TRANSPORTS
&lt;/h1&gt;

&lt;p&gt;SignalR supports the following techniques for handling real-time communication (in order of graceful fallback):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5tu57phfpdg3cqia1dvg.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5tu57phfpdg3cqia1dvg.PNG" alt="Transports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebSockets has the best performance, but it is only available if both the client and the server support it. If that is not the case, SSE or Long Polling is used instead.&lt;/p&gt;

&lt;h1&gt;
  
  
  BACKEND
&lt;/h1&gt;

&lt;p&gt;Let's start by creating a blank web API .Net Core 3.1 Solution in visual studio&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff1b1w6fj3t70pidwx3m6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff1b1w6fj3t70pidwx3m6.PNG" alt="Web API Net Core Solution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have a solution, let's install the following required nugets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3s39ge9vtz37bn6bpe07.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3s39ge9vtz37bn6bpe07.PNG" alt="Required Nugets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first one is the core NuGet required for SignalR, and the second will be required to use the MessagePack protocol&lt;/p&gt;

&lt;p&gt;Now let's create a ChatHub class and the IChatHub interface that will represent the proxy between the client and server&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

public class ChatHub : Hub&amp;lt;IChatHub&amp;gt;
    {
        public async Task BroadcastAsync(ChatMessage message)
        {
            await Clients.All.MessageReceivedFromHub(message);
        }
        public override async Task OnConnectedAsync()
        {
            await Clients.All.NewUserConnected("a new user connectd");
        }
    }

    public interface IChatHub
    {
        Task MessageReceivedFromHub(ChatMessage message);

        Task NewUserConnected(string message);
    }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As you can see the ChatMessage class will be a simple Data Transfer Object that will be used to transfer the messages&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    public class ChatMessage
    {
        public string Text { get; set; }
        public string ConnectionId { get; set; }
        public DateTime DateTime { get; set; }
    }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, we need to tell Asp.Net Core we want to use SignalR, registering the services in the ConfigureServices Method&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddSignalR().AddMessagePackProtocol();

            services.AddCors(options =&amp;gt;
            {
                options.AddDefaultPolicy(builder =&amp;gt;
                {
                    builder
                        .WithOrigins(
                        "http://localhost")
                        .AllowCredentials()
                        .AllowAnyHeader()
                        .SetIsOriginAllowed(_ =&amp;gt; true)
                        .AllowAnyMethod();
                });
            });
        }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Take a look at the CORS default policy, we are also going to need that since this we are building a SPA.&lt;/p&gt;

&lt;p&gt;Now, let's Map the ChatHub class we previously wrote in the Configure method&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

        app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapControllers();
                endpoints.MapHub&amp;lt;ChatHub&amp;gt;("/signalr");
            });


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And to finish the server part, let's write the ChatController&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    [Route("api/[controller]")]
    [ApiController]
    public class ChatController : ControllerBase
    {
        private readonly IHubContext&amp;lt;ChatHub&amp;gt; hubContext;

        public ChatController(IHubContext&amp;lt;ChatHub&amp;gt; hubContext)
        {
            this.hubContext = hubContext;
        }

 [HttpPost]
        public async Task SendMessage(ChatMessage message)
        {
            //additional business logic 

            await this.hubContext.Clients.All.SendAsync("messageReceivedFromApi", message);

            //additional business logic 
        }
    }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Pay attention to the dependency injected in the controller constructor. It is not a &lt;em&gt;ChatHub&lt;/em&gt;, It is an &lt;em&gt;IHubContext&lt;/em&gt;. This is the correct way of injecting a Hub Reference in a controller according to SignalR docs. We can use this hub reference to call hub methods from outside the hub. &lt;br&gt;
It's important to say here that, although we are injecting a Hub reference in the controller, we don't actually need to. As we discuss below, this is only required if you need to execute additional logic in the controller before or after calling the hub.&lt;/p&gt;

&lt;p&gt;if you want extra config options you can take a look at &lt;a href="https://github.com/dotnet/AspNetCore.Docs/blob/master/aspnetcore/signalr/configuration.md" rel="noopener noreferrer"&gt;this doc&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  FRONTEND
&lt;/h1&gt;

&lt;p&gt;We’ll use a simple Angular app without much styling effort since we are only interested in showing how SignalR works.  You can see the UI in the following image &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5jylea65u2jka31aqdkt.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5jylea65u2jka31aqdkt.PNG" alt="CHAT UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Write the following CLI commands to create the UI for the chat app&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;&lt;em&gt;ng new chat-ui&lt;/em&gt;&lt;/em&gt; in any folder to scaffold and create a new angular app&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;em&gt;npm i @microsoft/signalr@latest --save&lt;/em&gt;&lt;/em&gt; to install the required SignalR libraries.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;em&gt;ng g s signalr&lt;/em&gt;&lt;/em&gt; to scaffold the SignalR service &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;em&gt;npm i @microsoft/signalr-protocol-msgpack --save&lt;/em&gt;&lt;/em&gt; to use the MessagePack protocol in the frontend&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, let's write the SignalR service which will be used from the UI Component.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr'
import { from } from 'rxjs';
import { tap } from 'rxjs/operators';
import { chatMesage } from './chatMesage';
import { MessagePackHubProtocol } from '@microsoft/signalr-protocol-msgpack'

@Injectable({
  providedIn: 'root'
})
export class SignalrService {

  private hubConnection: HubConnection
  public messages: chatMesage[] = [];
  private connectionUrl = 'https://localhost:44319/signalr';
  private apiUrl = 'https://localhost:44319/api/chat';

  constructor(private http: HttpClient) { }

  public connect = () =&amp;gt; {
    this.startConnection();
    this.addListeners();
  }

  public sendMessageToApi(message: string) {
    return this.http.post(this.apiUrl, this.buildChatMessage(message))
      .pipe(tap(_ =&amp;gt; console.log("message sucessfully sent to api controller")));
  }

  public sendMessageToHub(message: string) {
    var promise = this.hubConnection.invoke("BroadcastAsync", this.buildChatMessage(message))
      .then(() =&amp;gt; { console.log('message sent successfully to hub'); })
      .catch((err) =&amp;gt; console.log('error while sending a message to hub: ' + err));

    return from(promise);
  }

  private getConnection(): HubConnection {
    return new HubConnectionBuilder()
      .withUrl(this.connectionUrl)
      .withHubProtocol(new MessagePackHubProtocol())
      //  .configureLogging(LogLevel.Trace)
      .build();
  }

  private buildChatMessage(message: string): chatMesage {
    return {
      connectionId: this.hubConnection.connectionId,
      text: message,
      dateTime: new Date()
    };
  }

  private startConnection() {
    this.hubConnection = this.getConnection();

    this.hubConnection.start()
      .then(() =&amp;gt; console.log('connection started'))
      .catch((err) =&amp;gt; console.log('error while establishing signalr connection: ' + err))
  }

  private addListeners() {
    this.hubConnection.on("messageReceivedFromApi", (data: chatMesage) =&amp;gt; {
      console.log("message received from API Controller")
      this.messages.push(data);
    })
    this.hubConnection.on("messageReceivedFromHub", (data: chatMesage) =&amp;gt; {
      console.log("message received from Hub")
      this.messages.push(data);
    })
    this.hubConnection.on("newUserConnected", _ =&amp;gt; {
      console.log("new user connected")
    })
  }
}



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;connect()&lt;/em&gt; is the first method. This method will be called from the OnInit() in the UI component. This method is in charge of connecting to the ChatHub and registering the listeners that will be listening when the server tries to send messages to the client.&lt;/p&gt;

&lt;p&gt;In this case and since we are in a SPA, we have 2 options to send messages from the UI to the HUB:&lt;/p&gt;

&lt;p&gt;A. We can send messages directly to the HUB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff94hxcc5um9v3i5hpxow.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff94hxcc5um9v3i5hpxow.PNG" alt="calling the hub directly"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;B. We can send Http requests to the API Controller and let the controller call the hub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyo3e9pcjug5o6d8nqfxm.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyo3e9pcjug5o6d8nqfxm.PNG" alt="calling the hub thru the API controller"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Either option is fine and this depends on your requirements. If you need to execute additional business rules besides sending the message, it is a good idea to call the API controller and execute your business rules there and not in the HUB. Just to separate concerns.&lt;/p&gt;

&lt;p&gt;this is the Component in charge :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { Component, OnInit } from '@angular/core';
import { SignalrService } from './signalr.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
  title = 'chat-ui';
  text: string = "";

  constructor(public signalRService: SignalrService) {

  }

  ngOnInit(): void {
    this.signalRService.connect();
  }

  sendMessage(): void {
    // this.signalRService.sendMessageToApi(this.text).subscribe({
    //   next: _ =&amp;gt; this.text = '',
    //   error: (err) =&amp;gt; console.error(err)
    // });

    this.signalRService.sendMessageToHub(this.text).subscribe({
      next: _ =&amp;gt; this.text = '',
      error: (err) =&amp;gt; console.error(err)
    });
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can see here that the connect() method is called on the OnInit() to initialize the connection.&lt;/p&gt;

&lt;p&gt;The SendMessage() method is called whenever the user clicks the Send Button. Just for demo purposes, you have both options. Sending the message directly to the hub and sending the message thru a request to an action method in a controller.&lt;/p&gt;

&lt;p&gt;and finally this is the markup with some bootstrap classes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;div class="container mt-5"&amp;gt;
  &amp;lt;h1&amp;gt;SignalR Chat DEMO&amp;lt;/h1&amp;gt;
  &amp;lt;input type="text" class="mt-3 mb-3 mr-3" [(ngModel)]="text"&amp;gt;
  &amp;lt;button class="btn btn-primary" [disabled]="text.length==0" (click)="sendMessage()"&amp;gt;Send Message&amp;lt;/button&amp;gt;
  &amp;lt;h4 class="mb-3"&amp;gt;List of Messages&amp;lt;/h4&amp;gt;

  &amp;lt;div *ngIf="signalRService.messages.length==0"&amp;gt;
    &amp;lt;p&amp;gt;You haven't send or received messages&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div *ngFor="let m of signalRService.messages"&amp;gt;
    &amp;lt;div class="mb-2 mt-2"&amp;gt;
      &amp;lt;div&amp;gt;&amp;lt;strong&amp;gt;ConnectionID&amp;lt;/strong&amp;gt; {{m.ConnectionId}}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;&amp;lt;strong&amp;gt;Date&amp;lt;/strong&amp;gt; {{m.DateTime | date}}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;&amp;lt;strong&amp;gt;Message&amp;lt;/strong&amp;gt; {{m.Text}}&amp;lt;/div&amp;gt;
      &amp;lt;hr&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you want to take a look at the source code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/javiergacrich/chat-ui" rel="noopener noreferrer"&gt;https://github.com/javiergacrich/chat-ui&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/javiergacrich/chat-server" rel="noopener noreferrer"&gt;https://github.com/javiergacrich/chat-server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My Name is Javier Acrich and I work as a software engineer @ Santex&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Exposing a GraphQL API using .Net Core 3.1 and HotChocolate.</title>
      <dc:creator>Javier Acrich</dc:creator>
      <pubDate>Tue, 26 May 2020 15:35:40 +0000</pubDate>
      <link>https://dev.to/javier1984/exposing-a-graphql-api-using-net-core-3-1-and-hotchocolate-5hmj</link>
      <guid>https://dev.to/javier1984/exposing-a-graphql-api-using-net-core-3-1-and-hotchocolate-5hmj</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is GraphQL?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GraphQL is not a library. It is a syntax that describes how to ask for data and it is generally used to load data from a server to a client. GraphQL has three main characteristics:&lt;/p&gt;

&lt;p&gt;-It lets the client specify EXACTLY what data it needs.&lt;br&gt;
-It makes it easier to aggregate data from multiple sources.&lt;br&gt;
-It uses a type system to describe data.&lt;/p&gt;

&lt;p&gt;GraphQL is like a middle layer between our data and our clients, and it can be considered as an alternative to REST API or maybe even an evolution.&lt;br&gt;&lt;br&gt;
We can find in this flexibility also an improvement phase of the API: in fact, the addition of fields returned to our structure will not impact the existing clients.&lt;br&gt;
GraphQL is strongly typed: each query level matches a given type, and every type describes a set of available fields. Thanks to this feature, GraphQL can validate a query before running it, and in case of error, GraphQL can also return descriptive error messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the pros of GraphQL over rest?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With GraphQL, the client is able to make a single request to fetch the required information rather than constructing several REST requests to fetch the same.&lt;br&gt;
This makes the app faster since you only have to wait for a single request to finish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the cons of using GraphQL ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;-A lot of boilerplate and schema code at both frontend and backend.&lt;br&gt;
-You need to learn how to set up GraphQL. The ecosystem is still rapidly evolving so you have to keep up.&lt;br&gt;
-Nested queries in GraphQL can lead to &lt;em&gt;circular queries&lt;/em&gt; and can crash the server. Extra care has to be taken.&lt;br&gt;
-&lt;em&gt;Rate limiting&lt;/em&gt; of calls becomes difficult because now the user can fire multiple queries in one call.&lt;br&gt;
-&lt;em&gt;Cache at Network Level&lt;/em&gt;: Because of the common way GraphQL is used over HTTP (a POST in a single endpoint), cache at network level becomes hard. A way to solve it is to use &lt;em&gt;Persisted Queries&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should I use GraphQL?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have an app that needs to get lots of complex data from a backend. &lt;br&gt;
Let's say data with multiple nested hierarchical levels. With a REST API you can achieve it, but it will take you several &lt;em&gt;for loops&lt;/em&gt;, data synchronization, and API calls to the backend to get the result you need. This translates into long wait times for the calls to finish and overall diminished user experience. With GraphQL only one endpoint is needed in the backend for all the needs the frontend might have. And also you can get exactly all the data you need in only one call. No &lt;em&gt;over-fetching&lt;/em&gt; and no &lt;em&gt;under-fetching&lt;/em&gt;. This reduces drastically the latency time and bandwidth&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the best GraphQL library I can use in .Net Core?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In .Net there are 2 libraries you can use to implement a GraphQL server:&lt;br&gt;
-&lt;a href="https://github.com/graphql-dotnet/graphql-dotnet"&gt;graphql-dotnet&lt;/a&gt; (please don't use this one. Please)&lt;br&gt;
-&lt;a href="//hotchocolate.io"&gt;hotchocolate&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;graphql-dotnet is old and it is not being actively maintained. Besides, it consumes more memory and it is slower than Hotchocolate.&lt;br&gt;
Hotchocolate is way more flexible. It has a faster release cycle and it also has unique features like sorting and filtering thru the use of &lt;em&gt;directives&lt;/em&gt;&lt;br&gt;
although HotChocolate has good documentation I found several orthographic/grammatical errors. I sent several pull requests with corrections but the author didn't update the docs so far.&lt;/p&gt;

&lt;p&gt;There are four key concepts in GraphQL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Schema&lt;/li&gt;
&lt;li&gt;  Resolver&lt;/li&gt;
&lt;li&gt;  Query&lt;/li&gt;
&lt;li&gt;  Mutation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A GraphQL  &lt;strong&gt;schema&lt;/strong&gt;  consists of object types that define the type of objects that are possible to receive and the type of fields available.&lt;/p&gt;

&lt;p&gt;The  &lt;strong&gt;resolvers&lt;/strong&gt;  are the collaborators that we can associate with the fields of our scheme which will take care of recovering data from these fields.&lt;/p&gt;

&lt;p&gt;Considering a typical CRUD, we can define the concept of  &lt;strong&gt;query&lt;/strong&gt;  and  &lt;strong&gt;mutation&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The first one will deal with the information reading, while the creation, modification, and deletion are tasks managed by mutation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I use HotChocolate in .Net Core?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First of all, we need to get the nugets required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;HotChocolate.AspNetCore&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;&lt;em&gt;HotChocolate.AspNetCore.Playground&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is Playground?&lt;/strong&gt;&lt;br&gt;
If you ever used &lt;em&gt;Swagger&lt;/em&gt; for rest APIs, then you will find Playground familiar. Playground is the swagger of rest APIs, It has 2 panels. It lets you write GraphQL queries on the left, click play, and then receive the result on the right, It also has code completion and automatic scheme documentation. It is an excellent tool to test your code and queries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v-5DgEeW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.blexin.com/storage/articles/graph-ql-hotchocolate/image01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v-5DgEeW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.blexin.com/storage/articles/graph-ql-hotchocolate/image01.png" alt="GraphQL Playground" width="880" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to play with Playground you can take a look at it at &lt;a href="https://localhost:%5Bport%5D/playground/"&gt;https://localhost:[port]/playground/&lt;/a&gt; when debugging your app.&lt;br&gt;
remember to register it in the startup first.&lt;/p&gt;

&lt;p&gt;HotChocolate has 2 approaches: &lt;em&gt;code first&lt;/em&gt; and &lt;em&gt;schema first&lt;/em&gt;. In order to make this article as short as possible we'll use &lt;em&gt;code first&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We define the  &lt;strong&gt;Author&lt;/strong&gt;  and  &lt;strong&gt;Book&lt;/strong&gt;, which will be the types exposed by our API.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
}

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public decimal Price { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;At this point, we can create the class Query, starting with defining the authors.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Query
{
    private readonly IAuthorService _authorService;
    public Query(IAuthorService authorService)
    {
        _authorService = authorService;
    }

    public IQueryable&amp;lt;Author&amp;gt; Authors =&amp;gt; _authorService.GetAll();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After adding the nugets to our solution,  we add the necessary statements to configure GraphQL in the Startup.cs file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace Demo
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGraphQL(s =&amp;gt; SchemaBuilder.New()
                .AddServices(s)
                .AddType&amp;lt;Author&amp;gt;()
                .AddType&amp;lt;Book&amp;gt;()
                .AddQueryType&amp;lt;Query&amp;gt;()
                .Create());
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UsePlayground();
            }
            app.UseGraphQL();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With the annotation &lt;em&gt;[UsePaging]&lt;/em&gt;, we are instructing GraphQL so that the authors returned by the service will have to be made available with pagination.&lt;br&gt;
This way, by starting the application and going to the playground, we can make the following query and see the result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v-5DgEeW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.blexin.com/storage/articles/graph-ql-hotchocolate/image01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v-5DgEeW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.blexin.com/storage/articles/graph-ql-hotchocolate/image01.png" alt="Paging" width="880" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By adding the HotChocolate.Types and HotChocolate.Types.Filters nuget you can add a new annotation to enable filters.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[UsePaging]
[UseFiltering]
public IQueryable&amp;lt;Author&amp;gt; Authors =&amp;gt; _authorService.GetAll();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ktjzCQ5A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.blexin.com/storage/articles/graph-ql-hotchocolate/image02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ktjzCQ5A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.blexin.com/storage/articles/graph-ql-hotchocolate/image02.png" alt="Filtering by name" width="880" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persisted Queries?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Persisted queries are a great way to improve the performance of your GraphQL server.&lt;br&gt;
Persisted queries are validated once no matter if your server restarts or your cache is cleared.&lt;br&gt;
Persisted queries are stored close to your server either in the file system or in a  &lt;em&gt;Redis&lt;/em&gt;  cache. This helps to reduce request sizes since your application can send in a query key instead of the whole query.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hot Chocolate&lt;/em&gt; supports out of the box two flows on how to handle persisted queries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Ahead of time query persistence&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Active Query Persistence&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first approach is to store queries ahead of time (ahead of deployment of your application). This can be done by extracting the queries from your client application, hashing them, and pushing them to the query storage.&lt;/p&gt;

&lt;p&gt;Active query persistence builds upon the query persistence pipeline and adds the ability to store queries on the fly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
GraphQL and HotChocolate are a great alternative to REST APIs if you care about performance, latency, and bandwidth. It has some drawbacks like all the boilerplate required to make it work and also the learning curve required to build a production-ready API, but It is worth the time trying.&lt;/p&gt;

&lt;p&gt;In my next post I'll be analyzing GRPC Apis, and comparing it to GrapqhQL and REST. &lt;/p&gt;




&lt;p&gt;My Name is Javier Acrich, &lt;br&gt;
I work as a software engineer at Mobomo.&lt;br&gt;
I hope you liked this article!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
