Thursday, July 02, 2026

Trust, But Verify: Reverse-Engineering a Wallet's Key Derivation

"Non-custodial" is a claim, not a fact. Any wallet can say your keys never leave your device — the only way to actually know is to open the source, find the code that turns your seed phrase into a private key, and check it yourself. That's true reverse engineering, and it's the same instinct behind WalletScrutiny's reproducible-build work: don't trust the label on the box, verify what's inside.

This post walks through doing exactly that for ADAMANT Messenger, an open-source decentralized messenger with a built-in multi-coin wallet (ADM, BTC, ETH, DOGE, DASH, USDT, USDC, ERC-20 tokens). The trigger was simple: I exported my passphrase from ADAMANT, tried to import it into Electrum as a BTC seed, and got a completely different address than the one ADAMANT shows me. Same passphrase, two different wallets, two different answers for "where is my money." That mismatch is either a red flag or a clue — this post is about figuring out which.




Part 1 — The methodology: how do you even start?

You don't need to be a cryptographer or a full-time programmer to do this. You need a computer, a terminal (the black-box text window your OS ships with — Terminal on macOS, or a shell like bash on Linux), and two free tools: git (downloads a copy of a project's source code) and grep (searches text). Both come pre-installed on Linux and macOS; on Windows, install Git for Windows, which bundles a terminal (Git Bash) with both tools already in it.


Step 1 — Get the actual source code onto your computer

"Open source" means the company publishes their code on a site like GitHub — but that code isn't on your machine yet, and you can't grep a website. The first real step is always to download ("clone") a copy of the repository. ADAMANT publishes theirs at github.com/Adamant-im/adamant-im. To clone it, open your terminal and run:

git clone https://github.com/Adamant-im/adamant-im.git

This creates a new folder called adamant-im in whatever directory you were in, containing a full copy of every source file in the project. Move into it:

cd adamant-im

Everything from here on happens inside that folder.

Step 2 — Frame the question before you start searching

Before touching ADAMANT's code, it helps to separate the mismatch (ADAMANT's address vs. Electrum's address, for the same passphrase) into two possibilities:

The two apps are using completely different derivation algorithms — different math entirely, or
They're using the same algorithm but different parameters (a different "derivation path," a different address format, different network settings).

That framing matters because it tells you what you're hunting for isn't "bitcoin code" in general — it's specifically the one function that takes a string (your passphrase) and turns it into a private key (a secret number that controls funds). That's a much smaller target than "the whole wallet app," which for ADAMANT is hundreds of files.

Step 3 — Where to look in a JS/TS wallet repo

ADAMANT is written in JavaScript/TypeScript (you can tell from the .js/.ts/.vue files when you look inside the folder — ls or your file manager will show you). Two complementary ways to narrow hundreds of files down to the handful that matter:

1. Look at the folder structure first. Multi-coin wallet apps almost always organize code per-coin or in a shared "coin logic" module. Run ls src/lib/ inside the cloned repo and look for folder names like wallets/, coins/, crypto/, or — in ADAMANT's case — bitcoin/. That's usually a strong hint before you've read a single line of code.

2. Search ("grep") for the vocabulary of key derivation. grep searches every file for a piece of text you give it. The trick is knowing which words to search for — key-derivation code almost always uses a handful of recognizable terms regardless of which wallet app you're looking at:

bip39, bip32 — names of the standards most wallets use to turn a 12/24-word phrase into keys
hdkey, derivePath — "HD" (Hierarchical Deterministic) wallet code, the mechanism behind those standards
mnemonicToSeed, fromPrivateKey — common function names in crypto libraries
bitcoinjs — the most popular JavaScript Bitcoin library, and a good sign you've found the right area

Run this from inside the adamant-im folder:

grep -rniE "bip39|bip32|hdkey|derivePath|mnemonicToSeed|fromPrivateKey|bitcoinjs" \
--include="*.js" --include="*.ts" -l

Breaking that command down: grep is the search tool; -r means "search recursively" (every file in every subfolder, not just the current one); -n shows line numbers; -i ignores uppercase/lowercase differences; -E allows the | ("or") syntax between search terms; --include="*.js" restricts the search to JavaScript/TypeScript files so you're not wading through images or config files; -l prints just the filenames that matched, not every matching line (useful for a first pass).

Run that before reading anything else. It narrows an entire repository (hundreds of files) down to 3-5 files worth opening by hand.

Step 4 — Read the smallest function that touches "passphrase" and "key"

Running that grep against the ADAMANT repo points straight at one file: src/lib/bitcoin/btc-base-api.js. Open it in any text editor (even a basic one) and look for a function — a named, reusable block of code — that takes the passphrase as input. Here it is, in full, with nothing trimmed out:

export function getAccount(crypto, passphrase) {
const network = networks[crypto]
const pwHash = bitcoin.crypto.sha256(Buffer.from(passphrase))
const keyPair = ECPairAPI.fromPrivateKey(pwHash, { network })

return {
network,
keyPair,
address: bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network }).address
}
}

A quick vocabulary check, since none of this is obvious on a first read:

sha256 — a hashing function. Feed it any input (here, your passphrase as plain text) and it always produces the exact same 32-byte output for that input, every time, on any computer. That determinism is exactly what makes a wallet "non-custodial": no server is involved, no randomness, just math you can rerun yourself.

secp256k1 — the specific elliptic curve (a type of math used for cryptographic keys) that Bitcoin, and this wallet, build private/public key pairs on. You don't need to understand the curve math — just know that a "private key" for secp256k1 is simply a 32-byte number, and the SHA256 output above is exactly 32 bytes, which is why it can be used directly as one.

P2PKH ("Pay to Public Key Hash") — the oldest, simplest Bitcoin address format, the kind that starts with 1. There are newer formats, but P2PKH is what this code produces.
So the whole derivation, stripped of jargon, is:

private_key = SHA256(the passphrase, typed exactly as shown, as raw text)
address     = a Bitcoin "1..." address computed from that private key

No BIP32 master key, no derivation path like m/44'/0'/0'/0/0, no PBKDF2 (a slow-hashing step BIP39 wallets use). Just one SHA256 hash of the literal passphrase text, used directly as a private key.

A necessary terminology correction: "passphrase" vs. "seed phrase" vs. "BIP39 passphrase"
Before going further, three words that sound similar but mean different things need untangling — because ADAMANT's own naming makes this genuinely confusing, even for people who already know standard Bitcoin wallet terms.

Seed phrase / mnemonic — the 12 (or 15/18/21/24) words most wallets show you on first setup ("write these down"). These are generated by the app itself, drawn from a fixed, public list of exactly 2048 words defined by the BIP39 standard. You don't get to pick them; the app picks them for you from device randomness.

BIP39 passphrase (sometimes called the "25th word") — a completely separate, optional extra secret that some wallets let you add on top of the 12-word mnemonic. Unlike the mnemonic, this one genuinely is user-typed, arbitrary text — any word or sentence you want, not restricted to the 2048-word list. If you set one, it gets mixed into the seed-derivation math alongside the mnemonic; the same 12 words plus a different (or missing) passphrase produce a completely different wallet. It exists mainly for plausible deniability (a "decoy" wallet vs. a "real" one, both reachable from the same 12 words).

What ADAMANT calls "passphrase" — despite the name, this is actually the first thing on this list, not the second. Checking src/components/PassphraseGenerator.vue confirms it: passphrase.value = bip39.generateMnemonic() — ADAMANT generates it the exact same way a standard BIP39 wallet generates its seed phrase (real entropy, real 2048-word list, real checksum, machine-generated, not user-typed). ADAMANT's product team just chose to call their seed phrase a "passphrase" in the UI and the code, which collides with the actual BIP39 meaning of that word above. When this post says "ADAMANT passphrase" from here on, it means ADAMANT's seed phrase — the 12-word mnemonic — not an optional 25th-word extension.

It gets more interesting: not every coin gets the same treatment


Given that ADAMANT's "passphrase" is a real, valid BIP39 mnemonic, a natural next question is whether it's used the standard BIP39 way. The answer is: it depends on which coin, and this is the most surprising thing this investigation turned up.

Grepping src/lib/ for mnemonicToSeedSync (the actual BIP39 function that turns a mnemonic into a 64-byte seed) shows three different fates for the same 12 words:

CoinUses BIP39's mnemonicToSeedSync?What happens nextReproducible in a standard wallet?
BTC / DOGE / DASHNo — skipped entirelySHA256(raw mnemonic text) directlyNever. No standard wallet can replicate this; the BIP39 seed step is bypassed altogether.
ADM (native coin)Yes (src/lib/adamant.js)Seed is then hashed again with SHA256 and fed into an Ed25519 keypair function (sodium.crypto_sign_seed_keypair) — a Lisk-style step, not part of BIP39/32/44Only by a wallet that reimplements this exact extra step. (ADAMANT is a fork of Lisk, and this is Lisk's own historical scheme.)
ETH (src/lib/eth-utils.js)YesStandard BIP32 HD derivation — but at a nonstandard path, m/44'/60'/3'/1/0, instead of the usual default m/44'/60'/0'/0/0Only if you manually type that exact custom path. Any wallet that lets you override the derivation path (MetaMask's advanced settings, Ledger Live, many others) can get there — just not with default settings.

So "does ADAMANT use BIP39" doesn't have one answer — it's "yes for the seed-generation step, on 2 of the 4 coin families it supports, and then each of those two takes its own non-default detour afterward." BTC/DOGE/DASH ignore BIP39's machinery from the start.

Why the Electrum import produced a different address

Electrum is a different wallet app entirely — it doesn't read ADAMANT's code, it just assumes any 12-word phrase you type in follows the industry-standard recipe called BIP39. That recipe runs the words through a much heavier process before it ever becomes a private key:

seed = PBKDF2-HMAC-SHA512(mnemonic, salt="mnemonic"+passphrase, 2048 rounds)
master_key = BIP32_from_seed(seed)
private_key = derive(master_key, "m/44'/0'/0'/0/0") # or similar

In plain terms: Electrum stretches the words through a slow hashing process 2,048 times over (PBKDF2), then uses the result to build a whole tree of possible keys (BIP32), then picks one specific branch of that tree (the m/44'/0'/0'/0/0 "path"). That's a completely different pipeline from ADAMANT's single, direct SHA256(passphrase).

Neither approach is "wrong" cryptographically — they're just incompatible standards, like two people using different formulas to convert the same word into a number. ADAMANT rolled its own, simpler scheme instead of using BIP39/BIP32, which means BIP39-aware wallets like Electrum can never reproduce an ADAMANT-derived address from the same words, even though both are valid, deterministic, passphrase-derived keys.

That's an important nuance for anyone auditing "self-custodial" claims: the absence of BIP39 compatibility isn't itself proof of custodial risk — the passphrase-derived key is still generated and held entirely client-side. But it does mean you can't use a generic wallet as an independent cross-check the way you normally could. You have to speak the app's own derivation dialect.

A notable design detail: address reuse across coins
Digging one level further, in src/lib/bitcoin/networks.js:

const nets = {
[Cryptos.DOGE]: coininfo.dogecoin.main.toBitcoinJS(),
[Cryptos.DASH]: coininfo.dash.main.toBitcoinJS(),
[Cryptos.BTC]: coininfo.bitcoin.main.toBitcoinJS()
}

getAccount() is shared across BTC, DOGE, and DASH — meaning the exact same 32-byte private key (SHA256(passphrase)) is reused for all three chains. Only the network version bytes differ (via the coininfo library), which changes the address encoding, not the underlying key. That's a legitimate, common pattern for multi-chain wallets built on secp256k1 (same curve, same private key, different address prefixes) — but it's worth knowing, since it means compromising the BTC key compromises DOGE and DASH funds too.

Part 2 — Proving it yourself

Reading the code and understanding the algorithm is most of the work, but it isn't the proof yet. Anyone can read getAccount() and say they understand it — the actual "trust but verify" moment is writing a second, completely independent implementation of that same math, from scratch, using none of ADAMANT's own code, and checking whether it produces the exact same address ADAMANT shows you. If it does, that's real, checkable proof the key really is computed client-side from your passphrase alone — not proof by reading, proof by reproducing.

Why write a second implementation instead of just trusting the read-through


Reading code can mislead you in ways that are easy to miss: a function could look correct but never actually get called from the real account-creation flow, there could be a second, different code path used in production, or a subtle bug in my reading of the JavaScript could go unnoticed. An independent reimplementation sidesteps all of that — it either produces the address you see in ADAMANT, or it doesn't, with nothing left to interpretation.

Setting up

The script uses the same three public libraries ADAMANT's own code depends on (bitcoinjs-lib, ecpair, tiny-secp256k1) — reusing the well-tested cryptography those libraries provide is reasonable and doesn't undermine the independence of the test, since the whole point is to verify how ADAMANT calls them, not to reinvent elliptic curve math from first principles. What matters is that none of ADAMANT's own source files are imported or reused.

mkdir adamant-btc-verify && cd adamant-btc-verify
npm install bitcoinjs-lib ecpair tiny-secp256k1

That downloads just those three packages (and their own dependencies) into a fresh, empty folder — much faster than a full npm install inside the cloned ADAMANT repo, which would pull in Electron and hundreds of unrelated packages for the full app.

The script

import * as bitcoin from 'bitcoinjs-lib'
import { ECPairFactory } from 'ecpair'
import * as tinysecp from 'tiny-secp256k1'
import readline from 'node:readline'

const ECPair = ECPairFactory(tinysecp)

// Reads a line from the terminal without echoing it back to the screen, so your
// passphrase never appears in your terminal's visible output or scrollback.
function readPassphraseHidden(promptText) {
return new Promise((resolve) => {
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
process.stdin.on('data', (char) => {
char = char.toString()
if (char === '\n' || char === '\r' || char === '') return
process.stdout.clearLine(0)
readline.cursorTo(process.stdout, 0)
process.stdout.write(promptText + '*'.repeat(rl.line.length))
})
rl.question(promptText, (value) => {
rl.close()
process.stdout.write('\n')
resolve(value)
})
})
}

const passphrase = await readPassphraseHidden('Paste your ADAMANT passphrase (hidden): ')

// ---- This block is the exact algorithm from getAccount() in btc-base-api.js ----
const network = bitcoin.networks.bitcoin
const pwHash = bitcoin.crypto.sha256(Buffer.from(passphrase))
const keyPair = ECPair.fromPrivateKey(pwHash, { network })
const address = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network }).address
// ----------------------------------------------------------------------------

console.log('\nDerived BTC address:', address)

Two deliberate safety choices worth calling out, since this script is handling real key material even though it's just a learning exercise:

The passphrase is never echoed to the screen. readPassphraseHidden() intercepts each keystroke and redraws the line as asterisks instead of letting the terminal print what you typed — the same idea as a password field on a website, just implemented by hand since Node's built-in readline doesn't hide input on its own.

The private key is never printed, logged, or stored anywhere. Only the final address is shown. The address alone is sufficient proof (it's what you compare against ADAMANT's own display); there's no reason a verification script should ever need to reveal the actual secret it computed along the way.

Running it

node verify-btc-address.mjs

The script prompts for a passphrase, computes the address, and prints it:

Paste your ADAMANT passphrase (hidden): 
Derived BTC address: 1JTpYrn6TWYjgwk3...
That address is then compared by hand against what ADAMANT itself shows under Wallet → BTC.

The result

They matched. Running an independent, from-scratch implementation of the same three lines of math — SHA256(passphrase) → private key → P2PKH address — using different code, on a different machine process, with no connection to ADAMANT's app whatsoever, produced the identical Bitcoin address ADAMANT displays for that same passphrase.

That's the actual proof this whole post has been building toward: the BTC key isn't generated on a server, isn't something ADAMANT's company could quietly recreate or withhold, and isn't hidden behind proprietary logic. It's fully determined by one thing — the passphrase — and computable by anyone who reads the (public, open) source code closely enough to reimplement it. That's what "non-custodial" is supposed to mean, and now it isn't just a claim on ADAMANT's website — it's something checked, independently, end to end.

One more nuance: non-custodial isn't the same as portable

It's tempting to stop at "the address matched, so this is fine" — but there's a real cost to ADAMANT's custom derivation scheme that a match test alone doesn't capture: you can only recover these funds using ADAMANT's own software. A standard BIP39 wallet's whole selling point is that your 12 words work in any compliant wallet — Electrum, Sparrow, a hardware wallet, whatever you want, forever, even if the original company disappears. ADAMANT's passphrase only ever produces the right BTC address inside ADAMANT itself (or a from-scratch reimplementation like the one above). If ADAMANT the project ever shuts down and nobody's kept a copy of this derivation logic, recovering those funds gets a lot harder — not impossible (the algorithm is public, in the open-source repo, forever, as long as someone can find and run it), but nothing close to "type your words into any wallet."

That's a genuine, separate axis from custody, worth being clear-eyed about: your funds are non-custodial, but not portable. Checked WalletScrutiny's own definitions for both (custodial.yml and the hd entry in features.yml) — the custody question is narrowly "does the provider hold your keys," which ADAMANT passes cleanly, while the portability question already has its own, separate feature flag (hd), which correctly isn't claimed for ADAMANT here. Two different questions, two different answers, and it's worth asking both about any wallet, not just the custody one.

Takeaways

  • "Non-custodial" claims are verifiable, not just trustable — the actual proof lives in a handful of lines of derivation code, and it's provable by reproducing it independently, not just by reading and nodding along.
  • Finding that code is a search problem before it's a reading problem: grep for the vocabulary (bip39, bip32, hdkey, sha256, fromPrivateKey) before opening files. Any wallet's derivation is a small, greppable target inside a much larger app.
  • A failed cross-wallet import (e.g. ADAMANT → Electrum) is not automatically a red flag — it can simply mean the app uses a non-standard (non-BIP39) derivation scheme. The mismatch is a clue to keep digging, not a verdict on its own.
  • Don't trust a wallet's own vocabulary. ADAMANT calls its seed phrase a "passphrase," which collides with the actual BIP39 term for a completely different, optional thing (an extra user-typed secret on top of a seed phrase). Always confirm what a word means in this specific app's code, not what it means industry-wide.
  • "Does this wallet use BIP39" can be true for some of its coins and false for others, in the same app, from the same 12 words. ADAMANT's BTC/DOGE/DASH skip BIP39's seed step entirely; ADM and ETH use it, then each diverges from the standard afterward in its own way. Check every coin's path separately — don't generalize from one.
  • Non-custodial and portable are two different questions with two different answers. ADAMANT passes the first cleanly and fails the second — funds are genuinely self-controlled, but only recoverable through ADAMANT's own (open-source) code, not any standard wallet. Ask both questions about any wallet you're evaluating.
  • When writing a verification script that touches real key material, treat it like it matters even in a "just learning" context: hide passphrase input, never print or log the private key, only ever surface what's needed to prove the point (here, just the resulting address).

Friday, November 24, 2023

EventId's in Nostr - from CGPT4

The mathematical operation used to derive the event.id in your getSignedEvent function is the SHA-256 hash function, applied to a string representation of the event's data.

async function getSignedEvent(event, privateKey) {
          var eventData = JSON.stringify([
          0,            // Reserved for future use
          event['pubkey'],  // The sender's public key
          event['created_at'],  // Unix timestamp
          event['kind'],    // Message "kind" or type
          event['tags'],    // Tags idnetify replies/recipients
          event['content']  // Your note contents
          ])
          event.id = sha256( eventData ).toString( 'hex' )
          event.sig = await schnorr.sign( event.id, privateKey )
          return event
       }        

Let's break down this process:

String Representation of Event Data:

First, a string eventData is created from the event object. This string is a JSON representation that includes several fields of the event object, such as the sender's public key (event['pubkey']), timestamp (event['created_at']), message type (event['kind']), tags (event['tags']), and content (event['content']).

These fields are combined into an array and then serialized into a JSON string.

Applying the SHA-256 Hash Function:

The SHA-256 hash function is then applied to this string. SHA-256 stands for Secure Hash Algorithm 256-bit and is a member of the SHA-2 cryptographic hash functions designed by the NSA.

Cryptographic hash functions like SHA-256 have several key properties:

  • Deterministic: The same input will always produce the same output.
  • Fixed Size: Regardless of the input size, the output (hash) is always of a fixed length. In the case of SHA-256, the output is 256 bits (32 bytes) long.
  • Fast Computation: The hash value is quick to compute for any given input.
  • Pre-image Resistance: Given a hash value, it's computationally infeasible to find the original input.
  • Small Changes in Input Produce Significant Changes: Even a tiny change in the input will produce a significantly different output.
  • Collision Resistance: It's extremely unlikely (though not impossible) that two different inputs will produce the same output hash.

Creating event.id:

The output of the SHA-256 hash function (applied to eventData) is then converted to a hexadecimal string. This hex string becomes the value of event.id.

This event.id serves as a unique identifier for the event, and due to the properties of the SHA-256 hash, it also ensures the integrity of the event's data. Any change in the event's data would result in a completely different event.id.

In summary, the event.id is derived through a process of serialization (converting the event data to a JSON string) and hashing (applying SHA-256 to this string). This process is fundamental in many cryptographic applications, including blockchain and digital signatures, as it ensures data integrity and uniqueness.

Monday, August 07, 2023

The Change We Deserve Comes at a Steep Price




At 41 years of age, I am starting to become a grumpy old man. So when I saw people on FB "debating" how the Germans can do this, I start to philosophize about how we are, as we are today. What made the Germans and the Japanese so orderly? I am sure that some young one, would be studying these cultures as a topic of their thesis some day. 

I replied to the FB thread and posited a challenge and a rhetorical question: 

I'm happy that we are discussing this. It's a little bit of social science and a little bit of philosophy.

I've been following some Japanese "shorts" showing how orderly Japan is, and marveling at how they do that as well.

Among the answers I found here are:
  1. Law enforcement
  2. Discipline - with some dissent
  3. Culture - with some reservations
  4. Fines
  5. Education
I would offer the notion that it's all of the above. Now, if we combine these 5 ideas, we'll actually get to the bottom of this.

The problem with **law enforcement** is the sheer number of **undisciplined** people in our country. The **culture** of **corruption** is deeply ingrained, that **fines** are subverted because **corruption** allows people to make bribes. Our **education** system has also been **corrupted** because all that is being taught today, is to get out of the country so that "you'll make it.". **Law enforcement** is also difficult because our **leaders** are not accountable. They are often exempted. The mass **culture** is of personal gratification rather than collective responsibility. More often than not, the defense of errant drivers is **what about that guy**. Or, what about politician X, who did not even pay estate tax. ad infinitum. 

So here are the boldest questions: the change we need is going to be tough. It has to be cultural. And it will require changes.

Are we really ready for the change that we need?
Do we really even want to change?

Have a pleasant morning to all of us.

P.S. Lawrence Celestino - you really remind me of my younger self. I hope you are successful in your - in **our** dream of an orderly society. The question really is - what is the next BIG STEP? Is it still possible given the leadership we currently have?

Are there people willing to risk their lives to make this happen? Because, as you have said - people are violent. That is true.

Friday, December 23, 2022

c++ study notes

 terms: flooding network propagation


--- cpp


statement - type of instruction that causes the program to perform some action.


function - a collection of statements that execute sequentially


Declaration statements

Jump statements

Expression statements

Compound statements

Selection statements (conditionals)

Iteration statements (loops)

Try blocks


####################

Rule


Every C++ program must have a special function named main (all lower case letters). When the program is run, the statements inside of main are executed in sequential order.

####################


preprocessor directive

#include <iostream>


{

function body

}


// single line comments

/* multiple line comments */


data is any information that can be moved, processed, or stored by a computer.


 value - a single piece of data stored somewhere


In C++, direct memory access is not allowed. Instead, we access memory indirectly through an object. 


An object is a region of storage (usually memory) that has a value and other associated properties


 A named object is called a variable, and the name of the object is called an identifier.


runtime - when the program is run


instantiation - object is created and assigned a memory address


variable - a named region of memory


identifier - name that a variable is accessed by


type - tells the program how to interpret a value in memory.


copy assignment / assignement = after a variable has been defined, you can give it a value 


= assignment operator


initialization - variable defined and provided an initial value


initializer - the value used to initialize a variable


4 ways to initialize


int a; // no initializer

int b = 5; // initializer after equals sign - copy initialization

int c( 6 ); // initializer in parenthesis - direct initialization

int d { 7 }; // initializer in braces


copy initialization - when initializer follows an equal sign

direct initialization 

brace initialization/uniform initialization/list initialization


 3 kinds of brace initialization

 - int width { 5 }; // direct brace initialization of value 5 into variable width (preferred)

 - int height = { 6 }; // copy brace initialization of value 6 into variable height

 - int depth {}; // value initialization (see next section


value initialization and zero initialization

- variable initialized with empty braces

- value assigned is 0

- zero initialization



Initialization gives a variable an initial value at the point when it is created. Assignment gives a variable a value at some point after the variable is created.


Direct brace initialization.


<< - insertion operator - cout


>> - extraction operator - cin


using namespace std; - "using directive" avoid


std::endl vs ‘\n’


######

Best practice


Prefer ‘\n’ over std::endl when outputting text to the console.

######


_____1.6


- initialization - object given value at the point of definition

- assignment - object given value beyond the point of definition

- uninitialized - object not given a known value yet


always initialize your variables


Undefined behavior - executing code whose behavior not well defined in c++


_____1.7 


keywords - 92 words reserved by c++ for 

identifiers - override, final, import, and module.


ide changes color to blue of these words


c++ is case sensitive


always start lowercase

not number

no symbols

no space

no reserved words


snake_case

camelCase or interCapped


######

Best practice


When working in an existing program, use the conventions of that program (even if they don’t conform to modern best practices). Use modern best practices when you’re writing new programs.

######


_ underscores - OS, library, and/or compiler use


correct (follows convention)

incorrect (does not follow convention)

invalid (will not compile)


_____1.8 Whitespace


_____1.9 Literals and operators


literals or literal constant - fixed values inserted into source code


arity, the number of operatands an operator takes as input


- unary

- binary

- tertiary


_____1.10 Expressions


Expression

An expression is a combination of literals, variables, operators, and function calls that can be executed to produce a singular value. 


Evaluation 

The process of executing an expression is called evaluation, 


Result

and the single value produced is called the result of the expression.


_____2.1


function = reusable sequence of statements to do a job

user-defined function = function that user writes himself

function call = an expression that tells the CPU to interrupt the current function and execute another function


caller = the function that initiated the function call

callee or called function = the function being called


### syntax to define a user defined function


return-type identifier() // identifier replaced with the name of your function

{

// Your code here

}


the curly braces identify the function body


###


metasyntactic variable - placeholder names


_____2.2


return value

return type 

return statement

return value


""""""

When you write a user-defined function, you get to determine whether your function will return a value back to the caller or not. To return a value back to the caller, two things are needed.


First, your function has to indicate what type of value will be returned. This is done by setting the function’s return type, which is the type that is defined before the function’s name. In the example above, function getValueFromUser has a return type of void, and function main has a return type of int. Note that this doesn’t determine what specific value is returned -- only the type of the value.


Second, inside the function that will return a value, we use a return statement to indicate the specific value being returned to the caller. The specific value returned from a function is called the return value. When the return statement is executed, the return value is copied from the function back to the caller. This process is called return by value.""""""


status code 

exit code

return code


DRY = Don't Repeat Yourself


_____2.3 Function parameters and arguments



function parameter - is a variable used in a function. 


A function parameter is a variable used in a function. Function parameters work almost identically to variables defined inside the function, but with one difference: they are always initialized with a value provided by the caller of the function.


argument - value that is passed from the caller to the function when a function call is made


pass by value - parameters of the function created as variables, value is copied


//This is a hard topic, learn more about passing of value


**function prototyping


_____2.4 Local scope


Function parameters, as well as variables defined inside the function body, are called local variables (as opposed to global variables, which we’ll discuss in a future chapter).


An identifier’s scope determines where the identifier can be accessed within the source code. When an identifier can be accessed, we say it is in scope. When an identifier can not be accessed, we say it is out of scope.


_____2.5 Why functions are useful and how to use them effectively


- organization

- reusability

- testing

- extensibility

- abstraction


refactoring - when a function is split into multiple sub-functions 


_____2.6 forward declarations


A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier.


function prototyping - a declaration statement. Is composed of 


    - return type

    - name

    - parameters



#### ODR #####


One Definition Rule


1. Within a given file, a function, object, type, or template can only have one definition.

2. Within a given program, an object or normal function can only have one definition. This distinction is made because programs can have more than one file (we’ll cover this in the next lesson).

3. Types, templates, inline functions, and variables are allowed to have identical definitions in different files. 


Declaration - a statement that tells the compiler about the existence of an identifier and its type information. 


in C++ - all definitions are also declarations


but not all declarations are definitions


Pure declarations - "An example of this is the function prototype -- it satisfies the compiler, but not the linker. These declarations that aren’t definitions are called pure declarations. Other types of pure declarations include forward declarations for variables and type declarations (you will encounter these in future lessons, no need to worry about them now)."


Function prototype - A function prototype is a declaration statement that includes a function’s name, return type, and parameters. It does not include the function body.


Forward declaration - A forward declaration tells the compiler that an identifier exists before it is actually defined.

 - according to Bucky this is actually called "Function prototyping"


Notes:


Compiler fails to compile if function does not have the same number of parameters.


Other compiler link problems - if a function is undefined (no body), linker can't resolve the function call.  


Violating ODR rule 2 - "Within a given program, an object or normal function can only have one definition"


_____2.8 naming collisions and namespaces


:: in std::cout - scope resolution operator 

The identifier to the left of the :: symbol identifies the namespace that the name to the right of the :: symbol is contained within. If no identifier to the left of the :: symbol is provided, the global namespace is assumed.


using directive - (using namespace std) -  tells the compiler to check a specified namespace when trying to resolve an identifier that has no namespace prefix


_____2.9 introduction to the pre-processor


Prior to compilation, program goes through translation.


Translation has many phases.


Preprocessor directive (or simply directive) scans from top to bottom of file. Start with # and end with a new line.


Macro defines 


a macro is a rule that defines how input text is converted into replacement output text.


object-like macros

function-like macros


Object-like macros can be defined in one of two ways:


#define identifier

#define identifier substitution_text


When the preprocessor encounters this directive, any further occurrence of the identifier is replaced by substitution_text. The identifier is traditionally typed in all capital letters, using underscores to represent spaces.


Tuesday, April 05, 2022

Fatherhood is like...

 Having a JP Drain stuck on your tummy and with people harnessed while you try to climb a mountain.

Wednesday, November 24, 2021

Trying to Install c-lightning

In my work with walletscrutiny.com, I had to test an app called Spark Wallet. The app needs a c-lightning node, which means installing c-lightning.

Several issues cropped up. 

One, the instructions given here, are for Ubuntu, and not for Linux Mint, which is the machine I'm trying this. 

Issue 1: 

sudo add-apt-repository -u ppa:lightningnetwork/ppa

does not work. No such option as -u

I removed the -u and it worked.

Issue 2:

gpg: keyserver receive failed: General error

Issue 3:

Package 'snapd' has no installation candidate
Fixed by moving a file that causes the restriction, which enabled snap.

2021-11-24 Installing Bitcoin-Core

Friday, August 27, 2021

How to find Private Key in Mycelium Bitcoin Wallet

1. Accounts Tab > My HD Accounts

2. Three Dots

3. Export

4. Show Private

* BIP32 Root Key Shows Up, starts with xprv

5. Use Mnemonic Code Converter - Recovers HD Wallet using mnemonic keywords

    a. Download/access here:

        https://iancoleman.github.io/bip39/ >> redirects to:

        https://iancoleman.io/bip39/


7. Copy BIP32 Root Key shown in the wallet

8. Paste in the "BIP32 Root Key" field

9. Click on BIP32 TAB, Under Derivation Path

10. Shows BIP32 Extended Private Key field.

Source: Reddit

Saturday, July 24, 2021

TheNewBoston.com Blockchain and Cryptocurrency Project


2.6 million people know Bucky Roberts. 

There are 481,000,000 views on his youtube channel. 

What he started has caught on like wildfire.

What did Bucky Roberts do?

P.S. This is not Bucky Roberts

Coding Tutorials

It all began with simple coding tutorials on YouTube. It started sometime in 2008 with a tutorial on XHTML. From there, it branched out to Photoshop, Dreamweaver, Adobe Flash, CSS, Adobe Illustrator, Javascript, Web Design, E-Commerce, PHP, C++, How to Build a Computer, Robotics Electronics, Python, Java, Adobe After Effects, Game Development, 3DS Max, Blender, Assassin's Creed Walkthroughs, --- and more.

He also ran a vlog where he talked about any topic he thinks about. By 2010, thenewboston was starting to take shape as a podcast and later on - a social media network

Everything seemed to be on the up and up, but then sometime between 2015 to 2020, Bucky went on an unannounced sabbatical. 

Where in the World is Bucky Roberts?

People missed him so much that you could find entire threads about "Where is Bucky Roberts now?" littered all around the Internet:

Work and Penguin Chess




Hello World - Bucky Roberts Comes Back


After a lot of speculation, Bucky uploads "Hello World" on Nov. 6, 2021.



Sunday, July 11, 2021

Creating Freecodecamp Tribute Page


I started getting back into my freecodecamp.com HTML and CSS tutorials. When I started in 2017, I figured that it's something that I could use. I guess, back then I wanted to put up my own business startup. Nowadays when I send a job application to some companies on LinkedIn, I can't help but be skeptical. 

Practically anybody who can think of a cool name, think of a clever dot com domain, could "pretend" to be a legitimate company. 

I'm still grappling with this idea of remote businesses - since they could be prone to abuse. As you get older, you tend to get more cautious. 

Trust, But Verify: Reverse-Engineering a Wallet's Key Derivation

"Non-custodial" is a claim, not a fact. Any wallet can say your keys never leave your device — the only way to actually know is to...