On the digital wallet

Block chain recently swept the Internet industry, but also a special understanding of the relevant personal technology, but also bought a digital currency, of course, there is a digital wallet. Been thinking about this to the center of the wallet, in the end it safe, the principle is Gesha:

  • Our wallet password (private key) purse or other information, whether transmission in the network?
  • The major trading platforms, I buy digital currency Where children?
  • Block chain wallet in the end there is no user information?

With these questions, we need to look at the digital wallet in the end is the Editor? To find out some concepts:

  • encryption
  • Symmetric encryption
  • Asymmetric encryption
    • Public, private
  • signature
    • Check test

& Encrypted symmetric encryption & asymmetric encryption

Cryptography technology is one of the core technologies in the block chain, wallet generated by the encryption algorithm is done, of course, if encryption technology to tell me this is not professional people who can not talk very clear, but we from it the function probably look up concepts.

Popular talk:

  • Encryption: things (information) with a key lock in the box, only to get the key people who can use this stuff (see information);
  • Symmetric encryption: key off the box opening the box and if the same;
  • Asymmetric encryption: key off box and open the box is not the same;

Professional speaking:

  • Encryption: changing a plaintext into ciphertext content difficult to read, making it unreadable. Only the owner of the object decryption method, via the decryption process in order to restore the normal ciphertext readable content;
  • Symmetric encryption: when using the same key for encryption and decryption;
  • Asymmetric encryption: two keys required for encryption and decryption, which are public and private keys used to encrypt the data if the public key can only be decrypted with the corresponding private key; private data if encryption, public key can only be decrypted with;

Why use asymmetric encryption, application scenarios where?

Its better security: symmetric encryption communicating parties use the same secret key, if one of the keys has been leaked, the entire communication will be cracked. Instead of using a pair of symmetric encryption keys, one for encryption and one for decryption and public key is published, a secret key held by itself, did not like the first synchronization symmetric encryption keys before the communication.

However, asymmetric encryption to encrypt and decrypt the disadvantage that it takes a long time, slow, suitable only for small amounts of data to be encrypted.

signature

In order to let the recipient know the identity of the sender of the message, the use of digital signature technology born.

Digital signature is a data exists in electronic form on the information in, or as a data link on its accessories or logic, data can be used to identify the signer's identity and the name of the table for people to sign information contained in the data recognition technology.

  • The signing process:
    • Data generated Abstract: The data to be transmitted to be Hash
    • Generating signature information: a sender's private key to encrypt the summary data
    • It sends the data to be sent to a recipient signature information +
  • Check test procedure:
    • Decrypt signature information: The sender's public key to decrypt the signature information
    • Generates summary data: the received data Hash
    • Comparative data: If the decrypted signature information and the generated summary data is the same as the digital signature can identify the sender

Encryption Algorithm

There are many encryption algorithms: RSA, RC2, RC4, IDEA, RSA, DSA, ADS, MD5, PKCS, ECC, etc., want to know the algorithm of Baidu, the students themselves.

Purse what needs to function?

Purse core functions:

  • Purse initialization
    • create
    • Importing
  • Queries assets wallet
  • transaction
    • Transfer
    • Call contract

Related Js library

  • ethereumjs-util: Tools
    • bn.js: BigNumber Data Type
    • safe-buffer: Buffer binary data type
    • create-hash: Hash algorithm
    • secp256k1: elliptic curve algorithm
    • keccak: SHA-3 algorithm
    • rlp: RLP coding
    • ethjs-util
  • ethereumjs-wallet: create a wallet
  • ethereumjs-tx: transaction information processing, signature, Hash, check, etc.
  • ethereumjs-abi: ABI Processing
  • web3: Square and communication between Ethernet

Create a wallet (private, public, address)

Create a wallet, we can use ethereumjs-walletthe library to complete, it is to create a key pair ECDSA algorithm based on elliptic curves. Look Source:

  • Generating a public key: (ethereumjs-wallet) generate () -> (ethereumjs-util) privateToPublic -> secp256k1.publicKeyCreate -> publicKey
  • 地址生成:(ethereumjs-wallet)generate() -> (ethereumjs-util)privateToAddress -> (ethereumjs-util)sha3 -> (keccakjs)SHA3 -> address
// ethereumjs-wallet 模块
Wallet.generate = function (icapDirect) {
    if (icapDirect) {
        while (true) {
            var privKey = crypto.randomBytes(32)
            if (ethUtil.privateToAddress(privKey)[0] === 0) {
                return new Wallet(privKey)
            }
        }
    } 
    else {
        return new Wallet(crypto.randomBytes(32))
    }
}

var Wallet = function (priv, pub) {
    //...
}

Object.defineProperty(Wallet.prototype, 'pubKey', {
  get: function () {
    if (!this._pubKey) {
        this._pubKey = ethUtil.privateToPublic(this.privKey)
    }
        return this._pubKey
    }
})

// ethereumjs-util 模块
exports.privateToAddress = function (privateKey) {
    return exports.publicToAddress(privateToPublic(privateKey))
}

var privateToPublic = exports.privateToPublic = function (privateKey) {
    privateKey = exports.toBuffer(privateKey)
    // skip the type flag and use the X, Y points
    return secp256k1.publicKeyCreate(privateKey, false).slice(1)
}

exports.pubToAddress = exports.publicToAddress = function (pubKey, sanitize) {
    pubKey = exports.toBuffer(pubKey)
    if (sanitize && (pubKey.length !== 64)) {
        pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1)
    }
    assert(pubKey.length === 64)
    // Only take the lower 160bits of the hash
    return exports.sha3(pubKey).slice(-20)
}

exports.sha3 = function (a, bytes) {
    a = exports.toBuffer(a)
    if (!bytes) bytes = 256

    var h = new SHA3(bytes)
    if (a) {
        h.update(a)
    }
    return new Buffer(h.digest('hex'), 'hex')
}

Very simple for the user:

Related documents: https://github.com/ethereumjs/ethereumjs-wallet

const ethUtil = require('ethereumjs-util')
const Wallet = require('ethereumjs-wallet');

// 生成钱包
var wallet = Wallet.generate();
var privateKey = wallet.getPrivateKey(); // 返回 Buffer,可以通过 wallet.getPrivateKeyString() 直接得到字符串
var publicKey = wallet.getPublicKey(); // 返回 Buffer,可以通过 wallet.getPublicKeyString() 直接得到字符串
var address = wallet.getAddress(); // 返回 Buffer,可以通过 wallet.getAddressString() 直接得到字符串

// 导入钱包
var privateKey2 = ethUtil.toBuffer('0xe601e598111629240e4dc6ec7a95534e025838bd0f638dabad9ad4152d80443b');
var wallet2 = Wallet.fromPrivateKey(privateKey2);
var publicKey2 = wallet2.getPublicKey();

Queries assets wallet

Queries wallet assets by web3.js very easy to implement:

var balance = web3.eth.getBalance("0x407d73d8a49eeb85d32cf465507dd71d507100c1");
console.log(balance); // instanceof BigNumber
console.log(balance.toString(10)); // '1000000000000'
console.log(balance.toNumber()); // 1000000000000

Purse transaction

Wallet transaction process:

  • Transaction data structure
    • Ethernet currency transactions
    • Contract transaction data
  • Transaction signature
  • Simulated trading, estimate Gas
  • Send transaction

Trading partners

{
    nonce: '0x00',
    gasPrice: '0x01',
    gasLimit: '0x01',
    to: '0x633296baebc20f33ac2e1c1b105d7cd1f6a0718b',
    value: '0x00',
    data: '0xc7ed014952616d6100000000000000000000000000000000000000000000000000000000',
    // EIP 155 chainId - mainnet: 1, ropsten: 3
    chainId: 3
}

Square Ethernet reference document:

  • nonce: The total number of transaction accounts have been executed, the value of the nonce with the implementation of each new transaction increasing
  • gasPrice: per unit of gas you willing to pay the price of the transaction, the price of gas currently GWei units, which range 0.1-> 100 + Gwei
  • gasLimit: You are willing to pay the highest total amount of gas in the transaction. The upper limit can ensure that in the implementation of the transaction occurs (such as an infinite loop), the account you will not run out of funds. Once the transaction is finished, all the remaining gas will be returned to your account
  • to: destination address, if the transaction is a transfer payment address, if the call is a contract is a contract Address
  • value: that is, the total amount you intend Ethernet currency sent. If you want to perform a transfer transaction, send money to another person Ethernet or contract, you will need to set the value value.
  • data: This field will be different transaction types are different, there will be a detailed description of the field in the next presentation
  • chainId: This field is used to indicate the transaction data to be transmitted to which network, a network-based, network 3 ropsten

Construction of data

If the transaction is a contract, it is necessary to build a data field with the contract information. This process is relatively complex, can refer Ethereum Contract ABI divided into two processes:

  • Function call to the contract function names are encoded
  • The contract calls for function parameters are encoded
  • Details omitted ten thousand words ...

Source: https://github.com/ethereumjs/ethereumjs-abi/blob/master/lib/index.js

Very simple for the user

Related documents: https://github.com/ethereumjs/ethereumjs-abi

var abi = require('ethereumjs-abi');

var methodID = abi.methodID('sam', ['bytes', 'bool', 'uint256[]']);
// returns the encoded binary (as a Buffer) data to be sent
var encoded = abi.rawEncode(['bytes', 'bool', 'uint256[]'], ['dave', true, [1, 2, 3]]);

var data = methodID.toString('hex') + rawEncode.toString('hex');
console.log(data);

signature

After a good deal of the data structure, then we will sign the data, and the sequence of the last data can be traded, and continue to look at the source code:

  • Hash:(ethereumjs-tx)hash -> (ethereumjs-util)rlphash -> (rlp)encode -> (keccak)SHA3
  • Signature: (ethereumjs-util) ecsign -> secp256k1.sign
// ethereumjs-tx 模块
Transaction.prototype.sign = function sign(privateKey) {
    var msgHash = this.hash(false);
    var sig = ethUtil.ecsign(msgHash, privateKey);
    if (this._chainId > 0) {
        sig.v += this._chainId * 2 + 8;
    }
    Object.assign(this, sig);
};

Transaction.prototype.hash = function hash(includeSignature) {
    if (includeSignature === undefined) includeSignature = true;

    // EIP155 spec:
    // when computing the hash of a transaction for purposes of signing or recovering,
    // instead of hashing only the first six elements (ie. nonce, gasprice, startgas, to, value, data),
    // hash nine elements, with v replaced by CHAIN_ID, r = 0 and s = 0

    var items = void 0;
    if (includeSignature) {
        items = this.raw;
    } else {
        if (this._chainId > 0) {
            var raw = this.raw.slice();
            this.v = this._chainId;
            this.r = 0;
            this.s = 0;
            items = this.raw;
            this.raw = raw;
        } else {
            items = this.raw.slice(0, 6);
        }
    }

    // create hash
    return ethUtil.rlphash(items);
};

// ethereumjs-util 模块
exports.ecsign = function (msgHash, privateKey) {
    const sig = secp256k1.sign(msgHash, privateKey)

    const ret = {}
    ret.r = sig.signature.slice(0, 32)
    ret.s = sig.signature.slice(32, 64)
    ret.v = sig.recovery + 27
    return ret
}

Also very simple for the user

Related documents: https://github.com/ethereumjs/ethereumjs-tx

const EthereumTx = require('ethereumjs-tx');

var privateKey = ...;
var txParams = {
    nonce: '0x00',
    gasPrice: '0x09184e72a000', 
    gasLimit: '0x2710',
    to: '0x0000000000000000000000000000000000000000', 
    value: '0x00', 
    data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057',
    // EIP 155 chainId - mainnet: 1, ropsten: 3
    chainId: 3
};

var tx = new EthereumTx(txParams);
tx.sign(privateKey);

var serializedTx = tx.serialize(); // 这是最终交易需要发送的数据

Gas estimates

Require the signature of the transaction, it is necessary to estimate the cost of Gas, Gas unreasonable if to a transaction will not be sent successfully. We can estimate a relatively reasonable Gas by Web3, so that trading can proceed smoothly.

var transactionObject = {
    nonce: '',
    gasPrice: '',
    from: '',
    to: '',
    value: '',
    data: '',
}

web3.eth.estimateGas(transactionObject, function(err, res) {
    if (!err)
        console.log(res);
});

Send transaction

We used to send trade agreement web3 is very easy to get:

  • It does not require the signature of the transaction: web3.eth.sendTransaction
  • Require the signature of the transaction: web3.eth.sendRawTransaction
var transactionObject = {
    nonce: '',
    gasPrice: '',
    gasLimit: '',
    from: '',
    to: '',
    value: '',
    data: '',
}

web3.eth.sendTransaction(transactionObject, function(err, address) {
    if (!err)
        console.log(address);
});

or

// ...
// 32字节的16进制格式的交易哈希串
web3.eth.sendRawTransaction(serializedTx.toString('hex'), function(err, hash) {
    if (!err)
        console.log(hash);
});

Wallet transaction process

1304324-59b59b1a38626d45.jpg
Flowchart

回顾一下钱包的核心功能:

  • 钱包初始化:
    • 创建:ethereumjs-wallet.generate()
    • 导入:ethereumjs-wallet.fromPrivateKey(privateKey)
  • 查询钱包的资产:web3.eth.getBalance(addressHexString [, defaultBlock] [, callback])
  • 交易:
    • 构造交易数据:
      • 交易对象:{ from: '', to: '', ...}
      • data:ethereumjs-abi.methodID() + ethereumjs-abi.rawEncode()
    • 交易签名:ethereumjs-tx.sign(privateKey) -> ethereumjs-tx.serialize()
    • 发送交易:
      • 转账:web3.eth.sendTransaction(transactionObject [, callback])
      • 合约(已经签名的交易):web3.eth.sendRawTransaction(signedTransactionData [, callback])

有了以上几个核心方法,你就可以完成数字钱包应用了。

钱包核心 SDK 的封装

为了简化以上的操作,并且让钱包具有更好的扩展性(支持以太币、比特币等),我们将上面的整过过程进行一次封装,让开发人员更好的使用,我们做成了 trip-wallet

Install

yarn add trip-wallet
Or
npm install trip-wallet

Usage

import Wallet from 'trip-wallet';

let wallet = Wallet('eth');
wallet.generate();
wallet.setProvider('http://host:port');

// async/await
let balance = await wallet.getBalance(wallet.address);

// Promise
wallet.getBalance(wallet.address).then(res => {
    balance = res;
}, err => {

});

Object & Attributes

  • walletObject
    • privateKey: String (hex string)
    • publicKey: String (hex string)
    • address: String (hex string)
    • currency: String
  • transactionObject
    • contract: Object
    • methodName: String
    • arguments: Array[]
    • privateKey: String (hex string)
    • from: String (hex string)
    • to: String (hex string)
    • value: Number | String | BigNumber
    • gasLimit: Number | String | BigNumber
    • gasPrice: Number | String | BigNumber
    • data: String
    • none: Number

Methods

  • generate([currency]): Object
  • import(key [, type] [, currency]): Object
    • type: 'privateKey', 'keystore', 'mnemonicPhrase', 'readonly'
    • key: String
    • currency: String
  • setProvider(host)
  • getBalance(addressHexString): Promise
  • sendTransaction(transactionObject): Promise
  • getTransaction(transactionHash): Promise
  • contract(abi, address): Object
  • estimateGas(transactionObject): Promise
  • gasPrice(): Promise

eth-util

  • toWei(num, unit)
  • fromWei(num, unit)
  • toBigNumber
  • toBuffer
  • toHex
  • verifyPrivateKey
  • decodeAbi
  • encodeAbi
  • signTransaction

钱包 App 的整体架构

1304324-ddff58c7450ae853.png
Wallet

问题:

We learned about the general principles of the wallet, take a look at the first questions asked:

  • Our wallet password (private key) purse or other information, whether transmission in the network?
    • Block chain does not store any private account information, at least in the transaction process, we will not pass out private information;
    • In the generation or import purse, the build process transaction information, are done locally, we will not disclose user's private key;
    • Play tricks on the code unless the software itself;
    • So open the wallet application needs;
  • The major trading platforms, I buy digital currency Where children?
  • Block chain wallet in the end there is no user information?
    • When the wallet address generation transaction, only the address information stored in the wallet
    • If the wallet does not address any transaction, the relevant information is not stored in the wallet

So, Nakamoto through this unique way of thinking, the wallet user information (account system) all managed by the user's own local; or books transactions (public information) in addition to the wallet does not store any address other account information. As a block chain appears to be open and transparent and is safe and reliable.

〗 〖Adhere to a Xiu

Reproduced in: https: //www.jianshu.com/p/15ff67cbbcef

Guess you like

Origin blog.csdn.net/weixin_34205076/article/details/91058346