contract Question1 {
function iterateEachElementInArrayAndReturnTheSum(uint256[] calldata array) external pure returns (uint256) {
// TODO: Iterate each element in the array using only assembly
// creates a new in-memory copy of the input array
uint256[] memory arrayM = array;
uint256 sum = 0;
for (uint i = 0; i < arrayM.length; ++i) {
assembly {
// 0x20 needs to be added to an array because the first slot contains the array length.
sum := add(sum, mload( add(add(arrayM, 0x20), mul(i, 0x20)) ))
}
}
return sum;
}
}
WORKING: https://docs.soliditylang.org/en/v0.8.17/assembly.html
function iterateEachElementInArrayAndReturnTheSum(uint256[] calldata array) external pure returns (uint256) {
// TODO: Iterate each element in the array using only assembly
uint256[] memory arrayM = array;
uint256 sum = 0;
for (uint i = 0; i < arrayM.length; ++i) {
assembly {
sum := add(sum, mload(add(add(arrayM, 0x20), mul(i, 0x20))))
}
}
return sum;
}
create a copy of calldata in memory and worh with that.
since the Solidity for loop does not allow direct access to the elements of a calldata array.
for (uint i = 0; i < arrayM.length; ++i)
starts a loop that iterates over each element of the arrayM copy using the loop variable i.
The loop runs as long as i is less than the length of arrayM.
assembly { sum := add(sum, mload(add(add(arrayM, 0x20), mul(i, 0x20)))) }
reads the value of the i-th element of arrayM and adds it to the sum variable
The outermost add function is used to perform the addition, and the mload function is used to read a 256-bit word from memory.
add(add(arrayM, 0x20), mul(i, 0x20))
The add and mul functions are used to calculate memory offsets.
The add and mul functions are used to calculate the memory address of the i-th element of the array.
The 0x20 value is added to arrayM to skip over the first 32 bytes (the length field),
and then i is multiplied by 0x20 to calculate the offset of the i-th element (since each element is 32 bytes in size).
```solidity
for (uint i = 0; i < array.length; ++i) {
assembly {
let a := add(mload(0x40), mul(i, 0x20)) //memory pointer for 1st var
calldatacopy(a, add(4, mul(i, 0x20)), 32) //to store the first parameter in memeory location, a
sum := add(sum, mload(a))
}
}
```