<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Raphael Roullet's Blog]]></title><description><![CDATA[On Crypto, Identity, Tech and Life.]]></description><link>https://blog.raphaelroullet.com/</link><image><url>https://blog.raphaelroullet.com/favicon.png</url><title>Raphael Roullet&apos;s Blog</title><link>https://blog.raphaelroullet.com/</link></image><generator>Ghost 5.27</generator><lastBuildDate>Tue, 05 May 2026 05:55:47 GMT</lastBuildDate><atom:link href="https://blog.raphaelroullet.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Hybrid Crypto-Credentials:  Using Decentralized Learning As An Example]]></title><description><![CDATA[An implementation example of combining NFTs and Verifiable Credentials for the purpose of decentralized learning.]]></description><link>https://blog.raphaelroullet.com/hybrid-crypto-credentials-decentralized-learning/</link><guid isPermaLink="false">63bb0818b8202902100a1f72</guid><category><![CDATA[Ethereum]]></category><category><![CDATA[Decentralized Identity]]></category><dc:creator><![CDATA[Raphael Roullet]]></dc:creator><pubDate>Sun, 06 Mar 2022 18:28:20 GMT</pubDate><media:content url="https://res-5.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/modestas-urbonas-vj_9l20fzj0-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://res-5.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/modestas-urbonas-vj_9l20fzj0-unsplash.jpg" alt="Hybrid Crypto-Credentials:  Using Decentralized Learning As An Example"><p></p><h2 id="context">Context</h2><p>At the core of the Self-Sovereign Identity movement are the new W3 specs for <em><a href="https://www.w3.org/TR/did-core/">Decentralized Identifiers</a> (DIDs)</em> and <em><a href="https://www.w3.org/TR/vc-data-model/">Verifiable Credentials</a> (VCs).</em><br>From working on <a href="https://jaygraber.medium.com/introducing-interrep-255d3f56682">InterRep</a> I was already familiar with using an NFT as a way to represent credentials on-chain, but VCs appeared as an interesting alternative with different characteristics. Here are some similarities and differences:</p><ul><li>VCs are not tied to any single blockchain, whereas NFTs live in smart contracts on a specific blockchain.</li><li>If DeFi has shown something, it&apos;s how powerful composability can become when building on top of an open, permissionless platform. As soon as an NFT is generated by one protocol it becomes usable by all other smart contracts out of the box! (NFT ownership can be verified in one line of code)<br>VCs, however, can&apos;t be used natively in blockchain applications as they don&apos;t live on chain. <br>It&apos;s still possible to use a VC with smart contracts by relying on an oracle or passing a proof as part of the transaction data but the process is much more cumbersome.</li><li>Everything stored on a blockchain, like Ethereum, is public. As a result, NFTs and any data related to them stored in their smart contract also is. That has massive implications in terms of privacy. As a rule of thumb, no personally identifiable information (PII) should be stored on-chain. VCs are like fancy JSON documents so they don&apos;t suffer from the same characteristic, they can be stored securely and privately. What&apos;s more with zero-knowledge proof and selective disclosure, a VC holder can choose to reveal only a part of the information attested by a VC or a true statement derived from it.</li><li>Both rely on cryptographic signatures and are tamper-resistant, although in the case of NFTs you are also relying on the security of the underlying blockchain for a few things; chief among them is preserving ownership of the tokens according to the rules written in the NFT smart contract.<br></li></ul><p><strong>But why not combine both?</strong></p><p>Since NFTs <a href="https://docs.opensea.io/docs/metadata-standards">often have a reference to some metadata</a>, that reference could actually point to a VC!</p><p>Only the VC&apos;s URI would be stored in the NFT smart contract. Note that this URI could actually point to a &quot;location&quot; in an encrypted user data vault such that permissions could be put in place: then this URI would only resolve to the VC document only if you have been granted read access. With this approach, you get the best of both worlds, personal, private information can stay off-chain and stored in the VC, while the token, free of personally identifiable or private information, can be used on-chain. <br>This is what I would call <em>hybrid crypto-credentials</em>.</p><p>Right when I wanted to test this idea, a friend of mine suggested that we participate in the HackFS21 hackathon. It seemed like the perfect opportunity. We fleshed out the idea a bit more and chose to create an online learning platform that would issue these hybrid crypto-credentials<em>.</em> As an additional requirement, the whole system we set ourselves to create should be as much decentralized as possible: in other words no traditional backend servers (!). </p><p>The lessons for this online learning platform could be crowdsourced as the code is public on Github. Anyone would be able to create a new lesson and submit a Pull Request to add it to the catalog. This gives added meaning to the word &quot;open&quot; in <em>Massive Open Online Courses</em>: access <strong>and</strong> contributions are open to everyone. A DAO could be formed and tokens awarded to contributors whose lessons are added, but I digress... This blog post focuses on describing this &quot;Proof Of Concept&quot; that <a href="https://github.com/iustin-nita">Iustin</a> and I built.</p><p>Although it&apos;s clear that some improvements can be made (again, it&apos;s just a hack!), I&apos;m pretty happy with the end result: it proves that hybrid crypto-credentials work and the whole system has very few centralized parts. Only one server is needed to sign VCs while keeping the signing key private (but even that could potentially be upgraded to a threshold signature scheme to avoid full centralization).</p><h2 id="overview">Overview</h2><p>Here&apos;s an overview of how this decentralized learning platform works and issues hybrid crypto-credentials:<br><br>Lessons are accessible via a front-end. They are interactive in the sense that they require users to write some code and submit transactions to a smart contract (not a backend API).<br>To pass a lesson, the user has to submit a final transaction with the right data. If it&apos;s successful, a chain of actions are triggered: a Chainlink oracle asks for the issuance of a Verifiable Credential which gets stored on the decentralized storage network Ceramic, then, a non-transferrable NFT is minted on-chain and the location on the Ceramic Network of its VC counterpart is associated to it. Everything is pseudonymous as users are identified by a DID or their Ethereum address.</p><h2 id="how-it-works">How it works</h2><p>Curious to know more details? Here are the different step that go into getting the hybrid credentials.</p><figure class="kg-card kg-image-card kg-width-full"><img src="https://res-1.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/open-classes-architecture.jpg" class="kg-image" alt="Hybrid Crypto-Credentials:  Using Decentralized Learning As An Example" loading="lazy"></figure><p>The system is composed of two distinct parts: <strong>Open_Cred</strong> which can be re-used to create hybrid crypto-credential for any kind of use case and <strong>Open_Classes </strong>(which uses Open_Cred) containing everything related to this decentralized learning example.</p><h3 id="open_classes">Open_Classes</h3><p>First a user / student connects their wallet and log in with 3ID (<strong>step #0</strong>) on the Open_Classes website. <a href="https://developers.ceramic.network/authentication/3id-did/method/">3ID is a DID method created by Ceramic</a>. This is so we can issue an NFT to their address but also a VC to their DID.</p><p>&#x1F4A1; We could have simply used the <a href="https://github.com/decentralized-identity/ethr-did-resolver/blob/master/doc/did-method-spec.md">ethr did method</a> as we already know the user&apos;s address, but 3ID offers more flexiblity. It gives users the ability to control a DID via multiple blockchain accounts.</p><h4 id="lesson-1">Lesson 1</h4><p>The first lesson teaches you how to query events using <a href="https://docs.ethers.io/v5/">ethers.js</a>. The user first calls the smart contract for this lesson (#1) which triggers the generation of a unique random number using <a href="https://docs.chain.link/docs/chainlink-vrf/">Chainlink VRF</a> (#2, #3). This random number is stored and associated with the student&apos;s address. In addition, an event is emitted containing both this random number and the student&apos;s address.<br>The goal for this lesson is to find this random number, using Javascript and ethers.js, filtering the events by your address.</p><figure class="kg-card kg-image-card"><img src="https://res-5.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/open-classes-screenshot-1.png" class="kg-image" alt="Hybrid Crypto-Credentials:  Using Decentralized Learning As An Example" loading="lazy"></figure><p>As a shortcut we added a <a href="https://codesandbox.io/">CodeSandbox</a> to have an IDE embedded right in our lesson&apos;s page. By following the instructions on the left side and adding some code on the right side, the random number can be printed to its console! &#x1F4AA;</p><p>Once the random number is found, it can be submitted on this same page which crafts a transaction to the lesson smart contract containing the number and the user&apos;s DID (#5). The smart contract in turn verifies it corresponds to the number expected for the sender&apos;s address (#6). If that&apos;s the case, the student passed the lesson and the credential issuance flow is initiated: the DID is passed as credential subject and the name of the lesson as credential title to the OpenCredentials smart contract (#7).</p><h3 id="open_cred">Open_Cred</h3><p>Once the OpenCredentials smart contract receives a request to generate a hybrid credential with all the properties needed, it forwards this request to a Chainlink node via an on-chain Oracle (#8). It also stores the <em>requestId</em> along with the recipient&apos;s address and the credential id (each &quot;lesson smart contract&quot; submitting a request is mapped to a credential id), these will be needed later.</p><p>Then, the Chainlink node calls a Lambda function on AWS via an <a href="https://docs.chain.link/docs/external-adapters/">external adapter</a> (#9). You can view this lambda as the &quot;VC issuer module&quot; deployed by our Open Classes University to generate Verifiable Credentials and sign them (#10).<br>How are they signed? Inside the Lambda, a seed is used to create a DID which is authenticated with Ceramic, this time simply using the <a href="https://developers.ceramic.network/authentication/key-did/method/">Key DID method</a>, and able to create JSON Web Signatures (JWS).</p><p>Next, the signed VC is stored on the Ceramic (Clay test) Network in a <em><a href="https://developers.ceramic.network/learn/advanced/overview/#streams">Stream</a></em> and the issuer&apos;s DID is passed as <em>controller </em>(#11). This returns a <em>streamId</em> which enables anyone to retrieve the VC from Ceramic (#12).</p><p>&#x1F4A1; For simplicity, a lot of thing were done from inside the Lambda, however I think only the signature could be performed there and the rest, handled by the Chainlink node including generating and storing the VC.</p><p>With the VC created and stored, now it&apos;s a matter of taking the same route in the opposite direction: the streamId is passed back from the lambda to the Chainlink node (#13) and back to the OpenCredentials smart contract with the right <em>requestId</em> (Chainlink handles that automatically). <br>Here&apos;s one of such transactions: <a href="https://rinkeby.etherscan.io/tx/0xa7c13f10ec64f9ba7607fe09f74b987c8984d35c1d82c191b9950942ad31e07a">https://rinkeby.etherscan.io/tx/0xa7c13f10ec64f9ba7607fe09f74b987c8984d35c1d82c191b9950942ad31e07a</a></p><p>&#x1F62C; Fun fact showing how early this tech is: For a while Chainlink only permitted 32 bytes to be returned to a smart contract. As a result, any string you&apos;d want to return from a Chainlink node was getting truncated, only keeping the first 32 characters. So I was actually stuck for a bit for that last step because a Ceramic <em>streamId</em> is more than 32 characters long... Fortunately Chainlink recently released a new version supporting &quot;<a href="https://docs.chain.link/docs/large-responses/">large responses</a>&quot; and unblocked me after I upgraded my node and Oracle smart contract.</p><p>From there, the OpenCredentials contract is able to retrieve the token recipient&apos;s address and the credential / lesson id from the <em>requestId</em>, it then calls the NFT contract to mint a token with recipient, <em>lessonId</em> and <em>streamId.</em></p><p>The NFT contract is a ERC721 contract with some modifications:</p><ul><li>The NFTs are non-transferrable. They can be minted by authorized addresses and burnt by their owner or authorized parties, but they cannot be transferred. If they were transferrable, someone would be able to acquire these tokens just by buying them and they would lose their significance as proof of completion of a lesson for all token recipients.<br>Because it&apos;s a ERC721 contract the non-transferrability restriction of this contract is not straighforward at all at first glance. Plus, a lot of unused code for transfers and approvals ends up being deployed. For these reasons, I&apos;ve been working on <a href="https://github.com/ethereum/EIPs/issues/1238#issuecomment-1029055365">ERC1238</a> towards making a streamline token standard for non-transferable tokens a.k.a Badges.</li><li>Each token is uniquely identified by a unique <em>tokenId - </em>they&apos;re Non-Fungible Tokens after all - but they also belong to a group under a <em>lessonId.</em> From a tokenId you can retrieve the lessonId it is associated with.</li><li>Balances for a lesson are tracked. This lets someone see if an address received a credential for a specific lesson (querying by <em>lessonId</em>) and how many of them they own. This comes from the assumption that an address may own several tokens for the same lesson. For example if lessons were graded, someone might decide to obtain the crypto-credential of a lesson again but with a higher grade.<br></li></ul><p>I created a demo video going through the whole flow and getting credentials as an end user: </p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/Fh8nzp4yppI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>All the code is available here:</p><ul><li><a href="https://github.com/Web3-Architects/open-cred">Open_Cred</a></li><li><a href="https://github.com/Web3-Architects/open-classes">Open_Classes</a></li></ul><p>Deployments on Rinkeby:<br>OpenClasses: <a href="https://rinkeby.etherscan.io/address/0xb25873E1fd210EF76D4528F04d1142434efbA8bc">0xb25873E1fd210EF76D4528F04d1142434efbA8bc</a><br>VCNFT: <a href="https://rinkeby.etherscan.io/address/0x0D7f626141Ab3866533f98b4D4406b23e8bE7608">0x0D7f626141Ab3866533f98b4D4406b23e8bE7608</a><br>OpenCredentials: <a href="https://rinkeby.etherscan.io/address/0x27187729F39de1bEB68e9Aa4E3D52240DD409730">0x27187729F39de1bEB68e9Aa4E3D52240DD409730</a></p><p>Usual disclaimer: it&apos;s been developed for demonstration purposes only, has not been tested nor audited and must contain bugs, do not use in production!<br></p><p>If you&apos;re interested in the topic of decentralized identity and crypto-credentials, don&apos;t hesitate to <a href="https://twitter.com/RaphaelRoullet">reach out to me on Twitter</a>!</p>]]></content:encoded></item><item><title><![CDATA[Solidity Tutorial (ERC20 & AAVE)]]></title><description><![CDATA[<p></p><p>The code for this tutorial was written by <a href="https://github.com/JulienKode">JulienKode</a> and I. <br>Disclaimer: The code obviously hasn&apos;t been audited so it may contain vulnerabilities.</p><p>If you want to jump straight into it, the repository is accessible <a href="https://github.com/Web3-Architects/open-rental">here</a> (spoiler alert!).</p><h1 id="what-we-will-be-building">What we will be building</h1><p>For this tutorial, we are</p>]]></description><link>https://blog.raphaelroullet.com/solidity-tutorial-erc20-aave/</link><guid isPermaLink="false">63bb0818b8202902100a1f70</guid><category><![CDATA[Solidity]]></category><category><![CDATA[Ethereum]]></category><dc:creator><![CDATA[Raphael Roullet]]></dc:creator><pubDate>Sat, 09 Oct 2021 13:34:35 GMT</pubDate><media:content url="https://res-3.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/grant-lemons-jTCLppdwSEc-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://res-3.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/grant-lemons-jTCLppdwSEc-unsplash.jpg" alt="Solidity Tutorial (ERC20 &amp; AAVE)"><p></p><p>The code for this tutorial was written by <a href="https://github.com/JulienKode">JulienKode</a> and I. <br>Disclaimer: The code obviously hasn&apos;t been audited so it may contain vulnerabilities.</p><p>If you want to jump straight into it, the repository is accessible <a href="https://github.com/Web3-Architects/open-rental">here</a> (spoiler alert!).</p><h1 id="what-we-will-be-building">What we will be building</h1><p>For this tutorial, we are going to build a decentralized application that is a bit more suited for a blockchain than, say, a to-do app. Using <em>smart contracts, </em>the goal will be to replace, or rather complement, a rental agreement. In brief, it should be able to manage rent payments and security deposits for landlords and tenants <strong>without any third-party or guarantors</strong> AND generate interests on the deposit.</p><p>For the full context and motivation of what we will develop in this tutorial, please refer to this <a href="https://blog.raphaelroullet.com/rent-guarantee-on-a-blockchain/">post</a>. However, beyond the &quot;why&quot;, here&apos;s the &quot;what&quot;, i.e the requirements.</p><h2 id="requirements">Requirements</h2><p>First, let&apos;s define a <em>security deposit</em> as money protecting against damage to the property and <em>rent guarantee</em> as protecting against unpaid rent. There&apos;s usually no distinction between the two. Here we&apos;re making one because the latter is verifiable on-chain, the former is not, so the way to reach a settlement differs.</p><p><strong>1. Moving in</strong></p><p>After agreeing upon an amount for rent and security deposit, landlord and tenants should be able to enter into an agreement.</p><p>As a tenant:</p><ul><li>I should be able to lock up a certain amount as security deposit and rent guarantee, and pay the first month rent to start the lease.</li><li>I should earn interest on the money locked up.</li></ul><p><strong>2. Renting</strong></p><p>As a tenant:</p><ul><li>I should be able to pay my rent on time</li></ul><p>As a landlord:</p><ul><li>I should be able to withdraw from the protocol the rent from the moment it&apos;s due</li><li>If rent payment is late, I should be able to withdraw from the rent guarantee an amount equivalent to the unpaid rent</li></ul><p><strong>3. Moving out</strong></p><p>As a tenant:</p><ul><li>If I always paid my rent in time, I should be able to get the rent guarantee back in full</li><li>I should get all earned interests on the security deposit and rent guarantee</li></ul><p>As a landlord:</p><ul><li>I should have control over how much of the security deposit is given back to the tenant (in case there were damages)</li></ul><p>Let&apos;s dive in!</p><h1 id="prerequisites">Prerequisites</h1><ul><li>Some familiarity with Solidity, in particular types, visibility specifiers, functions definitions... My <a href="https://blog.raphaelroullet.com/solidity-types/">previous post</a> has got you covered.</li><li>Node and Yarn installed</li></ul><p>And that&apos;s it! This is a tutorial for beginners. :)</p><h1 id="boilerplate">Boilerplate</h1><p>Instead of spending too much time, setting things up we are going to re-use an excellent template created by Paul Razvan Berg: <a href="https://github.com/paulrberg/solidity-template">Solidity-template</a>.</p><p>It comes with many plugins and super useful tools already installed for us:</p><ul><li><a href="https://github.com/nomiclabs/hardhat">Hardhat</a>: My favorite framework to develop, compile and run smart contracts locally</li><li><a href="https://github.com/ethers-io/ethers.js/">Ethers</a>: An essential library to interact with smart contracts from client-side apps and tests</li><li><a href="https://github.com/ethereum-ts/TypeChain">TypeChain</a>: Generates TypeScript types for smart contracts</li><li><a href="https://github.com/EthWorks/Waffle">Waffle</a>: Tooling for writing comprehensive smart contract tests</li><li><a href="https://github.com/protofire/solhint">Solhint</a>: Linter</li><li><a href="https://github.com/sc-forks/solidity-coverage">Solcover</a>: Generates code coverage for smart contracts</li><li><a href="https://github.com/prettier-solidity/prettier-plugin-solidity">Prettier Plugin Solidity</a>: Code formatter for Solidity</li></ul><p>If you want to follow along, click on &quot;Use this template&quot; on Github, follow <a href="https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/creating-a-repository-from-a-template">these steps</a> and then clone your repo locally. Inside of it, we install the dependencies by running:</p><pre><code>yarn install</code></pre><h1 id="lending-service">Lending Service</h1><h2 id="interface">Interface</h2><p>We are going to create a <em>Lending Service</em> which will be responsible for interacting with a DeFi protocol as we want the deposit and rent guarantee to earn interests.</p><p>Because we could potentially have a lending service for each yield-earning DeFi protocol (Aave, Compound, Yearn etc...), we first define an <code>interface</code> that any <em>Lending Service</em> will have to implement.</p><pre><code class="language-javascript">// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ILendingService {
    /// @notice Deposits funds from current smart contract to a lending
    /// protocol
    /// @dev Will revert if the amount exceeds the contract balance or
    /// caller is not the owner.
    /// @param amount The amount to deposit
    function deposit(uint256 amount) external;

    /// @notice Withdraws `amount` from a lending protocol
    /// @dev Will revert if the amount exceeds the balance of capital
    /// deposited or caller is not the owner.
    /// @param amount The amount to withdraw
    function withdraw(uint256 amount) external;

    /// @notice Withdraws all capital and interests earned from a 
    /// lending protocol
    /// @dev Will revert if the caller is not the owner.
    function withdrawCapitalAndInterests() external;

    /// @notice Returns the amount deposited on a lending protocol
    function depositedBalance() external view returns (uint256);
}</code></pre><p>The first line specifies the <a href="https://spdx.org/licenses/">license</a> for this file.</p><p>The second line indicates to the Solidity compiler the Solidity version this file was written for, in this case <code>^0.8.0</code>. If the compiler&apos;s version does not match, an error will be thrown. &#xA0;The syntax to specify a valid version is the same as <a href="https://docs.npmjs.com/cli/v6/using-npm/semver">npm</a>.</p><p>Then, in the interface itself, we have function declarations for depositing, withdrawing and checking the balance of deposited tokens on a lending protocol. They are declared without their implementation, because they&apos;re in an <code>interface</code>.</p><h2 id="aave-lending-service">Aave Lending Service</h2><p>Now that we have a generic interface we can define a smart contract that inherits it. It will be responsible for interacting with AAVE v2, a DeFi protocol that we can use to lend tokens.</p><pre><code>import &quot;./ILendingService.sol&quot;;

contract AAVELendingService is ILendingService { }</code></pre><h3 id="erc20-">ERC20 &#x1F911;</h3><p>We need to declare the token that will be used as currency. This token must follow the widely-used ERC20 standard and adhere to its <a href="https://docs.openzeppelin.com/contracts/3.x/api/token/erc20#IERC20">interface</a> (<strong>IERC20</strong>) which we import from OpenZeppelin.</p><p>With Aave, whenever you deposit tokens, you get aTokens in return. Deposit 100 DAI, you get 100 aDAI; 300 USDC, you get 300 aUSDC etc... We declare both token types as ERC20 tokens.</p><pre><code> import &quot;@openzeppelin/contracts/token/ERC20/IERC20.sol&quot;;

 contract AAVELendingService is ILendingService {
   IERC20 public aToken;
   IERC20 public tokenUsedForPayments;
 }</code></pre><p>We&apos;re also indicating that our contract uses the SafeERC20 library from OpenZeppelin by 1. importing it and 2. including <code>using SafeERC20 for IERC20;</code>.</p><p>The <code>SafeERC20</code> library makes interacting with an ERC20 token a bit safer by reverting if an operation fails and sends back a return value equals to <code>false</code>.</p><pre><code>import &quot;@openzeppelin/contracts/token/ERC20/IERC20.sol&quot;;
import &quot;@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol&quot;;

contract AAVELendingService is ILendingService {
    using SafeERC20 for IERC20;

    // this shouldn&apos;t be harcoded normally
    address public aDaiTokenAddress = 0xdCf0aF9e59C002FA3AA091a46196b37530FD48a8;

    IERC20 public aToken;
    IERC20 public tokenUsedForPayments;

    constructor(address _tokenUsedToPay) {
        tokenUsedForPayments = IERC20(_tokenUsedToPay);
        aToken = IERC20(aDaiTokenAddress);
    }
}</code></pre><p>The address of the token used as currency is passed in the constructor which offers some flexibility, but normally the <strong>aToken&apos;s</strong> address should be retrieved based on that token address (only kovan DAI will work here). I leave that to you to implement ;) (Hint: <a href="https://docs.aave.com/developers/the-core-protocol/protocol-data-provider#getreservetokensaddresses">this method</a>).</p><h3 id="ownership">Ownership</h3><p>Granted their visibility is public or external, functions defined in a smart contract can be <strong>called by anyone</strong>. We don&apos;t want anyone to withdraw the funds here so we&apos;ll need some access control.</p><pre><code>address payable public owner;

modifier onlyOwner() {
  require(msg.sender == owner, &quot;Restricted to the owner only&quot;);
  _;
}

constructor(address _tokenUsedToPay) {
   ...
   owner = payable(msg.sender);
}</code></pre><p>We first declare a variable for the <code>owner</code> of the smart contract.<br>We then add a modifier, <code>onlyOwner</code>. It contains a <code>require</code> statement which reverts the transaction if the caller is not the owner that we defined. When applied to a function, that check will be performed before executing the function itself (<code>_</code> represents the function body).</p><p>In the constructor, the address that deployed the current smart contract gets assigned to that variable.</p><p>It&apos;s great to have an owner defined, but we should also enable transferring ownership. Here&apos;s how to do it and a first example of applying our <code>onlyOwner</code> modifier:</p><pre><code>function transferOwnership(address newOwner) public onlyOwner {
  require(newOwner != address(0), &quot;new owner is the zero address&quot;);
  owner = payable(newOwner);
}</code></pre><h3 id="deposit-withdraw">Deposit &amp; Withdraw</h3><p>Let&apos;s move on to the core features now.</p><p>First, we define a variable which will be helpful to keep track of the balance of token that were deposited in AAVE.</p><pre><code>uint256 public depositedAmountBalance;</code></pre><p>Next, we define a function used to deposit some <code>amount</code> of tokens in AAVE.</p><pre><code>function deposit(uint256 amount) external override(ILendingService) onlyOwner {
  require(amount &lt;= tokenUsedForPayments.balanceOf(address(this)), &quot;amount exceeds contract balance&quot;);
  // Approve the LendingPool contract to pull the amount to deposit
  tokenUsedForPayments.approve(address(aaveLendingPool), amount);
  // Deposit the amount in the LendingPool
  aaveLendingPool.deposit(address(tokenUsedForPayments), amount, address(this), 0);

  depositedAmountBalance += amount;
}</code></pre><p>It first does a preventive check, verifying that the smart contract holds the amount to deposit.</p><p>The AAVE lending pool will pull these tokens from our contract. So if you&apos;re not familiar with how ERC20 tokens work, we first need to allow Aave&apos;s smart contract to transfer the tokens the Lending Service holds on its behalf (<code>tokenUsedForPayments.approve</code>).</p><p>We then call <code>aaveLendingPool.deposit</code> &#xA0;passing in 1. the underlying asset, 2. amount to be deposited, 3. the address that will receive the aTokens in exchange which is the current contract&apos;s address and 0 as we&apos;re not using any referral code.</p><p><code>depositedAmountBalance</code> &#xA0;gets logically incremented by <code>amount</code>.</p><p>To <code>withdraw</code>, it&apos;s almost the same process but in reverse. After checking that the contract holds a balance superior to the amount to withdraw (of <em>aTokens</em> this time!), we need to approve the lending pool to transfer aTokens from our smart contract in order to get our underlying tokens back in exchange.</p><pre><code>function withdraw(uint256 amount) external override(ILendingService) onlyOwner {
    uint256 aTokenBalance = aToken.balanceOf(address(this));
    // Check that the amount to withdraw is less than what the contract holds
    require(aTokenBalance &gt;= amount, &quot;Amount exceeds balance&quot;);

    // Approve the aToken contract to pull the amount to withdraw
    aToken.approve(address(aaveLendingPool), amount);
    // Withdraw from the LendingPool
    aaveLendingPool.withdraw(address(tokenUsedForPayments), amount, address(this));
}</code></pre><p>At that point if all goes well, our lending service should hold the amount in underlying tokens so we can transfer it and then decrease the <code>depositedAmountBalance</code>.</p><pre><code>function withdraw(uint256 amount) external override(ILendingService) onlyOwner {
    uint256 aTokenBalance = aToken.balanceOf(address(this));
    // Check that the amount to withdraw is less than what the contract holds
    require(aTokenBalance &gt;= amount, &quot;Amount exceeds balance&quot;);

    // Approve the aToken contract to pull the amount to withdraw
    aToken.approve(address(aaveLendingPool), amount);
    // Withdraw from the LendingPool
    aaveLendingPool.withdraw(address(tokenUsedForPayments), amount, address(this));
    // Transfer withdrawn amount
    tokenUsedForPayments.safeTransfer(msg.sender, amount);

    depositedAmountBalance -= amount;
}</code></pre><h3 id="view-function">View Function</h3><p>Finally, let&apos;s define a function that will return the <code>depositedAmountBalance</code>. It will be needed later.</p><pre><code> function depositedBalance() external override(ILendingService) view returns (uint256) {
  return depositedAmountBalance;
}</code></pre><p>It is a simple <code>view</code> &#xA0;function as it simply reads data from the blockchain.</p><h1 id="developing-the-rental-agreement">Developing the rental agreement</h1><p>With our lending service created, we can now develop a smart contract called <code>RentalAgreement</code>. It will make use of the <em>Lending Service</em> and contain the &quot;rules&quot; of the agreement between a landlord and a tenant, embedded programmatically (&#x1F525;&#x1F525;&#x1F525;).</p><p>Inside our contract, &#xA0;let&apos;s declare some <em>state variables</em>. They get assigned their values in the constructor which will be provided when deploying a <code>RentalAgreement</code>.</p><pre><code>// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import &quot;./ILendingService.sol&quot;;

contract RentalAgreement {
    address public landlord;
    address public tenant;
    uint256 public rent;
    uint256 public deposit;
    uint256 public rentGuarantee;

    ILendingService public lendingService;

    constructor(
        address _landlord,
        address _tenantAddress,
        uint256 _rent,
        uint256 _deposit,
        uint256 _rentGuarantee,
        address _tokenUsedToPay,
        address _lendingService
    ) {
        require(_landlord != address(0), &quot;Landlord address cannot be the zero address&quot;);
        require(_tenantAddress != address(0), &quot;Tenant address cannot be the zero address&quot;);
        require(_tokenUsedToPay != address(0), &quot;Token address cannot be the zero address&quot;);
        require(_lendingService != address(0), &quot;Lending Service address cannot be the zero address&quot;);
        require(_rent &gt; 0, &quot;rent cannot be 0&quot;);

        landlord = _landlord;
        tenant = _tenantAddress;
        rent = _rent;
        deposit = _deposit;
        rentGuarantee = _rentGuarantee;
        lendingService = ILendingService(_lendingService);
    }
}</code></pre><p>The different variables declared are:</p><ul><li>addresses for landlord and tenant</li><li>unsigned integer for the rent</li><li>unsigned integer for deposit and rent guarantee (these two are different! See specs above)</li></ul><p>They all have a <code>public</code> visibility.</p><p>The <code>require</code> statements are used for input validation. If the condition provided, such as <code>_rent &gt; 0</code>, is true, execution will proceed; otherwise, the transaction will revert and since it&apos;s in the constructor, contract deployment will fail. Boohoo.</p><p>This smart contract also expects the address of a <code>lendingService</code> to be passed to its constructor. We keep it simple for now and assume the landlord deploys a lending service, and then has to transfer ownership <strong>to the rental agreement</strong> once deployed.</p><h2 id="modifiers">Modifiers</h2><p>Let&apos;s add two <code>modifiers</code> to restrict permissions:</p><pre><code>modifier onlyTenant() {
        require(msg.sender == tenant, &quot;Restricted to the tenant only&quot;);
        _;
 }

modifier onlyLandlord() {
        require(msg.sender == landlord, &quot;Restricted to the landlord only&quot;);
        _;
}</code></pre><p>Once added to a function, the <code>onlyTenant</code> modifier will revert the transaction if the caller is not the tenant (that we defined previously as state variable).</p><p>Same thing for the second modifier, <code>onlyLandlord</code> but only allowing the landlord.</p><h2 id="erc20-again-">ERC20 (again!)</h2><p>The <code>RentalAgreement</code> will be transferring the tokens used as currency so we need to add the following lines, just like we did in the Lending Service.</p><pre><code>import &quot;@openzeppelin/contracts/token/ERC20/IERC20.sol&quot;;
import &quot;@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol&quot;;

contract RentalAgreement {
    using SafeERC20 for IERC20;

    IERC20 public tokenUsedForPayments;

    constructor(
        ...
        address _tokenUsedToPay,
    ) {
        ...
        tokenUsedForPayments = IERC20(_tokenUsedToPay);
    }

 }</code></pre><h2 id="entering-the-agreement-">Entering the agreement &#x1F91D;</h2><p>Assuming the landlord has to deploy the <code>RentalAgreement</code>, we are now going to add a function which will make the tenant acknowledge the terms by providing them as arguments and start the lease. (A cool improvement would be to have the tenant sign these terms with Metamask for example, and verify the signature in our RentalAgreement smart contract).</p><p>Here&apos;s what we add, explained with comments:</p><pre><code>// Timestamp (e.g. 1622131469) used to keep track of when the rent will be due next
uint256 public nextRentDueTimestamp;

// Event emitted at the start of the lease
event TenantEnteredAgreement(uint256 depositLocked, uint256 rentGuaranteeLocked, uint256 firstMonthRentPaid);

// ...

function enterAgreementAsTenant(
    address _landlordAddress,
    uint256 _deposit,
    uint256 _rentGuarantee,
    uint256 _rent
) public onlyTenant {
    // Makes sure the tenant &quot;agrees&quot; with the terms first registered by the landlord
    require(_landlordAddress == landlord, &quot;Incorrect landlord address&quot;);
    require(_deposit == deposit, &quot;Incorrect deposit amount&quot;);
    require(_rentGuarantee == rentGuarantee, &quot;Incorrect rent guarantee amount&quot;);
    require(_rent == rent, &quot;Incorrect rent amount&quot;);

    uint256 deposits = deposit + rentGuarantee;
    // Transfers the deposits to this smart contract
    tokenUsedForPayments.safeTransferFrom(tenant, address(this), deposits);
    // Approve the transfer of the deposits to the lending service
    tokenUsedForPayments.approve(address(lendingService), deposits);
    // Deposit the `deposits` amount in the lending service
    lendingService.deposit(deposits);

    // Transfer the first month of rent to the landlord
    tokenUsedForPayments.safeTransferFrom(tenant, landlord, rent);
    // First rent payment was made, we set the next time it&apos;s due as 4 weeks from now
    nextRentDueTimestamp = block.timestamp + 4 weeks;

    emit TenantEnteredAgreement(deposit, rentGuarantee, rent);
}</code></pre><p>Note that we&apos;re using <code>lendingService</code> &#xA0;which was declared and coded previously.</p><h2 id="tests">Tests</h2><p>This tutorial wouldn&apos;t be complete without explaining how to test the Solidity code we write.</p><p>You can dive in the repository for the full test suite but let&apos;s focus on a test for the previous function. And before we can test it, we actually need to initialize several things:</p><h3 id="init">Init</h3><pre><code class="language-javascript">import hre from &quot;hardhat&quot;;
import { Artifact } from &quot;hardhat/types&quot;;
import { SignerWithAddress } from &quot;@nomiclabs/hardhat-ethers/dist/src/signer-with-address&quot;;

import { RentalAgreement } from &quot;../typechain/RentalAgreement&quot;;
import { MockLendingService } from &quot;../typechain/MockLendingService&quot;;
import { expect } from &quot;chai&quot;;
import { deployMockLendingService } from &quot;./utils/mockLendingService&quot;;
import { parseUnits18 } from &quot;../utils/parseUnits&quot;;

const { deployContract } = hre.waffle;
const { ethers } = hre;

describe(&quot;Rental Agreement&quot;, function () {
  let landlord: SignerWithAddress;
  let tenant1: SignerWithAddress;
  let rental: RentalAgreement;
  let lendingService: MockLendingService;

  let rent: BigNumber;
  let deposit: BigNumber;
  let rentGuarantee: BigNumber;
  let dai: Contract;

  before(async function () {
    [landlord, tenant1] = await ethers.getSigners();

    // deploy an ERC20 token to mock dai
    const daiFactory = await ethers.getContractFactory(&quot;ERC20PresetMinterPauser&quot;);
    dai = await daiFactory.deploy(&quot;dai&quot;, &quot;DAI&quot;);
    console.log(&quot;dai deployed at:&quot;, dai.address);

    // Give 1 000 000 mock dai to tenant1
    const initialTenant1Balance = parseUnits18(&quot;1000000&quot;);
    const mintingTx = await dai.mint(tenant1.address, initialTenant1Balance);
    await mintingTx.wait();

    expect(await dai.balanceOf(tenant1.address)).to.eq(initialTenant1Balance);
  });</code></pre><p>Here we assign 2 signers: the first one playing the role of landlord and the other tenant (<em>tenant1)</em>. Then a simple ERC20 contract is deployed to serve as a mock token used for payments. We use it to grant 1M of them to <code>tenant1</code>. That should be enough to pay rent for a little while. &#x1F604;</p><pre><code>beforeEach(async function () {
  rent = parseUnits18(&quot;500&quot;);
  deposit = parseUnits18(&quot;500&quot;);
  rentGuarantee = parseUnits18(&quot;1500&quot;);

  lendingService = await deployMockLendingService(landlord, dai);

  const rentalArtifact: Artifact = await hre.artifacts.readArtifact(&quot;RentalAgreement&quot;);
  rental = &lt;RentalAgreement&gt;(
    await deployContract(landlord, rentalArtifact, [
      landlord.address,
      tenant1.address,
      rent,
      deposit,
      rentGuarantee,
      dai.address,
      lendingService.address,
    ])
  );

  const transferOwnershipTx = await lendingService.connect(landlord).transferOwnership(rental.address);
  await transferOwnershipTx.wait();
});</code></pre><p>Next, <code>beforeEach</code> is used to re-deploy our smart contracts before each test in order to isolate them. Deployment is done in 2 steps:</p><ol><li>Getting the contract&apos;s artifact with <code>await hre.artifacts.readArtifact(&lt;CONTRACT NAME&gt;);</code></li><li>Calling <code>deployContract</code> &#xA0;passing in a signer, the contract&apos;s artifact and then an array of parameters expected by the constructor.</li></ol><p>As mentioned before, after deploying, a landlord needs to give up ownership of the lending service.</p><h2 id="testing-enteragreementastenant">Testing <em>enterAgreementAsTenant</em></h2><p>First we compute the sum of everything a tenant needs to transfer upfront when entering the agreeement: <em>deposit</em>, <em>rentGuarantee</em> and first month&apos;s rent. That sum is used to call <em>approve</em> first so that our smart contract is allowed to pull that amount from the tenant.</p><pre><code>  it(&quot;should let the tenant enter the agreement&quot;, async () =&gt; {
      const deposits = deposit.add(rentGuarantee);
      const totalUpfront = deposits.add(rent);

      const approveTx = await dai.connect(tenant1).approve(rental.address, totalUpfront);
      await approveTx.wait();
    });</code></pre><p>We can then call the function to enter the agreement, wait for the transaction to be mined and get the block that included it.</p><pre><code> const tx = await rental.connect(tenant1).enterAgreementAsTenant(landlord.address, deposit, rentGuarantee, rent);
 const txReceipt = await tx.wait();
 const blockHash = txReceipt.blockHash;
 const block = await ethers.provider.getBlock(blockHash);</code></pre><p>Calling <code>nextRentDueTimestamp</code>, &#xA0;we can check that it&apos;s set 4 weeks from the block&apos;s timestamp.</p><pre><code>const nextRentDueTimestamp = await rental.nextRentDueTimestamp();
expect(nextRentDueTimestamp).to.eq(block.timestamp + FOUR_WEEKS_IN_SECS);</code></pre><p>Finally we check that the deposits were indeed deposited in the lending service, the <em>rentalAgreement</em>&apos;s balance is 0 and the landlord received the first month&apos;s rent!</p><pre><code>expect(await dai.balanceOf(lendingService.address)).to.eq(deposits);
expect(await dai.balanceOf(rental.address)).to.eq(parseUnits18(&quot;0&quot;));
expect(await dai.balanceOf(landlord.address)).to.eq(rent);</code></pre><p>Everything should pass &#x2705;</p><h2 id="paying-rent">Paying Rent</h2><p>Back to Solidity, we define a function to allow the tenant to pay rent, fittingly called <code>payRent</code>.</p><pre><code> event RentPaid(address tenant, uint256 amount, uint256 timestamp);
 // ...
function payRent() public onlyTenant {
    require(tokenUsedForPayments.allowance(tenant, address(this)) &gt;= rent, &quot;Not enough allowance&quot;);

    tokenUsedForPayments.safeTransferFrom(tenant, landlord, rent);

    nextRentDueTimestamp += 4 weeks;

    emit RentPaid(tenant, rent, block.timestamp);
}</code></pre><p>Let&apos;s unpack the 4 lines in the function body.</p><p>The first one checks on the token&apos;s smart contract that the allowance given to our current smart contract by the tenant is at least the amount of rent. If it wasn&apos;t the case, the transfer would fail but we catch that possibility earlier here.</p><p>The second line executes the transfer from tenant to landlord of the <code>rent</code> &#xA0;amount.</p><p>Once done, we consider that the tenant just &quot;bought 4 more weeks&quot; in the property so we add 4 weeks to the current value of <code>nextRentDueTimestamp</code>.</p><p>The last line emits a <code>RentPaid</code> event, notifying that rent was paid.</p><h2 id="what-if-the-tenant-stops-paying-rent-">What if the tenant stops paying rent?! &#x1F628;</h2><p>We are going to add a function that handles this situation and lets the landlord withdraw from the money locked up by the tenant.</p><pre><code>function withdrawUnpaidRent() public onlyLandlord {
    // Checks that rent payment is late
    require(block.timestamp &gt; nextRentDueTimestamp, &quot;There are no unpaid rent&quot;);
    // Pushes back next time rent is due by 4 weeks
    nextRentDueTimestamp += 4 weeks;
    // Registers that the amount for rent was taken out of `rentGuarantee`
    rentGuarantee -= rent;
    // Withdraws from the Lending Service
    lendingService.withdraw(rent);
    // Transfers &quot;rent&quot; to the landlord
    tokenUsedForPayments.safeTransfer(landlord, rent);
}</code></pre><p>As you can see the landlord is still getting rent but from the rent guarantee, not the tenant directly.</p><h2 id="ending-the-tenancy">Ending the tenancy</h2><p>Let&apos;s recap what needs to happen at the end of a tenancy:</p><p>The tenant should get:</p><ul><li>her deposit back minus any amount retained by the landlord for damages</li><li>her rent guarantee back (or whatever is left of it)</li><li>any interest earned on both of these deposits</li></ul><p>Let&apos;s code this up!</p><p>We add a public function but with the <code>onlyLandlord</code> &#xA0;modifier so only the landlord can call it passing as parameter how much should be given back to the tenant from the deposit amount (<code>_amountOfDepositBack</code>).</p><p>We&apos;re also checking that this amount is inferior or equal to the <em>deposit</em>.</p><pre><code>function endRental(uint256 _amountOfDepositBack) public onlyLandlord {
  require(_amountOfDepositBack &lt;= deposit, &quot;Invalid deposit amount&quot;);
}</code></pre><p>Next, we need to send to the tenant the right amount which includes the amount of deposit back, the rent guarantee (or whatever is left of it) and the interests earned.</p><pre><code>function endRental(uint256 _amountOfDepositBack) public onlyLandlord {
    require(_amountOfDepositBack &lt;= deposit, &quot;Invalid deposit amount&quot;);

    uint256 depositedOnLendingService = lendingService.depositedBalance();
    uint256 beforeWithdrawBalance = tokenUsedForPayments.balanceOf(address(this));
    lendingService.withdrawCapitalAndInterests();
    uint256 afterWithdrawBalance = tokenUsedForPayments.balanceOf(address(this));
    uint256 interestEarned = (afterWithdrawBalance - depositedOnLendingService) - beforeWithdrawBalance;

    // compute and transfer funds to tenant
    uint256 fundsToReturnToTenant = _amountOfDepositBack + rentGuarantee + interestEarned;
    tokenUsedForPayments.safeTransfer(tenant, fundsToReturnToTenant);
}</code></pre><p>There&apos;s a bit going on here because we are computing how much interest was earned. With this amount known, that means we could easily split it between tenant and landlord.</p><p>This computation is done by comparing the capital deposited in the lending service with how much was transferred to the smart contract after withdrawing everything from it.</p><p>If the landlord is keeping some of the deposit we need to figure this out and transfer it to &#xA0;them!</p><pre><code> uint256 landlordWithdraw = deposit - _amountOfDepositBack;
// landlord is keeping some of the deposit
if (landlordWithdraw &gt; 0) {
    tokenUsedForPayments.safeTransfer(landlord, landlordWithdraw);
}</code></pre><p>Finally, we set both deposit and <code>rentGuarantee</code> &#xA0;to 0 and emit an event to signal the end of the tenancy:</p><pre><code>deposit = 0;
rentGuarantee = 0;
emit EndRental(fundsToReturnToTenant, landlordWithdraw);</code></pre><p>And that&apos;s it for the Rental Agreement!</p><h1 id="factory">Factory</h1><p>Let&apos;s now create a smart contract that will make it easy for landlords to deploy rental agreements.</p><pre><code>import &quot;./RentalAgreement.sol&quot;;

contract RentalFactory {

    function createNewRental(
        address _tenantAddress,
        uint256 _rent,
        uint256 _deposit,
        uint256 _rentGuarantee,
        address _tokenUsedToPay,
        address _lendingService
    ) public {
        RentalAgreement newRental =
            new RentalAgreement(msg.sender, _tenantAddress, _rent, _deposit, _rentGuarantee, _tokenUsedToPay, _lendingService);
    }
}</code></pre><p>We import the contract we created and add a public function that forwards all the parameters needed to create a new <code>RentalAgreement</code>.</p><p>Next, let&apos;s add an event for whenever a new agreement is deployed.</p><pre><code>  event NewRentalDeployed(address contractAddress, address landlord, address tenant);

    function createNewRental(
        address _tenantAddress,
        uint256 _rent,
        uint256 _deposit,
        uint256 _rentGuarantee,
        address _tokenUsedToPay,
        address _lendingService
    ) public {
        RentalAgreement newRental =
            new RentalAgreement(msg.sender, _tenantAddress, _rent, _deposit, _rentGuarantee, _tokenUsedToPay, _lendingService);

        emit NewRentalDeployed(address(newRental), msg.sender, _tenantAddress);
    }</code></pre><p>Note that we are getting the address of the freshly deployed contract as the first event argument.</p><p>Finally, we use a mapping that keeps track of the <code>RentalAgreements</code> &#xA0;deployed by address. Any new rental deployed gets pushed to it.</p><pre><code class="language-javascript">mapping(address =&gt; RentalAgreement[]) public rentalsByOwner;

...
function createNewRental( ...
  RentalAgreement newRental = new RentalAgreement(msg.sender, _tenantAddress, _rent, _deposit, _rentGuarantee, _tokenUsedToPay, _lendingService);

  emit NewRentalDeployed(address(newRental), msg.sender, _tenantAddress);
  
 rentalsByOwner[msg.sender].push(newRental);
}</code></pre><p>&#x1F3C1;&#x1F3C1; And we&apos;re done! &#x1F3C1;&#x1F3C1;<br>If you have any comment or feedback about this tutorial, we&apos;d love to hear it, so please don&apos;t hesitate to reach out!</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[How to import crypto prices in Google Sheets]]></title><description><![CDATA[<p></p><p>Here&apos;s how to get the current price of any cryptocurrency directly in Google Sheets. <br>After following the steps below, you&apos;ll be able to use a function <code>GETCRYPTOPRICE</code> which takes 2 parameters: 1. the ticker / symbol of a cryptocurrency and 2. the fiat currency.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://res-2.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/image.png" class="kg-image" alt loading="lazy"><figcaption>Example: This will</figcaption></figure>]]></description><link>https://blog.raphaelroullet.com/how-to-import-crypto-prices-in-google-sheets/</link><guid isPermaLink="false">63bb0818b8202902100a1f6f</guid><dc:creator><![CDATA[Raphael Roullet]]></dc:creator><pubDate>Sat, 15 May 2021 17:36:09 GMT</pubDate><media:content url="https://res-1.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/crypto-price3.png" medium="image"/><content:encoded><![CDATA[<img src="https://res-1.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/crypto-price3.png" alt="How to import crypto prices in Google Sheets"><p></p><p>Here&apos;s how to get the current price of any cryptocurrency directly in Google Sheets. <br>After following the steps below, you&apos;ll be able to use a function <code>GETCRYPTOPRICE</code> which takes 2 parameters: 1. the ticker / symbol of a cryptocurrency and 2. the fiat currency.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://res-2.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/image.png" class="kg-image" alt="How to import crypto prices in Google Sheets" loading="lazy"><figcaption>Example: This will return the current price of BTC in euro</figcaption></figure><p>It doesn&apos;t take long to set up, I promise!</p><h3 id="step-1-add-the-script-to-google-sheets">STEP 1: Add the script to Google Sheets</h3><p>In Google Sheets, go to &quot;Extensions&quot; and then &quot;Apps Script&quot;. Once the script editor is open, replace all the existing code with the following code:</p><pre><code class="language-javascript">
const CMC_PRO_API_KEY = &quot;YOUR_API_KEY&quot;;

function GETCRYPTOPRICE(ticker, currency) {
  try {
    // fetch data from url
    const res = UrlFetchApp.fetch(`https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=${ticker}&amp;convert=${currency}&amp;CMC_PRO_API_KEY=${CMC_PRO_API_KEY}`);
    
    const content = res.getContentText();
    
    // parse content
    const json = JSON.parse(content);

    // return the price
    return json.data[ticker.toString()].quote[currency.toString()].price;
  }
  catch (err) {
    return JSON.stringify(err);
  }
}</code></pre><p>Save the code and rename it as &#x201C;GETCRYPTOPRICE&#x201D;.</p><h3 id="step-2-get-your-coinmarketcap-key">STEP 2: Get your CoinMarketCap key</h3><p>Go to <a href="https://coinmarketcap.com/api/">https://coinmarketcap.com/api/</a> and click on &quot;Get your API key now&quot;. Create an account, which takes less than 2 minutes.<br>Then on your dashboard, click on &quot;COPY KEY&quot;.</p><figure class="kg-card kg-image-card"><img src="https://res-2.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/image.png" class="kg-image" alt="How to import crypto prices in Google Sheets" loading="lazy"></figure><h3 id="step-3-add-your-api-key">STEP 3: Add your API key</h3><p>Back to the script editor, replace &quot;YOUR_API_KEY&quot; with your actual API key that you just copied. The line should look like this:</p><p><code>const CMC_PRO_API_KEY = &quot;xxxxxxx-xxxx-xxxx-xxxx-xxxxxxx&quot;;</code></p><p>Hit &quot;Save project&quot; or Ctrl/Cmd + S.</p><h3 id="step-4-use-getcryptoprice-function-in-your-google-sheet">STEP 4: Use GETCRYPTOPRICE function in your Google Sheet</h3><p>You can now use the following formula in a cell:</p><p><code>=GETCRYPTOPRICE(ticker, fiatCurrency)</code></p><p>So for example to get the price of ETH in USD: <code>=GETCRYPTOPRICE(&quot;ETH&quot;,&quot;USD&quot;)</code></p><h3 id="step-5-sit-back-and-enjoy-monitoring-your-portfolio">STEP 5: Sit back and enjoy monitoring your portfolio</h3><figure class="kg-card kg-image-card"><img src="https://res-2.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/image.png" class="kg-image" alt="How to import crypto prices in Google Sheets" loading="lazy"></figure>]]></content:encoded></item><item><title><![CDATA[Guaranteeing rent payments on a blockchain]]></title><description><![CDATA[Using smart contracts to manage rent payments disintermediates the process and opens the door to new possibilities.]]></description><link>https://blog.raphaelroullet.com/rent-guarantee-on-a-blockchain/</link><guid isPermaLink="false">63bb0818b8202902100a1f6e</guid><category><![CDATA[Ethereum]]></category><dc:creator><![CDATA[Raphael Roullet]]></dc:creator><pubDate>Mon, 10 May 2021 16:49:18 GMT</pubDate><media:content url="https://res-1.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/francesca-tosolini-tHkJAMcO3QE-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://res-1.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/francesca-tosolini-tHkJAMcO3QE-unsplash.jpg" alt="Guaranteeing rent payments on a blockchain"><p></p><p>Disclaimer: I am not a real estate expert, the following just comes from personal experience and I realize it might potentially gloss over some regulatory constraints.</p><hr><p>Have you ever had difficulties renting a place? Or maybe you know someone who has. Landlords usually ask prospective tenants to provide proof of recurring income, which is easy if you&apos;re an employee with a solid contract. However, it can get more difficult for someone who&apos;s self-employed, on a temp contract, or even just moved from abroad.</p><p>Some companies offer to automate the screening process with a neat web interface and API connections to banks and databases, only to fall short if an applicant who&apos;s just moved from abroad is not yet registered in any of them. The complexities, don&apos;t end there. Countries that rely on a credit score system consider you inexistant in their system&apos;s eyes until you start building up your score, regardless of you physically being on their soil.</p><p>In cities like Paris, the market for apartment rentals has been incredibly favorable to landlords - although the COVID pandemic might have helped relieve some of that pressure.<br>As a result of this imbalance between supply and demand, which in this case we call a seller&apos;s market, landlords might receive hundreds of applicants within hours of posting a listing. They can afford to be picky. You may have provided all the proofs and guarantees that you would be a model tenant, your application is just one among many, as good as yours, if not better, in the pile. And if you&apos;re a freelancer, without stable earnings then good luck! Companies have increasingly been embracing contractors over the years; landlords seem to be lagging behind. This is a real problem for people without a full-time, long-term work contract and results in weeks-long hassle, fraught with rejections. </p><p>Apart from damages, landlords&apos; biggest fear is a tenant that doesn&apos;t pay rent. As a cover, it&apos;s not uncommon to get an insurance policy against it. So prospective tenants sometimes get a rejection that actually and indirectly comes from the insurance company. </p><p>Using something like Airbnb is one solution, but it&apos;s often more expensive. And it might feel homey, but not like <em>your home</em>. That&apos;s why it works well but only as a temporary solution.<br>Another solution is to use a guarantor, who&apos;s liable for the rent in case you can&apos;t pay, and pray you make it out of the pile of applicants this way. <br>But what if you can&apos;t provide worthy guarantors? <br>What&apos;s mind boggling, by the way, is that guarantors might not be able to actually pay themselves if need be. They might have their own debts or mortgage to pay first, but we don&apos;t check that, do we?!</p><p>So another solution, which I recognize only few could afford, would be to lock up a number of months worth of rent which would essentially replace the insurance company. That&apos;s already common practice in several countries and is known as a <a href="https://en.wikipedia.org/wiki/Security_deposit">security deposit</a>. Though it usually protects the landlord against damages, the amount here would be large enough to protect against default by the tenant as well.<br>Wouldn&apos;t it be reassuring to know that a sum is locked up and would be automatically transferred to a landlord in case of a missed rent payment? <br>That money has to be locked up and can&apos;t be trusted in hands of either the landlord or the tenant: the other would object. So one way to solve this trust issue is to put that money in escrow. Doing so, however, can incur some fees.<br>That&apos;s where a blockchain like Ethereum can shine, acting as an <strong>escrow account without a third-party</strong>. &#xA0;The security deposit would be managed by a smart contract with rules agreed upon between landlord and tenant. With rent being paid through this smart contract, it becomes not only very easy to verify if it was paid on time, it also becomes automatically actionable, i.e the money locked is released to the landlord if rent is due and wasn&apos;t paid. In case that undesirable event happens, it can be considered that rent was paid from the security deposit. Another - harsher - variant would be to consider that rent is <em>still due </em>for that &quot;missed month&quot; although the tenant lost some of that deposit.</p><p>Thanks to the composable nature of DeFi that &quot;rent guarantee&quot; could even earn interest while being locked up! Because it can represent quite a large sum, it might as well be put to work. <br>The earned interest on it can also be programmatically split between landlord and tenant. This would bear some similarities to <a href="https://en.wikipedia.org/wiki/Jeonse">Jeonse</a>, a type of lease common in South Korea which was born out of an environment with high interest rates, just like in DeFi today! <br>Many designs in terms of micro-economics are possible. For example, it could be programmed that tenants lose the earned interest if they don&apos;t pay on time, as an additional incentive to do so.</p><p>If we want to take things even further, it might make sense to use money streams, introduced by protocols such as <a href="https://sablier.finance/">Sablier</a> or <a href="https://www.superfluid.finance/">Superfluid</a>, which allow money to be streamed from an account to another just like a video stream! <br>If you think about it, isn&apos;t paying rent once a month kind of arbitrary? Why not every 2 weeks? Or once a week? Renting a space is agreed for a period of time, which is continuous; why not pay continuously then?! I haven&apos;t explored the pros and cons of doing just that but it is just as arbitrary, if not a more natural way of paying rent. <br>Whereas with traditional banking it would be absurd to wire a small fraction of your monthly rent every minute, now it&apos;s at least <em>technically</em> <em>feasible</em> on a blockchain.</p><p>With a friend a mine we even started a basic implementation of what I just described. I&apos;ve been wanting to write a technical tutorial about smart contract development, so it will be published here, taking that application as an example. Subscribe to my newsletter if you want to get notified when it comes out!</p><p></p>]]></content:encoded></item><item><title><![CDATA[Developing on Ethereum: Top resources to get started]]></title><description><![CDATA[A compilation of resources to get started with Ethereum development and learn about the EVM, Solidity, Hardhat...]]></description><link>https://blog.raphaelroullet.com/getting-started-ethereum-resources/</link><guid isPermaLink="false">63bb0818b8202902100a1f6d</guid><category><![CDATA[Ethereum]]></category><category><![CDATA[Solidity]]></category><dc:creator><![CDATA[Raphael Roullet]]></dc:creator><pubDate>Mon, 29 Mar 2021 15:32:55 GMT</pubDate><media:content url="https://res-2.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/jukan-tateisi-bJhT_8nbUA0-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://res-2.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/jukan-tateisi-bJhT_8nbUA0-unsplash.jpg" alt="Developing on Ethereum: Top resources to get started"><p></p><p>A friend of mine told me he was interested to learn how to make decentralized applications. After having been through part of this journey myself, I can recommend some resources that I personally used. Hopefully it will help answer the question: Where do I start?</p><p>So here we go, here&apos;s a list of <em>free</em> resources that I found the most helpful for learning how to build decentralized applications on Ethereum:</p><h2 id="1-mastering-ethereum">1 - Mastering Ethereum</h2><p>This is a book written by crypto OG Andreas Antonopoulos and Gavin Wood, co-creator of Ethereum. It&apos;s meant to serve both &quot;as a reference manual and as a cover-to-cover exploration of Ethereum&quot;. <br>It&apos;s ideal for developers wanting to learn how Ethereum works from a technical perspective. It starts with the fundamentals (addresses, transaction, gas etc...) up to the inner workings (EVM) and teaches how to build a complete decentralized application with examples.<br>Originally published at the end of 2018, it is getting outdated though (the Ethereum space has been evolving quite a lot since!). The good news is that a 2nd edition is in the works.</p><p>You can either buy the paperback version <a href="https://aantonop.com/books/">here</a> or find it as open-source <a href="https://github.com/ethereumbook/ethereumbook">here</a>.</p><h2 id="2-cryptozombies">2 - CryptoZombies</h2><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://cryptozombies.io/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">#1 Solidity Tutorial &amp; Ethereum Blockchain Programming Course | CryptoZombies</div><div class="kg-bookmark-description">CryptoZombies is The Most Popular, Interactive Solidity Tutorial That Will Help You Learn Blockchain Programming on Ethereum by Building Your Own Fun Game with Zombies &#x2014; Master Blockchain Development with Web3, Infura, Metamask &amp; Ethereum Smart Contractsand Become a Blockchain Developer in Record Ti&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://cryptozombies.io/images/favicon.ico" alt="Developing on Ethereum: Top resources to get started"><span class="kg-bookmark-author">CryptoZombies</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://cryptozombies.io/course/static/image/preview-zombie.png" alt="Developing on Ethereum: Top resources to get started"></div></a></figure><p>This an interactive tutorial that has become a reference recommended by many. It is well-polished and provides a fun introduction to Solidity (and more!). <br>Plus, you&apos;ll get to develop a simplified version of the famous <a href="https://www.cryptokitties.co/">CryptoKitties</a> game. &#x1F431;&#x2728;</p><h2 id="3-eth-build">3 - ETH.Build</h2><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://eth.build/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">ETH.Build - Educational Sandbox For Web3</div><div class="kg-bookmark-description">Educational sandbox for prototyping Web3. Learn Ethereum visually with drag-and-drop programming.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://eth.build/icons/icon-512x512.png?v=5cfd71ec4d000b3fd8e1dac3cf53716a" alt="Developing on Ethereum: Top resources to get started"><span class="kg-bookmark-author">Educational Sandbox For Web3</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://eth.build/title.jpg" alt="Developing on Ethereum: Top resources to get started"></div></a></figure><p><a href="https://twitter.com/austingriffith">Austin Griffith</a> has put out fantastic videos that help understanding how a blockchain works, starting from the ground up. You can learn by watching him, literally manipulating the building blocks of Ethereum thanks to a really awesome sandbox he has developed. Try it out yourself at <a href="https://sandbox.eth.build/">https://sandbox.eth.build/</a></p><h2 id="4-eattheblocks">4 - EatTheBlocks</h2><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.youtube.com/channel/UCZM8XQjNOyG2ElPpEUtNasA"><div class="kg-bookmark-content"><div class="kg-bookmark-title">EatTheBlocks</div><div class="kg-bookmark-description">Do you want to learn how to build Solidity smart contracts and Ethereum decentralized applications (Dapps)? On this channel, you will find a ton of high-quality tutorials on Solidity and Ethereum Dapps development:- How to learn Solidity programming?- How to develop Ethereum smart contracts?- H&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.youtube.com/s/desktop/b70e86a1/img/favicon_144.png" alt="Developing on Ethereum: Top resources to get started"><span class="kg-bookmark-author">YouTube</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://yt3.ggpht.com/ytc/AAUvwnhO_sUoim9P4Kd6w47Ahf26D7qDu6WfKdaiAaQb=s900-c-k-c0x00ffffff-no-rj" alt="Developing on Ethereum: Top resources to get started"></div></a></figure><p>EatTheBlocks is a Youtube channel covering a broad range of topics related to Ethereum and DeFi. Although its videos have veered more and more towards news coverage with time, broadening its target audience to not only include developers, the channel still contains very helpful tutorials. Its host, Julian, offers some <a href="https://eattheblocks-pro.teachable.com/">courses</a> as well.</p><h2 id="5-tutorials-for-smart-contract-development-frameworks">5 - Tutorials for smart contract development frameworks</h2><p>As part of the web 3 stack, you should master a framework for developing on Ethereum that will help with compiling your smart contracts, running tests, deploying them, etc... </p><p>The one that seems to be winning the community over at the moment is <a href="https://hardhat.org/">Hardhat</a> &#x1F477;. Their tutorial is <a href="https://hardhat.org/tutorial/">here</a>.</p><p>You might also come across <a href="https://www.trufflesuite.com/truffle">Truffle</a> which was the main framework for a while. It has this <a href="https://www.trufflesuite.com/tutorials/pet-shop">tutorial</a> in particular (though it might have become a bit old).</p><h2 id="6-scaffold-eth">6 - Scaffold-Eth</h2><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/austintgriffith/scaffold-eth"><div class="kg-bookmark-content"><div class="kg-bookmark-title">austintgriffith/scaffold-eth</div><div class="kg-bookmark-description">&#x1F3D7; forkable Ethereum dev stack focused on fast product iterations - austintgriffith/scaffold-eth</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/favicons/favicon.svg" alt="Developing on Ethereum: Top resources to get started"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">austintgriffith</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://avatars.githubusercontent.com/u/2653167?s=400&amp;v=4" alt="Developing on Ethereum: Top resources to get started"></div></a></figure><p>Scaffold-eth, also made by Austin Griffith, comes with a lot of handy things out of the box, just as its name suggests. Beyond just smart contracts, it uses React and Hardhat so it&apos;s a good playground to practice your skills across the whole web 3 stack thanks to tutorials such as <a href="https://github.com/austintgriffith/scaffold-eth#tutorial-1--programming-decentralized-money">this one</a>. <br>Then, at some point, it&apos;s wise to avoid &quot;the Tutorial trap&quot; and starts developing on your own, without following a tutorial. Scaffold-eth can help there too, as a launchpad to quickly take your idea and build a prototype from it.</p><h2 id="7-chainshot">7 - ChainShot</h2><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.chainshot.com/courses"><div class="kg-bookmark-content"><div class="kg-bookmark-title">ChainShot</div><div class="kg-bookmark-description">Fast-track your Ethereum Developer career in an instructor-led and challenging bootcamp focused on discussion and application!</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.chainshot.com/client/favicon.png?v=3" alt="Developing on Ethereum: Top resources to get started"></div></div><div class="kg-bookmark-thumbnail"><img src="http://res.cloudinary.com/divzjiip8/image/upload/v1529612088/center-out_lqp2jr.png" alt="Developing on Ethereum: Top resources to get started"></div></a></figure><p>Chainshot provides a great interactive tutorial to learn how to build on top of <a href="https://aave.com/">Aave</a>. Though I really liked it and felt like a game, it&apos;s the only one that I&apos;ve completed from them, so I cannot vouch for the rest.</p><h2 id="8-solidity-docs">8 - Solidity Docs</h2><p>Adding to the list, the Solidity docs are obviously <strong>the</strong> reference when it comes to getting a good grasp on Solidity and its subtleties. <br><em>However</em>, they are rightfully exhaustive so they might be a bit intimidating as a place to start.</p><h2 id="alternatives-">Alternatives &#x1F40D; </h2><p>As an alternative to Solidity, you might want to learn Vyper with <a href="https://vyper.fun/">Vyper.fun</a>. Especially if you&apos;re more into Python than JavaScript, then check out <a href="https://github.com/eth-brownie/brownie">Brownie</a>!</p><hr><p>If you want to get notified of a new post, <a href="https://blog.raphaelroullet.com/newsletter/">subscribe here</a>.</p>]]></content:encoded></item><item><title><![CDATA[Introduction to Solidity types]]></title><description><![CDATA[An introduction to the different types available in Solidity]]></description><link>https://blog.raphaelroullet.com/solidity-types/</link><guid isPermaLink="false">63bb0818b8202902100a1f6a</guid><category><![CDATA[Solidity]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Programming]]></category><dc:creator><![CDATA[Raphael Roullet]]></dc:creator><pubDate>Sun, 31 Jan 2021 20:50:21 GMT</pubDate><content:encoded><![CDATA[<h2></h2><p>One of the first important steps in learning Solidity, a <a href="https://stackoverflow.com/a/1517670">statically-typed</a> language, is to get a good understanding of the types available to use. So here they are!</p><p><em>Note: This was written for the latest Solidity version at the time of writing which is 0.8.1.</em></p><h2 id="value-types">Value Types</h2><p>Variables with value types hold data directly and passing them as argument or assignment creates a copy. Let&apos;s start with the simplest of them!</p><h3 id="boolean">Boolean</h3><p>They are declared with the <code>bool</code> keyword and can be either <code>true</code> or <code>false</code></p><pre><code class="language-Solidity">bool myBoolean;   // declaration
myBoolean = true; // assignment</code></pre><h3 id="integer">Integer</h3><p>You can specify if a variable is a signed integer with <code>int</code> or unsigned with <code>uint</code> followed by their range by appending the number of bits needed. <br>For example <code>uint8</code> represents an unsigned integer of 8 bits. <br>It goes in increment of 8 from <code>int8</code> to <code>int256</code> and from <code>uint8</code> to <code>uint256</code>. &#xA0;</p><p>&#x1F4A1; If you simply declare an <code>int</code> or <code>uint</code> it will take the <strong>maximum</strong> range by default of 256 bits.</p><h3 id="integer-literal">Integer Literal</h3><p>Interpreted as decimals, <a href="https://en.wikipedia.org/wiki/Integer_literal">integer literals</a> are comprised of numbers. Ex: 69, 88, 11...</p><p>Decimals are possible such as <code>.3</code> , <code>1.6</code>. </p><p>And so is scientific notation: <code>3e10</code> , <code>-4.3e-2</code></p><p>&#x1F4A1; For better readability integers can be written with an underscore, i.e <code>456_000</code> and <code>456000</code> are both valid and equivalent.</p><h3 id="string-literal">String Literal</h3><p>String literals can either be written with single (<code>&apos;unicorn&apos;</code>) or double quotes (<code>&quot;sushi&quot;</code>).</p><p>&#x1F4A1; <code>&quot;a long&quot; &quot; text&quot;</code> is considered the same as <code>&quot;a long text&quot;</code></p><p>So what if you actually want to have a string with quotes in it? You need to escape them. Escaping a character is done by adding <code>\</code> in front. So <code>&apos;\&quot;hello!\&quot;&apos;</code> becomes <code>&quot;hello!&quot;</code>. Other characters that need to be escaped include newline, backslash, carriage return etc... </p><p>&#x1F4A1; By default string literals can only contain ASCII but unicode literals with UTF-8 encoding can be written like this:</p><pre><code>string memory congrats = unicode&quot;Congrats! &#x1F389;&quot;</code></pre><h3 id="hexadecimal-literal">Hexadecimal Literal</h3><p>Hexadecimal literals are recognizable as they start with the prefix <code>hex</code> such as <code>hex&quot;0d2c&quot;</code>. They behave a lot like string literals.</p><h3 id="enum">Enum</h3><p>An <code>enum</code> is a convenient way to declare your own type with a limited, well-defined list of options:</p><pre><code>enum CustomerType { EarlyBird, Regular, VIP }
CustomerType customer;</code></pre><p>Behind the scenes, options are just integers starting from 0 for the first option (which is also the enum&apos;s default value). Hence, enums are explicitly convertible from and to integers.</p><h3 id="address">Address</h3><p>Here&apos;s where we are starting to see how Solidity was uniquely designed to write smart contracts.</p><p>They are 2 ways to declare an address:</p><pre><code>address plainAddress;

address payable payableAddress;</code></pre><p>The difference is that an <code>address payable</code> is meant to receive Ether through a method such as <code>.transfer()</code> which is <strong>not available</strong> on a &quot;simple&quot; <code>address</code>. </p><p>One being a sort of extension of the other, it makes sense that you can cast an address payable to an address <em>implicitly</em>...</p><pre><code>address myAddress = payableAddress;</code></pre><p>...But the opposite has to be done <em>explicitly</em>.</p><pre><code>address payable foo = payable(plainAddress); 

</code></pre><p>You can learn more about the possible conversions <a href="https://docs.soliditylang.org/en/latest/types.html#address">here</a>.</p><p>The balance of an address can be obtained by simply writing <code>myAddress.balance</code>. For the current contract&apos;s balance, you first convert it to an address <code>address(this)</code> so it becomes: <code>address(this).balance</code></p><h3 id="address-literal">Address Literal</h3><p>It&apos;s an hexadecimal literal such as <code>0xBA2E7Fed597fd0E3e70f5130BcDbbFE06bB94fe1</code> that matches the right format of an Ethereum address. It has to pass a checksum test to be hardcoded in a contract like this:</p><pre><code>address deployedContract = 0xBA2E7Fed597fd0E3e70f5130BcDbbFE06bB94fe1;</code></pre><p>It has the type <code>address</code> and not <code>address payable</code> starting from Solidity 0.8 but can be converted to the latter.</p><h3 id="contract">Contract</h3><p>Contracts have their own type which can be converted:</p><ul><li>to a contract they inherit from</li><li>to or from an address:</li></ul><p><code>address contractAddress = address(MyContract)</code></p><p>&#x26A0;&#xFE0F; There are some subtleties in case you want to cast to an <code>address payable</code> and the contract does not have a receive or payable fallback function, you need to use <code>payable(address(x))</code>. &#xA0;</p><p>On a contract type, the members are the external functions (<code>myContract.getReward(args)</code>) as well as all the <strong>public</strong> variables defined in it (<code>myContract.foo</code>): Solidity automatically creates a getter function of the same name for any variable marked as <code>public</code>.</p><h3 id="fixed-size-byte-array">Fixed-size byte array</h3><p>If you want to store a sequence of bytes which you know won&apos;t change in size you can use one of the following types: <code>byte</code> (= <code>bytes1</code>), <code>bytes2</code>, <code>bytes3</code>, ..., <code>bytes32</code>. Pick the right size!</p><h3 id="function">Function</h3><p>Functions are defined this way:</p><pre><code>function myFunction(&lt;parameter types&gt;) {private|internal|external|public} [pure|view|payable] [returns (&lt;return types&gt;)]</code></pre><p>Let&apos;s unpack the few different options!<br>A function declaration starts with the <code>function</code> keyword, followed by the function name and then by parentheses which, optionally, contain parameters in between them such as <code>transfer(address to, uint value)</code></p><p>You then need to specify and pick between</p><h4 id="private-vs-internal-vs-external-vs-public">private vs. internal vs. external vs. public</h4><p><strong>Private</strong> functions can only be called from other functions inside the current contract. Their name generally start with <code>_</code> by convention.</p><p><strong>Internal</strong> functions are like <code>private</code> functions but can also be executed from contracts <em>deriving</em> from the contract they were defined in.<br><br><strong>External</strong> functions are meant to be called from outside the contract declaring them. (You can only call them internally by using <code>this.foo()</code> instead of <code>foo()</code>)</p><p><strong>Public</strong> functions can be called from anywhere, both internally and externally.</p><p>&#x26A0;&#xFE0F; Needless to say that getting this right is important from a security perspective. It&apos;s good practice to restrict visibility as much as possible, only exposing what needs to be exposed. With newer versions of Solidity, a function&apos;s visibility must be declared. Using an older version and not specifying any of these keywords means opting for the default function visibility which is <code>public</code>.</p><h4 id="pure-vs-view-vs-payable">pure vs. view vs. payable</h4><ul><li><code>payable</code>: include this function type if you want your function to be able to receive ETH while being called. <br>(Note that it doesn&apos;t mean it <strong>must</strong> be sent some eth to work. Depending on your implementation it can really well function with a payment of 0 ETH)</li><li><code>view</code>: this function modifier ensures that the function does not modify the state, basically it doesn&apos;t save or change anything on the ethereum blockchain</li><li><code>pure</code>: pure functions can neither save <strong>nor read</strong> data from the blockchain</li></ul><p>&#x1F4A1; Marking a function with <code>view</code> or <code>pure</code> means that it doesn&apos;t cost any gas to call it from outside the current contract but does when called internally!</p><h4 id="function-return-types">Function return types</h4><p>Unless the function returns nothing you must state what types are returned:</p><pre><code>uint public minimumContribution;
uint public contributorCount;
address public manager;

// ...
function getSummary() public view returns (uint, uint, address) {
        return (
            minimumContribution,
            contributorCount,
            manager
        );
    }</code></pre><h2 id="reference-types">Reference Types</h2><p>As opposed to value types, data location of a reference type must be declared: it corresponds to where the data is stored. There are 3 options:</p><ul><li><strong>storage</strong>: This is where to store <em>permanent</em> data written on the blockchain. It&apos;s the more expensive data location. Data in <code>storage</code> for a smart contract is like data in a file on your hard drive, it will exists as long the contract does.</li><li><strong>memory</strong>: The <code>memory</code> location is for data that will be held temporarily during a function execution and discarded after. Data in <code>memory</code> is cheaper and analogous to data stored in RAM.</li><li><strong>calldata</strong>: <code>calldata</code> is a special data location where function arguments are stored. This data is non-modifiable and non-persistent. <br>&#x1F4A1; The data location for parameters of external functions must be <code>calldata</code>.</li></ul><h3 id="array">Array</h3><p>There are 2 kinds of arrays: <strong>fixed-size arrays</strong> and <strong>dynamic-size arrays.</strong></p><p>The way to declare them is different. For example:</p><ul><li><code>uint[3] foo</code> is an array that will always containing 3 unsigned integers</li><li><code>string[] bar</code> is an array of strings of dynamic size</li></ul><p>Either way, note that all items of an array must share the same type!</p><p>You can create arrays of any type, including <code>array</code>, which gives you an array of arrays. For instance, <code>uint[][5] myArray</code> is a dynamic array of arrays of 5 uint (each). &#xA0;&#x1F92F;<br>Arrays indices start at 0 so you access the third <code>uint</code> in the second dynamic arrays with <code>myArray[1][2]</code>.<br>&#x26A0;&#xFE0F; Depending on the version of Solidity you&apos;re using, you might need to add <code>pragma experimental ABIEncoderV2;</code> at the top of your file to enable that.</p><p><strong>Special arrays</strong></p><p><code>bytes</code> and <code>string</code> are types used for variables with arbitrary-length of raw byte data and arbitrary-length of string (UTF-8) data respectively. However, if the length can be limited to a certain number of bytes it is better to use a value type like <code>bytes32</code> instead of <code>bytes</code>.</p><p><strong>Storage vs memory arrays</strong></p><p>You can create an array stored in memory with:</p><pre><code> function f(uint len) public pure {
       uint[] memory a = new uint[](len); // length is dynamically set
       return a.length;
 }</code></pre><p>However its size can&apos;t change from the one provided and you can&apos;t <code>push</code> an element in it.</p><p><strong>Array literals</strong></p><pre><code>string memory AAVE = &apos;AAVE&apos;;
string[3] memory bag = [&apos;SNX&apos;, AAVE, &apos;UNI&apos;];</code></pre><p>In this example [&apos;SNX&apos;, AAVE, &apos;UNI&apos;] is an array literal. <br>Array literals are memory arrays of static size. Their elements, if not of the same type, should at least be convertible to the same type.</p><p>&#x1F4A1;You can use an <em>array slice</em> to get only a part of an array:<br>- <code>bar[2:]</code> returns a slice from the 3rd element to the last<br>- <code>bar[:3]</code> returns a slice from the 1st element to the 3rd<br>- <code>bar[1:3]</code> returns a slice from the 2nd element to the 3rd</p><h3 id="struct">Struct</h3><p>Structs are great for grouping variables together. They somewhat resemble objects in JavaScript. Here&apos;s how to declare one:</p><pre><code class="language-Solidity">struct Proposal {	
    address owner;
    string name;
    string description;
    uint approvals;
}</code></pre><p>and here&apos;s how to create an instance of our struct:</p><pre><code>Proposal memory myProposal = Proposal({owner: msg.sender, name: &quot;Proposal 1&quot;, description: &quot;foo&quot;, approvals: 0});</code></pre><p>&#x1F4A1; It is not possible for a struct to declare a member as a struct of its own type. However, it can contain another struct type, arrays or mappings.</p><pre><code>struct OtherStruct {
    uint n;
}
    
struct MyStruct {
    uint[] myArray;							// &#x2705; OK
    mapping(address =&gt; bool) approvals;		// &#x2705; OK
    OtherStruct bar; 						// &#x2705; OK
    MyStruct foo;    						// &#x274C; NOT OK
}</code></pre><h2 id="mapping">Mapping</h2><p>Mappings are like hash tables than can be declared with <code>mapping(_keyType =&gt; _ValueType) mappingVariableName</code>. For example in <code>mapping(address =&gt; bool) approvers</code> all keys have the same <em>address</em> type and all values are of <em>boolean</em> type. This is a major difference with <code>Structs</code> which contain key-value pairs of different types.</p><p>There are some good things to know and a few gotchas about mappings:</p><ul><li>Mappings can be nested!</li><li>The value type can be any type (even <em>Contract</em> type<em>).</em></li><li>All key-value pairs exist and are initialized with the default value according to the value type (empty string <code>&quot;&quot;</code> for a mapping of strings, <code>false</code> for booleans, etc...).</li><li>The key type cannot be a <em>mapping</em>, <em>struct</em> or <em>array.</em></li><li>Keys are not stored! So there is no way to retrieve them all, or loop through all the assigned keys (or <a href="https://docs.soliditylang.org/en/latest/types.html#iterable-mappings">not without a data structure on top of it</a> anyway). Mappings are used to lookup one value with a specific key.</li><li>Data location of a mapping can only be <code>storage</code>. As a result, mappings or arrays and structs containing a mapping cannot be used as parameters or parameters of <code>public</code> functions.</li></ul><p>The more items you have in array the more costly it becomes to loop through it. If you face this problem, a much more efficient solution in terms of computation and gas can be to use a mapping instead.<br></p><p>&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;&#x1F3C1;</p><p>This post is meant to be an introduction so a lot things about conversion, operations etc has been omitted. For more details on Solidity types, please refer to the <a href="https://docs.soliditylang.org/en/latest/types.html">official Solidity documentation</a>, making sure to select the version corresponding to the version pragma of your Solidity files.<br>Comments? Questions? Feedback? You spotted a mistake? Please hit me up on Twitter <a href="https://twitter.com/RaphaelRoullet">@RaphaelRoullet</a> !<br></p><p></p><p> </p>]]></content:encoded></item><item><title><![CDATA[Favorite Quotes]]></title><description><![CDATA[Some of my favorites quotes compiled here.]]></description><link>https://blog.raphaelroullet.com/favorite-quotes/</link><guid isPermaLink="false">63bb0818b8202902100a1f69</guid><category><![CDATA[Living Documents]]></category><dc:creator><![CDATA[Raphael Roullet]]></dc:creator><pubDate>Sun, 09 Feb 2020 16:59:14 GMT</pubDate><media:content url="https://res-3.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/patrick-tomasso-Oaqk7qqNh_c-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://res-3.cloudinary.com/hixaewgzp/image/upload/q_auto/v1/ghost-blog-images/patrick-tomasso-Oaqk7qqNh_c-unsplash.jpg" alt="Favorite Quotes"><p>&#x1F4A1; This is a living document. It will probably get updated with time.</p><p>Here are some of my favorite quotes, in no particular order:</p><p>&quot;Learn who you are to become who you are.&quot; <br>Pindar</p><p>&#x201C;Take care to get what you like or you will be forced to like what you get.&#x201D; <br>Bernard Shaw</p><p>&quot;Men press towards the light, not so as to see better, but so as to shine better.&quot; <br>Friedrich Nietzsche</p><p>&quot;The difference between a successful person and others is not a lack of strength, not a lack of knowledge, but rather in a lack of will.&quot;<br>Vince Lombardi</p><p>&#x201C;Happiness is not a finish line, and if we can&#x2019;t feel content amid the mess and the striving, we might never feel it.&#x201D; <br>Ben Saunders</p><p>&quot;I have not failed. I&apos;ve just found 1000 ways that don&apos;t work.&quot; <br>Thomas A. Edison</p><p>&#x201C;Only passions, great passions can elevate the soul to great things.&#x201D; <br>Denis Diderot</p><p>&quot;The most exciting phrase to hear in science, the one that heralds new discoveries, is not &apos;Eureka!&apos; but &apos;That&apos;s funny...&#x2019; &quot;<br>Isaac Asimov</p><p>&#x201C;The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man.&#x201D; <br>George Bernard Shaw</p><p>&#x201C;Strong minds discuss ideas, average minds discuss events, weak minds discuss people.&#x201D; <br>Socrates</p><p>&#x201C;There is surely nothing quite so useless as doing with great efficiency what should not be done at all.&#x201D; <br>Peter Drucker</p><p>&quot;We suffer more often in imagination than in reality.&quot; <br>Seneca</p><p>&quot;An investment in knowledge always pays the best interest.&quot;<br>Benjamin Franklin</p><p>&#x201C;The two most important days in your life are the day you are born and the day you find out why.&#x201D; <br>Mark Twain.</p>]]></content:encoded></item></channel></rss>