{"id":857,"date":"2023-03-18T04:05:59","date_gmt":"2023-03-17T20:05:59","guid":{"rendered":"https:\/\/vinta.ws\/code\/?p=857"},"modified":"2026-02-18T01:20:34","modified_gmt":"2026-02-17T17:20:34","slug":"solidity-calldata-memory-and-storage","status":"publish","type":"post","link":"https:\/\/vinta.ws\/code\/solidity-calldata-memory-and-storage.html","title":{"rendered":"Solidity: calldata, memory, and storage"},"content":{"rendered":"<h2>Variables<\/h2>\n<p>There are three types of variables in Solidity:<\/p>\n<ul>\n<li>Global variables\n<ul>\n<li>Provide information about the blockchain<\/li>\n<li>For example, <code>block.number<\/code>, <code>block.timestamp<\/code>, or <code>msg.sender<\/code><\/li>\n<\/ul>\n<\/li>\n<li>State variables\n<ul>\n<li>Declared outside a function<\/li>\n<li>Stored on the blockchain<\/li>\n<li>Also called &quot;storage&quot;<\/li>\n<\/ul>\n<\/li>\n<li>Local variables\n<ul>\n<li>Declared inside a function<\/li>\n<li>Not stored on the blockchain, stored in memory instead<\/li>\n<li>Erased between function calls<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>References:<br \/>\n<a href=\"https:\/\/docs.soliditylang.org\/en\/v0.7.6\/units-and-global-variables.html\">https:\/\/docs.soliditylang.org\/en\/v0.7.6\/units-and-global-variables.html<\/a><br \/>\n<a href=\"https:\/\/solidity-by-example.org\/variables\">https:\/\/solidity-by-example.org\/variables<\/a><\/p>\n<h2>Data Types<\/h2>\n<p>There are two types of data:<\/p>\n<ul>\n<li>Value types: <code>YourContract<\/code>, <code>address<\/code>, <code>bool<\/code>, <code>uint256<\/code>, <code>int256<\/code>, <code>enum<\/code>, and <code>bytes32<\/code> (fixed-size byte arrays)<\/li>\n<li>Reference types: <code>array<\/code>, <code>mapping<\/code>, and <code>struct<\/code><\/li>\n<\/ul>\n<p>It's worth noting that <code>bytes<\/code> and <code>string<\/code> are dynamically-sized byte arrays and are considered reference types. However, <code>byte<\/code> (<code>bytes1<\/code>), <code>bytes2<\/code>, ..., <code>bytes32<\/code> are value types since they're fixed-size byte arrays.<\/p>\n<p>References:<br \/>\n<a href=\"https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#value-types\">https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#value-types<\/a><br \/>\n<a href=\"https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#reference-types\">https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#reference-types<\/a><\/p>\n<h2>Data Location<\/h2>\n<p>When using a reference type, you must explicitly provide the data location where the type is stored. There are three data locations:<\/p>\n<ul>\n<li><code>storage<\/code> is where the state variables are stored, and its lifetime is the lifetime of the contract<\/li>\n<li><code>memory<\/code> means variables are temporary and erased between external function calls<\/li>\n<li><code>calldata<\/code> behaves mostly like <code>memory<\/code>, but is immutable<\/li>\n<\/ul>\n<p>For reference types in function arguments, you must declare them as <code>memory<\/code> or <code>calldata<\/code>.<\/p>\n<p>If possible, use <code>calldata<\/code> as the data location because it avoids copying, reduces gas usage, and ensures that the data cannot be modified. Arrays and structs with <code>calldata<\/code> data location can also be returned from functions, but it is not possible to allocate such types.<\/p>\n<p>References:<br \/>\n<a href=\"https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#data-location\">https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#data-location<\/a><br \/>\n<a href=\"https:\/\/medium.com\/coinmonks\/solidity-storage-vs-memory-vs-calldata-8c7e8c38bce\">https:\/\/medium.com\/coinmonks\/solidity-storage-vs-memory-vs-calldata-8c7e8c38bce<\/a><br \/>\n<a href=\"https:\/\/gist.github.com\/hrkrshnn\/ee8fabd532058307229d65dcd5836ddc\">https:\/\/gist.github.com\/hrkrshnn\/ee8fabd532058307229d65dcd5836ddc<\/a><\/p>\n<p>It is also a best practice to use <code>external<\/code> if you expect that the function will only ever be called externally, and use <code>public<\/code> if you need to call the function internally. The difference between both is that <code>public<\/code> function arguments are copied to <code>memory<\/code>, while in <code>external<\/code> functions, arguments are read directly from <code>calldata<\/code>, which is cheaper than memory allocation. <code>external<\/code> functions are sometimes more efficient when they receive large arrays.<\/p>\n<p>References:<br \/>\n<a href=\"https:\/\/medium.com\/newcryptoblock\/best-practices-in-solidity-b324b65d33b1\">https:\/\/medium.com\/newcryptoblock\/best-practices-in-solidity-b324b65d33b1<\/a><\/p>\n<h3>Assignment Behaviour<\/h3>\n<ul>\n<li>Assignments between <code>storage<\/code> and <code>memory<\/code> (or from <code>calldata<\/code>) always create an independent copy.<\/li>\n<li>Assignments from <code>memory<\/code> to <code>memory<\/code> only create references.<\/li>\n<li>Assignments from <code>storage<\/code> to a <strong>local<\/strong> storage variable also only assign a reference.<\/li>\n<li>All other assignments to <code>storage<\/code> always copy.<\/li>\n<\/ul>\n<p>References:<br \/>\n<a href=\"https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#data-location-and-assignment-behaviour\">https:\/\/docs.soliditylang.org\/en\/v0.7.6\/types.html#data-location-and-assignment-behaviour<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you can, try to use\u00a0calldata\u00a0as data location because it will avoid copies, reduce gas usage, and also make sure that the data cannot be modified.<\/p>\n","protected":false},"author":1,"featured_media":858,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[137],"tags":[138,147,143],"class_list":["post-857","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blockchain","tag-ethereum","tag-smart-contract","tag-solidity"],"_links":{"self":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/857","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/comments?post=857"}],"version-history":[{"count":0,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/857\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media\/858"}],"wp:attachment":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media?parent=857"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/categories?post=857"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/tags?post=857"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}