Proficient in IPFS: one of the system startups
const {createNode} = require('ipfs') const node = createNode()
At the time, although there are only two simple codes, but a very large amount of code is executed internally, let us see how the system is executed and how to initialize the system.
When we execute the createNode
function, the function that is actually executed is in the ipfs/core/index.js
file. The code is as follows:
module.exports.createNode = (options) => { return new IPFS(options) }
The IPFS object initialized above represents the IPFS system, which is in the same file and inherits from the EventEmitter
object. When we initialize the IPFS object, we start executing its constructor, and then we analyze the constructor.
- Opinion: The best use case for Bitcoin is as an anti-corruption tool
- Depth: How to ensure the safety of the Bitcoin network when there is no mine to mine?
- During the year, six listed companies were continuously “named” because of the “blockchain” supervision letter.
- Call the parent class constructor.
- Set the environment variables used by the system. First, set the system default options.
const defaults = { init: true, start: true, EXPERIMENTAL: {}, preload: { enabled: true, addresses: [ '/dnsaddr/node0.preload.ipfs.io/https', '/dnsaddr/node1.preload.ipfs.io/https' ] } }
Second, verify that the option is valid.
options = config.validate(options || {})
Next, call the
mergeOptions
function to merge the default options with user-specified option arguments.
Finally, the init
and start
options of the processing options are as follows:
if (options.init === false) { this._options.init = false }
If (!(options.start === false)) { this._options.start = true }
if (typeof options.repo === 'string' || options.repo === undefined) { this._repo = defaultRepo(options.repo) } else { this._repo = options.repo }
The default repository definition is located in the runtime/repo-nodejs.js
file. The contents of this file are relatively simple, as follows:
'use strict'
Const os = require('os') const IPFSRepo = require('ipfs-repo') const path = require('path')
Module.exports = (dir) => { const repoPath = dir || path.join(os.homedir(), '.jsipfs')
Return new IPFSRepo(repoPath) } Because we did not specify the location of the repository, it defaults to the .jsipfs
directory under the user's .jsipfs
directory. Below, we look at the IPFSRepo
object, which is located in the index.js file of the ipfs-repo project. Its constructor is as follows:
Constructor (repoPath, options) { assert.strictEqual(typeof repoPath, 'string', 'missing repoPath')
this.options = buildOptions(options) this.closed = true this.path = repoPath
This._locker = this._getLocker()
This.root = backends.create('root', this.path, this.options) this.version = version(this.root) this.config = config(this.root) this.spec = spec(this.root) this.apiAddr = apiAddr(this.root) }
In the constructor of the repository, first call the buildOptions
function to set the options for the repository. This function combines the user-specified options with the warehouse default options, and handles both the storageBackends
and storageBackendOptions
options. Because the default repository is only specified when the repository is created, and no other options for the task are specified, the default repository uses the default options. The default options are as follows.
{ lock: 'fs', storageBackends: { root: require('datastore-fs'), blocks: require('datastore-fs'), keys: require('datastore-fs'), datastore: require('datastore-level') }, storageBackendOptions: { root: { extension: '' }, blocks: { sharding: true, extension: '.data' }, keys: { } } }
From the default options, we found that the lock uses files, the root directory, the block directory, and the keys directory use normal file system storage, the data store uses a level data system, and the default data file suffix is .data
.
After processing the warehouse options, you can then process the warehouse. Call the function defined in the backends.js
file to create the directory of the repository. Create the home directory object according to the option configuration. By default, the home directory is created in ~/.jsipfs
, and then the version file, configuration file, storage rules, etc. are created in turn. .
Note that after these actions are completed, the warehouse object is initially completed, but at this time, other directories and files are not actually created except the home directory, and their actual creation will not be performed until the initialization is started.
this._peerInfoBook = new PeerBook() this._peerInfo = undefined this._bitswap = undefined
this._blockService = new BlockService(this._repo) this._ipld = new Ipld(ipldOptions(this._blockService, this._options.ipld, this.log)) this._preload = preload(this)
this._mfsPreload = mfsPreload(this) _bitswap
object is actually generated in the start phase. The block service object saves the repository object and the bitswap object. The system processes the specific block by calling the put, get, and delete operations of the block service object. The specific block can be from the local repository. In the middle processing, you can also process specific blocks through the bitswap object. The bitswap object is now empty and will not be generated and set until the system startup phase.
this.init = components.init(this) this.preStart = components.preStart(this) this.start = components.start(this) this.stop = components.stop(this) this.shutdown = this.stop this.isOnline = components.isOnline(this)
These commands will be explained in detail later, and will not be mentioned here.
Object.assign(this, components.filesRegular(this)) this.version = components.version(this) this.id = components.id(this) this.repo = components.repo(this) this.bootstrap = components.bootstrap(this) this.config = components.config(this) this.block = components.block(this) this.object = components.object(this) this.dag = components.dag(this) this.files = components.filesMFS(this) this.libp2p = null // assigned on start this.swarm = components.swarm(this) this.name = components.name(this) this.bitswap = components.bitswap(this) this.pin = components.pin(this) this.ping = components.ping(this) this.pingPullStream = components.pingPullStream(this) this.pingReadableStream = components.pingReadableStream(this) this.pubsub = components.pubsub(this) this.dht = components.dht(this) this.dns = components.dns(this) this.key = components.key(this) this.stats = components.stats(this) this.resolve = components.resolve(this)
The above two steps can be directly called for the expansion of the system, or can be called by the program. Corresponds to the relevant commands in the command line.
boot
function is called to start the system. At this point, the IPFS node has been started macro, and various commands can be called to play the system.
We will continue to update Blocking; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- Large factory enclosure, small factory group: blockchain standard gunshots
- Tens of millions of EOS have been unlocked, and the price of the currency has not fallen, but what is it?
- Useful way – the initial solution of BYSTACK application
- Bitwise: There are only 10 Bitcoin exchanges with real trading volume
- Quietly buy RAM worth 3.3 million EOS, is Block.one really going to be a social network?
- Still don't know "Staking"? The currency that should belong to you is slipping away
- Opinion: written on the Bitcoin station for 8888 dollars