title: "初探orbitdb" date: "2023-08-27" tag: ["orbitdb", "chat", "ipfs"]

orbitdb

npm init -y package.json 加入:"type": "module" pnpm add @orbitdb/core@next pnpm add ipfs-core

import { createOrbitDB } from '@orbitdb/core'
import { create } from 'ipfs-core'
// Create an IPFS instance with defaults.
const ipfs = await create()
const orbitdb = await createOrbitDB({ ipfs })
const db = await orbitdb.open('my-db')
console.log('my-db address', db.address)
// my-db address /orbitdb/zdpuAvAG3zG4zF3E2s5KVS3pcrqXFK2ky6fMiyi6TsU2mb9qo

加入資料

await db.add('hello world 1')
await db.add('hello world 2')
console.log(await db.all())
// my-db address /orbitdb/zdpuAvAG3zG4zF3E2s5KVS3pcrqXFK2ky6fMiyi6TsU2mb9qo
[
  {
    hash: 'zdpuAtx71Mp1C1Cxf1brNmP8iw8sEFCtrvcprnyEH5XsFJYXu',
    value: 'hello world 1'
  },
  {
    hash: 'zdpuAviVoAXeTyGSbXJnZdTa4TTvb85JzgJsLHTFijY2dqXFh',
    value: 'hello world 2'
  }
]

用完關閉

await db.close()
await orbitdb.stop()
await ipfs.stop()

有很多種型別(documents/keyvalue/metadata)

const db2 = await orbitdb.open('my-documents-db', {type:'documents'})
await db2.put({_id:"1", doc:{ hello: "world 1", hits: 5 }})
console.log(await db2.all())
//output
[
  {
    hash: 'zdpuAo5vKYV2Fp3Swdk7bnFWEicV4S5BQQZcHJ3geNRRAUt3w',
    key: '1',
    value: { _id: '1', doc: [Object] }
  }
]
const db3 = await orbitdb.open('my-keyvalue-db', {type:'keyvalue'})
await db3.put( "name","alan")
await db3.put( "2","alice")
console.log(await db3.all())
//output
[
  {
    key: '1',
    value: 'alan',
    hash: 'zdpuB2uA4qKzu7Cvgk2Fxuw7co9KARSbkLpv6iYwvqemkkf9t'
  },
  {
    key: '2',
    value: 'alice',
    hash: 'zdpuAtxQZw3EoEu2SuAnQ8ZkM5GG7QoaXGvbyLB6CAnP3wsCz'
  }
]

建立對等節點

npm init -y package.json 加入:"type": "module" pnpm add @orbitdb/core@next pnpm add ipfs-core

import { createOrbitDB, getAccessController } from '@orbitdb/core'
import { create } from 'ipfs-core'

這邊如果沒有getAccessController,到@orbitdb/core裡新增:

export {
	...
	getAccessController
} from './access-controllers/index.js'

設定初始config,且指定儲存位址 randDir,會在./randDir/底下新增ipfs、orbitdb資料夾

  
const config = {
	Addresses: {
		API: '/ip4/127.0.0.1/tcp/0',
		Swarm: ['/ip4/0.0.0.0/tcp/0'],
		Gateway: '/ip4/0.0.0.0/tcp/0'
	}
}
let randDir = `db/${(Math.random() + 1).toString(36).substring(2)}`
const ipfs = await create({ config, repo: './' + randDir + '/ipfs' })
const orbitdb = await createOrbitDB({ ipfs, directory: './' + randDir + '/orbitdb' })
const AccessController = getAccessController('ipfs')
let db
if (process.argv[2]) {
	db = await orbitdb.open(process.argv[2])
} else {
	db = await orbitdb.open('my-db', { AccessController: AccessController({ write: ['*'] }) })
}

console.log('my-db address', db.address)
//output
// my-db address /orbitdb/zdpuB2aYUCnZ7YUBrDkCWpRLQ8ieUbqJEVRZEd5aDhJBDpBqj

監聽事件

db.events.on('join', async (peerId, heads) => {
	console.log(`${peerId} join.`)
})
//output 有人加入時
//12D3KooWP9yBfg9rEWrSQrTw3SPvbFGstKFMQprfiVzoYZVLMNGx join.

開另一個視窗同樣下 node index.js 原本視窗會印出:12D3KooWP9yBfg9rEWrSQrTw3SPvbFGstKFMQprfiVzoYZVLMNGx join.,且會在db/新增一個備份

訪問權限

import { createOrbitDB, Identities, getAccessController } from '@orbitdb/core'
const identities = await Identities()
const anotherIdentity = await identities.createIdentity({id:'userB'})
console.log(anotherIdentity)

會印出:

{
  id: '0270af91e526fdd233c1a2798fc3a20718dc1141e2597cbd126d53d0e1cb3b9e09',publicKey: '02869393a00093df037d9c6f9fd2d7f85cc14301c321cd272ad1f761f01849fe80',
  signatures: {
    id: '3044022055c48f1dd1fd81c67e10c905cbeee504b703da47160a76835b3cd70e2b2efff202204adb92a20b69e08d7d4ce4e5c1d385b74b35cc00e83eae06149aa3d959c06fb2',
    publicKey: '3044022002547e93f402e16ed34920c1be3c736fa64dc841e30c2542cbec48f6da42ae2d02207547dd41657c041e3e1ea3ac57d32ad8efeb842ac1243fe94c82b25a9edc15a4'
  },
  type: 'publickey',
  sign: [AsyncFunction: sign],
  verify: [AsyncFunction: verify],
  hash: 'zdpuArphGKQ3QQqQCcvu6GwhwLTUXze47UTLuCgWmULytddQS',
  bytes: ...
}

使用上面的id(0270af91e526fdd233c1a2798fc3a20718dc1141e2597cbd126d53d0e1cb3b9e09),將原本db 修改成,讓第二個身份也可以使用db

const db = orbitdb.open('my-db', { AccessController: OrbitDBAccessController(
{ write: [orbitdb.identity.id, anotherIdentity.id] })}
)

也可以之後使用

db.access.grant('write', anotherIdentity.id)
db.access.revoke('write', anotherIdentity.id)

[[20230828-libp2p]]

orbitdb-examples

https://github.com/orbitdb/orbitdb-examples.git npx create-react-app . pnpm add @orbitdb/core pnpm add ipfs-core pnpm add @achingbrain/nat-port-mapper@1.0.7

import { create } from 'ipfs-core';
import { createOrbitDB } from '@orbitdb/core';

https://github.com/alanhc/orbit-chat

Ref

  • orbitdb
    • https://github.com/orbitdb/orbitdb-examples
    • https://api.orbitdb.org/
    • https://github.com/orbitdb/orbitdb/blob/main/docs/GETTING_STARTED.md
    • https://github.com/orbitdb/orbitdb/blob/main/docs/DATABASES.md
    • https://github.com/orbitdb/orbit-db-docstore
    • https://github.com/orbitdb/orbit-db-access-controllers
    • https://github.com/orbitdb/orbitdb/blob/main/docs/ACCESS_CONTROLLERS.md
    • https://dev.to/logrocket/a-guide-to-working-with-orbitdb-in-node-js-55kb