智能合约从入门到精通:Solidity语法之内存变量的布局和状态变量的存储模型

简介:在前面我们已经讲过Solidity语言的一些语法内容,在矩阵元JUICE开放平台的JIDE开发时,一定要注意Layout in Memory和Layout of State Variables in Storage,即内存变量的布局和状态变量的存储模型。
内存变量的布局(Layout in Memory)

Solidity预留了3个32字节大小的槽位:

  • 0-64:哈希方法的暂存空间(scratch space)
  • 64-96:当前已分配内存大小(也称空闲内存指针(free memory pointer))
    暂存空间可在语句之间使用(如在内联编译时使用)
    Solidity总是在空闲内存指针所在位置创建一个新对象,且对应的内存永远不会被释放(也许未来会改变这种做法)。
    有一些在Solidity中的操作需要超过64字节的临时空间,这样就会超过预留的暂存空间。他们就将会分配到空闲内存指针所在的地方,但由于他们自身的特点,生命周期相对较短,且指针本身不能更新,内存也许会,也许不会被清零(zerod out)。因此,大家不应该认为空闲的内存一定已经是清零(zeroed out)的。
    状态变量的存储模型(Layout of State Variables in Storage)
    大小固定的变量(除了映射,变长数组以外的所有类型)在存储(storage)中是依次连续从位置0开始排列的。如果多个变量占用的大小少于32字节,会尽可能的打包到单个storage槽位里,具体规则如下:
  • 在storage槽中第一项是按低位对齐存储(lower-order aligned)(译者注:意味着是大端序了,因为是按书写顺序。)。
  • 基本类型存储时仅占用其实际需要的字节。
  • 如果基本类型不能放入某个槽位余下的空间,它将被放入下一个槽位。
  • 结构体和数组总是使用一个全新的槽位,并占用整个槽(但在结构体内或数组内的每个项仍遵从上述规则)
    优化建议
    当使用的元素占用少于32字节,你的合约的gas使用也许更高。这是因为EVM每次操作32字节。因此,如果元素比这小,EVM需要更多操作来从32字节减少到需要的大小。
    因为编译器会将多个元素打包到一个storage槽位,这样就可以将多次读或写组合进一次操作中,只有在这时,通过缩减变量大小来优化存储结构才有意义。当操作函数参数和memory的变量时,因为编译器不会这样优化,所以没有上述的意义。
    最后,为了方便EVM进行优化,尝试有意识排序storage的变量和结构体的成员,从而让他们能打包得更紧密。比如,按这样的顺序定义,uint128, uint128, uint256,而不是uint128, uint256, uint128。因为后一种会占用三个槽位。
    非固定大小
    结构体和数组里的元素按它们给定的顺序存储。
    由于它们不可预知的大小。映射和变长数组类型,使用Keccak-256哈希运算来找真正数据存储的起始位置。这些起始位置往往是完整的堆栈槽。
    映射和动态数组根据上述规则在位置p占用一个未满的槽位(对映射里嵌套映射,数组中嵌套数组的情况则递归应用上述规则)。对一个动态数组,位置p这个槽位存储数组的元素个数(字节数组和字符串例外,见下文)。而对于映射,这个槽位没有填充任何数据(但这是必要的,因为两个挨着的映射将会得到不同的哈希值)。数组的原始数据位置是keccak256(p);而映射类型的某个键k,它的数据存储位置则是keccak256(k . p),其中的.表示连接符号。如果定位到的值以是一个非基本类型,则继续运用上述规则,是基于keccak256(k . p)的新的偏移offset。
    bytes和string占用的字节大小如果足够小,会把其自身长度和原始数据存在当前的槽位。具体来说,如果数据最多31位长,高位存数据(左对齐),低位存储长度lenght 2。如果再长一点,主槽位就只存lenght 2 + 1。原始数据按普通规则存储在keccak256(slot)
    所以对于接下来的代码片段:
    pragma solidity ^0.4.4;
    
    contract C {
    struct s { uint a; uint b; }
    uint x;
    mapping(uint => mapping(uint => s)) data;
    }

    按上面的代码来看,结构体从位置0开始,这里定义了一个结构体,但并没有对应的结构体变量,故不占用空间。uint x实际是uint256,单个占32字节,占用槽位0,所以映射data将从槽位1开始。
    data[4][9].b的位置在keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1
    有人在这里尝试直接读取区块链的存储值,https://github.com/ethereum/solidity/issues/1550

参考内容:https://open.juzix.net/doc

智能合约开发教程视频:区块链系列视频课程之智能合约简介

原文地址:http://blog.51cto.com/13544628/2136767

时间: 2024-10-06 15:01:42

智能合约从入门到精通:Solidity语法之内存变量的布局和状态变量的存储模型的相关文章

智能合约从入门到精通:用Solidity开发一个“Hello World”

简介:上一章中我们聊到了智能合约的应用场景,在了解区块链技术目前的发展情况.智能合约的概念以及其应用场景之后,我们将在后续的文章中共同学习智能合约的编成语言.今天,我们就来简单地谈一谈用于编写智能合约的语言--Solidity语言. 那么,什么是Solidity语言呢?在前面的文章中我们反复提到过以太坊,以太坊做区块链2.0的典型代表,Solidity在以太坊中是撰写智能合约最受欢迎的语言,因此今天我们就和大家介绍一下这个作为智能合约开发中最主流的语言. Solidity是运行于Ethereum

智能合约从入门到精通:Solidity汇编语言

简介:上一节,我们讲过在JUICE平台开发智能合约的开发规范,本节我们将继续就Solidity定义的汇编语言进行更加深入的讨论.Solidity定义的汇编语言可以达到下述的目标:1.使用它编写的代码要可读,即使代码是从Solidity编译得到的.2.从汇编语言转为字节码应该尽可能的少坑.3.控制流应该容易检测来帮助进行形式验证与优化.为了达到第一条和最后一条的目标,Solidity汇编语言提供了高层级的组件比如,for循环,switch语句和函数调用.这样的话,可以不直接使用SWAP,DUP,J

智能合约从入门到精通:Solidity Assembly

简介:上一节,我们讲过Solidity 汇编语言,这个汇编语言,可以不同Solidity一起使用.这个汇编语言还可以嵌入到Solidity源码中,以内联汇编的方式使用.下面我们将从内联汇编如何使用着手,介绍其与独立使用的汇编语言的不同,最后再介绍这门汇编语言.Solidity Assembly内联汇编通常我们通过库代码,来增强语言我,实现一些精细化的控制,Solidity为我们提供了一种接近于EVM底层的语言,内联汇编,允许与Solidity结合使用.由于EVM是栈式的,所以有时定位栈比较麻烦,

智能合约从入门到精通:Solidity语言的开发规范和开发流程

简介:上面介绍的在Solidity中嵌入的内联汇编语言也可以单独使用.实际上,它是被计划用来作为编译器的一种中间语言.本文我们将介绍开发智能合约过程中Solidity语言的开发规范和开发流程. Solidity作为编译器的一种中间语言.在开发智能合约时需要遵守相应的开发规范和开发流程. 开发规范 命名规范 目录和文件 目录使用小写,请勿使用特殊符号: 库文件和合约文件统一以.sol为后缀: 合约文件名保持与合约名一致: 文件名采用驼峰命名(首字母大写): 合约.库文件命名 合约名采用驼峰命名(首

智能合约从入门到精通:完整范例

简介:前几篇文章我们一直在讨论Solidity语言的相关语法,从本文开始,我们将介绍智能合约开发.今天我们将介绍一个完整范例.此章节将介绍一个完整案例来帮助开发者快速了解合约的开发规范及流程.注意:在进行案例编写前,请先前往JUICE开放服务平台,完成用户注册,JUICE区块链账户创建:并下载.安装.配置好JUICE客户端.场景描述在案例实践前请确保已拥有可用的JUICE区块链平台环境!!!现假设一个场景,编写一个顾客管理合约.主要实现以下功能: 提供增加顾客信息功能,手机号作为唯一KEY: 提

智能合约从入门到精通:JIDE集成开发工具

简介:前面两节,我们介绍了JIDE的工具库,本节我们将介绍智能合约开发最后一段内容,JIDE集成开发工具.除了JIDE的安装,我们还将介绍智能合约的编写.编译.部署.运行以及查看日志等.您看过所有的内容之后,将可以完整的开发出一个智能合约.JIDE简介JIDE是JUICE开放服务平台提供用来编写智能合约及DApp的免费开发工具,JIDE集成了JUICE底层测试链.编辑器和Solidity运行时环境,用户无需搭建任何环境就可以快速地编写.编译.部署.运行智能合约与发布DApp.目前JIDE支持So

智能合约从入门到精通:智能合约的前世今生

简介:区块链技术由来已久.2008年,神秘的日裔美国人中本聪天才设计出来的电子货币系统:比特币,为人类打开了区块链的大门.2009年,他发布了首个比特币软件,并正式启动了比特币金融系统.依靠POW算法的比特币随着人们认知,2016年以后区块链也为人们所追捧.而以太坊的快速发展,区块链已经进化出智能合约.DApp等新的技术,区块链2.0.3.0时代也正在来临.本文将详细介绍智能合约是什么.区块链是分布式数据存储.点对点传输.共识机制.加密算法等计算机技术的新型应用模式.所谓共识机制是区块链系统中实

智能合约从入门到精通:智能合约的应用场景

简介:上一章我们简单介绍了区块链技术的发展情况,并详细介绍智能合约的基础概念.可以说,区块链1.0时代(比特币)除了代币功能,与现实生活相去甚远.智能合约的出现,给区块链带来了巨大的变化,区块链也从一种账本形式,变成了下一代计算网络的雏形.这一章我们将聊聊智能合约的应用场景.在上一篇文章中我们聊过,尼克·萨博对智能合约定义已经说的很清楚,智能合约不是一定要用区块链来实现,很久之前就已经出现了:比如微信和支付宝的信用卡自动还款,您可以认为他是一种智能合约.当还款日到了,还款条件也满足(支付宝的余额

Unreal SDK 游戏开发从入门到精通(UnrealScript语法、UI Scene界面、UDK独立开发游戏)

对这个课程有兴趣的朋友可以加我的QQ2059055336和我联系 课程内容简介 本系列讲座主要讲述如何利用UDK开发游戏程序. 本课程主要分为四个部分: 1.学习UnrealScript的基本语法, 为下面的学习打下良好的基础 2.系统学习UDK的主要模块, 熟悉并掌握游戏开发的各个系统 3.使用UDK独立开发游戏Demo, 体验和理解UDK对游戏开发流程的整合 课程大纲 第一章初步接触Unreal SDK 1.1 Unreal sdk简介aaa 1.2 UC语言的基本介绍 1.3 搭建UDK的