如何在solidity中动态分配内存
在某些情况下,我们希望在solidity中构造一个buffer,首先我们应该为这个buffer分配内存。在solidity中,只有bytes这样的结构给我们用,但是现在切片和替换对应位置的数据的操作在bytes上不容易实现。我们只好借助于assembly来完成,首先就是为buffer分配内存。
直接上代码:
struct buffer {
bytes buf;
uint capacity;
}
function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
if (capacity % 32 != 0) {
capacity += 32 - (capacity % 32);
}
// Allocate space for the buffer data
buf.capacity = capacity;
assembly {
let ptr := mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
mstore(0x40, add(32, add(ptr, capacity)))
}
return buf;
}
我们先定义了一个结构体buffer,包含其内容buf和总容量capacity
再定义一个init方法(其实buffer是传入的,也可以用来resize).
以太坊保在0x40地址保存了下一个可用的指针(free pointer)。
let ptr := mlod(0x40)
注意函数第一个参数buffer memory buf
,有个memory关键字,说明buf也是在内存中的,buf是指针的别名,其值是buf对象存放的地址。
mstore(buf, ptr)
把可用的指针的地址替换了buf的地址
mstore(ptr ,0)
是把ptr地址的指向的数据变成0,也就是说把buf初始化成0,因为EVM不保证0x40地址中的指针指向的是全0数据
mstore(0x40, add(32, add(ptr, capacity)))
这行的作用是更新0x40的地址,指向下一个可用的指针。EVM不会处理0x40的更新,用户必须要自己处理。如何更新0x40的值呢?我们可以跳过刚刚开辟出来的buffer,把接下来的地址赋到0x40上。刚刚开辟的空间是capacity大小,再加上前32位(0x20)是数据的长度,所以0x40要在ptr的基础上偏移
capacity + 32
web3从入门到实战-理论篇
MangoGoing赞 4阅读 2.1k评论 2
从0系列(第一篇)---NFT平台的底层关系及注册流程
一句话赞 1阅读 2.4k
代码走读(第一篇)---ethereumj之Repository快照功能
一句话阅读 826
4EVERLAND 因对 Dfinity 生态系统的贡献而获得 Dfinity 资助
4EVERLAND社区阅读 640
4EVERLAND | AWS月度明星计划(一月):新年最好的开始
4EVERLAND社区阅读 530
EIP1559与传统Gas定价模型转账逻辑
米花儿团儿阅读 428
初学Solidity(五):Solidity的事件与文件
BSN研习社阅读 418
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。