back with another question towards solidity Guru's. I am trying to call a method which takes bytes array as an input, but either I am encoding this parameter wrongly or decoding it wrongly. Solidity docs on the matter is fairly vague, so I implemented as I saw was written in the example. The function callback receives the said parameter, but than fails as reverted whenever I call it in a testnet. What am I missing regarding bytes abi.decode()
function, or have just encoded my data wrongly?
Any help would be greatly appreciated, thank you!
Here's the relevant kovan testnet transaction: https://kovan.etherscan.io/tx/0xc4a158d99f78dcf68ad8a3e9e26e4b8bad8b8a631dd09661ea09fdac23a0729a
The intended packed structure of the data passed in was as follows:
ff - operId
ffffffffff - txId
6bc84f6a0fabbd7102be338c048fe0ae54948c2e - forwardAddress
6bc84f6a0fabbd7102be338c048fe0ae54948c2e - refundAddress
And from what I could see in the transaction linked above the parameters where received in the precise order and in the expected sequence.
contract StoForwarder is Controllable {
constructor(address _controller, address _controllerAgent) public Controllable(_controller, _controllerAgent) {}
event NewTask(bytes5 txId, address forwardAddress, address refundAddress, address tokenContract,
bytes32 partition, uint256 amount);
struct Task {
bytes5 txId;
address forwardAddress;
address refundAddress;
IERC1410 tokenContract;
bytes32 partition;
uint256 amount;
}
mapping (bytes5 => Task) public pendingTasks;
function callback(IERC1410 _stoContract, bytes32 _partition, uint256 _amount, bytes calldata _data) external {
require(_data.length >= 46, "Insufficient data provided");
byte operCode;
bytes5 txId;
address forwardAddress;
address refundAddress;
(operCode, txId, forwardAddress, refundAddress) = abi.decode(_data, (byte, bytes5, address, address));
require(txId != "", "TransactionId not specified");
require(_partition != "", "Bad Partition");
require(forwardAddress != address(0), "Bad Forward Address");
require(refundAddress != address(0), "Bad refund Address");
pendingTasks[txId].txId = txId;
pendingTasks[txId].forwardAddress = forwardAddress;
pendingTasks[txId].refundAddress = refundAddress;
pendingTasks[txId].tokenContract = _stoContract;
pendingTasks[txId].partition = _partition;
pendingTasks[txId].amount = _amount;
emit NewTask(txId, forwardAddress, refundAddress, address(_stoContract), _partition, _amount);
}
function controllerTransfer(bytes5 txId, bool forward) onlyController external {
require(pendingTasks[txId].txId != "");
Task storage task = pendingTasks[txId];
address targetAddress;
if (forward) {
targetAddress = task.forwardAddress;
} else {
targetAddress = task.refundAddress;
}
task.tokenContract.transferByPartition(task.partition, targetAddress, task.amount, "");
}
}
P.S.
A total noob question: how is it possible to read require()
error message after it has occurred on the blockchain? This parts eludes me a bit.