如何在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

程序猿,连续创业者,目前从事以太坊DApp开发

1 声望
1 粉丝
0 条评论
推荐阅读
web3从入门到实战-理论篇
中心化网络已经帮助数十亿人融入了互联网,并在其上创建了稳定、可靠的基础设施。 与此同时,少数中心化巨头几乎垄断了互联网,甚至可以为所欲为。Web3 是摆脱这一困境的方案。 不同于科技巨头垄断的传统互联网,...

MangoGoing4阅读 2.1k评论 2

封面图
从0系列(第一篇)---NFT平台的底层关系及注册流程
nft的价值不在现实世界而在区块链和虚拟世界。nft的平台,功能在nft内容审核,替内容创造者生成区块链上证明也就是nft,价值在在流量,流量带来的信用凭证。

一句话1阅读 2.4k

代码走读(第一篇)---ethereumj之Repository快照功能
ethereum有个replayBlock功能,就是将块放到指定的世界状态中,重新执行一次,获取执行结果。这个功能依赖于能够获得指定块高时的世界状态,具体就是根据块hash获取块所在的Repository快照。

一句话阅读 826

4EVERLAND 因对 Dfinity 生态系统的贡献而获得 Dfinity 资助
DFINITY 开发者资助计划旨在通过为有前途的开发者和团队提供支持来促进互联网计算机生态系统的发展,使全球更多的开发者能够访问和使用互联网计算机。

4EVERLAND社区阅读 640

封面图
4EVERLAND | AWS月度明星计划(一月):新年最好的开始
MSP I 的最后一个月,即 MSP I January,现在可以申请了!我们很高兴看到本月将有哪些项目脱颖而出!在 MSP I 的最后一个月,4EVERLAND 将与我们的合作伙伴一起努力,努力得出一个好的结论。

4EVERLAND社区阅读 530

封面图
EIP1559与传统Gas定价模型转账逻辑
传统的gas定价模型(Txn Type===0) {代码...} 伦敦硬分叉EIP1559(Txn Type===2) {代码...} 外部签名 {代码...}

米花儿团儿阅读 428

初学Solidity(五):Solidity的事件与文件
Solidity是面向对象的高级编程语言,是用于开发智能合约的语言之一,语法类似于JavasSript,但又有所不同。本期,我们为初学Solidity的开发者们推荐了CSDN作者super_lixiang关于学习Solidity的事件与文件的一篇总...

BSN研习社阅读 418

封面图

程序猿,连续创业者,目前从事以太坊DApp开发

1 声望
1 粉丝
宣传栏