14个版本 (9个重大突破)
13.1.0 | 2024年7月15日 |
---|---|
12.1.0 | 2024年6月25日 |
11.1.0 | 2024年6月13日 |
10.1.0 | 2024年5月21日 |
1.1.0 | 2023年10月27日 |
#1 in #encointer
1,814 每月下载量
210KB
4.5K SLoC
pallet-encointer-bazaar
这个crate是Encointer区块链逻辑的一部分,基于substrate / polkadot-sdk
有关高级技术以及用例文档,请参阅我们的书籍
设计
这是一个设计文档WIP,并不总是反映当前的实现
范围
Encointer bazaar应当
- 尽可能遵循电子商务的GoodRelations词汇表
- 与schema.org json兼容
- LocalBusiness 许多商店可能已经为谷歌地图准备了这些
- Product 任何提供的商品或服务。例如:一双鞋;音乐会门票;租用汽车;理发;或在线流式传输的电视剧集。
- Offer / Demand 带有价格和交付方式
自定义rpc方法
为了良好的API性能和开发体验,encointer节点应提供对bazaar的方便查询。通常,查询仅涉及一个社区
bazaar_getMyLocalBusinesses(谁:AccountId)
返回:JsonArray<local_business: AccountId>
获取由who控制的全部业务。需要遍历所有代理账户,以查看哪些账户委托给who
bazaar_getLocalBusinesses(cid:CommunityIdentifier)
返回:JsonArray<(local_business: AccountId, json: url)>
获取特定社区的所有业务账户及其元数据URL
bazaar_getOfferings(cid:CommunityIdentifier,local_business?:AccountId,since?:区块编号)
返回: JsonArray<(offering: url)>
可选
- local_business: 仅查询该业务提供的商品
- since: 允许通过更新的区块高度进行过滤,以查询最新的条目
用例
- 业务管理
- 创建业务
- 编辑业务
- 删除业务
- 商品管理
- 创建商品
- 编辑商品
- 删除商品
- 查看(RPC)
- 每个社区的业务
- 每个社区的商品
- 每个业务的商品
建议的存储模型
BusinessRegistry: double_map(CommunityId, BusinessAccountId) -> (business_url, last_oid)
OfferingRegistry: double_map((CommunityId, BusinessAccountId), OfferingId) -> (offering_url)
BusinessAccountId是匿名代理(即业务)的公钥。所描述的元组/三元组被封装在值类型对象中。
分派伪代码
createBusiness(CommunityId, business_url) {
var BusinessAccountId = new AnonymousProxy(sender);
BusinessRegistry.insert(CommunityId,
BusinessAccountId,
(business_url, 1, currrent_block_number));
}
updateBusiness(CommunityId, BusinessAccountId, new_business_url) {
verify(BusinessAccountId, sender);
BusinessRegistry.mutate(CommunityId, BusinessAccountId, (new_business_url, counter, current_block_number));
}
deleteBusiness(CommunityId, BusinessAccountId) {
verify(BusinessAccountId, sender);
BusinessRegistry.remove(CommunityId, BusinessAccountId);
OfferingRegistry.remove_prefix((CommunityId, BusinessId));
}
createOffering(CommunityId, BusinessAccountId, offering_url) {
verify(BusinessAccountId, sender);
var OfferingId = BusinessRegistry.get(CommunityId, BusinessAccountId).counter++
OfferingRegistry.insert((CommunityId, BusinessAccountId), OfferingId, (offering_url, block_number));
return OfferingId;
}
updateOffering(BusinessAccountId, OfferingId, new_offering_url) {
verify(BusinessAccountId, sender);
OfferingRegistry.mutate((CommunityId, BusinessAccountId), OfferingId, (BusinessAccountId, new_offering_url));
}
deleteOffering(BusinessAccountId, OfferingId) {
verify(BusinessAccountId, sender);
OfferingRegistry.remove((CommunityId, BusinessAccountId), OfferingId);
}
RPCs
viewBusinesses(cid) {
return BusinessRegistry.get(cid);
}
viewOfferings(cid) {
return BusinessRegistry.get(cid).flatMap(bid -> OfferingRegistry.get(bid));
}
viewOfferings(bid) {
return OfferingRegistry.get(bid);
}
性能考虑
对于特定业务提出的viewOfferings实现具有O(n)的复杂度。它应仅通过链外RPC进行评估。
复杂度 Vec
与 map
对于集合
操作 | vec |
map |
---|---|---|
成员检查 | 数据库读取:O(1) 解码:O(n) 搜索:O(log n) | 数据库读取:O(1) |
更新 | 数据库写入:O(1) 编码:O(n) | 数据库读取:O(1) 编码:O(1) 数据库写入:O(1) |
迭代 | 数据库读取:O(1) 解码:O(n) 处理:O(n) | 数据库读取:O(n) 解码:O(n) 处理:O(n) |
迭代复杂度(其中vec会更好)是不相关的,因为bazaar pallet不进行迭代
显然,map
在大型n(无n较小调用数量的缺点)的情况下,在可调度weight
方面具有更好的扩展性。此外,weight
是常数,与n
无关
移动应用或Web界面通常会获取给定cid
的整个集合,因此Vec
更易于使用。然而,如果我们添加自定义RPC API来获取这些集合,我们可以提供一个方便的API,同时只对API节点产生轻微的额外负载
依赖项
~20–36MB
~603K SLoC