0x0000000000000000000000000000000000000000000000160b0a00327fff0100 slot0 //0x00 a false //0x01 b true //0x7fff c 32767 //0x0032 d 0x32 //0x0a e 10 //0x0b f 11 //0x0016 g 22 0x0000000000000000000000000000000000000000000000000000000000000001 slot1 // h 0x1 0x000000000000000000000000bc6581e11c216b17adf5192e209a7f95a49e6837 slot2 // i 0x2
从上面可以看出
各个类型的存储长度
存储顺序从后往前
存储优化原则
byte.length==bytes1.length==8bits
0x05 数组类型
定长数组
1 2 3 4 5 6 7
pragma solidity ^0.4.25;
contract TEST{
bytes8[5] a = [byte(0x6a),0x68,0x79,0x75]; bool b=true; }
a=sha3.keccak_256(byte32(0)).hexdigest() print(a) #0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 x
此后a[1],a[2]对应偏移1,2个插槽
然后我们在调用add()函数看,发生了什么
第一步改变了数组a的长度
第二步在a[2]后面的一个插槽写入0x66
0x06 字符串类型
1 2 3 4 5 6 7
pragma solidity ^0.4.25;
contract TEST{
string a='whoami'; }
1 2 3 4 5
from Crypto.Util.number import * b=0x77686f616d69 print(long_to_bytes(b)) #b'whoami' #0xc代表字符串长度 每个字母占2个十六进制位
1 2 3 4 5 6 7
pragma solidity ^0.4.25;
contract TEST{
string a='先知社区'; }
1 2 3 4 5
from Crypto.Util.number import * b=0xe58588e79fa5e7a4bee58cba print(long_to_bytes(b).decode('utf-8')) #先知社区 #0x18 每个汉字占6个十六进制位
1 2 3 4 5 6 7
pragma solidity ^0.4.25;
contract TEST{
string a='Genius only means hard-working all one\'s life.'; }
此时的存储方式和数组类似
1 2 3 4
from Crypto.Util.number import * b=0x47656e697573206f6e6c79206d65616e7320686172642d776f726b696e6720616c6c206f6e652773206c6966652e print(long_to_bytes(b)) #b"Genius only means hard-working all one's life."
思考了一下,比如像下面这样写,调用add函数后会发生什么
1 2 3 4 5 6 7 8
pragma solidity ^0.4.25;
contract TEST{ string a='abcdf'; functionadd(){ a='Genius only means hard-working all one\'s life.'; } }
contract StorageExample6 { uint256 a = 11; uint8 b = 12; uint128 c = 13; bool d = true; uint128 e = 14; uint256[] public array = [401,402,403,405,406];
address owner; mapping(address => UserInfo) public users; string str="name value";