[Ethereum Source Code Analysis] V. FROM wallet to client

Source: Internet
Author: User
Tags hash json new set time limit

Ethereum is a digital currency of the etheric currency operating system, it is obvious that it will also have a wallet-like client program, to provide management account balance and other functions. We know that the account that holds (or binds to) the etheric currency is present in the code with the address type variable, so being able to manage multiple ethereum accounts should belong to one of the basic functions of the client program. This article starts with a code package that manages account information, and introduces some of the main modules of the Ethereum client program from the bottom up. 1. Code pack accounts for managing account information

In the accounts code package of the Ethereum source code, the smallest structure that renders the account address is called account{}, and its main member is a common. Address type variable; The interface class that manages the account is called Wallet, and the class, such as its name,<wallet>, declares operations such as caching account objects and parsing account objects, managing multiple <Wallet> The structure of the object is called the manager, and these types of UML relationships are shown in the following figure:


In the various structures/interfaces inside the accounts code package, accounts. The manager is undoubtedly at the top of the mutual invocation relationship, which itself is a public class, exposing outward including querying a single account, returning single or multiple wallet objects, subscribing to Wallet update events, and so on. Inside it, it maintains a list of wallet, holding a set of account object objects through each wallet implementation class, and passing an event. The feed member variable to manage all the requirements to subscribe to wallet update events. Manager subscribes to wallet update events

To highlight the subscription (subscribe) operation here, the manager's subscribe () function is defined as follows:

[Plain] View plain copy///accounts/manager.go func (AM *manager) Subscribe (sink chan<-wallletevent) event. Subscription {return am.feed.Subscribe (sink)} First note that the Subscribe () function is an operation that allows an external calling object to subscribe to the manager, in fact the manager itself is also using the same Subscription mechanism to learn about the newly added wallet object whose member variable updates is the channel in which the manager itself gets the subscribed event. Second, the Manager.subscribe () function has only one Chan parameter, and because of the powerful channel mechanism in the Golang language, the subscription operation requires only one Chan object to be sufficient, and it is simply not necessary to know who initiated the subscription. Still, it's worth thinking about what kind of an object has subscribed to the manager. In fact, subscribing to a manager object for the Wallet update event is another manager object, the implementation class for <Backend>.

It is very meaningful to come to this conclusion. You can see later, accounts. The manager is primarily a eth.ethereum (or les). Ethereum) A member exists while this ETH. Ethereum is the most important part of the Ethereum client program, which provides the functionality needed to run virtually all ethereum systems as a service, so an Ethereum client can be considered a accounts. Manager exists, then the truth is that all Ethereum clients are passing through accouts. The manager subscribes to Wallet update events with each other.


In addition to the manager, several other important structures here include the following:
event. feed{}: It can manage a one-to-many subscription pattern, with each caller providing a Chan object to send the subscribed content. The subscription content processed by feed{} is type-generalized, and each feed{} object can only handle one type of subscription during its lifetime, that is, the value sent to the Chan object. The Feed.subscribe () method returns the implementation body of the <Subscription> Interface Feedsub{},feed.subscribe () to help manager implement <Backend> The declared method is subscribe (). Within the feed structure, caselist is used to manage the Chan objects sent by all subscribers. Accounts. account{}: Its members are in addition to a common. Address type, which is 20bytes long, has an optional member URL, which can be either a URL or a locally stored path + full file name. URL when it exists as a URL. Scheme is the network protocol name, and as a local storage file, the URL. Scheme is the string constant "KeyStore". Accounts.<wallet>: It is much like a "purse" in the general sense, its management of multiple accounts, just as the individual user in the reality of the multiple bank account, the balance of ether on each accounting, can be from the database ( Core.state.StateDB) in the query. In the functions declared by the <Wallet> interface, it is particularly important to note that signxxx (), where Signtx () is digitally signing a transaction (TX) object, and Signhash () is digitally signing a hash value. Since any object (as long as serializable) can be used as a hash, Signhash () Here is actually a digital signature for any object, especially block blocks.

<Wallet> is the interface type, its implementation includes software wallet (keystore.keystorewallet) and hardware wallet (usbwallet.wallet), note that the hardware wallet here is physical. The code system under <Wallet> is not public for the outside, and all outward-exposed "wallet" objects and related update events are in the form of <Wallet>.
Wallet-keystore of software implementation

The software implementation Wallet manages the account address primarily by storing files locally. At the same time, the,<wallet> object needs to provide a digital signature for the transaction or chunk object, which requires a public key + key in the Elliptic Curve Digital signature (ECDSA), and each public key is also the source of an account address. So we also need to store ECDSA's public key information locally. This mechanism for implementing accounts.<wallet> functionality through the local storage of files in Ethereum has been keystore.

<Wallet> 's software wallet implementation of the relevant code is under the/accounts/keystore/path, the main UML relationship of this group of code is as follows:


keystorewallet{}: It is a accounts.<wallet> implementation class that has an account object that represents its own address and implements the upper-level interface through the Account.url () method <wallet . URL () method; There is also a keystore{} object, which is the core class in this set of code.

keystore{}: It provides the keystorewallet structure with all the substantive data and operations related to the account. keystore{} has two members for the data cache: the member cache of the Accountcache type, which is the collection of all the address information (account{} types) to be found; map[address]unlocked{} member Unlocked , because the unlocked{} struct simply encapsulates the key{} object (which explicitly contains a digital signature public key pair in key{}), the address variable can be used to find the original public key and the key corresponding to it in map[].

In addition, keystore{} has a member of the <keyStore> interface type storage, which is used to operate the public key information key stored in the local file.

unlocked{}: The encapsulated class of the public key data class key{}, with its internal members in addition to key{}, provides a Chan type variable abort, which plays a role in KeyStore's management mechanism for public key information.

key{}: A data class that holds the public key of a digital signature, which explicitly stores a ECDSA. The member variable of type privatekey{}, described earlier, contains a member of the publickey{} type in ecdsa.privatekey{} in the Golang native code package. The key{} also carries the address type member variable, which avoids the recurrence of the public Key's conversion to the address type.

<KEYSTORE>: This interface type declares a function that operates on key, noting that it differs from keystore{} with only one letter case on the name.

The implementation class of Keystorepassphrase{}:<keystore> interface, which realizes the encryption management of public key information by WEB3 Secret Storage encryption method.

accountcache{}: All account objects under a known path in the in-memory cache KeyStore can provide an operation to find the corresponding account object from the address type.

Filecache{}:keystore can be observed in the cache of files, it can be stored in a path to the file to scan, respectively, to return new files, missing files, change the collection of files.

watcher{}: Used to monitor the changes in the account files stored in a path, you can periodically call the Accountcache method to scan the file. local files explicitly store account information

Accountcache Cached account information comes from a collection of local files stored under a known path. Each file is in JSON format to explicitly store address: {address: "@Address"}, so accountcache can be converted directly to account{} object after reading the file and used in code. There is no problem in storing the address information in an explicit file, without worrying about the compromise of the Address information disclosure (the public key that cannot be parsed from address to the source ECDSA), or it can be easily called by code.

In use, the Watcher object maintains a timer, constantly notifies Accountcache to scan a given path, and Accountcache invokes the Filecache object to scan the file under that path. And according to the Filecache returned by the three kinds of file collection: New files, missing files, change files, in their own maintenance of the account collection to do the corresponding operation.
storing public key keys with locally encrypted files

key{} through ECDSA. The Privatekey object thus carries the public key keys used by the ECDSA, so this involves the public key part, which is the operation for the key object. In the KeyStore mechanism, the JSON format of the encrypted key object is stored locally, and the encryption method used is known as the Web3 Secret Storage, and its implementation details are found on the ethereum git wiki. The following diagram is a simple schematic diagram of this storage method:


A total of three parameters are required for an encrypted stored key object, including the caller providing an arbitrary string named passphrase, and the two integer number SCRYPTN,SCRYPTP given in keystorepassphrase{}. These two integer parameters are fixed within the life cycle of the Keystorepassphrase object and can only be assigned at creation time. This way, the caller must pass in the correct parameter passphrase each time a new key object is stored, or an existing key object is fetched, so that in practice, the customer of the Ethereum wallet must remember the string itself. In fact, the password password created by the customer for each account is the encryption parameter passphrase in the program. the public key that was taken out is exposed in memory for a limited time

The key{} object is encapsulated as a unlocked{} object after it is removed from the encrypted local file and is keystore into its map[address]*unlocked type member. Because of the importance of public key keys, it is clear that the unlocked objects that are stored in KeyStore should also control the duration of the exposure. For different time-frame requirements, keystore{} provides the following two functions:

[Plain] View plain copy//accounts/keystore/keystore.go func (KS *keystore) Unlock (a accounts. Account, passphrase String) error {return KS. Timedunlock (A, passphrase, timeout:0)} func (KS *keystore) Timedunlock (a accounts. Account, passphrase string, timeout time. Duration) the error Timedunlock () function destroys the private key of the Privatekey in the unlocked object that is known to the account immediately after the given time limit is reached (bit 0). and removes the unlocked object from the KeyStore member. The unlock () function exposes the unlocked object until the program exits. Note that the cleanup work here is only for key objects in memory, and the local key file is not affected by encryption.

The KeyStore mechanism provides the storage and reading of the account information and the public key of the digital signature in the form of a local file, thus realizing the function of accounts.<wallet> in software mode. Its two sets of independent local storage files, considering both the encryption of the public key and the quick reading of account information, embody a very comprehensive design idea.
Wallet of hardware device implementation

In addition to providing software-implemented wallets, Ethereum also has a hardware-implemented wallet. Of course, for hardware wallets, there must be a layer of code in the Ethereum code that encapsulates this. The code is under/accounts/usbwallet/, and their uml relationships are shown in the following figure:


The main structures in Pkg accounts/usbwallet include wallet{}, hub{} and the <driver> interface.
wallet{} structure implements the upper interface Accounts.<wallet>, and provides accounts.<wallet> function implementation; <driver> interfaces can be seen from the name, It is used to encapsulate the code of the underlying hardware implementation wallet. Although strictly speaking, this interface and its implementation have nothing to do with the general sense of "driver". ledgerdriver{},trezordriver{} corresponds to the hardware digital wallets issued by two vendors, ledger and Trezor are brand names respectively. They can support multiple digital currencies, including the etheric currency.
<Hub> structure, it realizes the upper Accounts.<backend> interface, the status is equivalent to account. Manager. From the code point of view, the <Wallet> part of all hardware implementations is managed by this hub object. hub{} is exposed in the form of a <Backend> interface so that the higher-level code does not have to distinguish between software and hardware for the underlying wallet.

It is important to note that in the current Ethereum backbone code, the hardware implementation of the wallet about the digital signature part, currently can only provide for the transaction of the original digital signature function, that is, only <wallet> The Signtx () function is available, other signature features include Signhash (), and signxxxwithpassphrase () are not supported and do not know whether other branch code is different.
2. Ethereum Service

After understanding the accounts code package, we can take a look at the most famous types of Ethereum source code, as well as the core part of the client program-ETH. Ethereum. The type of struct that can be named with the entire system name, presumably the function should be very powerful, the following diagram is a simple UML diagram of it:


In the middle of the picture is ETH. Ethereum type, surrounded by its member variable types, let's see what we've learned: Ethdb.<database> is a function interface corresponding to core.state.statedb{}, with <database A member variable of the > interface type that can be called in use statedb{} consensus.<engine> is a function interface exposed by the consensus algorithm code package, and its implementation includes the POW-based Ethash algorithm, and the POA-based clique algorithm. Accounts. The manager is the code that manages the account information and digital signature public key information. Miner. Miner is the code that digs new chunks, it can manage the whole process of mining new chunks, call consensus.<engine> to complete the new Block's Honours/certifications, and broadcast the block event to the outside. Core. Txpool is the code that accumulates new transactions (Transaction, TX) objects, each new mining block needs to listen for the TX update event from the Txpool and acquire a new set of transactions to assemble into the block. Core. BlockChain is a struct that manages the entire blockchain data structure.


These are the sections of code that have been specifically described in the previous article, and then look at the new types: Node.<service>, which is the interface that the client program uses to abstract functions from the node. Each client sees itself as a node in the network, and all the functions provided by the node are defined by the <Service> interface. <LESSERVER>: The function interface that implements LES protocol,eth.<lesserver> is actually to call les. lesserver{} and a specially created local function interface. Ethapibackend, which is a module that helps Ethereum expose functions in the form of RPC Services (service), external callers invoke these functions/services in an API manner.
Protocolmanager, which is used to manage peer communication. Within Ethereum, the communication protocol between each individual (peer) and other individual groups is referred to as a new protocol based on the peer communication Protocol. Considering the ETH. Ethereum provides comprehensive functionality, and it is also known as a communication protocol for full-node services. In the Protocolmanager member variable, Fetcher is used to receive messages from other individuals announcing the discovery of new chunks and decides to get the necessary parts to the other, downloader responsible for synchronizing the entire blockchain structure (download).

In particular, the Les:light Ethereum subprotocol (LES) is a sub-protocol specifically designed for lightweight clients. Compared to the ETH. Ethereum provides clients with full-node services, and those lightweight clients do not participate in the mining of new chunks, only the head (Block.header) of each region is downloaded in communication with other nodes, and only parts of the blockchain are synchronized as needed. Eth. Ehereum also supports Les so that a client that provides a full-node service can communicate with other lightweight clients in the same protocol.


People with a little knowledge of digital currencies should be aware of the significance of peer-to-peer communication protocols for such "de-centralized" systems. It is true that one of the cornerstones of a peer-communication protocol called the Ethereum system is not too much, and from a code perspective, Protocolmanager and its code family are part of the ETH code package, but because of the complexity of the code, the implementation details of these communication protocols are specifically described in the next article. 3. Ethereum client program

In understanding the ETH. After ethereum this core service, the client execution program is also on the horizon. First, there is a node. node{} as a container that hosts a service module like Eth,ethereum:

There is a Service list inside the node{} object, and all objects that implement the Node.<service> interface can be stored in node, such as ETH. Ethereum.

Next, the code for the Go-ethereum client program Geth is simple:

[plain]  View Plain  copy// /cmd/geth/main.go   func main ()  {       if err := app. Run (OS. Args); err != nil {           fmt. Fprintln (OS. Stderr, err)            os. Exit (1)        }  }   func geth (ctx *cil. Context)  error {       node := makefullnode (CTX)        startnode (CTX,

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.