Advertisement
Guest User

Untitled

a guest
Jun 24th, 2018
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scheme 2.65 KB | None | 0 0
  1. ;;; blockchain.scm
  2.  
  3. (import :std/crypto
  4.         :std/text/hex)
  5.  
  6. (define-syntax for
  7.   (syntax-rules ()
  8.     ((for var to body)
  9.      (let loop ((var 0))
  10.        (if (< var to)
  11.            (begin body (loop (+ var 1))))))))
  12.  
  13. (define (char-is-zero? string index)
  14.   (if (eq? #\0 (string-ref string index)) #t #f))
  15.  
  16. ;; start counting from the n'th position should fail faster most of the time
  17. (define (n-chars-are-zero? string n)
  18.   (let loop ((i (- n 1)))
  19.     (if (>= i 0)
  20.         (if (equal? (string-ref string i) #\0)
  21.             (loop (- i 1))
  22.             #f)
  23.         #t)))
  24.  
  25. ;; our blocks are just vectors of length 3
  26. (define-structure block
  27.   number
  28.   data
  29.   nonce
  30.   prevhash)
  31.  
  32. ;; required for block hashes to be identical between restarts
  33. (define (block-to-string block)
  34.   (let ((o (open-output-string)))
  35.     (write (block-number block) o)
  36.     (write (block-data block) o)
  37.     (write (block-nonce block) o)
  38.     (write (block-prevhash block) o)
  39.     (get-output-string o)))
  40.  
  41. (define (hash-block block)
  42.   (hex-encode (md5 (block-to-string block))))
  43.  
  44. ;; zeroth (genesis) block is pre-defined
  45. (define zeroth-block (make-block
  46.                       0
  47.                       ":)"
  48.                       70924
  49.                       "00000000000000000000000000000000"))
  50.  
  51. ;; Block found!
  52. ;; #<block #2 number: 0 data: ":)" nonce: 70924 prevhash: "00000000000000000000000000000000">
  53. ;; 00002983b797351053bd7a2fd1f9da8f
  54.  
  55. (define leading-zeros 4) ; 4 leading zeros of md5 hash
  56.  
  57. (define blockchain (list zeroth-block))
  58.  
  59. (define blockchain-height ; there is only 1 blockchain
  60.   (block-number (car blockchain)))
  61.  
  62. (define (new-block data)
  63.   (make-block
  64.    (+ 1 blockchain-height)
  65.    data
  66.    0
  67.    (hash-block (car blockchain))))
  68.  
  69. (define (add-block-to-chain block)
  70.   (if (and (equal? (hash-block (car blockchain)) (= (block-number block) (+ 1 (block-number (car blockchain))))))
  71.       (block-prevhash block)
  72.       (set! blockchain (cons block blockchain))))
  73.  
  74. (define (u8vector->string v)
  75.   (list->string (map integer->char (u8vector->list v))))
  76.  
  77. (define (mine-block block)
  78.   (let loop ((i 0) (block-hash (hash-block block)))
  79.     (if (n-chars-are-zero? block-hash leading-zeros)
  80.         (begin
  81.           (print "\nBlock found!\n")
  82.           (print block "\n")
  83.           (print (hash-block block) "\n")
  84.           (add-block-to-chain block))
  85.         (begin
  86.           (block-nonce-set! block (+ (block-nonce block) 1))
  87.           (loop (+ i 1) (hash-block block))))))
  88.  
  89. ;; > (mine-block (new-block "test"))
  90. ;; Block found!
  91. ;; #<block #7 number: 1 data: "test" nonce: 11650 prevhash: "00002983b797351053bd7a2fd1f9da8f">
  92. ;; 0000728a8b7f72ce14279cddca5972d1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement