How to resolve the algorithm Bitcoin/address validation step by step in the Seed7 programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Bitcoin/address validation step by step in the Seed7 programming language

Table of Contents

Problem Statement

Write a program that takes a bitcoin address as argument, and checks whether or not this address is valid. A bitcoin address uses a base58 encoding, which uses an alphabet of the characters 0 .. 9, A ..Z, a .. z, but without the four characters:

With this encoding, a bitcoin address encodes 25 bytes:

To check the bitcoin address, you must read the first twenty-one bytes, compute the checksum, and check that it corresponds to the last four bytes. The program can either return a boolean value or throw an exception when not valid. You can use a digest library for SHA-256.

It doesn't belong to anyone and is part of the test suite of the bitcoin software.
You can change a few characters in this string and check that it'll fail the test.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Bitcoin/address validation step by step in the Seed7 programming language

Source code in the seed7 programming language

$ include "seed7_05.s7i";
  include "msgdigest.s7i";
  include "encoding.s7i";

const func boolean: validBitcoinAddress (in string: address) is func
  result
    var boolean: isValid is FALSE;
  local
    var string: decoded is "";
  begin
    if succeeds(decoded := fromBase58(address)) and
        length(decoded) = 25 and decoded[1] = '\0;' and
        sha256(sha256(decoded[.. 21]))[.. 4] = decoded[22 ..] then
      isValid := TRUE;
    end if;
  end func;

const proc: checkValidationFunction (in string: address, in boolean: expected) is func
  local
    var boolean: isValid is FALSE;
  begin
    isValid := validBitcoinAddress(address);
    writeln((address <& ": ") rpad 37 <& isValid);
    if isValid <> expected then
      writeln(" *** Expected " <& expected <& " for " <& address <& ", but got " <& isValid <& ".");
    end if;
  end func;

const proc: main is func
  begin
    checkValidationFunction("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9",  TRUE);   # okay
    checkValidationFunction("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9",  FALSE);  # bad digest
    checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",  TRUE);   # okay
    checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j",  FALSE);  # bad digest
    checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X",  FALSE);  # bad digest
    checkValidationFunction("1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",  FALSE);  # bad digest
    checkValidationFunction("oMRDCDfyQhEerkaSmwCfSPqf3MLgBwNvs",   FALSE);  # not version 0
    checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz", FALSE);  # wrong length
    checkValidationFunction("1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",  FALSE);  # bad digest
    checkValidationFunction("1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",  FALSE);  # bad char
    checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I",  FALSE);  # bad char
    checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!",  FALSE);  # bad char
    checkValidationFunction("1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i",  FALSE);  # bad digest
    checkValidationFunction("1111111111111111111114oLvT2",         TRUE);   # okay
    checkValidationFunction("17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j",  TRUE);   # okay
    checkValidationFunction("1badbadbadbadbadbadbadbadbadbadbad",  FALSE);  # wrong length
    checkValidationFunction("BZbvjr",                              FALSE);  # wrong length
    checkValidationFunction("i55j",                                FALSE);  # wrong length
    checkValidationFunction("16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM",   TRUE);   # okay
  end func;

  

You may also check:How to resolve the algorithm 100 doors step by step in the Perl5i programming language
You may also check:How to resolve the algorithm Sorting Algorithms/Circle Sort step by step in the Racket programming language
You may also check:How to resolve the algorithm Create a file step by step in the Raven programming language
You may also check:How to resolve the algorithm Check output device is a terminal step by step in the Nemerle programming language
You may also check:How to resolve the algorithm Permutations step by step in the Eiffel programming language