I was using the following function to convert bytes to uint:
function bytesToUint(bytes b) public pure returns (uint){
uint number;
for(uint i=0;i<b.length;i++){
number = number + uint(b[b.length-1-i])*(10**i);
}
return number;
}
Since explicit byte1 to uint conversion is no longer supported I found the following alternative:
function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
require(_bytes.length >= (_start + 32), "Read out of bounds");
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
The bytes is the input in the ApproveAndCall function of the ERC20 Token
function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
return true;
}
which is sent over to the receiveApproval of my smart contract.
function receiveApproval(address _from, uint _token, address _tokenContract, bytes memory _data) public {
if(!ERC20Interface(_tokenContract).transferFrom(_from, address(this), _token)) {
revert();
}
_0xChangeLib.place_sell_order(exchange, _from, _tokenContract, _token, _0xChangeLib.toUint256(_data, 0));
}
Could someone explain how this new BytesToUint256 works? I can't get my head around the assembly code and how to use this function. I don't understand the uint256 _start argument. I am also not sure if I could use the same format as input as I was using. As argument I was converting a wei amount as a bytes, e.g. 100 wei = 0x100, with a simple function in javascript and sent over to the token address with Web3.js.
I would like within ReceiveApproval function of the smart contract to call the BytesToUint function to further process the data.
Thank you very much in advance for your help!
_start
is just the initial value to add to, instead ofuint number = 0;
. But I don't see it multiplying by 10, so it looks like it's just adding all the digits ignoring their place values. Or maybe it's turning an array of integer digits into an ASCII string as a uint256? But ASCII'0'
is 0x30, not 0x20, so that's not it. – Peter Cordes