[Tut] Solidity Ether Units, Time Units, and Global Variables - Printable Version +- Sick Gaming (https://www.sickgaming.net) +-- Forum: Programming (https://www.sickgaming.net/forum-76.html) +--- Forum: Python (https://www.sickgaming.net/forum-83.html) +--- Thread: [Tut] Solidity Ether Units, Time Units, and Global Variables (/thread-100247.html) |
[Tut] Solidity Ether Units, Time Units, and Global Variables - xSicKxBot - 11-17-2022 Solidity Ether Units, Time Units, and Global Variables <div> <div class="kk-star-ratings kksr-auto kksr-align-left kksr-valign-top" data-payload='{"align":"left","id":"895145","slug":"default","valign":"top","ignore":"","reference":"auto","class":"","count":"1","readonly":"","score":"5","best":"5","gap":"5","greet":"Rate this post","legend":"5\/5 - (1 vote)","size":"24","width":"142.5","_legend":"{score}\/{best} - ({count} {votes})","font_factor":"1.25"}'> <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/ether-and-time-units-and-globally-available-variables-in-solidity/"><img src="https://blog.finxter.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=https%3A%2F%2Fi.ytimg.com%2Fvi%2FCrgcoIru1xs%2Fhqdefault.jpg" alt="YouTube Video"></a><figcaption></figcaption></figure> <p>With this article, we’re opening a new area of our study, that of <strong>units and globally available variables</strong> in <a href="https://blog.finxter.com/solidity-deep-dive-syllabus-video-tutorial-resources/" data-type="post" data-id="777532" target="_blank" rel="noreferrer noopener">Solidity</a>.</p> <p>To begin with, we’ll learn about ether units and time units. After that, we’ll start with a block of subsections on special variables and functions, stretching through this and the next two articles.</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="572" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-166-1024x572.png" alt="" class="wp-image-895441" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-166-1024x572.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-166-300x168.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-166-768x429.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-166.png 1044w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <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/units-and-global-variables.html" data-type="URL" data-id="https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html" target="_blank">official Solidity documentation</a>.</p> <h2>Ether Units</h2> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="682" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-163-1024x682.png" alt="" class="wp-image-895432" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-163-1024x682.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-163-300x200.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-163-768x512.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-163.png 1375w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <p>When mentioning <a href="https://blog.finxter.com/introduction-to-ethereums-gas-in-solidity-development/" data-type="post" data-id="37644" target="_blank" rel="noreferrer noopener">Ether units of currency</a>, we can express them with a literal number and a suffix of <em><strong>wei</strong></em>, <em><strong>gwei </strong></em>or <strong><em>ether</em></strong>. </p> <p>These suffixes specify a sub-denomination of Ether. We assume amounts written without a suffix as Wei. </p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="573" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-167-1024x573.png" alt="" class="wp-image-895445" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-167-1024x573.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-167-300x168.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-167-768x430.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-167.png 1047w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <p>The purpose and effect of using sub-denomination is a multiplication of the denomination by a power (exponent) of ten.</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="">assert(1 wei == 1); assert(1 gwei == 1e9); assert(1 ether == 1e18); </pre> <p class="has-base-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>: There can be found denominations, such as <em>finney</em> and <em>szabo</em>, but they were deprecated in Solidity v0.7.0.</p> <h2>Time Units</h2> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="768" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-164-1024x768.png" alt="" class="wp-image-895436" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-164-1024x768.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-164-300x225.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-164-768x576.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-164.png 1221w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <p>Solidity has a nice and natural way of expressing time units with suffixes, such as seconds, minutes, hours, days, and weeks. </p> <p>Seconds are the base unit, and units are considered to correspond to:</p> <ul> <li>1 == 1 seconds</li> <li>1 minutes == 60 seconds</li> <li>1 hours == 60 minutes</li> <li>1 days == 24 hours</li> <li>1 weeks == 7 days</li> </ul> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="571" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-168-1024x571.png" alt="" class="wp-image-895446" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-168-1024x571.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-168-300x167.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-168-768x429.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-168.png 1050w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <p>When working with calendar calculations using these units, we should take extra care, because only some years have 365 days, and because of leap seconds, not even every day has 24 hours. </p> <p>Since leap seconds are unpredictable, an exact calendar always has to be updated by an external source (<a href="https://blog.finxter.com/earn-passive-and-active-income-200-h-as-a-chainlink-validator-and-freelance-consultant/" data-type="post" data-id="36581" target="_blank" rel="noreferrer noopener">oracle</a>), which motivated Solidity authors to remove the suffix years in Solidity v0.5.0.</p> <p>We should remember that these suffixes cannot be applied to variables, meaning if we want to interpret a function parameter expressed in days, we can easily do so like in the example below:</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="">function f(uint start, uint daysAfter) public { if (block.timestamp >= start + daysAfter * 1 days) { // ... } } </pre> <h2><a></a>Special Variables and Functions</h2> <p>The global namespace contains special variables and functions primarily used to provide us with information about the blockchain. They are also available utility functions for general use.</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="572" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-169-1024x572.png" alt="" class="wp-image-895448" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-169-1024x572.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-169-300x167.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-169-768x429.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-169.png 1048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <h3><a></a>Block and Transaction Properties</h3> <p>The following is a list of block and transaction properties, as shown in the <a rel="noreferrer noopener" href="https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#block-and-transaction-properties" data-type="URL" data-id="https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#block-and-transaction-properties" target="_blank">official Solidity documentation</a>. Parentheses next to each block/transaction property define the <code><a href="https://blog.finxter.com/solidity-array-members-and-manipulation-techniques/" data-type="post" data-id="830098" target="_blank" rel="noreferrer noopener">member</a></code> type:</p> <ul> <li><code>blockhash(uint blockNumber)</code> returns (<code>bytes32</code>): hash of the given block when <code>blocknumber</code> is one of the 256 most recent blocks; otherwise returns zero</li> <li><code>block.basefee (uint)</code>: current block’s base fee (as defined in Ethereum Improvement Proposals EIP-3198 and <a href="https://blog.finxter.com/ultrasound-money-%f0%9f%a6%87%f0%9f%94%8a-eth-supply-equilibrium-burn-rate-for-non-stakers/" data-type="post" data-id="779949" target="_blank" rel="noreferrer noopener">EIP-1559</a>)</li> <li><code>block.chainid (uint)</code>: current chain id</li> <li><code>block.coinbase (<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/" data-type="post" data-id="753297" target="_blank" rel="noreferrer noopener">address payable</a>)</code>: current block miner’s address</li> <li><code>block.difficulty (uint)</code>: current block difficulty</li> <li><code>block.gaslimit (uint)</code>: current block gas limit</li> <li><code>block.number (uint)</code>: current block number</li> <li><code>block.timestamp (uint)</code>: current block timestamp as seconds since Unix epoch</li> <li><code>gasleft() returns (uint256)</code>: remaining gas</li> <li><code>msg.data (bytes calldata)</code>: complete calldata</li> <li><code>msg.sender (address)</code>: the sender of the message (current call)</li> <li><code>msg.sig (bytes4)</code>: first four bytes of the calldata (i.e. function identifier)</li> <li><code>msg.value (uint)</code>: number of Wei sent with the message</li> <li><code>tx.gasprice (uint)</code>: the gas price of the transaction</li> <li><code>tx.origin (address)</code>: the sender of the transaction (full call chain)</li> </ul> <p class="has-base-background-color has-background"><strong>Note</strong>: We should expect the values of all members of <code>msg</code>, including <code>msg.sender</code> and <code>msg.value</code> will change with every external function call. This expectation also applies to library functions.</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>: Off-chain computation is simply a computation that takes place outside a blockchain. Oracle networks can provide a trust-minimized form of off-chain computation to extend the capabilities of blockchains – this is known as oracle computation. (<a href="https://blog.chain.link/off-chain-data-and-computation/" target="_blank" rel="noreferrer noopener">Chainlink</a>)</p> <p>Contracts can be evaluated both off-chain and on-chain, i.e. in the context of a transaction included in a block. </p> <p>If a contract is evaluated off-chain, we should assume that <code>block.*</code> and <code>tx.*</code> members don’t refer to a specific block or transaction. Instead, the values we’d find in these members are provided by the <a rel="noreferrer noopener" href="https://blog.finxter.com/mastering-the-ethereum-virtual-machine-evm-for-solidity-smart-contracts/" data-type="post" data-id="572801" target="_blank">EVM</a> implementation executing the contract, and therefore, they can be completely arbitrary.</p> <p class="has-base-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f5d2.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Note</strong>: It is suggested to avoid <code>block.timestamp</code> or <code>blockhash</code> member values as sources of randomness. The reason for this suggestion lies in the fact that, in some instances, miners can manipulate both the timestamp and the block hash. The timestamp of the current block must be strictly larger than the timestamp of the last block, and the only thing we can know for sure is that it will be between the timestamps of two neighboring blocks in the canonical chain; how far it will be from any particular block timestamp is not known.</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>“The word canonical is used to indicate a particular choice from a number of possible conventions. This convention allows a mathematical object or class of objects to be uniquely identified or standardized.” </em>(<a rel="noreferrer noopener" href="https://mathworld.wolfram.com/Canonical.html" target="_blank">Wolfram.com</a>)</p> <p>Only the recent 256 blocks’ hashes are available, due to scalability reasons. A hash of any older block will be zero.</p> <p>In Solidity versions prior to 0.5, the current <code>blockhash(...)</code> function was previously known and available as <code>block.blockhash(...)</code>; the current <code>gasleft(...)</code> function was previously known and available as <code>msg.gas(...)</code>. </p> <p>In Solidity v0.7.0 the <code>now</code> alias (for <code>block.timestamp</code>) was removed.</p> <h3>ABI Encoding and Decoding Functions</h3> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="571" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-170-1024x571.png" alt="" class="wp-image-895450" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-170-1024x571.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-170-300x167.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-170-768x428.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-170.png 1055w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <p>The following list contains ABI-appropriate functions for low-level interactions with EVM, as laid out in the official Solidity documentation:</p> <ul> <li><code>abi.decode(bytes memory encodedData, (...)) returns (...)</code>: ABI-decodes the given data, while the types are given in parentheses as second argument. Example: <code>(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))</code></li> <li><code>abi.encode(...) returns (bytes memory)</code>: ABI-encodes the given arguments</li> <li><code>abi.encodePacked(...) returns (bytes memory)</code>: Performs packed encoding of the given arguments. Note that packed encoding can be ambiguous!</li> <li><code>abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)</code>: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector</li> <li><code>abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)</code>: Equivalent to <code>abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)</code></li> <li><code>abi.encodeCall(function functionPointer, (...)) returns (bytes memory)</code>: ABI-encodes a call to <code>functionPointer</code> with the arguments found in the tuple. Performs a full type-check, ensuring the types match the function signature. Equivalent to <code>abi.encodeWithSelector(functionPointer.selector, (...))</code></li> </ul> <p class="has-base-background-color has-background"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f5d2.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Note</strong>: <em>“These encoding functions can be used to craft data for external function calls without actually calling an external function. Furthermore, <code>keccak256(abi.encodePacked(a, b))</code> is a way to compute the hash of structured data (although be aware that it is possible to craft a “hash collision” using different function parameter types).”</em> (<a href="https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#abi-encoding-and-decoding-functions" target="_blank" rel="noreferrer noopener">docs</a>)</p> <h2>Conclusion</h2> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="576" src="https://blog.finxter.com/wp-content/uploads/2022/11/image-165-1024x576.png" alt="" class="wp-image-895439" srcset="https://blog.finxter.com/wp-content/uploads/2022/11/image-165-1024x576.png 1024w, https://blog.finxter.com/wp-content/uploads/2022/11/image-165-300x169.png 300w, https://blog.finxter.com/wp-content/uploads/2022/11/image-165-768x432.png 768w, https://blog.finxter.com/wp-content/uploads/2022/11/image-165.png 1387w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> </div> <p>In this article, we learned about ether and time units, followed by special variables and functions.</p> <p>First, we introduced ether units and discussed the use of the main unit and its sub-denominations.</p> <p>Second, we introduced time units and discussed the possibilities of expressing time in different time units.</p> <p>Third, we took a closer look at the block and transaction properties, but also listed many of them with descriptions and notes on specific behaviors for a more thorough understanding.</p> <p>Fourth, we also touched on the topic of ABI encoding and decoding functions, described them, and gave a usage hint in a form of a note.</p> <h2>What’s Next?</h2> <p>This tutorial is part of our extended Solidity documentation with videos and more accessible examples and explanations. You can navigate the series here (all links open in a new tab):</p> <div class="is-content-justification-center is-layout-flex wp-container-1 wp-block-buttons"> <div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://blog.finxter.com/solidity-conversions-elementary-types/" target="_blank" rel="noreferrer noopener"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f448.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Prev Tutorial</a></div> <div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://blog.finxter.com/solidity-deep-dive-syllabus-video-tutorial-resources/" target="_blank" rel="noreferrer noopener"><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/261d.png" alt="☝" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Syllabus</a></div> <div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://blog.finxter.com/solidity-deep-dive-syllabus-video-tutorial-resources/" target="_blank" rel="noreferrer noopener"><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;" /> Next Tutorial</a></div> </div> </div> https://www.sickgaming.net/blog/2022/11/15/solidity-ether-units-time-units-and-global-variables/ |