Думаю хорошим дополнением к этой теме может послужить неплохой онлайновый инструмент, который позволяет визуализировать получение BTC адресов.
It was the Bitcointalk forum that inspired us to create Bitcointalksearch.org - Bitcointalk is an excellent site that should be the default page for anybody dealing in cryptocurrency, since it is a virtual gold-mine of data. However, our experience and user feedback led us create our site; Bitcointalk's search is slow, and difficult to get the results you need, because you need to log in first to find anything useful - furthermore, there are rate limiters for their search functionality.
The aim of our project is to create a faster website that yields more results and faster without having to create an account and eliminate the need to log in - your personal data, therefore, will never be in jeopardy since we are not asking for any of your data and you don't need to provide them to use our site with all of its capabilities.
We created this website with the sole purpose of users being able to search quickly and efficiently in the field of cryptocurrency so they will have access to the latest and most accurate information and thereby assisting the crypto-community at large.
//Generating random 128 bits. 128 - 256 bits can be used but for this tutorial we are strictly generating 128 bits entropy
const getRandomBytes = () => {
const array = new Uint32Array(4); //creating Uint32 array having length = 4
const randomBytes = crypto.getRandomValues(array); //Filling array with random 32-bits integers
let binaryString = '';
let hexString = '';
randomBytes.forEach(byte => {
let binChunk = byte.toString(2);
binChunk = binChunk.length === 32 ? binChunk : '0'.repeat(32 - binChunk.length)+binChunk;
let hexChunk = parseInt(binChunk,2).toString(16);
binaryString += binChunk;
hexString += hexChunk;
})
return [binaryString,hexString];
}
//Generating SHA-256 hash of random bytes for checksum
let [randomBits,randomBitsHex] = getRandomBytes();
const byteHash = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(randomBitsHex)).toString(); //SHA-256 Hash of random bytes
let checksum = parseInt(byteHash[0],16).toString(2); //Taking (entropy-length / 32) bits of SHA256 hash which in our case is 4 bits
checksum = checksum.length === 4 ? checksum : '0'.repeat(4 - checksum.length)+checksum; //Adding '0' bits if hex is smaller than '8' or '0b1000' in binary
//Adding checksum at the end of random bytes
randomBits += checksum;
//Splitting random bytes into segments of 11-bits length and storing in an array
const segmentArray = [];
let i = 0;
while (i < randomBits.length) {
segmentArray.push(randomBits.substring(i,i+11));
i += 11;
}
//Converting every 11-bits segment into decimal equivalent
const decimalArray = segmentArray.map(segment => parseInt(segment,2));
//Picking 'word' at position equivalent to decimal array from 'mnemonic words list' (words.js)
const mnemonicArray = decimalArray.map(decimal => wordsArray[decimal]);
//getMnemonic Function - This function will be called in front-end when user will create new seed
const getMnemonic = () => {
return mnemonicArray.join(' '); //Converting mnemonic array into mnemonic string
}
//This function will generate Legacy bitcoin address (public key hash) using public key
const generateLegacyAddress = (publicKey) => {
const keyHex = CryptoJS.enc.Hex.parse(publicKey);
const ripedHashedKey = CryptoJS.RIPEMD160(CryptoJS.SHA256(keyHex)).toString();
const mainRipeKeyString = '00'+ripedHashedKey;
const mainRipeKey = CryptoJS.enc.Hex.parse(mainRipeKeyString);
const doubleHashedKey = CryptoJS.SHA256(CryptoJS.SHA256(mainRipeKey)).toString();
const checkSum = doubleHashedKey.substr(0, 8);
const binaryAddress = mainRipeKeyString+checkSum;
const arrayBinary = binaryAddress.match(/.{1,2}/g); //Converting serialization into array of every 2nd character
const binaryUint = new Uint8Array(arrayBinary.map(hex => parseInt(hex,16))); //Converting hex array into uint8array to be used as input in base58 function
return to_b58(binaryUint,bs58Chars);
}
//This function will generate P2SH bitcoin address (P2WPKH-in-P2SH) using public key
const generateP2SHAddress = (publicKey) => {
const keyHex = CryptoJS.enc.Hex.parse(publicKey);
const ripeHash = CryptoJS.RIPEMD160(CryptoJS.SHA256(keyHex)).toString();
const script = '0014'+ripeHash;
const scriptHex = CryptoJS.enc.Hex.parse(script);
const scriptRipeHash = '05'+CryptoJS.RIPEMD160(CryptoJS.SHA256(scriptHex)).toString();
const doubleHashedKey = CryptoJS.SHA256(CryptoJS.SHA256(CryptoJS.enc.Hex.parse(scriptRipeHash))).toString();
const checkSum = doubleHashedKey.substr(0, 8);
const binaryAddress = scriptRipeHash+checkSum;
const arrayBinary = binaryAddress.match(/.{1,2}/g); //Converting serialization into array of every 2nd character
const binaryUint = new Uint8Array(arrayBinary.map(hex => parseInt(hex,16))); //Converting hex array into uint8array to be used as input in base58 function
return to_b58(binaryUint,bs58Chars);
}
//This file contains code for generating public key from private key using Elliptic Curve Cryptography
const Pcurve = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F');
const Gx = BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240');
const Gy = BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424');
const G = [Gx, Gy];
const generatePublicKey = privateKey => {
const ECCPoints = ECMultiply(G, privateKey);
const checkKey = key => key.length < 64 ? '0'.repeat(64 - key.length)+key : key;
const publicKeyX = checkKey(ECCPoints[0].toString(16));
if (ECCPoints[1]%BigInt(2)===BigInt(1)) {
return '03'+publicKeyX;
} else {
return '02'+publicKeyX;
}
}
//mod inverse function
function modInverse(a, n) {
a = (a % n + n) % n
const dArray = [];
let b = n;
while(b) {
[a, b] = [b, a % b];
dArray.push({a, b});
}
if (a !== BigInt(1)) {
return null;
}
let x = BigInt(1);
let y = BigInt(0);
for(let i = dArray.length - 2; i >= 0; --i) {
[x, y] = [y, x - y * BigInt(dArray[i].a / dArray[i].b)];
}
return (y % n + n) % n;
}
//mod of function
function modOf(a,b) {
const r = ((a % b) + b)% b;
return r;
}
//ECAdd - Elliptic Curve Addition Function
function ECAdd(a,b) {
const lamAdd = modOf((b[1] - a[1]) * BigInt(modInverse(b[0] - a[0], Pcurve)), Pcurve);
const x = modOf((lamAdd*lamAdd - a[0] - b[0]), Pcurve);
const y = modOf((lamAdd*(a[0] - x) - a[1]), Pcurve);
return [x, y];
}
//ECDouble - Elliptic Curve Point Doubling
function ECDouble(a) {
const lamda = modOf(((BigInt(3)*a[0]*a[0])*(modInverse(BigInt(2)*a[1], Pcurve))), Pcurve);
const x = modOf((lamda*lamda - BigInt(2)*a[0]), Pcurve);
const y = modOf((lamda*(a[0] - x) - a[1]), Pcurve);
return [x, y];
};
//ECMultiply - Ellptic Curve Multiplication
function ECMultiply(genPoint, pvtKey) {
const scalarBinary = BigInt('0x'+pvtKey).toString(2);
let GP = genPoint;
for (let i=1; i < scalarBinary.length; i++) {
GP = ECDouble(GP)
if (scalarBinary[i] === '1') {
GP = ECAdd(GP, genPoint);
}
}
return GP;
}
//This javascript code for base58 encoding is taken from https://gist.github.com/diafygi/90a3e80ca1c2793220e5/
var to_b58 = function(B,A){var d=[],s="",i,j,c,n;for(i in B){j=0,c=B[i];s+=c||s.length^i?"":1;while(j in d||c){n=d[j];n=n?n*256+c:c;c=n/58|0;d[j]=n%58;j++}}while(j--)s+=A[d[j]];return s};
var bs58Chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';n*58+c:c;c=n>>8;d[j]=n%256;j++}}while(j--)b.push(d[j]);return new Uint8Array(b)};
//This function will take mnemonic code as the input and produce addresses
const detailsFromMnemonic = mnemonic => {
// 1. Creating 'seed' from mnemonic code
const salt = 'mnemonic'; //constant string 'mnemonic' used for salt in PBKDF2 function (custom passphrase could be used as well)
const seed = CryptoJS.PBKDF2(mnemonic, salt, {
hasher:CryptoJS.algo.SHA512,
keySize: 512 / 32,
iterations:2048
}).toString(); //using 2048 rounds of PBKDF2 key-stretching function
// 2. Creating 'Master Private Key' and 'Chain Code' from 'seed'
const hmacHash = CryptoJS.HmacSHA512(CryptoJS.enc.Hex.parse(seed),'Bitcoin seed').toString();
const masterPrivateKey = hmacHash.substr(0,64); //Left 256 bits of HMAC-512 hash
const chainCode = hmacHash.substr(64,64); //Right 256 bits of HMAC-512 hash
let masterPublicKey = generatePublicKey(masterPrivateKey);
// 3. Generating childs using BIP-44 Derivation Path for LEGACY (Derivation Path - m/44'/0'/0'/0); - Hardened Child - 0x8000002c
let {addresses: legacyAddresses, privateKeys: legacyPrivateKeys} = returnChild(masterPrivateKey,masterPublicKey,chainCode,'8000002c');
// Converting Public Key in the Array to Legacy Bitcoin Addresses
legacyAddresses = legacyAddresses.map(publicKey => generateLegacyAddress(publicKey));
// 4. Generating childs using BIP-49 Derivation Path for P2SH (Derivation Path - m/49'/0'/0'/0); - Hardened Child - 0x80000031
let {addresses: p2shAddresses, privateKeys: p2shPrivateKeys} = returnChild(masterPrivateKey,masterPublicKey,chainCode,'80000031');
// Converting Public Key in the Array to P2SH Bitcoin Addresses
p2shAddresses = p2shAddresses.map(publicKey => generateP2SHAddress(publicKey));
// 5. Generating childs using BIP-84 Derivation Path for Bech32 (Derivation Path - m/84'/0'/0'/0); - Hardened Child - 0x80000054
let {addresses: bech32Addresses, privateKeys: bech32PrivateKeys} = returnChild(masterPrivateKey,masterPublicKey,chainCode,'80000054');
// Converting Public Key in the Array to P2SH Bitcoin Addresses
bech32Addresses = bech32Addresses.map(publicKey => generateBech32Address(publicKey));
return {
masterPrivateKey,
masterPublicKey,
legacyPrivateKeys,
legacyAddresses,
p2shAddresses,
p2shPrivateKeys,
bech32Addresses,
bech32PrivateKeys
}
}
//Function for Deriving Children based on Hardened Child
function returnChild(masterPrivateKey,masterPublicKey,chainCode,hardenedChild) {
// First Level: m/H':
const [firstChildPrivate,firstChildPublic,firstChildChain] = generatingChild(masterPrivateKey,masterPublicKey,chainCode,hardenedChild,'private');
// Second Level: m/H'/0':
const [secondChildPrivate,secondChildPublic,secondChildChain] = generatingChild(firstChildPrivate,firstChildPublic,firstChildChain,'80000000','private');
// Third Level: m/H'/0'/0':
const [thirdChildPrivate,thirdChildPublic,thirdChildChain] = generatingChild(secondChildPrivate,secondChildPublic,secondChildChain,'80000000','private');
// Fourth Level: m/H'/0'/0'/0 - For main receiving addresses:
const [fourthChildPrivate,fourthChildPublic,fourthChildChain] = generatingChild(thirdChildPrivate,thirdChildPublic,thirdChildChain,'00000000','public');
// Fifth Level: This level will be used for addresses
// We will generate 10 addresses from m/H'/0'/0'/0/0 to m/H'/0'/0'/0/9 branch to be used as receiving addresses
let addresses = [];
const privateKeys = [];
for (let i=0;i<10;i++) {
const childSet = generatingChild(fourthChildPrivate,fourthChildPublic,fourthChildChain,'0000000'+i,'public');
addresses.push(childSet[1]); //Pushing Public Key in the Array
privateKeys.push(childSet[0]); //Pushing Private Key in the Array
}
return {
addresses,
privateKeys
}
}
//Function to generate child private key, child public key and child chain code
function generatingChild(parentPrivateKey, parentPublicKey, parentChainCode,index,type) {
let parentPrivate = parentPrivateKey.length === 64 ? parentPrivateKey : '0'.repeat(64-parentPrivateKey.length)+parentPrivateKey;
const keyToUse = type === 'private' ? '00'+parentPrivate : parentPublicKey; //Use private key if hardened-index else public key
const hmacHash = CryptoJS.HmacSHA512(CryptoJS.enc.Hex.parse(keyToUse+index),CryptoJS.enc.Hex.parse(parentChainCode)).toString();
const [leftBits,childChainCode] = separateKeyChain(hmacHash);
const N = '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'; //As defined in secp256k1 ecc
let childPrivateKey = (BigInt('0x'+parentPrivate) + BigInt('0x'+leftBits)) % BigInt(N);
childPrivateKey = childPrivateKey.toString(16); //Converting from decimal to hex
const childPublicKey = generatePublicKey(childPrivateKey); //Using ECC function taken from 'ecc.js' file
return [childPrivateKey,childPublicKey,childChainCode];
}
//Function to be used in generatingChild function to separate hash into private key and chain code
function separateKeyChain(hmacHash) {
const privateKeyPart = hmacHash.substr(0,64);
const chainCodePart = hmacHash.substr(64,64);
return [privateKeyPart,chainCodePart];
}
Bitcoin Addresses from Mnemonic Code
Deriving Bitcoin Address from Seed Phrase (Mnemonic Seed)
OR
Enter your Seed:
//This function will generate P2SH bitcoin address (P2WPKH-in-P2SH) using public key
const generateBech32Address = (publicKey) => {
const bech32schema = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
const keyHex = CryptoJS.enc.Hex.parse(publicKey);
const ripeHash = CryptoJS.RIPEMD160(CryptoJS.SHA256(keyHex)).toString();
let binString = BigInt('0x'+ripeHash).toString(2);
binString = binString.length === 160 ? binString : '0'.repeat(160-binString.length)+binString;
const decArray = binString.match(/.{1,5}/g).map(binary => parseInt(binary,2));
decArray.unshift(0);
const checkSum = createChecksum(decArray);
const hexString = decArray.map(decimal => ('00'+decimal.toString(16)).substr(-2)).join('');
let address = '';
(hexString+checkSum).match(/.{1,2}/g).forEach(hexVal => {
address += bech32schema[parseInt(hexVal,16)];
});
return 'bc1'+address;
}
//Checksum generation using BCH Codes
function createChecksum(decArr) {
const GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
let chk = 1
let decArray = [3,3,0,2,3].concat(decArr)
decArray = decArray.concat([0,0,0,0,0,0]);
decArray.forEach(dec => {
let b = chk >> 25;
chk = (chk & 0x1ffffff) << 5 ^ dec;
for (let i=0;i<5;i++) {
chk ^= ((b >> i) & 1) ? GEN[i] : 0;
}
});
const polymod = chk ^ 1;
const returnVal = [];
for (let v=0;v<6;v++) {
returnVal.push((polymod >> 5 * (5 - v)) & 31)
}
return returnVal.map(val => ('00'+val.toString(16)).substr(-2)).join('');
}
Master Private Key = a0ccf14c939faa07b896cd5fb306a37fb3f9cb041196c5364d0cca9dbd82e53a (взято из раздела 5)
Index = 8000002c (= 2147483692 т.e. 2^31+44 в шестнадцатиричной системе)
Chain Code = 5bc9d1368631ae579f02ed8e46a56dd9dd9de8ac59e3c4e18247ff96988bdf1f (взято из раздела 5)
Итак,
Message = 00a0ccf14c939faa07b896cd5fb306a37fb3f9cb041196c5364d0cca9dbd82e53a8000002c
(00, т.е. 8 пустых бит в начале добавлено из-за требования получения сообщения –Message- размером в 296 бит. Поскольку размер секретного мастер ключа составляет 256 бит, а индекса –Index- 32 бита, потребовалось дополнительные 8 бит)
Key = 5bc9d1368631ae579f02ed8e46a56dd9dd9de8ac59e3c4e18247ff96988bdf1f
HMAC(message, key) = 7fc9ce32a6aeffbeaf5057f266f0d6ed6383ed84f21c96d53c0c1e3838a87e2481d4b120fcd3a11837e5d035fc508bb8b31c47285fdd7506d8d264144b4d8df7
Left 256 bits = 7fc9ce32a6aeffbeaf5057f266f0d6ed6383ed84f21c96d53c0c1e3838a87e24
Parent Private Key = a0ccf14c939faa07b896cd5fb306a37fb3f9cb041196c5364d0cca9dbd82e53a
N = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 (это и есть n)
Private Key of 45th Hardened Child of Master Private Key = ( Left 256 bits + Parent Private Key ) % N
Private Key of 45th Hardened Child of Master Private Key = 2096bf7f3a4ea9c667e7255219f77a6e5ccedba2546abbcfc9468a4925f5221d
Chain Code of 45th Hardened Child of Master Private Key = 81d4b120fcd3a11837e5d035fc508bb8b31c47285fdd7506d8d264144b4d8df7 (right 256 bits)
Private Key = 2096bf7f3a4ea9c667e7255219f77a6e5ccedba2546abbcfc9468a4925f5221d
Index = 80000000 (value of 2147483648 i.e. 2^31 in hexadecimal)
Chain Code = 81d4b120fcd3a11837e5d035fc508bb8b31c47285fdd7506d8d264144b4d8df7
So,
Message = 002096bf7f3a4ea9c667e7255219f77a6e5ccedba2546abbcfc9468a4925f5221d80000000
Key = 81d4b120fcd3a11837e5d035fc508bb8b31c47285fdd7506d8d264144b4d8df7
HMAC(message, key) = dee4c4cb625b27f231194cf3befea6e67a73122f77a748b987fded5333ca63f7d665636fd64693411687f8d4deeb8382d14deb3d9937e72635e77af48c4da4e6
Left 256 bits = dee4c4cb625b27f231194cf3befea6e67a73122f77a748b987fded5333ca63f7
Parent Private Key = 2096bf7f3a4ea9c667e7255219f77a6e5ccedba2546abbcfc9468a4925f5221d
N = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 (n as defined)
Private Key of first hardened child of Level 1 Child = ( Left 256 bits + Parent Private Key ) % N
Private Key of first hardened child of Level 1 Child = ff7b844a9ca9d1b899007245d8f62154d741edd1cc1204895144779c59bf8614
Chain Code of first hardened child of Level 1 Child: d665636fd64693411687f8d4deeb8382d14deb3d9937e72635e77af48c4da4e6
Private Key = ff7b844a9ca9d1b899007245d8f62154d741edd1cc1204895144779c59bf8614
Index = 80000000 (value of 2147483648 i.e. 2^31 in hexadecimal)
Chain Code = d665636fd64693411687f8d4deeb8382d14deb3d9937e72635e77af48c4da4e6
So,
Message = 00ff7b844a9ca9d1b899007245d8f62154d741edd1cc1204895144779c59bf861480000000
Key = d665636fd64693411687f8d4deeb8382d14deb3d9937e72635e77af48c4da4e6
HMAC(message, key) = 2839a8f276409794544cdc9f4d2748a3ea3ca988b64f82e72414d67dedaf751bfb106a1896e38ddc80b3d3b4fdaba9b003d1e6caa08c6cbbdc5d63fa6836b613
Left 256 bits = 2839a8f276409794544cdc9f4d2748a3ea3ca988b64f82e72414d67dedaf751b
Parent Private Key = ff7b844a9ca9d1b899007245d8f62154d741edd1cc1204895144779c59bf8614
N = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 (n as defined)
Private Key of first hardened child of Level 2 Child = ( Left 256 bits + Parent Private Key ) % N
Private Key of first hardened child of Level 2 Child = 27b52d3d12ea694ced4d4ee5261d69fa06cfba73d318e734b586ef8d7738b9ee
Chain Code of first hardened child of Level 2 Child: fb106a1896e38ddc80b3d3b4fdaba9b003d1e6caa08c6cbbdc5d63fa6836b613
Private Key = 27b52d3d12ea694ced4d4ee5261d69fa06cfba73d318e734b586ef8d7738b9ee
Public Key = 03fc371a6939557697a438cca5c81fc899d611d41f605d1b6d1a8096fd5e3e0343 (using ECC)
Index = 00000000 (value of 0 in hexadecimal)
Chain Code = fb106a1896e38ddc80b3d3b4fdaba9b003d1e6caa08c6cbbdc5d63fa6836b613
So,
Message = 03fc371a6939557697a438cca5c81fc899d611d41f605d1b6d1a8096fd5e3e034300000000
(Since we are using Public Key which is already of 264 bits, we needn't concat additional bits in the starting)
Key = fb106a1896e38ddc80b3d3b4fdaba9b003d1e6caa08c6cbbdc5d63fa6836b613
HMAC(message, key) = bd63f3fe2daf72bd61d983477a8330e377ecc1fa664bee4a90da90003de9ef8c29a2907541b35ab602c72d52c330184a2e7908060b98acca9b17ebfaea0135a8
Left 256 bits = bd63f3fe2daf72bd61d983477a8330e377ecc1fa664bee4a90da90003de9ef8c
Parent Private Key = 27b52d3d12ea694ced4d4ee5261d69fa06cfba73d318e734b586ef8d7738b9ee
N = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 (n as defined)
Private Key of first normal child of Level 3 Child = ( Left 256 bits + Parent Private Key ) % N
Private Key of first normal child of Level 3 Child = e519213b4099dc0a4f26d22ca0a09add7ebc7c6e3964d57f46617f8db522a97a
Chain Code of first hardened child of Level 3 Child: 29a2907541b35ab602c72d52c330184a2e7908060b98acca9b17ebfaea0135a8
Private Key = e519213b4099dc0a4f26d22ca0a09add7ebc7c6e3964d57f46617f8db522a97a
Public Key = 0321bd38eb2f97c56762b82f22e9677d6aa205a73664b93aaf8ed087bd9fc26420 (using ECC)
Index = 00000000, 00000001 and 00000002
Chain Code = 29a2907541b35ab602c72d52c330184a2e7908060b98acca9b17ebfaea0135a8
So,
Message1 = 0321bd38eb2f97c56762b82f22e9677d6aa205a73664b93aaf8ed087bd9fc2642000000000
Message2 = 0321bd38eb2f97c56762b82f22e9677d6aa205a73664b93aaf8ed087bd9fc2642000000001
Message3 = 0321bd38eb2f97c56762b82f22e9677d6aa205a73664b93aaf8ed087bd9fc2642000000002
Key = 29a2907541b35ab602c72d52c330184a2e7908060b98acca9b17ebfaea0135a8
HMAC(message1, key) = a8764acda4ebc575ff750e113353a805186febf32372deb4fab9ed180a7b4db3a3e1295ec9c664d73d77841b263d019306d914e431fdc84973cf53abaa0883cb
HMAC(message2, key) = fb58f1f53183d06aed97ba85ad30fc89d4500bb3c5d47880cc96c368f044618743a1580a9757af12b8597450ff8a5b37e9a51660b0a30e672b736464f4cdb7d0
HMAC(message3, key) = b30db2ea8ad0e61c43acf2052ecc0d3c174cf5a57655ba038ba8894f3bc2f0d8c140e5f51589c16e3d3502b08fc005e8a9acfa5a56dda2e08b520b3179c1f163
Left 256 bits of HMAC1 = a8764acda4ebc575ff750e113353a805186febf32372deb4fab9ed180a7b4db3
Left 256 bits of HMAC2 = fb58f1f53183d06aed97ba85ad30fc89d4500bb3c5d47880cc96c368f0446187
Left 256 bits of HMAC3 = b30db2ea8ad0e61c43acf2052ecc0d3c174cf5a57655ba038ba8894f3bc2f0d8
Parent Private Key = e519213b4099dc0a4f26d22ca0a09add7ebc7c6e3964d57f46617f8db522a97a
N = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 (n as defined)
Private Key of first normal child of Level 4 Child = 8d8f6c08e585a1804e9be03dd3f442e3dc7d8b7aad8f13f881490e18ef67b5ec (to be used for deriving first bitcoin address)
Private Key of second normal child of Level 4 Child = e0721330721dac753cbe8cb24dd19768985dab3b4ff0adc45325e469d530c9c0 (to be used for deriving second bitcoin address)
Private Key of third normal child of Level 4 Child = 9826d425cb6ac22692d3c431cf6ca81adb5a952d0071ef471237aa5020af5911 (to be used for deriving third bitcoin address)
m / 49' / 0' / 0' / 0 / address_index
Private Key of first normal child of Level 4 Child = 26e1061459e7961eeac018efa765339d785bd30de91f8fade64c639b275d74c4 (to be used for deriving first bitcoin address)
Private Key of second normal child of Level 4 Child = 501a42ccd834bf61c211f5277bcbebe4120eea952efc91fd71125f61a1e7eec4 (to be used for deriving second bitcoin address)
Private Key of third normal child of Level 4 Child = 13ae95a5d643b9ebe355d103679ad4bcf3863efef78873f4e4f20a57cf044a51 (to be used for deriving third bitcoin address)
Public Key of first normal child of Level 4 Child = 021549dd72d89cbc844bb74ab6247239cf60d184cbfb0cfc4d024150a4985412fe (to be used for deriving first bitcoin address)
Public Key of second normal child of Level 4 Child = 02e589abcbdbcf7b9746d1e2f5d97e5d2836c82b5910c5716f094801c0178ecfc2 (to be used for deriving second bitcoin address)
Public Key of third normal child of Level 4 Child = 020711fb2e08e67c13bcfb2cca60ff5ac3b7c6fb9e902722127ef776e5d2db6046 (to be used for deriving third bitcoin address)
SHA-256(public key) = Hash
SHA-256(021549dd72d89cbc844bb74ab6247239cf60d184cbfb0cfc4d024150a4985412fe) = 189a3015638daa02871973bf840b434aad92cb71775b65680acd266b81e85e3f
RIPEMD160(hash) = Hash160
RIPEMD160(189a3015638daa02871973bf840b434aad92cb71775b65680acd266b81e85e3f) = 2bf545ff88c159408f5ba759f99e78566763fe1a
serialization = 0x0014 + Hash160
serialization = 00142bf545ff88c159408f5ba759f99e78566763fe1a
SHA-256(script) = Hash
SHA-256(00142bf545ff88c159408f5ba759f99e78566763fe1a) = c2d24e021347966656ed4b0312f9b3a49498c257294bd75e9bc84ba8353deb9a
Then,
RIPEMD160(hash) = Hash160
RIPEMD160(c2d24e021347966656ed4b0312f9b3a49498c257294bd75e9bc84ba8353deb9a) = 2d7193893e4143fc11bb69c7f004452198bdf6cd
serialization = 0x05 + Hash160
serialization = 052d7193893e4143fc11bb69c7f004452198bdf6cd
checksum = first four bytes of SHA-256(SHA-256(hash))
SHA256(SHA256(052d7193893e4143fc11bb69c7f004452198bdf6cd)) = dcd3b30cd36dcef8265fbe414e435fc7841ced941f93ef86afd86e344c4a700e
First four bytes = dcd3b30c
final serialization = 052d7193893e4143fc11bb69c7f004452198bdf6cddcd3b30c
Base58(052d7193893e4143fc11bb69c7f004452198bdf6cddcd3b30c) = 35qJPbZX23wt3uuB9nz4pxhoouUfG28zxB
First four bytes = dcd3b30c
mushroom orange black valve erase brother submit biology tortoise debate arrive slim
DK = PBKDF2(PRF, Password, Salt, c, dkLen)
Или с конкретными значениями, взятыми для PRF, Password, Salt, c and dkLen:
DK = PBKDF2(HMAC, 'mushroom orange black valve erase brother submit biology tortoise debate arrive slim', 'mnemonic', 2048, 64)
65729d81d461591bac7384dea43dbd44438053cd1fdc113e0769c49c5fde025ba331eed2077497634e619948437d0448e769a86c0cbbecf01b13fd53540743b3
a0ccf14c939faa07b896cd5fb306a37fb3f9cb041196c5364d0cca9dbd82e53a5bc9d1368631ae579f02ed8e46a56dd9dd9de8ac59e3c4e18247ff96988bdf1f
Master Private Key: a0ccf14c939faa07b896cd5fb306a37fb3f9cb041196c5364d0cca9dbd82e53a
Chain Code: 5bc9d1368631ae579f02ed8e46a56dd9dd9de8ac59e3c4e18247ff96988bdf1f
Наш Master Public Key: 03d1cc1f6bdea4d17eb7f2573d676f9ddb087f8b784c912c4466407781d8acfe38
Path format: m / purpose' / coin_type' / account' / change / address_index
Bitcoin Main-net format: m / 44' / 0' / 0' / 0 / address_index
......................................................................../............ | . |
Pages:
Jump to:
|