0

how do i gas-efficiently check if a bytes32 begins with certain bytes?

the user gives me a bytes32 input, and i want to check if it start with 4 zero bytes.

thank you

9
  • What is your input to this problem? Sep 22, 2020 at 8:35
  • function startsWith(bytes32 x, bytes32 y) pure returns (bool) {return (x & y) == y;} Sep 22, 2020 at 8:38
  • thanks, i get a bytes32 value as an input and need to see if it starts with some certain bytes. if the first 4 bytes are zero
    – brocard
    Sep 22, 2020 at 8:51
  • Yeah that part is clear enough in your question. But there are two inputs here, as you can see in the possible solution that I gave you, which assumes that both inputs are bytes32. And you are stating only the type of the first input here! Sep 22, 2020 at 8:57
  • okay, well yeah, the user gives me a bytes32 input, and i want to check if it start with 4 zero bytes. that might be a bytes4 then ?
    – brocard
    Sep 22, 2020 at 9:00

2 Answers 2

2

Testing on remix the cheapest function I got uses 352 gas for execution

function g0(bytes32 x, bytes4 y) public pure returns (bool) {
    return bytes4(x) == y;
}
2
  • do you think I should delete my answer? Sep 23, 2020 at 10:54
  • 1
    @TheRenaissance Please don't delete it. I think it is a good starting point.
    – Ismael
    Sep 23, 2020 at 13:57
1

I can't speak to gas efficiency, unfortunately.

From the Solidity docs:

Index access: If x is of type bytesI, then x[k] for 0 <= k < I returns the k th byte (read-only).

So:

function fourLeadingZeroBytes(bytes32 b) public pure returns (bool) {
    return b[0] == 0 && b[1] == 0 && b[2] == 0 && b[3] == 0;
}
9
  • From the question: "how do i gas-efficiently check...?". Sep 22, 2020 at 13:49
  • is this gas inefficient? I couldn't find a good way to check. Sep 22, 2020 at 14:09
  • fwiw @goodvibration , I also couldn't get your solutions to work. I'm assuming it's my own lack of experience with bitwise in Solidity, but could it be that the visors you suggest aren't taking any of the rest of the byte string into account? I kept on getting false if any of the bytes returned something other than 0, not just the first 4. Sep 22, 2020 at 14:11
  • Regarding the gas - your solution is the most trivial one, so presumably, there is no worse solution in terms of gas. Is there a better one? Maybe not, but obviously no way to compare when there is only one option. Comparison (once you do have another solution) is easy BTW - you declare a state variable uint public gasUsed;, and then you call each solution from a function which starts with uint gasLeft = gasleft();, and ends with gasUsed = gasLeft - gasleft();. Sep 22, 2020 at 14:23
  • Finally, you need to run these two test functions from an off-chain script, where each function operates on a "clean" (i.e., brand new) instance of the contract, and then print the value of gasUsed. Sep 22, 2020 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.