学习区块链之记录
前言,请自行安装最新 nodejs 环境
安装所需依赖
1 2 3 4 5 6 7 | npm i bitcoinjs-lib npm i create-hash npm i bip32 npm install ecpair tiny-secp256k1 |
生成私钥、公钥、WIF、地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | const bitcoin = require( 'bitcoinjs-lib' ); // bitcoin -> mainnet, testnet -> testnet const TestNet=bitcoin.networks.bitcoin; const createHash = require( 'create-hash' ); const { ECPairFactory } = require( 'ecpair' ); const crypto = require( 'crypto' ); // 导入tiny-secp256k1库,它提供了必要的椭圆曲线加密功能 const tinysecp = require( 'tiny-secp256k1' ); //WIF编码 const wif=require( 'wif' ); // 使用ECPairFactory创建ECPair API,传入tinysecp作为ECC库 const ECPair = ECPairFactory(tinysecp); let keyPair=ECPair.makeRandom({network:TestNet}); //16进制表示的私钥和公钥 var private_key=keyPair.privateKey.toString( 'hex' ); var public_key=keyPair.publicKey.toString( 'hex' ); console.log( 'pri_key = ' +private_key); console.log( 'pub_key = ' +public_key); var encoded=wif.encode(0x80,Buffer.from(private_key, 'hex' ), false ); console.log( 'WIF编码 = ' +encoded); //利用公钥生成地址 const { address }=bitcoin.payments.p2pkh({pubkey:keyPair.publicKey}); console.log( 'address = ' +address); |
以上代码可能有点杂乱,看到一篇在 quicknode 的文档,比较规范 https://www.quicknode.com/guides/other-chains/bitcoin/how-to-create-a-bitcoin-address-using-bitcoinlibjs
找到有效 nonce 的过程确实可能很快,也可能很慢,这完全取决于运气。这种不可预测性是比特币工作量证明(Proof of Work)机制的核心,它确保了网络的安全性和去中心化特性。在实际的比特币网络中,由于难度极高,即使使用最先进的专用硬件,平均也需要大量的尝试才能找到有效的 nonce。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | const bitcoin = require( 'bitcoinjs-lib' ); const ECPairFactory = require( 'ecpair' ). default ; const ecc = require( 'tiny-secp256k1' ); const fs = require( 'fs' ); const ECPair = ECPairFactory(ecc); const network = bitcoin.networks.testnet; // Otherwise, bitcoin = mainnet and regnet = local async function createP2PKHwallet() { try { const keyPair = ECPair.makeRandom({ network: network }); const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: network, //这里是network,不填写该参数则默认为主网 }); const privateKey = keyPair.toWIF() console.log(`| Public Address | ${address} |`) console.log(`| Private Key | ${privateKey} |`) const wallet = { address: address, privateKey: privateKey }; const walletJSON = JSON.stringify(wallet, null , 4); fs.writeFileSync( 'wallet.json' , walletJSON); console.log(`Wallet created and saved to wallet.json`); } catch (error) { console.log(error) } } createP2PKHwallet(); |
在这里说下,如果你想使用更少的代码来生成这些信息,你可以使用 http://cryptocoinjs.com/guide/getting-started/
安装
npm i coinkey
使用
1 2 3 4 5 6 7 | var CoinKey = require( 'coinkey' ) //1.0.0 var ck = new CoinKey.createRandom() console.log( "Private Key (Wallet Import Format): " + ck.privateWif) console.log( "Private Key (Hex): " + ck.privateKey.toString( 'hex' )) console.log( "Address: " + ck.publicAddress) |
接下来是一个矿工接收到新的区块开始开始尝试计算出有效的 nonce 值的代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | const crypto = require( 'crypto' ); class Block { constructor(previousHash, transactions, timestamp) { this .previousHash = previousHash; this .transactions = transactions; this .timestamp = timestamp; this .nonce = 0; this .merkleRoot = this .calculateMerkleRoot(); } calculateMerkleRoot() { // 简化的 Merkle root 计算 return crypto.createHash( 'sha256' ).update( this .transactions.join( '' )).digest( 'hex' ); } calculateHash() { const blockHeader = this .previousHash + this .merkleRoot + this .timestamp + this .nonce; return crypto.createHash( 'sha256' ).update(blockHeader).digest( 'hex' ); } } class Miner { constructor() { this .currentTransactions = []; this .difficulty = 4; // 目标难度:哈希前4位必须为0 } receiveNewBlock(newBlock) { console.log(`收到新区块,哈希值: ${newBlock.calculateHash()}`); this .previousBlockHash = newBlock.calculateHash(); this .currentTransactions = []; // 重置当前交易池 } addTransaction(transaction) { this .currentTransactions.push(transaction); } mineBlock() { const timestamp = Math.floor(Date.now() / 1000); const newBlock = new Block( this .previousBlockHash, this .currentTransactions, timestamp); console.log( "开始挖矿..." ); const startTime = Date.now(); while ( true ) { const blockHash = newBlock.calculateHash(); if (blockHash.startsWith( '0' .repeat( this .difficulty))) { const endTime = Date.now(); console.log(`找到有效的 nonce: ${newBlock.nonce}`); console.log(`新区块哈希: ${blockHash}`); console.log(`挖矿耗时: ${(endTime - startTime) / 1000} 秒`); return newBlock; } newBlock.nonce++; } } } // 使用示例 const miner = new Miner(); // 模拟接收新区块 const previousBlock = new Block( "00000000000000" , [ "transaction1" , "transaction2" ], 1623456789); miner.receiveNewBlock(previousBlock); // 添加一些新交易 miner.addTransaction( "Alice支付Bob 1 BTC" ); miner.addTransaction( "Charlie支付David 0.5 BTC" ); // 开始挖矿 const minedBlock = miner.mineBlock(); console.log( "挖矿完成!新区块信息:" ); console.log(JSON.stringify(minedBlock, null , 2)); |
下面时关于以太坊区块链,先说一下和比特币两个的区别
以太坊和比特币作为两个最知名的区块链项目,有许多显著的区别。以下是它们最直观和重要的一些区别:
主要目的:
- 比特币:主要设计为一种去中心化的数字货币系统。
- 以太坊:设计为一个去中心化的应用平台,支持智能合约和去中心化应用(DApps)。
智能合约:
- 比特币:有限的脚本支持,主要用于简单的交易逻辑。
- 以太坊:完全支持图灵完备的智能合约,允许复杂的程序逻辑。
代币创建:
- 比特币:主要只有比特币一种原生代币。
- 以太坊:允许轻松创建和部署新的代币(如ERC-20代币)。
交易速度:
- 比特币:平均每10分钟生成一个新区块。
- 以太坊:平均每12-14秒生成一个新区块。
挖矿算法:
- 比特币:使用SHA-256算法。
- 以太坊:目前使用Ethash算法,但正在向权益证明(PoS)过渡。
总供应量:
- 比特币:固定上限2100万个。
- 以太坊:没有固定上限,但有通胀控制机制。
编程语言:
- 比特币:使用一种简单的脚本语言。
- 以太坊:使用Solidity等高级编程语言来编写智能合约。
账户系统:
- 比特币:使用UTXO(未花费交易输出)模型。
- 以太坊:使用账户余额模型。
区块大小:
- 比特币:有固定的区块大小限制。
- 以太坊:使用燃料(Gas)机制来限制区块容量。
应用生态系统:
- 比特币:主要聚焦于支付和价值存储。
- 以太坊:拥有丰富的DApp生态系统,包括DeFi、NFT等。
共识机制发展:
- 比特币:保持工作量证明(PoW)。
- 以太坊:正在从PoW过渡到PoS(以太坊2.0)。
代码更新频率:
- 比特币:相对保守,更新较少。
- 以太坊:更频繁地进行协议升级和改进。
货币单位:
- 比特币:使用BTC,最小单位是聪(Satoshi)。
- 以太坊:使用ETH,最小单位是Wei。
下面演示生成私钥、公钥、钱包地址,当然有更简单的库 https://www.quicknode.com/guides/ethereum-development/wallets/how-to-generate-a-new-ethereum-address-in-javascript
npm i randombytes
npm i ethereumjs-util
const randomBytes = require('randombytes'); ethUtil = require('ethereumjs-util'); // 生成256bit的随机数作为私钥: let priKey = randomBytes(32).toString('hex'); // 计算公钥(非压缩格式): let pubKey = ethUtil.privateToPublic(Buffer.from(priKey, 'hex')).toString('hex'); // 计算地址: let addr = ethUtil.pubToAddress(Buffer.from(pubKey, 'hex')).toString('hex'); console.log('Private key: 0x' + priKey); console.log('Public key: 0x' + pubKey); console.log('Address: 0x' + addr);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具