Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tut] Solidity Contract Types, Byte Arrays, and {Address, Int, Rational} Literals

#1
Solidity Contract Types, Byte Arrays, and {Address, Int, Rational} Literals

<div>
<div class="kk-star-ratings kksr-auto kksr-align-left kksr-valign-top" data-payload="{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;753297&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;top&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;1&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;5&quot;,&quot;greet&quot;:&quot;Rate this post&quot;,&quot;legend&quot;:&quot;5\/5 - (1 vote)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;width&quot;:&quot;142.5&quot;,&quot;_legend&quot;:&quot;{score}\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}">
<div class="kksr-stars">
<div class="kksr-stars-inactive">
<div class="kksr-star" data-star="1" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="2" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="3" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="4" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="5" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
</p></div>
<div class="kksr-stars-active" style="width: 142.5px;">
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
</p></div>
</div>
<div class="kksr-legend" style="font-size: 19.2px;"> 5/5 – (1 vote) </div>
</div>
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube"><a href="https://blog.finxter.com/data-types-in-solidity-smart-contract-part-21-contract-types-fixed-size-byte-arrays-dynamically-sized-byte-arrays-address-literals-rational-and-integer-literals/"><img src="https://blog.finxter.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=https%3A%2F%2Fi.ytimg.com%2Fvi%2F8UnpQvy3A1U%2Fhqdefault.jpg" alt="YouTube Video"></a><figcaption></figcaption></figure>
<p>With this article, we continue <a href="https://blog.finxter.com/solidity-crash-course/" data-type="post" data-id="445146" target="_blank" rel="noreferrer noopener">our journey</a> through the realm of <a href="https://blog.finxter.com/solidity-boolean-and-integer-types-a-helpful-guide-with-video/" data-type="post" data-id="728241" target="_blank" rel="noreferrer noopener">Solidity data types</a> following today’s topics: </p>
<ul>
<li>contract types,</li>
<li>fixed-size byte arrays, </li>
<li>dynamically-sized byte arrays, </li>
<li>address literals, </li>
<li>rational, and </li>
<li>integer literals. </li>
</ul>
<p>It’s part of our long-standing tradition to make this (and other) articles a faithful companion or a supplement to the <a rel="noreferrer noopener" href="https://docs.soliditylang.org/en/v0.8.15/types.html#contract-types" data-type="URL" data-id="https://docs.soliditylang.org/en/v0.8.15/types.html#contract-types" target="_blank">official Solidity documentation</a>.</p>
<p class="has-global-color-8-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f447.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Download PDF Slide Deck</strong> at the end of this tutorial!</p>
<h2>Contract Types</h2>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" width="1024" height="576" src="https://blog.finxter.com/wp-content/uploads/2022/10/image-37-1024x576.png" alt="" class="wp-image-753532" srcset="https://blog.finxter.com/wp-content/uploads/2022/10/image-37-1024x576.png 1024w, https://blog.finxter.com/wp-content/uplo...00x169.png 300w, https://blog.finxter.com/wp-content/uplo...68x432.png 768w, https://blog.finxter.com/wp-content/uplo...age-37.png 1423w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>
<p class="has-base-background-color has-background">To quote the official Solidity documentation, <em>“every contract defines its own type”</em>. </p>
<p>This statement might seem a bit cryptic, and since we’re an efficient crowd, we’d surely like to know what it means. </p>
<p>We can all remember that some number of articles ago, we mentioned how Solidity has key elements of an <a href="https://blog.finxter.com/data-types-in-solidity-smart-contract-part-20-fixed-point-numbers-address-and-address-type-members/" data-type="post" data-id="738934" target="_blank" rel="noreferrer noopener">object-oriented programming language (OOPL)</a>. We also emphasized how smart contracts in Solidity are very similar to classes in an OOPL. </p>
<p>Classes themselves are a mesh of custom data types, i.e. <a rel="noreferrer noopener" href="https://blog.finxter.com/solidity-structure-of-a-smart-contract-basic-elements/" data-type="post" data-id="723680" target="_blank">structs</a>, and <a href="https://blog.finxter.com/solidity-structure-of-a-smart-contract-basic-elements/" data-type="post" data-id="723680" target="_blank" rel="noreferrer noopener">functions</a>, which qualifies classes to be treated as types. </p>
<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f449.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>By extension, our contracts are also treated as types, and as every contract is unique in its own right, it defines its own type.</strong> Being a type, we can implicitly convert a specific contract to a contract it inherits from, i.e. if contract “Aa” inherits from contract A, it can also be converted to contract “A”. </p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" width="1024" height="768" src="https://blog.finxter.com/wp-content/uploads/2022/10/image-38-1024x768.png" alt="" class="wp-image-753543" srcset="https://blog.finxter.com/wp-content/uploads/2022/10/image-38-1024x768.png 1024w, https://blog.finxter.com/wp-content/uplo...00x225.png 300w, https://blog.finxter.com/wp-content/uplo...68x576.png 768w, https://blog.finxter.com/wp-content/uplo...age-38.png 1257w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>
<p>Besides that, we can explicitly convert each contract to and from the <a rel="noreferrer noopener" href="https://blog.finxter.com/data-types-in-solidity-smart-contract-part-20-fixed-point-numbers-address-and-address-type-members/" data-type="post" data-id="738934" target="_blank">address type</a>. Even more, we can conditionally convert a contract to and from the <code><a rel="noreferrer noopener" href="https://blog.finxter.com/data-types-in-solidity-smart-contract-part-20-fixed-point-numbers-address-and-address-type-members/" data-type="post" data-id="738934" target="_blank">address payable</a></code> type (remember, that’s the same type as the <code>address</code> type, but predetermined to receive <a rel="noreferrer noopener" href="https://blog.finxter.com/introduction-to-ethereums-gas-in-solidity-development/" data-type="post" data-id="37644" target="_blank">Ether</a>). </p>
<p>The condition is that the contract type must have a <code>receive</code> or <code><a rel="noreferrer noopener" href="https://blog.finxter.com/what-is-payable-in-solidity/" data-type="post" data-id="37282" target="_blank">payable</a></code> fallback function. If it does, we can make the conversion to address payable by using <code>address(x)</code>. </p>
<p>However, if the contract type does not implement (a more professional way to say “have”) a <code>receive</code> or <code>payable</code> fallback function, then the conversion to address payable has to be even more explicit (no swearing!) by stating <code>payable(address(x))</code>.</p>
<p>A local variable <code>obc</code> of a contract type <code>OurBeautifulContract</code> is declared by <code>OurBeautifulContract obc;</code>. </p>
<p>Once we point our variable <code>obc</code> to an instantiated (newly created) contract, we’d be able to call functions on that contract. </p>
<p>In terms of its data representation, a contract is identical to the <code>address</code> type. This is important because the contract type is not directly supported by the ABI, but the address type, as its representative, is supported by the ABI.</p>
<p>In contrast to the types mentioned so far, contract types don’t support any operators.</p>
<p>The members of contract types are the external functions (the functions only available to other contracts) and state variables whose visibility is set to <code>public</code>.</p>
<p>When we need to access type information about the contract, like the <code>OurBeautifulContract</code> above, we’d call the <code>type(OurBeautifulContract)</code> function (<a href="https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#type-information" target="_blank" rel="noreferrer noopener">docs</a>).</p>
<h2>Fixed-Size Byte Arrays</h2>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" width="1024" height="682" src="https://blog.finxter.com/wp-content/uploads/2022/10/image-39-1024x682.png" alt="" class="wp-image-753553" srcset="https://blog.finxter.com/wp-content/uploads/2022/10/image-39-1024x682.png 1024w, https://blog.finxter.com/wp-content/uplo...00x200.png 300w, https://blog.finxter.com/wp-content/uplo...68x512.png 768w, https://blog.finxter.com/wp-content/uplo...age-39.png 1415w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>
<p>The value type <code>bytesN</code> holds a sequence of bytes, whose length, and accordingly <code>N</code> goes from 1 to up to 32, i.e., <code>bytes1</code>, …, <code>bytes32</code>.</p>
<p>The available operators for fixed-size operators are:</p>
<ul>
<li><strong>Comparisons</strong>: <code>&lt;=, &lt;, ==, !=, >=, ></code> (evaluate to bool)</li>
<li><strong>Bit operators</strong>: <code>&amp;, |, ^</code> (bitwise exclusive or), <code>~</code> (bitwise negation)</li>
<li><strong>Shift operators</strong>: <code>&lt;&lt;</code> (left shift), <code>>></code> (right shift)</li>
<li><strong>Index access</strong>: If <code>x</code> is of type <code>bytesN</code>, then <code>x[k]</code> for <code>0 &lt;= k &lt; N</code> returns the <code>k</code>-th byte (read-only). In other words, <code>x[0]</code> up to (inclusive) <code>x[N-1]</code> is available for index access; if <code>N = 1</code>, then only <code>x</code> is of type <code>bytes1</code>, and <code>x[0]</code> is the only element, i.e. byte accessible by the index.</li>
</ul>
<p>The shifting operator always uses an unsigned integer type as a right operand, which represents the number of bits to shift by, and returns the type of the left operand. </p>
<p>Let’s take a look at a simple example to illustrate:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">bytes2 lo = 0x1234; // (lo is the left operand)
uint8 ro = 5; // (ro is the right operand variable, must be u... type)
lo &lt;&lt; ro // will evaluate to an lo type, bytes2
</pre>
<p>A fixed-size byte array has only one member, .length, that holds the fixed length of the byte array. This member is accessible as the read-only value.</p>
<p class="has-base-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Warning</strong>: Since the type <code>bytes1</code> is a sequence of 1 byte in length, the type <code>bytes1[]</code> is a fixed-size byte array of 1-byte sequences. However, each element of the array is padded with 31 bytes, due to padding rules for elements stored in memory, stack, and call data, i.e., except in storage. Therefore, according to the official Solidity documentation, it’s better to use <code>bytes</code> type instead of <code>bytes1[]</code>.</p>
<p class="has-global-color-8-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f4a1.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Note</strong>: Value types in storage are packed/compacted together and share a storage slot, taking only as much space per value type as really needed. In contrast, the stack, memory, and <code>calldata</code> pad value types and store in separate slots, meaning that each variable uses a whole slot of 32 bytes, even if the value type is shorter than 32 bytes, effectively wasting the memory space.</p>
<p>Before Solidity v0.8.0, the keyword <code>byte</code> was an alias for <code>bytes1</code>.</p>
<h2>Dynamically-Sized Byte Arrays</h2>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" width="1024" height="680" src="https://blog.finxter.com/wp-content/uploads/2022/10/image-40-1024x680.png" alt="" class="wp-image-753560" srcset="https://blog.finxter.com/wp-content/uploads/2022/10/image-40-1024x680.png 1024w, https://blog.finxter.com/wp-content/uplo...00x199.png 300w, https://blog.finxter.com/wp-content/uplo...68x510.png 768w, https://blog.finxter.com/wp-content/uplo...age-40.png 1420w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>
<p>There are two dynamically-sized non-value types, namely <code>bytes</code> and <code>string</code>. </p>
<ul>
<li><code>bytes</code> is a dynamically-sized byte array, while </li>
<li><code>string</code> is a dynamically-sized UTF-8-encoded string.</li>
</ul>
<h2><a></a>Address Literals</h2>
<p>Address literals are hexadecimal literals that pass the address checksum test, e.g. <code>0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF</code>. </p>
<p>Hexadecimal literals will produce an error if they are between 39 and 41 digits long and do not pass the checksum test.</p>
<p>However, we can remove the error by prepending zeros to integer types or appending zeros to <code>bytesNN</code> types.</p>
<p>The <strong>Ethereum Improvement Proposal <a rel="noreferrer noopener" href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md" data-type="URL" data-id="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md" target="_blank">EIP-55</a></strong> defines the mixed-case address checksum.</p>
<h2>Integer and Rational Literals</h2>
<h3>Integer Literals</h3>
<p><em><strong>Integer literals</strong></em> are created using a sequence of digits from a range 0-9, and each digit is interpreted (weighted) based on its position in the sequence. </p>
<p>Multiplied by an exponent of 10, e.g. 217 is interpreted as two hundred and seventeen, because, reading from right to left, we have 7 * 10<sup>0</sup> + 1 * 10<sup>1</sup> + 2 * 10<sup>2</sup>. </p>
<p>A reminder, 10<sup>0</sup> = 1. </p>
<p>Octal literals don’t exist in Solidity and leading zeros are invalid.</p>
<h3>Decimal Fractional Literals</h3>
<p><em><strong>Decimal fractional literals</strong></em> consist of a dot <code>.</code> (or, depending on the locale) and at least one number on either of the sides, e.g. <code>1.</code>, <code>.1</code>, and <code>1.3</code>.</p>
<p class="has-global-color-8-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f4a1.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Info</strong>: <em>“A locale consists of a number of categories for which country-dependent formatting or other specifications exist”</em> (<a href="https://docs.oracle.com/cd/E23824_01/html/E26033/glmbx.html">sou</a><a rel="noreferrer noopener" href="https://docs.oracle.com/cd/E23824_01/html/E26033/glmbx.html" target="_blank">rce</a>).</p>
<h3>Scientific Notation</h3>
<p>Solidity also supports scientific notation in the form of 2e10, where 2 (left of “e”) is called mantissa (M) and the exponent (E) must be an integer. In a general form, we would write it as MeE and it is interpreted as M * 10**E, e.g. 2e10, -2e10, 2e-10, 2.5e1.</p>
<h3>Readable Underscore Notation</h3>
<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" width="629" height="943" src="https://blog.finxter.com/wp-content/uploads/2022/10/image-41.png" alt="" class="wp-image-753567" srcset="https://blog.finxter.com/wp-content/uploads/2022/10/image-41.png 629w, https://blog.finxter.com/wp-content/uplo...00x300.png 200w" sizes="(max-width: 629px) 100vw, 629px" /></figure>
</div>
<p>We can also do a neat thing: separate the digits of a numeric literal for easier readability, such as in decimal <code>123_000</code>, hexadecimal <code>0x2eff_abde</code>, scientific decimal notation <code>1_2e345_678</code>. </p>
<p>However, there are no leading, trailing, or multiple underscores; they can only be added between two digits.</p>
<h3>Number Literal Expressions</h3>
<p>Expressions containing number literals preserve their precision until they are converted to a non-literal type. </p>
<p>Such a conversion means an <strong><em>explicit conversion</em></strong>, or that the number literals are used with something else than a number literal expression, like <a href="https://blog.finxter.com/solidity-boolean-and-integer-types-a-helpful-guide-with-video/" data-type="post" data-id="728241" target="_blank" rel="noreferrer noopener">boolean</a> literals. </p>
<p>This behavior implies that computations don’t overflow and divisions don’t truncate in number literal expressions.</p>
<p>A very good example would be a number literal expression (2**800 + 1) – 2**800, which results in the constant 1 (of type <code>uint8</code>), although the intermediate results would not fit the capacity of the <a href="https://blog.finxter.com/mastering-the-ethereum-virtual-machine-evm-for-solidity-smart-contracts/" data-type="post" data-id="572801" target="_blank" rel="noreferrer noopener">EVM</a> word length of 32 bytes. </p>
<p>One more example shows that an integer 4 is produced by computing the expression <code>.5 * 8</code>, although the intermediary results are not integers.</p>
<h3>More Operations</h3>
<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Warning</strong>: most operators produce a literal expression when applied to number literals, but there are also two exceptions:</p>
<ul>
<li>Ternary operator <code>(... ? ... : ...)</code>,</li>
<li>Array subscript (<code>&lt;array>[&lt;index>]</code>).</li>
</ul>
<p>In other words, expressions like <code>255 + (true ? 1 : 0)</code> or <code>255 + [1, 2, 3][0]</code> are not equivalent to using the literal 256 (the result of these two expressions), as they are computed within the type <code>uint8</code> and can lead to an overflow.</p>
<p>Number literal expressions can use the same operators as the integers, but both operands must compute yield an integer. </p>
<ul>
<li>If either of the operands is fractional, bit operations are inapplicable for use; </li>
<li>If the exponent is a decimal fractional literal, the exponentiation operation is also inapplicable for use.</li>
</ul>
<p>Shifts and exponentiation <code>*</code> operations with literal numbers in place of a left <code>(base*</code>) operand and integer types in place of the right (<code>exponent*</code>) operand are performed in the <code>uint256</code> for non-negative literals or <code>int256</code> for negative literals (a <code>*</code> symbol pertains to the exponentiation operations context).</p>
<p class="has-global-color-8-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Warning</strong>: Since Solidity v0.4.0 division on integer literals produces a rational number, e.g. 7 / 2 = 3.5.</p>
<p>Solidity has a number literal types for each rational number, e.g. integer literals and rational number literals belong to the same number literal type. </p>
<p>All number literal expressions (expressions with only number literals and operators) also belong to number literal types, e.g. 1 + 2 and 2 + 1 belong to the same number literal type.</p>
<p class="has-global-color-8-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f4a1.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Note</strong>: When number literal types are used with non-literal expressions, they are converted into a non-literal type, e.g.  <code>uint128 a = 1; uint128 b = 2.5 + a + 0.5;</code> </p>
<p class="has-global-color-8-background-color has-background">Here, 1 is converted into a non-literal type <code>uint128</code>, i.e. variable <code>a</code>, but a common type for both <code>2.5</code> and <code>uint128</code> doesn’t exist and the <a href="https://blog.finxter.com/how-to-install-the-solidity-compiler-overview-videos/" data-type="post" data-id="716526" target="_blank" rel="noreferrer noopener">compiler</a> will reject the code.</p>
<h2><a></a>Conclusion</h2>
<p>In this article, we added even more data types in Solidity under our proverbial belt!</p>
<ul>
<li>First, we introduced and learned about the contract type.</li>
<li>Second, we fixed our understanding of the fixed-size byte array type.</li>
<li>Third, the situation got dynamic by studying the dynamically-sized byte array type.</li>
<li>Fourth, we addressed the… what was it called… Aha – address literals!</li>
<li>Fifth, we came to the most rational decision and discovered what rational and integer literals are and, of course, how can they be put to good use.</li>
</ul>
<h2>Slide Deck Data Types</h2>
<p>You can scroll through the data types discussed in this tutorial here:</p>
<div class="wp-block-file"><object class="wp-block-file__embed" data="https://blog.finxter.com/wp-content/uploads/2022/10/Solidity-Overview-Data-Types-More.pdf" type="application/pdf" style="width:100%;height:600px" aria-label="Embed of Solidity-Overview-Data-Types-More."></object><a id="wp-block-file--media-8e52c6e3-e3f8-48d2-a65d-568d8f6f4290" href="https://blog.finxter.com/wp-content/uploads/2022/10/Solidity-Overview-Data-Types-More.pdf">Solidity-Overview-Data-Types-More</a><a href="https://blog.finxter.com/wp-content/uploads/2022/10/Solidity-Overview-Data-Types-More.pdf" class="wp-block-file__button" download aria-describedby="wp-block-file--media-8e52c6e3-e3f8-48d2-a65d-568d8f6f4290">Download</a></div>
</p>
<hr class="wp-block-separator has-alpha-channel-opacity"/>
</div>


https://www.sickgaming.net/blog/2022/10/...-literals/
Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016