p2p、分布式,区块链笔记(OrbitDB.ControlCenter 003) :数据库接口 src\database\index.js
这段代码是一个与 IPFS(InterPlanetary File System)和 OrbitDB(基于 IPFS 的去中心化数据库)交互的模块。下面是对代码的详细解释:
导入模块
import IPFS from 'ipfs'
import OrbitDB from 'orbit-db'
import Config from '../config'
- 此“index.js”文件作提供数据库处理相关功能,IPFS 和 OrbitDB 这两个库仅在此“index.js”文件中引入,用于处理去中心化的文件存储和创建数据库。
- Config 是一个配置文件,包含 IPFS 的相关配置。
变量声明
let orbitdb
let programs
orbitdb
:用于存储 OrbitDB 实例的变量。programs
:用于存储一个特定数据库的实例,用于保存程序信息。
初始化 IPFS:initIPFS
export const initIPFS = async () => {const ipfsOptions = { repo: './ipfs' } // repo: './ipfs'– 指定存储库的路径,通常仅以 Node.js 为单位 https://blog.logrocket.com/guide-to-orbitdb-node-js/return await IPFS.create(ipfsOptions)// return await IPFS.create(Config.ipfs)
}
initIPFS
:异步函数,用于创建 IPFS 实例。指定了一个本地存储库./ipfs
,下图为本地IPFS对象示例:- 当使用
return await IPFS.create(Config.ipfs)
与Swarm的WebRTC 节点创建存储库时可能创建失败。
初始化 OrbitDB:initOrbitDB
initOrbitDB
:使用刚刚创建的 IPFS 实例初始化 OrbitDB。
export const initOrbitDB = async (ipfs) => {orbitdb = await OrbitDB.createInstance(ipfs)return orbitdb
}
获取所有数据库:getAllDatabases
getAllDatabases
:检查programs
是否已加载,如果未加载且orbitdb
存在,则创建一个新的feed
数据库用于存储程序数据。然后,返回数据库中的所有条目。
export const getAllDatabases = async () => {console.log("getAllDatabases", orbitdb)if (!programs && orbitdb) {programs = await orbitdb.feed('network.programs', {accessController: { write: [orbitdb.identity.id] },create: true})await programs.load()}return programs? programs.iterator({ limit: -1 }).collect(): []
}
-
orbitdb.identity.id:
-
programs对象(但是orbitdb.feed函数不一定能执行成功):
feed函数
// node_modules\orbit-db\src\OrbitDB.js/* Databases */async feed (address, options = {}) {options = Object.assign({ create: true, type: 'feed' }, options)return this.open(address, options)}
this.open(address, options)函数
// node_modules\orbit-db\src\OrbitDB.js/*options = {localOnly: false // if set to true, throws an error if database can't be found locallycreate: false // whether to create the databasetype: TODOoverwrite: TODO}*/async open (address, options = {}) {logger.debug('open()')options = Object.assign({ localOnly: false, create: false }, options)logger.debug(`Open database '${address}'`)// If address is just the name of database, check the options to crate the databaseif (!OrbitDBAddress.isValid(address)) {if (!options.create) {throw new Error('\'options.create\' set to \'false\'. If you want to create a database, set \'options.create\' to \'true\'.')} else if (options.create && !options.type) {throw new Error(`Database type not provided! Provide a type with 'options.type' (${OrbitDB.databaseTypes.join('|')})`)} else {logger.warn(`Not a valid OrbitDB address '${address}', creating the database`)options.overwrite = options.overwrite ? options.overwrite : truereturn this.create(address, options.type, options)}}// Parse the database addressconst dbAddress = OrbitDBAddress.parse(address)options.cache = await this._requestCache(dbAddress.toString(), options.directory)// Check if we have the databaseconst haveDB = await this._haveLocalData(options.cache, dbAddress)logger.debug((haveDB ? 'Found' : 'Didn\'t find') + ` database '${dbAddress}'`)// If we want to try and open the database local-only, throw an error// if we don't have the database locallyif (options.localOnly && !haveDB) {logger.warn(`Database '${dbAddress}' doesn't exist!`)throw new Error(`Database '${dbAddress}' doesn't exist!`)}logger.debug(`Loading Manifest for '${dbAddress}'`)// Get the database manifest from IPFSconst manifest = await io.read(this._ipfs, dbAddress.root)logger.debug(`Manifest for '${dbAddress}':\n${JSON.stringify(manifest, null, 2)}`)// Make sure the type from the manifest matches the type that was given as an optionif (manifest.name !== dbAddress.path) { throw new Error(`Manifest '${manifest.name}' cannot be opened as '${dbAddress.path}'`) }if (options.type && manifest.type !== options.type) { throw new Error(`Database '${dbAddress}' is type '${manifest.type}' but was opened as '${options.type}'`) }// Save the database locallyawait this._addManifestToCache(options.cache, dbAddress)// Open the the databaseoptions = Object.assign({}, options, { accessControllerAddress: manifest.accessController, meta: manifest.meta })return this._createStore(manifest.type, dbAddress, options)}
获取特定数据库
export const getDB = async (address) => {let dbif (orbitdb) {db = await orbitdb.open(address)await db.load()}return db
}
getDB
:根据给定的地址打开特定的数据库,并加载其内容。
添加数据库
export const addDatabase = async (address) => {const db = await orbitdb.open(address)return programs.add({name: db.dbname,type: db.type,address: address,added: Date.now()})
}
addDatabase
:打开指定地址的数据库,并将其信息添加到programs
数据库中。
创建数据库
export const createDatabase = async (name, type, permissions) => {let accessControllerswitch (permissions) {case 'public':accessController = { write: ['*'] }breakdefault:accessController = { write: [orbitdb.identity.id] }break}const db = await orbitdb.create(name, type, { accessController })return programs.add({name,type,address: db.address.toString(),added: Date.now()})
}
createDatabase
:根据提供的名称、类型和权限创建新的数据库。根据权限设置写入控制器,然后将新数据库的信息添加到programs
中。
移除数据库
export const removeDatabase = async (hash) => {return programs.remove(hash)
}
removeDatabase
:从programs
数据库中移除指定哈希的条目。
CG
- 当前版本的代码在Start IPFS时的
src\database\index.js
line :return await IPFS.create(ipfsOptions)
往往会出现下图中的错误,可能需要新版本的IPFS替换。
// Start IPFS
export const initIPFS = async () => {const ipfsOptions = { repo : './ipfs', }return await IPFS.create(ipfsOptions)//return await IPFS.create(Config.ipfs)
}