Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Repository files navigation

Programming Bitcoin in TypeScript

This repository is a TypeScript implementattion of the Python code found in Jimmy Song's Programming Bitcoin book. The structure of this code differs from the book in a few ways:

  • The master branch is the completed code-base. I plan to add branches which have the completed code after each chapter for quick reference as you progress.
  • Exercises are sprinkled throughout the unit tests instead of explicitly being called out.
  • Jupyter is not being used, tests and execises can be run with npm commands below.

NPM Commands

npm can be used to run several commands:

# runs all unit tests
npm test # run a network daemon that retrieves block header (chapter 10)
npm run start:10
# run a network daemon that retrieves merkle blocks (chapter 12)
npm run start:12

Node.js 12+ Details

The book was originally coded with Python. Everything done in this repository is performed using TypeScript and Node.js 12+, even the Elliptic Curve code.

Here are some of the changes/challenges with porting to Node.js

  • This port uses the BigInt type to perform elliptic curve cryptography. This code is mostly found in src/ecc. While BigInt finally allows us to do some neat stuff (and support 64-bit integers) it does not have constant time operations and is not suitable for cryptography. So this code is just an exercise.
  • JavaScript does not support operator overloading (defining math operators +, *, %, etc), so it is not possible to code something like pointA + pointB where each variable is a S256Point instance. Instead I created types that support interface-based math operations. IOperableIntElementFieldElement
  • The Python example uses a modpow function to perform modular exponentiation efficiently. Neither BigInt nor Node.js have this capability. I created a modpow function that allows for efficient modular exponentiation of large numbers (such as those used in secp256k1). modpow
  • The % operator available to BigInt is actually the remainder operator, which means it allows negative numbers and is a problem for subtraction. A helper function was created that is heavily used in the ECC code. mod
  • There is not a divmod function, one has been added to return a tuple of the quotient and remainder. divmod
  • Node misses functionality for converting between BigInt and Buffer. I've create helper functions to easily go between the two. bigToBuf, bigToBufLE, bigFromBuf, bigFromBufLE
  • Most, but not all Script operations were added and can be found in src/script/operations.
  • Node.js TCP Sockets are asynchronous, this presents a few differences:
    • SimpleNode wraps the standard node Socket behavior and takes care of performing the handshake on connection. connection
    • The socket operates in paused mode which means that data is explicitly read from the socket stream.
    • For each message, the header is read and parsed first. If the full payload cannot be read in its entirety from the stream, the header is cached until more data is available on the stream. SimpleNode._onReadable
    • Once a payload has been fully read and validated against the checksum, SimpleNode emits a parsed payload as a corresponding event. event emission
  • Because IO in Node.js is async, any code that requires fetching from remote sources has caused async methods to be sprinkled throughout the application (Tx.verifyInput, etc).
  • MerkleBlock and MerkleTree construction were seperated into two classes to better help with understanding.
  • MerkleTree construction uses a pointer implementation instead of the array-based algorithm in the book. I found both partial merkle block parsing and construction to be simpler this way. ConstructionParsing

About

Programming Bitcoin in TypeScript

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - bmancini55/programming-bitcoin: Programming Bitcoin in TypeScript · GitHub
Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Repository files navigation

Programming Bitcoin in TypeScript

This repository is a TypeScript implementattion of the Python code found in Jimmy Song's Programming Bitcoin book. The structure of this code differs from the book in a few ways:

  • The master branch is the completed code-base. I plan to add branches which have the completed code after each chapter for quick reference as you progress.
  • Exercises are sprinkled throughout the unit tests instead of explicitly being called out.
  • Jupyter is not being used, tests and execises can be run with npm commands below.

NPM Commands

npm can be used to run several commands:

# runs all unit tests
npm test # run a network daemon that retrieves block header (chapter 10)
npm run start:10
# run a network daemon that retrieves merkle blocks (chapter 12)
npm run start:12

Node.js 12+ Details

The book was originally coded with Python. Everything done in this repository is performed using TypeScript and Node.js 12+, even the Elliptic Curve code.

Here are some of the changes/challenges with porting to Node.js

  • This port uses the BigInt type to perform elliptic curve cryptography. This code is mostly found in src/ecc. While BigInt finally allows us to do some neat stuff (and support 64-bit integers) it does not have constant time operations and is not suitable for cryptography. So this code is just an exercise.
  • JavaScript does not support operator overloading (defining math operators +, *, %, etc), so it is not possible to code something like pointA + pointB where each variable is a S256Point instance. Instead I created types that support interface-based math operations. IOperableIntElementFieldElement
  • The Python example uses a modpow function to perform modular exponentiation efficiently. Neither BigInt nor Node.js have this capability. I created a modpow function that allows for efficient modular exponentiation of large numbers (such as those used in secp256k1). modpow
  • The % operator available to BigInt is actually the remainder operator, which means it allows negative numbers and is a problem for subtraction. A helper function was created that is heavily used in the ECC code. mod
  • There is not a divmod function, one has been added to return a tuple of the quotient and remainder. divmod
  • Node misses functionality for converting between BigInt and Buffer. I've create helper functions to easily go between the two. bigToBuf, bigToBufLE, bigFromBuf, bigFromBufLE
  • Most, but not all Script operations were added and can be found in src/script/operations.
  • Node.js TCP Sockets are asynchronous, this presents a few differences:
    • SimpleNode wraps the standard node Socket behavior and takes care of performing the handshake on connection. connection
    • The socket operates in paused mode which means that data is explicitly read from the socket stream.
    • For each message, the header is read and parsed first. If the full payload cannot be read in its entirety from the stream, the header is cached until more data is available on the stream. SimpleNode._onReadable
    • Once a payload has been fully read and validated against the checksum, SimpleNode emits a parsed payload as a corresponding event. event emission
  • Because IO in Node.js is async, any code that requires fetching from remote sources has caused async methods to be sprinkled throughout the application (Tx.verifyInput, etc).
  • MerkleBlock and MerkleTree construction were seperated into two classes to better help with understanding.
  • MerkleTree construction uses a pointer implementation instead of the array-based algorithm in the book. I found both partial merkle block parsing and construction to be simpler this way. ConstructionParsing

About

Programming Bitcoin in TypeScript

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - bmancini55/programming-bitcoin: Programming Bitcoin in TypeScript · GitHub
Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Repository files navigation

Programming Bitcoin in TypeScript

This repository is a TypeScript implementattion of the Python code found in Jimmy Song's Programming Bitcoin book. The structure of this code differs from the book in a few ways:

  • The master branch is the completed code-base. I plan to add branches which have the completed code after each chapter for quick reference as you progress.
  • Exercises are sprinkled throughout the unit tests instead of explicitly being called out.
  • Jupyter is not being used, tests and execises can be run with npm commands below.

NPM Commands

npm can be used to run several commands:

# runs all unit tests
npm test # run a network daemon that retrieves block header (chapter 10)
npm run start:10
# run a network daemon that retrieves merkle blocks (chapter 12)
npm run start:12

Node.js 12+ Details

The book was originally coded with Python. Everything done in this repository is performed using TypeScript and Node.js 12+, even the Elliptic Curve code.

Here are some of the changes/challenges with porting to Node.js

  • This port uses the BigInt type to perform elliptic curve cryptography. This code is mostly found in src/ecc. While BigInt finally allows us to do some neat stuff (and support 64-bit integers) it does not have constant time operations and is not suitable for cryptography. So this code is just an exercise.
  • JavaScript does not support operator overloading (defining math operators +, *, %, etc), so it is not possible to code something like pointA + pointB where each variable is a S256Point instance. Instead I created types that support interface-based math operations. IOperableIntElementFieldElement
  • The Python example uses a modpow function to perform modular exponentiation efficiently. Neither BigInt nor Node.js have this capability. I created a modpow function that allows for efficient modular exponentiation of large numbers (such as those used in secp256k1). modpow
  • The % operator available to BigInt is actually the remainder operator, which means it allows negative numbers and is a problem for subtraction. A helper function was created that is heavily used in the ECC code. mod
  • There is not a divmod function, one has been added to return a tuple of the quotient and remainder. divmod
  • Node misses functionality for converting between BigInt and Buffer. I've create helper functions to easily go between the two. bigToBuf, bigToBufLE, bigFromBuf, bigFromBufLE
  • Most, but not all Script operations were added and can be found in src/script/operations.
  • Node.js TCP Sockets are asynchronous, this presents a few differences:
    • SimpleNode wraps the standard node Socket behavior and takes care of performing the handshake on connection. connection
    • The socket operates in paused mode which means that data is explicitly read from the socket stream.
    • For each message, the header is read and parsed first. If the full payload cannot be read in its entirety from the stream, the header is cached until more data is available on the stream. SimpleNode._onReadable
    • Once a payload has been fully read and validated against the checksum, SimpleNode emits a parsed payload as a corresponding event. event emission
  • Because IO in Node.js is async, any code that requires fetching from remote sources has caused async methods to be sprinkled throughout the application (Tx.verifyInput, etc).
  • MerkleBlock and MerkleTree construction were seperated into two classes to better help with understanding.
  • MerkleTree construction uses a pointer implementation instead of the array-based algorithm in the book. I found both partial merkle block parsing and construction to be simpler this way. ConstructionParsing

About

Programming Bitcoin in TypeScript

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - bmancini55/programming-bitcoin: Programming Bitcoin in TypeScript · GitHub
Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Repository files navigation

Programming Bitcoin in TypeScript

This repository is a TypeScript implementattion of the Python code found in Jimmy Song's Programming Bitcoin book. The structure of this code differs from the book in a few ways:

  • The master branch is the completed code-base. I plan to add branches which have the completed code after each chapter for quick reference as you progress.
  • Exercises are sprinkled throughout the unit tests instead of explicitly being called out.
  • Jupyter is not being used, tests and execises can be run with npm commands below.

NPM Commands

npm can be used to run several commands:

# runs all unit tests
npm test # run a network daemon that retrieves block header (chapter 10)
npm run start:10
# run a network daemon that retrieves merkle blocks (chapter 12)
npm run start:12

Node.js 12+ Details

The book was originally coded with Python. Everything done in this repository is performed using TypeScript and Node.js 12+, even the Elliptic Curve code.

Here are some of the changes/challenges with porting to Node.js

  • This port uses the BigInt type to perform elliptic curve cryptography. This code is mostly found in src/ecc. While BigInt finally allows us to do some neat stuff (and support 64-bit integers) it does not have constant time operations and is not suitable for cryptography. So this code is just an exercise.
  • JavaScript does not support operator overloading (defining math operators +, *, %, etc), so it is not possible to code something like pointA + pointB where each variable is a S256Point instance. Instead I created types that support interface-based math operations. IOperableIntElementFieldElement
  • The Python example uses a modpow function to perform modular exponentiation efficiently. Neither BigInt nor Node.js have this capability. I created a modpow function that allows for efficient modular exponentiation of large numbers (such as those used in secp256k1). modpow
  • The % operator available to BigInt is actually the remainder operator, which means it allows negative numbers and is a problem for subtraction. A helper function was created that is heavily used in the ECC code. mod
  • There is not a divmod function, one has been added to return a tuple of the quotient and remainder. divmod
  • Node misses functionality for converting between BigInt and Buffer. I've create helper functions to easily go between the two. bigToBuf, bigToBufLE, bigFromBuf, bigFromBufLE
  • Most, but not all Script operations were added and can be found in src/script/operations.
  • Node.js TCP Sockets are asynchronous, this presents a few differences:
    • SimpleNode wraps the standard node Socket behavior and takes care of performing the handshake on connection. connection
    • The socket operates in paused mode which means that data is explicitly read from the socket stream.
    • For each message, the header is read and parsed first. If the full payload cannot be read in its entirety from the stream, the header is cached until more data is available on the stream. SimpleNode._onReadable
    • Once a payload has been fully read and validated against the checksum, SimpleNode emits a parsed payload as a corresponding event. event emission
  • Because IO in Node.js is async, any code that requires fetching from remote sources has caused async methods to be sprinkled throughout the application (Tx.verifyInput, etc).
  • MerkleBlock and MerkleTree construction were seperated into two classes to better help with understanding.
  • MerkleTree construction uses a pointer implementation instead of the array-based algorithm in the book. I found both partial merkle block parsing and construction to be simpler this way. ConstructionParsing

About

Programming Bitcoin in TypeScript

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - bmancini55/programming-bitcoin: Programming Bitcoin in TypeScript · GitHub
Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Repository files navigation

Programming Bitcoin in TypeScript

This repository is a TypeScript implementattion of the Python code found in Jimmy Song's Programming Bitcoin book. The structure of this code differs from the book in a few ways:

  • The master branch is the completed code-base. I plan to add branches which have the completed code after each chapter for quick reference as you progress.
  • Exercises are sprinkled throughout the unit tests instead of explicitly being called out.
  • Jupyter is not being used, tests and execises can be run with npm commands below.

NPM Commands

npm can be used to run several commands:

# runs all unit tests
npm test # run a network daemon that retrieves block header (chapter 10)
npm run start:10
# run a network daemon that retrieves merkle blocks (chapter 12)
npm run start:12

Node.js 12+ Details

The book was originally coded with Python. Everything done in this repository is performed using TypeScript and Node.js 12+, even the Elliptic Curve code.

Here are some of the changes/challenges with porting to Node.js

  • This port uses the BigInt type to perform elliptic curve cryptography. This code is mostly found in src/ecc. While BigInt finally allows us to do some neat stuff (and support 64-bit integers) it does not have constant time operations and is not suitable for cryptography. So this code is just an exercise.
  • JavaScript does not support operator overloading (defining math operators +, *, %, etc), so it is not possible to code something like pointA + pointB where each variable is a S256Point instance. Instead I created types that support interface-based math operations. IOperableIntElementFieldElement
  • The Python example uses a modpow function to perform modular exponentiation efficiently. Neither BigInt nor Node.js have this capability. I created a modpow function that allows for efficient modular exponentiation of large numbers (such as those used in secp256k1). modpow
  • The % operator available to BigInt is actually the remainder operator, which means it allows negative numbers and is a problem for subtraction. A helper function was created that is heavily used in the ECC code. mod
  • There is not a divmod function, one has been added to return a tuple of the quotient and remainder. divmod
  • Node misses functionality for converting between BigInt and Buffer. I've create helper functions to easily go between the two. bigToBuf, bigToBufLE, bigFromBuf, bigFromBufLE
  • Most, but not all Script operations were added and can be found in src/script/operations.
  • Node.js TCP Sockets are asynchronous, this presents a few differences:
    • SimpleNode wraps the standard node Socket behavior and takes care of performing the handshake on connection. connection
    • The socket operates in paused mode which means that data is explicitly read from the socket stream.
    • For each message, the header is read and parsed first. If the full payload cannot be read in its entirety from the stream, the header is cached until more data is available on the stream. SimpleNode._onReadable
    • Once a payload has been fully read and validated against the checksum, SimpleNode emits a parsed payload as a corresponding event. event emission
  • Because IO in Node.js is async, any code that requires fetching from remote sources has caused async methods to be sprinkled throughout the application (Tx.verifyInput, etc).
  • MerkleBlock and MerkleTree construction were seperated into two classes to better help with understanding.
  • MerkleTree construction uses a pointer implementation instead of the array-based algorithm in the book. I found both partial merkle block parsing and construction to be simpler this way. ConstructionParsing

About

Programming Bitcoin in TypeScript

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - bmancini55/programming-bitcoin: Programming Bitcoin in TypeScript · GitHub
Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Repository files navigation

Programming Bitcoin in TypeScript

This repository is a TypeScript implementattion of the Python code found in Jimmy Song's Programming Bitcoin book. The structure of this code differs from the book in a few ways:

  • The master branch is the completed code-base. I plan to add branches which have the completed code after each chapter for quick reference as you progress.
  • Exercises are sprinkled throughout the unit tests instead of explicitly being called out.
  • Jupyter is not being used, tests and execises can be run with npm commands below.

NPM Commands

npm can be used to run several commands:

# runs all unit tests
npm test # run a network daemon that retrieves block header (chapter 10)
npm run start:10
# run a network daemon that retrieves merkle blocks (chapter 12)
npm run start:12

Node.js 12+ Details

The book was originally coded with Python. Everything done in this repository is performed using TypeScript and Node.js 12+, even the Elliptic Curve code.

Here are some of the changes/challenges with porting to Node.js

  • This port uses the BigInt type to perform elliptic curve cryptography. This code is mostly found in src/ecc. While BigInt finally allows us to do some neat stuff (and support 64-bit integers) it does not have constant time operations and is not suitable for cryptography. So this code is just an exercise.
  • JavaScript does not support operator overloading (defining math operators +, *, %, etc), so it is not possible to code something like pointA + pointB where each variable is a S256Point instance. Instead I created types that support interface-based math operations. IOperableIntElementFieldElement
  • The Python example uses a modpow function to perform modular exponentiation efficiently. Neither BigInt nor Node.js have this capability. I created a modpow function that allows for efficient modular exponentiation of large numbers (such as those used in secp256k1). modpow
  • The % operator available to BigInt is actually the remainder operator, which means it allows negative numbers and is a problem for subtraction. A helper function was created that is heavily used in the ECC code. mod
  • There is not a divmod function, one has been added to return a tuple of the quotient and remainder. divmod
  • Node misses functionality for converting between BigInt and Buffer. I've create helper functions to easily go between the two. bigToBuf, bigToBufLE, bigFromBuf, bigFromBufLE
  • Most, but not all Script operations were added and can be found in src/script/operations.
  • Node.js TCP Sockets are asynchronous, this presents a few differences:
    • SimpleNode wraps the standard node Socket behavior and takes care of performing the handshake on connection. connection
    • The socket operates in paused mode which means that data is explicitly read from the socket stream.
    • For each message, the header is read and parsed first. If the full payload cannot be read in its entirety from the stream, the header is cached until more data is available on the stream. SimpleNode._onReadable
    • Once a payload has been fully read and validated against the checksum, SimpleNode emits a parsed payload as a corresponding event. event emission
  • Because IO in Node.js is async, any code that requires fetching from remote sources has caused async methods to be sprinkled throughout the application (Tx.verifyInput, etc).
  • MerkleBlock and MerkleTree construction were seperated into two classes to better help with understanding.
  • MerkleTree construction uses a pointer implementation instead of the array-based algorithm in the book. I found both partial merkle block parsing and construction to be simpler this way. ConstructionParsing

About

Programming Bitcoin in TypeScript

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - bmancini55/programming-bitcoin: Programming Bitcoin in TypeScript · GitHub
Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Repository files navigation

Programming Bitcoin in TypeScript

This repository is a TypeScript implementattion of the Python code found in Jimmy Song's Programming Bitcoin book. The structure of this code differs from the book in a few ways:

  • The master branch is the completed code-base. I plan to add branches which have the completed code after each chapter for quick reference as you progress.
  • Exercises are sprinkled throughout the unit tests instead of explicitly being called out.
  • Jupyter is not being used, tests and execises can be run with npm commands below.

NPM Commands

npm can be used to run several commands:

# runs all unit tests
npm test # run a network daemon that retrieves block header (chapter 10)
npm run start:10
# run a network daemon that retrieves merkle blocks (chapter 12)
npm run start:12

Node.js 12+ Details

The book was originally coded with Python. Everything done in this repository is performed using TypeScript and Node.js 12+, even the Elliptic Curve code.

Here are some of the changes/challenges with porting to Node.js

  • This port uses the BigInt type to perform elliptic curve cryptography. This code is mostly found in src/ecc. While BigInt finally allows us to do some neat stuff (and support 64-bit integers) it does not have constant time operations and is not suitable for cryptography. So this code is just an exercise.
  • JavaScript does not support operator overloading (defining math operators +, *, %, etc), so it is not possible to code something like pointA + pointB where each variable is a S256Point instance. Instead I created types that support interface-based math operations. IOperableIntElementFieldElement
  • The Python example uses a modpow function to perform modular exponentiation efficiently. Neither BigInt nor Node.js have this capability. I created a modpow function that allows for efficient modular exponentiation of large numbers (such as those used in secp256k1). modpow
  • The % operator available to BigInt is actually the remainder operator, which means it allows negative numbers and is a problem for subtraction. A helper function was created that is heavily used in the ECC code. mod
  • There is not a divmod function, one has been added to return a tuple of the quotient and remainder. divmod
  • Node misses functionality for converting between BigInt and Buffer. I've create helper functions to easily go between the two. bigToBuf, bigToBufLE, bigFromBuf, bigFromBufLE
  • Most, but not all Script operations were added and can be found in src/script/operations.
  • Node.js TCP Sockets are asynchronous, this presents a few differences:
    • SimpleNode wraps the standard node Socket behavior and takes care of performing the handshake on connection. connection
    • The socket operates in paused mode which means that data is explicitly read from the socket stream.
    • For each message, the header is read and parsed first. If the full payload cannot be read in its entirety from the stream, the header is cached until more data is available on the stream. SimpleNode._onReadable
    • Once a payload has been fully read and validated against the checksum, SimpleNode emits a parsed payload as a corresponding event. event emission
  • Because IO in Node.js is async, any code that requires fetching from remote sources has caused async methods to be sprinkled throughout the application (Tx.verifyInput, etc).
  • MerkleBlock and MerkleTree construction were seperated into two classes to better help with understanding.
  • MerkleTree construction uses a pointer implementation instead of the array-based algorithm in the book. I found both partial merkle block parsing and construction to be simpler this way. ConstructionParsing

About

Programming Bitcoin in TypeScript

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages