在某些状况下,咱们心愿在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