bitcoin-spv - Unnecessary memory allocation in BTCUtils  Pending
`BTCUtils` makes liberal use of `BytesLib.slice`, which returns a freshly-allocated slice of an existing bytes array. In many cases, the desired behavior is simply to read a 32-byte slice of a byte array. As a result, the typical pattern used is: `bytesVar.slice(start, start + 32).toBytes32()`.\\nThis pattern introduces unnecessary complexity and memory allocation in a critically important library: cloning a portion of the array, storing that clone in memory, and then reading it from memory. A simpler alternative would be to implement `BytesLib.readBytes32(bytes _b, uint _idx)` and other “memory-read” functions.\\nRather than moving the free memory pointer and redundantly reading, storing, then re-reading memory, `readBytes32` and similar functions would perform a simple length check and `mload` directly from the desired index in the array.\\nextractInputTxIdLE:\\n```\\n/// @notice Extracts the outpoint tx id from an input\\n/// @dev 32 byte tx id\\n/// @param \\_input The input\\n/// @return The tx id (little-endian bytes)\\nfunction extractInputTxIdLE(bytes memory \\_input) internal pure returns (bytes32) {\\n    return \\_input.slice(0, 32).toBytes32();\\n}\\n```\\n\\nverifyHash256Merkle:\\n```\\nuint \\_idx = \\_index;\\nbytes32 \\_root = \\_proof.slice(\\_proof.length - 32, 32).toBytes32();\\nbytes32 \\_current = \\_proof.slice(0, 32).toBytes32();\\n\\nfor (uint i = 1; i < (\\_proof.length.div(32)) - 1; i++) {\\n    if (\\_idx % 2 == 1) {\\n        \\_current = \\_hash256MerkleStep(\\_proof.slice(i \\* 32, 32), abi.encodePacked(\\_current));\\n    } else {\\n        \\_current = \\_hash256MerkleStep(abi.encodePacked(\\_current), \\_proof.slice(i \\* 32, 32));\\n    }\\n    \\_idx = \\_idx  1;\\n}\\nreturn \\_current == \\_root;\\n```\\n
Implement `BytesLib.readBytes32` and favor its use over the `bytesVar.slice(start, start + 32).toBytes32()` pattern. Implement other memory-read functions where possible, and avoid the use of `slice`.\\nNote, too, that implementing this change in `verifyHash256Merkle` would allow `_hash256MerkleStep` to accept 2 `bytes32` inputs (rather than bytes), removing additional unnecessary casting and memory allocation.
```\\n/// @notice Extracts the outpoint tx id from an input\\n/// @dev 32 byte tx id\\n/// @param \\_input The input\\n/// @return The tx id (little-endian bytes)\\nfunction extractInputTxIdLE(bytes memory \\_input) internal pure returns (bytes32) {\\n    return \\_input.slice(0, 32).toBytes32();\\n}\\n```\\n