0

Is it possible (I believe so, especially with strings.lib) to implement Luhn's Algorithm (the math function that confirms all 16 digits of a credit card are valid) in a solidity function without severe gas costs for strings manipulations?

Here is a js example of Luhn's Algo - I'm a bit lost on best place to start in solidity.

// Takes a credit card string value and returns true on valid number
function valid_credit_card(value) {
  // Accept only digits, dashes or spaces
    if (/[^0-9-\s]+/.test(value)) return false;

    // The Luhn Algorithm. It's so pretty.
    let nCheck = 0, bEven = false;
    value = value.replace(/\D/g, "");

    for (var n = value.length - 1; n >= 0; n--) {
        var cDigit = value.charAt(n),
              nDigit = parseInt(cDigit, 10);

        if (bEven && (nDigit *= 2) > 9) nDigit -= 9;

        nCheck += nDigit;
        bEven = !bEven;
    }

    return (nCheck % 10) == 0;
}

Questions I have:

  • String, bytes, or uint? (for gas costs)
  • Assembly or string library? (for gas costs)
  • optimization of math functions for gas
  • Anyway to not use a loop?

Would love to see some starting points if anyone has any ideas

2 Answers 2

0

i have implemented a slim version which does not check the input for the correct format. it just expect numbers like 49927398716 or 1234567812345670. also, you pass the number as a sequence of bytes. by example if you want to check:

  • "49927398716" you need to pass "0x0409090207030908070106"

  • "1234567812345670" you need to pass "0x01020304050607080102030405060700"

     function valid_credit_card(bytes memory value) external returns (bool){
     // The Luhn Algorithm. It's so pretty.
     uint256 nCheck = 0;
     bool bEven = false;
    
     for (uint256 n = value.length; n > 0; n--) {
         uint256 nDigit = uint256(uint8(value[n-1]));
         if (bEven && (nDigit *= 2) > 9) nDigit -= 9;
    
         nCheck += nDigit;
         bEven = !bEven;
     }
     return (nCheck % 10) == 0;
    }
    
0

I convert your code into solidity language.

//SPDX-License-Identifier: MIT

pragma solidity >0.8.1;

contract Luhn {
  
   /// @title Lunh Algorithim implementation
   /// @author Atarpara
   /// @notice is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, Canadian Social Insurance Numbers.
   /// @return ture or false 
   function luhnalgo(string calldata _number) public pure returns(bool){
      bytes memory c = bytes(_number);
      uint length = c.length;
      uint8 sum = 0;
      uint8 zero = 48;
      bool _a = false;

    for(uint i = length ; i > 0 ; i--){
          uint8 temp = uint8(c[i-1]);

          if(temp < 47  && temp > 58){
            revert("Your Card Number is Invalid");
          }

          uint8 d = temp - zero;
          if(_a && (d <<= 1) > 9){
            d -= 9;
          }
          sum += d % 10;
         _a = !_a;
      } 
     return (sum%10==0);

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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