使用 PaySwarm 进行网络支付:资产和列表(共 3 部分,第 2 部分)

网络支付的承诺

本系列的第一篇文章介绍了 PaySwarm 如何以与发送和接收电子邮件一样的便捷方式设计用于传输和接收资金。文章还解释了如何将传统上只对银行、华尔街和大型公司开放的工具提供给所有人,从而以非常积极的方式重塑金融体系。目标不仅仅是一键式支付,还包括实现众筹创新,帮助网络开发者通过网络赚钱,促进初创企业的融资等。

本文是关于使用 PaySwarm 规范买卖内容的三个系列文章中的第二篇。它将回顾第一篇文章中介绍的一些基本概念,然后解释如何使用 PaySwarm 列出待售物品。

回顾:网络密钥和 JSON-LD

如第一部分所述,网络密钥规范为网络提供了一个基于公钥密码学的简单、去中心化的身份解决方案。它使网络应用程序能够发送既可以防止窥探又可以通过数字签名验证的消息。

消息使用用于链接数据的 JavaScript 对象表示法 (JSON-LD) 进行标记。顾名思义,JSON-LD 是一种用 JSON 表达链接数据 的方式。HTML 文档和 JSON-LD 文档都描述事物,并包含指向网络上其他文档的链接。JSON-LD 的主要优点是,整个文档可以被机器理解到可以提取和执行基本推理的程度,而不会给编写 JSON 标记的开发人员带来沉重的负担。

网络密钥与 JSON-LD 相结合,为 PaySwarm 执行网络支付提供了底层的信令和产品标记机制。

去中心化的产品和服务

网络支付系统的一个设计要求是,身份机制(网络密钥)必须是去中心化的。另一个要求是,数据标记机制 (JSON-LD) 必须能够表达去中心化的资源,如人员、地点、事件、商品/服务以及可能存在于第三方网站上的各种其他数据。

同样,PaySwarm 也不要求产品和服务列在网络上的中心位置。相反,它允许内容创建者和开发者控制自己的产品描述和价格,并为他们提供将此责任委托给应用商店或大型零售网站的选择。PaySwarm 对列出待售的产品和服务有以下要求

  • 列表必须能够去中心化,从而降低零售商之间出现垄断行为的可能性。
  • 待售产品必须与销售条款分离,使不同的价格能够与不同的许可证、联盟销售和业务模型(如每日特价)相关联。
  • 产品的创建者必须能够指定对定价、转售商、有效期以及与产品销售相关的各种其他属性的限制。这样可以确保产品创建者始终控制自己的产品。
  • 它必须支持去中心化扩展,使应用程序能够将特定于应用程序的数据添加到产品描述和销售条款中。
  • 它必须是安全的,从而最大程度地降低篡改产品描述和价格的风险。
  • 它必须是非可否认的,这样列表的创建者就无法对他们创建列表的事实提出异议。

资产和列表

有两个概念是理解如何通过 PaySwarm 列出产品和服务的核心。

第一个是资产。资产是对产品或服务的描述。资产的示例包括网页、电子书、杂货、演唱会门票、遛狗服务、捐赠、在特定无线电频率带上传输的权利以及已完成工作的发票。一般来说,任何有价值的东西都可以建模为资产。

资产通常描述待售物品、谁创建了它、销售它的限制集以及有效期。由于资产使用 JSON-LD 表达,因此可以与它关联许多其他特定于应用程序的属性。例如,一家 3D 打印店可以在实际打印时包含资产的尺寸、用于打印资产的材料以及一组组装说明。购买资产后,会生成包含资产描述的数字收据。此收据可以交给打印机以生成资产的物理表示。

理解 PaySwarm 中如何销售产品和服务的第二个关键概念是列表。列表是对以特定条款销售资产的描述。这些条款包括:待售的具体资产、与购买相关的许可证、将为资产支付款项的人员或组织的清单以及列表的有效期。与资产一样,列表可能包含其他特定于应用程序的属性。

本教程详细介绍了创建资产和列表以及将它们发布到网站的过程,如下面的视频简要介绍。

本教程将使用来自payswarm.js 节点模块 的代码。具体来说,它利用了资产发布示例。支付处理器将是PaySwarm 开发者沙盒,资产托管服务将是PaySwarm 开发者列表服务

创建资产

如前所述,资产使用 JSON-LD 描述。资产是在编程语言中以与构建要作为 JSON 文档发布的数据相同的方式构建的。这通常涉及使用对象(在 JavaScript 中)、字典(在 Python 中)、关联数组(在 PHP 中)或散列(在 Ruby 中)。以下是使用 JavaScript 创建资产的代码。请特别注意注释,因为它们将解释每个键值对的含义。让我们先尝试一个简单的示例

// create a PaySwarm asset
var asset = {
  // the @context is a hint to a JSON-LD processor on how to interpret the
  // key-value pairs in the document
  '@context': 'https://w3id.org/payswarm/v1',
  // this is the global identifier for the asset
  id: 'http://listings.dev.payswarm.com/mozhacks/demo#asset',
  type: ['Asset'],
  // this is the person who created the asset
  creator: { fullName: 'Developer Joe' },
  title: 'Mozilla Hacks Demo Asset',
  // this is typically the link to the paid content
  assetContent: 'http://listings.dev.payswarm.com/mozhacks/demo#asset',
  // this is the entity that has rights to the asset (or owns it)
  assetProvider: 'https://dev.payswarm.com/i/YOUR_IDENTITY_HERE'
};

上面的代码是关于 7 行代码的资产描述的工作示例(不含注释)。它描述了一个名为Mozilla Hacks Demo Asset 的资产,任何人都可以出售它。想法是,你将在网站上表达此数据,无论是作为单独的 JSON-LD 文档还是直接使用 RDFa 标记在 HTML5 页面中。任何与 PaySwarm 兼容的支付处理器都可以获取你的文档并准确地了解你创建了什么以及销售限制是什么。

让我们看一个更复杂的例子。下面的资产指定了一首歌曲,并对如何出售歌曲进行了调整。任何人都可以转售它,80% 的收益(或最低 0.50 美元)将归创建歌曲的乐队所有。

// create a PaySwarm asset
var asset = {
  // the @context is a hint to a JSON-LD processor on how to interpret the
  // key-value pairs in the document
  '@context': 'https://w3id.org/payswarm/v1',
  // this is the global identifier for the asset
  id: 'http://listings.dev.payswarm.com/mozhacks/html5-me-song#asset',
  type: ['Asset', 'schema:MusicRecording'],
  // this is the person who created the asset
  creator: { fullName: 'The Webdevs' },
  title: 'HTML5 Me, Baby',
  // this is the link to the paid content
  assetContent: 'http://listings.dev.payswarm.com/mozhacks/paid/html5-me-song',
  // this is the entity that has rights to the asset (the artist in this case)
  assetProvider: 'https://dev.payswarm.com/i/the-webdevs',
  // these are restrictions under which the asset can be sold
  listingRestrictions: {
    // validity dates so that the price information below doesn't
    // last forever (you may want to change your price)
    validFrom: payswarm.w3cDate(validFrom),
    validUntil: payswarm.w3cDate(validUntil),
    payee: [{
      // this is an entity that should be paid when the asset is sold
      type: 'Payee',
      // when the asset is sold, put the money for the asset provider here
      destination: 'https://dev.payswarm.com/i/the-webdevs/accounts/royalties',
      // the name of the group determines how this particular payee's rate comes
      // out of the total price of the sale
      payeeGroup: ['assetProvider'],
      // next 6 lines: the greater of 80% of the vendor's price or $0.50 should go
      // to the content creator
      payeeRate: '80',
      payeeRateType: 'Percentage',
      payeeApplyType: 'ApplyInclusively',
      payeeApplyGroup: ['vendor'],
      minimumAmount: '0.50',
      currency: 'USD',
      // show this to the buyer as one of the line items in the digital receipt
      comment: 'Payment to The Webdevs for creating the HTML5 Me, Baby song'
    }],
    payeeRule: [{
      // next 2 lines: allow the payment processor (the PaySwarm Authority) to add
      // a fee for processing the transaction
      type: 'PayeeRule',
      payeeGroupPrefix: ['authority']
    }, {
      // next 4 lines: vendors can only specify a flat fee for reselling the song
      // from their website
      type: 'PayeeRule',
      payeeGroup: ['vendor'],
      payeeRateType: 'FlatAmount',
      payeeApplyType: 'ApplyExclusively'
    }]
  }
};

上面的代码是关于 30 行代码的资产描述的更全面的示例(不含注释)。它描述了一个名为HTML5 Me, Baby 的资产(一首歌曲),任何符合其他限制的人都可以出售它。描述这种资产的内容创建者在网络上为其粉丝群创造了一种激励机制,使他们能够在自己的个人博客上宣传和转售内容。想象一下,一个 WordPress 插件允许你直接从你的博客中评论并转售你最喜欢的乐队的歌曲。无论哪个博客出售它或哪个 PaySwarm 授权机构处理支付,艺术家都能保证得到报酬。在这个特定的例子中,资产提供者已允许其粉丝获得 20% 的销售分成。

当上述歌曲销售发生时,80% 的售价(或最低 0.50 美元)将转给资产提供者。PaySwarm 授权机构可能会收取处理资产支付的费用。供应商可能会为歌曲设置一个固定价格。例如,如果歌曲售价为 1.00 美元,则 0.80 美元将归 The Webdevs 所有(80% 的最终价格限制生效)。如果歌曲售价为 0.60 美元,则 0.50 美元将归 The WebDevs 所有(0.50 美元的最低限制生效)。正如你所看到的,列表限制为资产提供者提供了极大的权力来精确指定其产品的销售方式。

创建资产后,开发者可以使用她的私钥对资产进行数字签名

payswarm.sign(asset, {
  publicKeyId: publicKey.id,
  privateKeyPem: privateKey.privateKeyPem
}, function(err, signedAsset) {
  // do something with the signed asset
});

对资产进行数字签名可确保没有人可以更改与它相关的任何信息。这很重要,因为至少内容创建者不希望从应在资产出售时得到报酬的人员名单中删除。数字签名还向买方保证,内容创建者确实按所示描述了资产及其销售限制。

准备待售资产的下一步是为资产创建一个特殊的标识符,以便可以准确地通过列表引用它。此标识符称为加密哈希,使用 payswarm.js 库的 hash() 函数生成

// generate a hash for the signed asset
payswarm.hash(signedAsset, function(err, assetHash) {
  // do something with the signed asset hash
});

有了已签名的资产和已签名的资产哈希,我们就可以创建用于购买资产的列表。

创建列表

如本文前面所述,清单是描述资产出售条款的文档。清单,就像资产一样,使用 JSON-LD 表达。下面的清单指定了要与出售资产相关的许可证,以及谁应该获得出售资产的款项。它还规定了对某些收款人的限制,例如 PaySwarm Authority 在处理付款时可以收取的费用上限。请特别注意每行上面的注释,它们解释了该行代码的作用。

// create the listing
var listing = {
  // the @context is a hint to a JSON-LD processor on how to interpret the
  // key-value pairs in the document
  '@context': 'https://w3id.org/payswarm/v1',
  // this is the identifier for the listing
  id: 'http://listings.dev.payswarm.com/mozhacks/html5-me-song#listing',
  type: ['Listing'],
  // the identity offering the item for sale is The WebDevs
  vendor: 'https://dev.payswarm.com/i/the-webdevs',
  payee: [{
    type: 'Payee',
    // payment should be deposited into this financial account
    destination: 'https://dev.payswarm.com/i/the-webdevs/accounts/royalties',
    // this is used to determine how fees are applied to the final price
    payeeGroup: ['vendor'],
    // the next 4 lines: Sell the song for $1.00
    payeeRateType: 'FlatAmount',
    payeeRate: '1.00',
    currency: 'USD',
    payeeApplyType: 'ApplyExclusively',
    // this should be displayed for the line item in the digital receipt
    comment: 'Payment to The Webdevs for creating the HTML5 Me, Baby song'
  }],
  // the next 6 lines: The payment processor cannot take more than 5% of
  // the total sale price.
  payeeRule : [{
    type: 'PayeeRule',
    payeeGroupPrefix: ['authority'],
    payeeRateType: 'Percentage',
    maximumPayeeRate: '5',
    payeeApplyType: 'ApplyInclusively'
  }],
  // this is the ID of the asset being sold
  asset: 'http://listings.dev.payswarm.com/mozhacks/html5-me-song#asset',
  assetHash: assetHash,
  // this is the license that should be associated with the asset upon sale
  license: 'https://w3id.org/payswarm/licenses/personal-use',
  licenseHash: 'urn:sha256:' +
    'd9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9',
  // the offer of sale is only valid between these two times
  validFrom: payswarm.w3cDate(validFrom),
  validUntil: payswarm.w3cDate(validUntil)
};

上面的代码表明歌曲 *HTML5 Me, Baby* 以 1.00 美元的价格出售,支付处理器在交易处理费用中不能收取超过总售价 5% 的费用。这首歌被许可用于个人使用,可以在提供的 URL 上找到 许可证全文。清单创建后,必须对其进行数字签名。

payswarm.sign(listing, {
  publicKeyId: cfg.publicKey.id,
  privateKeyPem: cfg.publicKey.privateKeyPem
}, function(err, signedListing) {
  // do something with the signed listing
});

清单进行数字签名与资产进行数字签名的理由相同:防止篡改并实现不可否认性。一旦资产和清单都签署,它们就可以发布。这可以通过将它们作为两个不同的文档或单个文档发布来完成。将它们作为单个 JSON-LD 文档发布的最简单方法是使用 “@graph” 关键字,它本质上表明您希望将两个独立的对象合并到同一个 JSON-LD 文档中。

var assetAndListing = {
  '@context': 'https://w3id.org/payswarm/v1',
  '@graph': [signedAsset, signedListing]
};

发布资产和清单

发布过程的最后一步是获取签名的资产和清单文档,并将它们发布到网络上。由于 PaySwarm 是去中心化的,我们可以将我们签名的资产和清单发布到 *任何* 网站上。由于资产是数字签名的,因此网站无需受到传输层安全协议 (TLS)(通常称为 HTTPS)的保护。数字签名保证没有人可以修改数据而不会使资产和清单上的签名无效。在以下示例中,我们使用 payswarm.js 库的 `postJsonLd()` 函数将资产和清单上传到公共 PaySwarm 清单服务。

var url = 'http://listings.dev.payswarm.com/mozhacks/html5-me-song';
payswarm.postJsonLd(url, assetAndListing, function(err, result) {
  // if result is a 200, then your listing has been published
});

资产和清单上传后,任何 PaySwarm 客户端都可以购买该资产。请注意,虽然资产和清单信息以 JSON-LD 表达,但它也可以轻松地作为 HTML5+RDFa 发布。PaySwarm Authority 能够解释 JSON-LD 和 RDFa。虽然我们不会在本博文中详细介绍,但一篇将来的博文将介绍如何获取上面表达的资产和清单链接数据,并将其作为 HTML5+RDFa 发布。

下一步:购买资产

这是关于开发支持 PaySwarm 的 Web 应用程序以进行商务活动的三部分系列文章中的第二篇。下一篇文章将解释如何购买本教程中创建的资产,以及如何检索销售的数字收据。

关于 Manu Sporny

W3C 网络支付创始人。RDFa 和 JSON-LD 工作组主席。PaySwarm、JSON-LD 和 HTML5+RDFa 规范的主要编辑。创立了创建世界上第一个商业 PaySwarm 支付处理器的公司 Meritora。领导将金融和支付集成到网络核心架构中。许多与标准相关的作品,重点是让世界变得对所有人更美好。其他帐户:@manusporny+Manu SpornyLinkedIn博客.

更多 Manu Sporny 的文章…

关于 Robert Nyman [名誉编辑]

Mozilla Hacks 技术布道师和编辑。发表关于 HTML5、JavaScript 和开放网络的演讲和博客。Robert 是 HTML5 和开放网络的坚定支持者,自 1999 年以来一直在瑞典和纽约市从事网络前端开发工作。他还经常在 http://robertnyman.com 上发表博客,喜欢旅行和结识新朋友。

更多 Robert Nyman [名誉编辑] 的文章…