{"id":21989337,"url":"https://github.com/blockai-unofficial/openpublish","last_synced_at":"2025-04-30T11:30:13.785Z","repository":{"id":31990559,"uuid":"35561059","full_name":"blockai-unofficial/openpublish","owner":"blockai-unofficial","description":"A publishing protocol for registering media as a digital asset on the Bitcoin blockchain.","archived":false,"fork":false,"pushed_at":"2016-03-14T19:20:46.000Z","size":1136,"stargazers_count":31,"open_issues_count":0,"forks_count":20,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-05-19T09:36:25.808Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blockai-unofficial.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-13T16:37:08.000Z","updated_at":"2024-02-18T05:37:42.000Z","dependencies_parsed_at":"2022-09-18T20:52:07.195Z","dependency_job_id":null,"html_url":"https://github.com/blockai-unofficial/openpublish","commit_stats":null,"previous_names":["blockai/openpublish"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockai-unofficial%2Fopenpublish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockai-unofficial%2Fopenpublish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockai-unofficial%2Fopenpublish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockai-unofficial%2Fopenpublish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blockai-unofficial","download_url":"https://codeload.github.com/blockai-unofficial/openpublish/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227198337,"owners_count":17746526,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T19:29:00.233Z","updated_at":"2024-11-29T19:29:00.804Z","avatar_url":"https://github.com/blockai-unofficial.png","language":"JavaScript","funding_links":[],"categories":["Blockchain Assets"],"sub_categories":["E-Books"],"readme":"# Open Publish\n\nA publishing protocol for registering media as a digital asset on the Bitcoin blockchain.\n\nOpen Publish creates a similar system to the those describe by de Soto in his essay [The Mystery of Capital](http://www.imf.org/external/pubs/ft/fandd/2001/03/desoto.htm) by fixing the economic potential of assets, integrating dispersed information into one system, making people accountable, making assets fungible, networking people, and protecting transactions.\n\nOpen Publish aims to give ownership of digital media back to the individual and allow individuals to create contracts for licensing and micropayment channels using Bitcoin. Think combining Proof of Existence, OpenAssets and a royalty payment mechanism.\n\nLike Proof of Existence, digital media is represented as a cryptographic digest but in a content-addressable format that works seamlessly with IPFS, BitTorrent and WebTorrent. This content-addressable representation is provably signed, timestamped, and recorded in perpetuity by the Bitcoin blockchain in a format compatible with both the BitTorrent Magnet URI scheme and IPFS address scheme.\n\nThe Open Publish protocol allows claiming ownership over a digital asset that can be used by other products to represent a limited and non-exclusive copyright of this document.\n\nThe Open Publish protocol allows for transfering partial ownership of these digital assets.\n\nAny honest third-party software can read the state of ownership from the Bitcoin blockchain and create software that directs payments to the legitimate owners of the content in the form of direct tips, dividends, monthly subscriptions or various synchronization licenses modeled on existing intellectual property systems.\n\nFor example, someone could write software that displays media with a consumer Bitcoin wallet allowing for people to easily and directly tip the rights-holders.\n\nIt assumes that the wallet address that posted the Open Publish registration transaction to the Bitcoin blockchain is controlled by the owner of the registered media.\n\nBlockai cannot control what assets are registered on the Bitcoin blockchain so it is up to individual developers or development teams to make sure they honor their local rules and regulations pertaining to copyright. For example, Blockai will not display content that is deemed to not be owned by the claimant Bitcoin address, fully adhering to any DMCA notices or other local regulations.\n\n# Install\n\n`npm install openpublish`\n\n# Browser Usage\n\nIn our examples we're going to use [```test-common-wallet```](https://github.com/blockai/test-common-wallet) to create our wallet.\n\nThis simple wallet and the Open Publish API adhere to the [Common Wallet](https://github.com/blockai/abstract-common-wallet) standard.\n\n## Bitcoin Wallet\n\nWe will assume that this wallet is owned and operated by Alice.\n\n```js\nvar aliceWallet = testCommonWallet({\n  seed: 'some-random-very-long-and-super-safe-passphrase',\n  network: 'testnet',\n  commonBlockchain: commonBlockchain\n})\n```\n\nWe'll need to provide an instance of a commonBlockchain which will provide functions for signing a transaction, propagating a transaction, and looking up a transaction by ```txid```.\n\nIn this example we're using the in memory version that is provided by ```mem-common-blockchain```.\n\n\n```javascript\nvar commonBlockchain = require('mem-common-blockchain')({\n  type: 'local'\n})\n\n// or we could connect to testnet\n\n// commonBlockchain = require('blockcypher-unofficial')({\n//   network: \"testnet\"\n// })\n```\n\n## Register Media with an Open Publish transaction posted to the Bitcoin network\n\nHosting and distribution of content is not the goal of Open Publish although an optional link to the content can be part of the metadata.\n\nFiles can be hosted on any existing web servers at the expense of the owner. A private service by Blockai called [Bitstore](https://github.com/blockai/bitstore-client) is a content-addressable file hosting and distribution service that uses Bitcoin public key infrastructure for authentication and payment. All files hosted on Bitstore are seeded on both BitTorrent and WebTorrent. As it uses Bitcoin wallets for authentication no account creation is necessary which makes it very convenient for application developers.\n\nIn this example, Alice is using her wallet along with a file that she draged and dropped on to a web page.\n\n```javascript\nvar openpublish = require('openpublish')\n\nvar file // a browser File object returned from drop or file select form\nvar fileUri // a permalink to the above file\n\nopenpublish.register({\n  file: file,\n  uri: fileUri,\n  commonWallet: aliceWallet,\n  commonBlockchain: commonBlockchain\n}, function(err, receipt) {\n  var registerData = receipt.data\n  var sha1 = registerData.sha1 // the SHA-1 that represents your media file\n  var blockcastTx = receipt.blockcastTx\n  var txid = blockcastTx.txid // the Bitcoin transaction where the first payload of the the data is embedded\n  var transactionTotal = blockcastTx.transactionTotal // the number of Bitcoin transactions in the data payload\n})\n```\n\n## Transfering ownership of digital assets\n\nOpen Publish allows for rights-holders to transfer partial ownership of the digital assets that represent their registered works, in a manner similar to how rights are transfered in music and book publishing.\n\nIn this example, Alice's is transfering part ownership of her digital asset to her friend Bob.\n\nAlice started with 100,000,000 of total value in her asset when she first registered her media file.\n\nAfter this transaction has been signed by both wallets and cleared by the Bitcoin network, Alice will have 70,000,000 and Bob will have 30,000,000.\n\nTransfers are only valid for a set number of days before full ownership reverts back to Alice.\n\n```js\nvar bobWallet = testCommonWallet({\n  seed: 'another-random-very-long-and-super-safe-passphrase',\n  network: 'testnet',\n  commonBlockchain: commonBlockchain\n})\n\nvar sha1 = 'dc724af18fbdd4e59189f5fe768a5f8311527050'\n\nopenpublish.transfer({\n  assetValue: 30000000, // the number of assets that Alice is transfering\n  bitcoinValue: 5000000, // the number of bitcoin that Bob is transfering\n  ttl: 365, // the number of days that the transfer is valid for before reverting back to Alice\n  sha1: registerData.sha1,\n  assetWallet: aliceWallet,\n  bitcoinWallet: bobWallet,\n  commonBlockchain: commonBlockchain\n}, function(err, receipt) {\n  var blockcastTx = receipt.blockcastTx\n  var txid = blockcastTx.txid // the Bitcoin transaction where the first payload of the the data is embedded\n  var transactionTotal = blockcastTx.transactionTotal // the number of Bitcoin transactions in the data payload\n});\n```\n\nAlice and Bob will probably not have their wallets open at the same time and also need a way to negotiate and settle on a price before they both independently sign the transfer transactions.\n\nBob decides he'd like to buy another 20,000,000 of the asset from Alice for 3,000,000 satoshi.\n\n```js\n// on Bob's computer\nopenpublish.createBid({\n  assetValue: 20000000,\n  bitcoinValue: 3000000,\n  ttl: ttl,\n  sha1: sha1,\n  assetAddress: aliceWallet.address,\n  bitcoinWallet: bobWallet,\n  commonBlockchain: commonBlockchain\n}, function (err, proposedBid) {\n  sendToAlice(proposedBid)\n})\n```\n\nAlice recieves the bid and decides to accept the offer.\n\n```js\n// on Alice's computer\nvar proposedBid = incomingBidOffersForAlice[0]\nproposedBid.assetWallet = aliceWallet\nproposedBid.commonBlockchain = commonBlockchain\n\nopenpublish.acceptBid(proposedBid, function (err, acceptedBid) {\n  sendToBob(acceptedBid)\n})\n```\n\nBob then recieves the accepted offer back, signs, and propagates the transfer.\n\n```js\n// on Bob's computer\nvar acceptedBid = acceptedBidOffersForBob[0]\nacceptedBid.bitcoinWallet = bobWallet\nacceptedBid.commonBlockchain = commonBlockchain\n\nopenpublish.transferAcceptedBid(acceptedBid, function (err, receipt) {\n  var transfer = receipt.transfer\n  var blockcastTx = receipt.blockcastTx\n  var txid = blockcastTx.txid // the Bitcoin transaction where the first payload of the the data is embedded\n  var transactionTotal = blockcastTx.transactionTotal // the number of Bitcoin transactions in the data payload\n})\n```\n\nThis functionality allows for independent messaging services to create public order books for Open Publish asset transfers.\n\n## Public stream\n\nOpen Publish transactions are native Bitcoin transactions. This means they are broadcast and stored on all nodes in the Bitcoin network. Anyone can freely stream, read, and write their own Open Publish transactions in same equal-access manner as native Bitcoin transactions. Open Publish takes advantage of the unique distributed yet single-source-of-truth nature of the Bitcoin blockchain.\n\nWhat this means is that neither Blockai nor any other private entity is required to register with Open Publish.\n\n### Running Your Own Open Publish State Engine\n\nIf you'd like to run your own Open Publish state engine you'll need a compatible data store and access to a Common Blockchain adapter like [```rpc-common-blockchain```](https://github.com/blockai/rpc-common-blockchain).\n\nYou can use this to independently verify the state of Open Publish registrations and transfers and to run your own Open Publish based services.\n\nCheck out the [```openpublish-state-engine```](https://github.com/blockai/openpublish-state-engine) for more info.\n\n## Tipping and Micropayments\n\nOpen Publish comes with some very basic tipping functionalities. The tip will only be valid if the destination address matches the owner of the asset as registered on the blockchain.\n\nIn this example, Alice found a really great photograph that is represented by the SHA-1 ```d1aef793e057364f8bd7a0344b4aa77be4aa7561```. She used the operations store she built for [```openpublish-state-engine```](https://github.com/blockai/openpublish-state-engine) to find out the wallet address of the rights-holder and then sent them a tip in bitcoin.\n\n```js\nvar sha1 = 'd1aef793e057364f8bd7a0344b4aa77be4aa7561'\n\nopenpublishOperationsStore.findRegistration({\n  sha1: sha1\n}, function(err, existingRegistration) {\n  var tipDestinationAddress = existingRegistration.addr\n  openpublish.tip({\n    destination: tipDestinationAddress,\n    sha1: sha1,\n    amount: 10000, // in satoshi\n    commonWallet: aliceWallet,\n    commonBlockchain: commonBlockchain\n  }, function(error, tipTx) {\n    var propagateResponse = tipTx.propagateResponse\n    var txid = tipTx.txid\n  })\n})\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockai-unofficial%2Fopenpublish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblockai-unofficial%2Fopenpublish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockai-unofficial%2Fopenpublish/lists"}