区块链-以太坊开发教程02-nodejs开发区块链钱包(带助记词)

一、创建一个新的项目
新建一个Express 框架的项目
区块链-以太坊开发教程02-nodejs开发区块链钱包(带助记词)_第1张图片
区块链-以太坊开发教程02-nodejs开发区块链钱包(带助记词)_第2张图片
二、安装web3
在此附上,web3 在github的地址:

https://github.com/ethereum/web3.js/tree/2.x

执行安装web3

[root@192 node]# cd jiaocheng			#node.js项目根目录

[root@192 jiaocheng]# npm install web3

三、引入现有的库

[root@192 jiaocheng]# npm install bip39 ethereumjs-wallet ethereumjs-util ethers ethereumjs-tx --save
var Web3 = require('web3');
var bip39 = require('bip39');
var hdkey = require('ethereumjs-wallet/hdkey');
var util = require('ethereumjs-util');
var ethers = require('ethers');
var EthereumTx = require('ethereumjs-tx').Transaction;

四、创建带助记词的钱包

if(req.query.fn === "walletNew"){   //创建钱包
        //1、生成助记词
        let mnemonic = bip39.generateMnemonic();
        //2、将助记词转成seed
        let seed = bip39.mnemonicToSeedSync(mnemonic);
        //3、通过hdkey 将seed生成HD Wallet
        let hdWallet = hdkey.fromMasterSeed(seed);
        //4、生成钱包中在m/44'/60'/0'/0/0路径的keypair
        let key = hdWallet.derivePath("m/44'/60'/0'/0/0");
        //5、从keypair中获取私钥
        let privateKey = util.bufferToHex(key._hdkey._privateKey);
        //6、从keypair中获取公钥
        let publicKey = util.bufferToHex(key._hdkey._publicKey);
        //7、使用keypair中的公钥生成地址
        let address = util.pubToAddress(publicKey,true);
        address = util.toChecksumAddress(address.toString('hex'));
        //8、生成keystore
        let keystore = web3.eth.accounts.encrypt(privateKey,req.query.password);
        res.json({
            code: 1,
            message: 'OK',
            data:{
                mnemonic:mnemonic,
                privateKey:privateKey,
                publicKey:publicKey,
                address:address,
                keystore:keystore,
                user_id:req.query.user_id
        }});

五、助记词方式导入钱包

if(req.query.type === "mnemonic") {     //助记词方式导入
            //2、将助记词转成seed
            let seed = bip39.mnemonicToSeedSync(req.query.mnemonic);
            //3、通过hdkey 将seed生成HD Wallet
            let hdWallet = hdkey.fromMasterSeed(seed);
            //4、生成钱包中在m/44'/60'/0'/0/0路径的keypair
            let key = hdWallet.derivePath("m/44'/60'/0'/0/0");
            //5、从keypair中获取私钥
            let privateKey = util.bufferToHex(key._hdkey._privateKey);
            //6、从keypair中获取公钥
            let publicKey = util.bufferToHex(key._hdkey._publicKey);
            //7、使用keypair中的公钥生成地址
            let address = util.pubToAddress(publicKey, true);
            address = util.toChecksumAddress(address.toString('hex'));
            //8、生成keystore
            let keystore = web3.eth.accounts.encrypt(privateKey, req.query.password);
            res.json({
                code: 1,
                message: 'OK',
                data: {
                    mnemonic: req.query.mnemonic,
                    privateKey: privateKey,
                    publicKey: publicKey,
                    address: address,
                    keystore: keystore,
                    user_id: req.query.user_id
                }
            });

六、私钥方式导入钱包

else if(req.query.type === "privateKey"){  //私钥方式导入
            //获取钱包对象
            wallet = new ethers.Wallet(req.query.privateKey);
            //生成keystore
            let keystore = web3.eth.accounts.encrypt(req.query.privateKey, req.query.password);
            res.json({
                code: 1,
                message: 'OK',
                data: {
                    privateKey: wallet.signingKey.keyPair.privateKey,
                    publicKey: wallet.signingKey.keyPair.compressedPublicKey,
                    address: wallet.signingKey.address,
                    keystore: keystore,
                    user_id: req.query.user_id
                }
            });

七、store对象方式导入钱包

else if(req.query.type === "keystore"){    //store对象方式导入
            wallet = web3.eth.accounts.decrypt(req.query.keystore,req.query.password);
            wallet = new ethers.Wallet(wallet.privateKey);
            res.json({
                code: 1,
                message: 'OK',
                data: {
                    privateKey: wallet.signingKey.keyPair.privateKey,
                    publicKey: wallet.signingKey.keyPair.compressedPublicKey,
                    address: wallet.signingKey.address,
                    keystore: req.query.keystore,
                    user_id: req.query.user_id
                }
            });

八、获取指定类型的余额

else if(req.query.fn === "getBalance"){    //获取指定类型的余额
        if(req.query.type === "ETH"){
            web3.eth.getBalance(req.query.address).then(function(balance){
                res.json({
                    code: 1,
                    message: 'OK',
                    data: {balance: web3.utils.fromWei(balance,'ether')}
                });
            });
        }else if(req.query.type === "SEA"){
            let abi = JSON.parse(fs.readFileSync('./routes/seaToken.abi','utf8'));
            con = new web3.eth.Contract(abi,conaddress);
            con.methods.getBalance().call({from: req.query.address}).then(function(balance){
                res.json({
                    code: 1,
                    message: 'OK',
                    data: {balance: web3.utils.fromWei(balance,'mwei')}
                });
            });

九、ETH链上转账操作

if(req.query.type === "ETH"){
            //先做交易签名
            //先获取当前付款账号的交易数量(nonce)
            web3.eth.getTransactionCount(req.query.address_from,web3.eth.defaultBlock.pending).then(function(nonce){
                //将私钥,转换为16进制
                let privateKey = Buffer.from(req.query.privateKey.substr(2),'hex');
                //设置交易数据
                let txData = {
                    // nonce每次++,以免覆盖之前pending中的交易
                    nonce: web3.utils.toHex(nonce++),
                    // 设置gasLimit和gasPrice
                    gasLimit: web3.utils.toHex(req.query.gas),
                    gasPrice: web3.utils.toHex(web3.utils.toWei(req.query.gasprice,'ether')),
                    // 要转账的哪个账号
                    to: req.query.address_to,
                    // 从哪个账号转
                    from: req.query.address_from,
                    // 以太币转账金额
                    value: web3.utils.toHex(web3.utils.toWei(req.query.money,'ether')),
                    data: ''
                }
                const tx = new EthereumTx(txData);
                //用私钥签署交易
                tx.sign(privateKey);
                //序列化
                const serializedTx = tx.serialize().toString('hex');
                //发送已签名交易
                web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'),function(error,hash){
                   if(!error){
                       res.json({
                           code: 1,
                           message: 'OK',
                           data: {hash: hash}
                       });
                   } else{
                       res.json({
                           code: -2,
                           message: error,
                           data: {}
                       });
                   }
                });
            });

十、代币链上发送交易操作

else if(req.query.type === "SEA"){
            //web.eth方法
           // 补齐64位,不够前面用0补齐
            function addPreZero(num){
                var t = (num+'').length,
                    s = '';
                for(var i=0; i<64-t; i++){
                    s += '0';
                }
                return s+num;
            }
            web3.eth.getTransactionCount(req.query.address_from, web3.eth.defaultBlock.pending).then(function(nonce){
                //将私钥,转换为16进制
                //let privateKey = Buffer.from(req.query.privateKey.substr(2),'hex');   //扣除用户eth
                let privateKey = Buffer.from("调用者私钥",'hex');   //扣除平台eth
                //设置交易数据
                let txData = {
                    // nonce每次++,以免覆盖之前pending中的交易
                    nonce: web3.utils.toHex(nonce++),
                    // 设置gasLimit和gasPrice
                    gasLimit: web3.utils.toHex(req.query.gas),
                    gasPrice: web3.utils.toHex(web3.utils.toWei(req.query.gasprice,'ether')),
                    // 这里是代币合约地址
                    to: conaddress,
                    // 从哪个账号转
                    from: req.query.address_from,
                    // 以太币转账金额
                    value: '0x00',
                    // data的组成,由:0x + 要调用的合约方法的function signature + 要传递的方法参数,每个参数都为64位(对transfer来说,第一个是接收人的地址去掉0x,第二个是代币数量的16进制表示,去掉前面0x,然后补齐为64位)
                    data: '0xa5cfc11f' + addPreZero(req.query.address_from.substr(2)) +addPreZero(req.query.address_to.substr(2))+ addPreZero(web3.utils.toHex(web3.utils.toWei(req.query.money,'mwei')).substr(2))
                }
                const tx = new EthereumTx(txData);
                //用私钥签署交易
                tx.sign(privateKey);
                //序列化
                const serializedTx = tx.serialize().toString('hex');
                //发送已签名交易
                web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'),function(error,hash){
                    if(!error){
                        res.json({
                            code: 1,
                            message: 'OK',
                            data: {hash: hash}
                        });
                    }else{
                        res.json({
                            code: -2,
                            message: error.toString(),
                            data: {}
                        });
                    }
                });
            });

你可能感兴趣的:(以太坊)