ethereum - 坚固组装。从存储和委托调用中读取结构
问题描述
我正在使用低级别的委托调用将我的调用转发到库,但我对内联汇编还不够熟悉,无法使其工作。
contract BountyProxy {
using BountyLibrary for BountyLibrary.Bounty;
BountyLibrary.Bounty bounty;
address impl;
constructor(bytes32 _reference, address _issuer, uint _deadline, address _lib) public payable {
impl = _lib;
bounty.init(_reference, _issuer, _deadline);
}
function forward(bytes32 _sig, bytes _data) external payable {
bytes memory data = _data;
bytes4 sig = bytes4(_sig);
address _impl = impl;
require(_impl != address(0));
assembly {
let _message := mload(0x40) //find empty memory location
mstore(_message, sig) //place sig at beginning of empty storage
//add _bounty
mstore(add(_message, 4), sload(bounty_slot))
//add _data
mstore(add(_message, 36), data)
let size := returndatasize
let result := delegatecall(gas, _impl, _message, msize, _message, size)
//return data ??????
returndatacopy(_message, 0, size)
switch result
case 0 {revert(_message, size) }
default { return(_message, size) }
}
}
function getBounty() external view returns (bytes32, address, uint, uint, uint, BountyLibrary.statusOptions) {
return bounty.getBounty();
}
}
完整的代码可以在这个小提琴中找到:https ://ethfiddle.com/sd1ATrDtjy 另外迁移可以在这里找到:https ://gist.github.com/kyriediculous/d2286a8a580d28a3903395490b15bcaa
我需要(按此顺序):
- 从内存中将 bytes4 sig 加载到 _message 中
- 将赏金(STRUCT)从存储中加载到 _message
- 将字节 _data 加载到 _message
- 使用新消息进行代表呼叫
- 获取返回值
我添加的 getBounty() 函数证明了合约和库的工作原理。货运代理是我遇到的麻烦。
- 如何从存储中加载赏金结构?
- 如何在前 4 个字节处正确拆分我的 calldata,将其复制到内存并将赏金结构放在两者之间?
当我调用 getStorageAt 时,似乎结构已解包,我是否必须重新打包它?
0x00
0x687474703a2f2f6170692e6269746275636b65742e636f6d2f33303433303430
0xe1bb4acb579f780cbaf21cef9ac3641b8e3fcd69
0x5b7eb10c
0x3334303330340000000000000000000000000000000000000000000000000000
0x012a05f200
0x00
0x00
0x059ce9161d4fb0
0x00
0x00
0x00
0x00
0x00
0x00
0x00
0x00
0x00
请随时参考 stackexchange:https ://ethereum.stackexchange.com/questions/57197/get-return-data-from-delegatecall
非常感谢。
解决方案
推荐阅读
- java - 从数字列表中找到所有不同和的算法
- c# - 使用 FirebaseAdmin 通过 Firebase Cloud Messaging 发送 Android 消息
- angular - Angular 2/4/5/6 如何获取对象属性
- redis - 从 Lua 脚本调用的未知 Redis 命令
- python - 试图理解 ''.join() 在列表理解中获取列表
- cookies - PHP:我需要在这个 cURL 脚本中使用 cookie 吗?
- python - django-import-export 如何处理 GenericRelations?
- ckeditor - 将 Vue 组件插入 CKEditor 5 可编辑正文
- android - Unity Android 构建失败
- excel - 在没有循环的情况下结束 .FindNext 包装?