Я использую делегатский вызов низкого уровня для переадресации своих вызовов в библиотеку, но я недостаточно знаком со встроенным ассемблером, чтобы заставить его работать.
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
- Делегат с новым сообщением
- Получить возвращаемые значения
Контракт и библиотека работают, как доказано добавленной мной функцией getBounty (). У меня проблемы с экспедитором.
- Как загрузить структуру bounty из хранилища?
- Как правильно разделить мои calldata на первые 4 байта, скопировать их в память и поместить структуру bounty между ними?
Кажется, что структура распаковывается, когда я вызываю 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
Большое спасибо.