引用类型/复合数据类型
Solidity中,有一些数据类型由简单数据类型组合而成,相比于简单的值类型,这些类型通常通过名称引用,被称为引用类型,
引用类型包括:
- 数组 (字符串与bytes是特殊的数组,所以也是引用类型)
- struct (结构体)
- map (映射)
这些类型涉及到的数据量较大,复制它们可能要消耗大量Gas,非常昂贵,所以使用它们时,必须考虑存储位置,例如,是保存在内存中,还是在EVM存储区中。
数据位置(data location)
在合约中声明和使用的变量都有一个数据位置,指明变量值应该存储在哪里。合约变量的数据位置将会影响Gas消耗量。
Solidity 提供4种类型的数据位置。
- Storage
- Memory
- Calldata
- Stack
Storage
该存储位置存储永久数据,这意味着该数据可以被合约中的所有函数访问。可以把它视为计算机的硬盘数据,所有数据都永久存储。
保存在存储区(Storage)中的变量,以智能合约的状态存储,并且在函数调用之间保持持久性。与其他数据位置相比,存储区数据位置的成本较高。
Memory
内存位置是临时数据,比存储位置便宜。它只能在函数中访问。
通常,内存数据用于保存临时变量,以便在函数执行期间进行计算。一旦函数执行完毕,它的内容就会被丢弃。你可以把它想象成每个单独函数的内存(RAM)。
Calldata
Calldata是不可修改的非持久性数据位置,所有传递给函数的值,都存储在这里。此外,Calldata是外部函数的参数(而不是返回参数)的默认位置。
Stack
堆栈是由EVM (Ethereum虚拟机)维护的非持久性数据。EVM使用堆栈数据位置在执行期间加载变量。堆栈位置最多有1024个级别的限制。
可以看到,要永久性存储,可以保存在存储区(Storage)。
附言
基础学习资料
- Solidity中文文档:https://learnblockchain.cn/docs/solidity/introduction-to-smart-contracts.html#
- ERC20:https://learnblockchain.cn/2018/01/12/create_token/
- ERC721:https://learnblockchain.cn/2018/03/23/token-erc721/
- cryptozombies游戏:https://cryptozombies.io/zh
- 学习列表:https://github.com/yippee-ki-yay/eth-dev-reading-list
- 语法基础:https://www.tryblockchain.org/solidity-libraries-%E5%BA%93.html
- https://www.qikegu.com/docs/4991
与智能合约交互
- ethers.js:https://learnblockchain.cn/docs/ethers.js/
- web3js:
源码
示例项目
- https://solidity-by-example.org/
- https://github.com/raineorshine/solidity-by-example
- https://github.com/cyrusadkisson/solidity-baby-steps
- https://github.com/flashbots/simple-arbitrage