/// @solidity memory-safe-assembly assembly {// solhint-disable-line no-inline-assembly let ptr:= mload(0x40) mstore(ptr, selector) mstore(add(ptr, 0x04),dstToken) mstore(add(ptr, 0x24),inputAmount) mstore(add(ptr, 0x44),outputAmount) mstore(add(ptr,0x64),goodUntil) mstore(add(ptr,0x84),recipient) mstore(add(ptr,Qxa4),add(27,shr(_SIGNATURE_V_SHIFT,vs)) mstore(add(ptr,0xc4),r) mstoreladd(ptr,0xe4),and(vs,SIGNATURE_S_MASK) mstore(add(ptr,0x104),0x120) mstoreladd(ptr,0x143),INCH TAG WITH LENGTH PREFIX) }
这段 Solidity 汇编代码的逻辑如下:
首先,声明了一个名为 ptr
的变量,用于存储动态分配的内存空间的起始地址。该地址被初始化为当前可用的内存地址(即 0x40
)。
接下来,使用 mload
指令从 0x40
地址读取一个 256 位的数值,即动态分配的内存空间的起始地址,并将其保存到 ptr
变量中。
然后,使用 mstore
指令在 ptr
指向的内存空间中写入不同的数据。
第一次调用 mstore
指令将 selector
写入内存空间中的第一个字(0x00
~0x1f
)。selector
是一个函数选择器,用于标识当前要执行的智能合约中的函数。这个选择器是根据 Solidity 函数的名称和参数类型计算出来的。
第二次调用 mstore
将 dstToken
写入内存空间中的第二个字(0x20
~0x3f
)。dstToken
是指定的目标代币地址。
第三次调用 mstore
将 inputAmount
写入内存空间中的第九个字(0x60
~0x7f
)。inputAmount
是要交换的输入代币数量。
第四次调用 mstore
将 outputAmount
写入内存空间中的第十五个字(0xa0
~0xbf
)。outputAmount
是期望获得的输出代币数量。
第五次调用 mstore
将 goodUntil
写入内存空间中的第二十一个字(0xc0
~0xdf
)。goodUntil
是订单的有效截止时间。
第六次调用 mstore
将 recipient
写入内存空间中的第二十七个字(0x100
~0x11f
)。recipient
是订单的接收者地址。
第七次调用 mstore
将对数字签名 v
进行位运算后得到的结果写入内存空间中的第三十三个字(0x140
~0x15f
)。具体来说,先将 _SIGNATURE_V_SHIFT
定义为 8,然后将 vs
中的高 24 位右移 8 位,并加上 27。这个值是数字签名中的 v 值。
第八次调用 mstore
将 r
写入内存空间中的第四十个字(0x180
~0x19f
)。r
是数字签名中的 r 值。
第九次调用 mstore
将对数字签名 s
进行位运算后得到的结果写入内存空间中的第四十五个字(0x1c0
~0x1df
)。具体地说,将 vs
中的低 24 位与 SIGNATURE_S_MASK
进行按位与运算。这个值是数字签名中的 s 值。
第十次调用 mstore
将一个以太坊地址写入内存空间中的第五十一个字(0x200
~0x21f
)。这个地址被定义为 0x120
。
最后一次调用 mstore
将一个带有长度前缀的标记写入内存空间中的第八十三个字(0x140
~0x15f
)。标记为 INCH TAG WITH LENGTH PREFIX
。
评论前必须登录!
注册