区块链上的订阅
为分散式应用程式(以太坊)实施订阅模型
介绍
您可能已经听说过,去中心化的应用程序将成为互联网的未来。 为了使这个分散的生态系统蓬勃发展并可持续发展,我们将需要许多开发人员来开发应用程序。 这些开发商显然想赚钱。 但是由于分散式应用程序太新了,因此如何使用它们来赚钱存在很多困惑。 我相信一些传统的收入模型可以在区块链上运行 。 因此,我创建了一个系列,在其中实现了它们,以作为将来应用程序的示例。 在本文中,我们将学习何时以及如何在Solidity中实现订阅模型。
生存能力-“何时”
在进入代码之前,让我们谈谈订阅何时可以在区块链上工作。 当您的应用程序分散时,任何人都可以看到组成该应用程序的合同; 这意味着他们可以复制和粘贴您的代码以立即复制产品的很大一部分。 如果前端是开源的或托管在分散存储中,则可以克隆所有应用程序代码。
那么,如何使用户继续使用我们的应用程序呢? 答案在于无法克隆的一个要素:网络。 如果您的应用程序具有网络效应 ,则用户将倾向于具有更好网络或更大用户群的应用程序。 表现出网络效应的应用包括社交应用,例如Tinder,Facebook和Instagram。 我喜欢认为这类似于中本聪共识,人们选择最长的链条作为有效链条。
回到订阅,在Tinder的示例中,订阅的价值与Tinder上的用户数量有关。 如果有人克隆了Tinder,那将毫无价值,因为几乎没有用户使用该克隆。 没有人会在克隆上订阅Superlike ,因为没有人让他们使用Superlike。
总而言之,如果订阅模型具有网络效应并具有一定的用户群,则可以与您的dApp一起使用。 为了对克隆具有更大的弹性,某些订阅功能本身也应具有网络效应。
实施-“如何”
在订阅模式中,用户可以付费在一定时间内解锁对特殊功能的访问。 当然,为了使用户支付使用该产品的经常性费用,它必须是一流的。 因此,在我们的示例中,高级功能将来自最佳订阅产品之一: Tinder Gold 。
为了实现此模型,我们将创建一种跟踪订户并制作只能由他们访问的高级功能的方法。 以下所有代码示例都可以在Github上找到。
我们将从两种结构开始:一种结构用于用户及其Tinder卡,另一种结构用于订阅。 我们将假定每个Tinder卡的数据(图像等)存储在IPFS (网络上的对等协议)上。 为了引用该数据,我们可以使用存储卡的哈希值。
User public userInfo;
struct User {
address userAddr; // user's ethereum address
Subscription subInfo; // store their subscription
bytes current; // hash of currently displayed card
bytes previous; // hash of previous swiped Card
}
struct Subscription {
bool status; // store if the user is subscribed (T/F)
uint expiry; // when the user susbcription expires
}
接下来,构造函数创建用户并将其订阅状态设置为false。 到期时间设置为当前时间,稍后我们将使用它。 对于Tinder Cards,我使用了一些任意哈希,它的特定值与我们的目的无关。
constructor() public
{
userInfo = User({
userAddr:msg.sender, //The address of the user
subInfo:Subscription({status: false, expiry: block.timestamp}),
current:"Qm78fg903b9209rh20f03dla",
previous:""
});
}
现在,我们需要一种供用户付款和订阅的方法。 让我们做一个改变用户订阅状态的付费功能。 订阅一个月将花费1 ETH。 他们可以通过调用函数适当的时间来订阅一个月的任意多个。
function subscribe() public payable
{
require(msg.value == 1 ether); //or else function will throw
userInfo.subInfo.status = true;
userInfo.subInfo.expiry = block.timestamp + 30 days;
}
您可能会注意到,以太币正在支付给合同,而不是应用程序所有者。 所有者需要有一种方式来接收他们新发现的财富。 为此,我们可以存储所有者的地址,并将以下行添加到subscribe()函数中。
address public appOwner = 0xac4013A20D0FDb5908673CBCD4d400e3DC68726b;
function subscribe() public payable //function from above
{
// ... omitted lines
appOwner.transfer(1 ether); //sending the money to the owner
}
对于订阅处理程序的最后一部分,我们需要一种内部方法来检查用户是否已订阅。 这比仅检查status变量是true还是false稍微复杂一点,因为当订阅到期时,合同无法自动将status设置为false。 为了解决这个问题,我们还需要检查当前时间是否超过了用户订阅时设置的过期时间戳记。
function checkSubscription() internal returns(bool status)
{
if(userInfo.subInfo.status != true) {
// if the user is not subscribed
return false;
}
if (block.timestamp >= userInfo.subInfo.expiry) {
// if the subscription has expired
// update status to false
userInfo.subInfo.status = false;
return false;
} else {
return true;
}
}
凉。 现在我们已经完成了所有这些工作,我们可以为订户实现高级功能。 Tinder Gold订户具有一项名为Rewind的功能,可让您取回上一次滑动。 我们可以利用我们之前的功能checkSubscription()来确保用户是允许订阅者回退之前的订阅者。
function rewind() public returns(bool success)
{
if(checkSubscription() != true) {
return false;
} else {
userInfo.current = previous; //rewinding swipe
userInfo.previous = "";
return true;
}
}
最后,我们可以创建一个公共函数来检查用户是否已订阅而不使用gas。 这一点很重要,因此应用程序的前端可以避免显示用户无法访问的功能(如果调用不正确,则会浪费大量气体)。 使此功能无气的关键字为“恒定”。
function peekSubscription() public constant returns(bool status) {
if(userInfo.subInfo.status != true ||
block.timestamp >= userInfo.subInfo.expiry) {
return false; //user is not subscribed
} else {
return true; //user is subscribed
}
}
我们必须制作一个新函数而不是以前使用checkSubscription()函数的原因是,如果订阅已过期,则checkSubscription()需要进行状态更改。 因此,不能使该函数恒定。
结束
好了,到此结束了我们进入订阅模型的尝试。 请记住,这只有在您的应用具有网络影响和庞大的用户群的情况下才有效。 现在使用dApp制作机架!
完整的合同代码在Github上 。 这是我第一次编写Solidity代码,因此请不要在未审核合同的情况下使用合同。
发现错误? 有建议或反馈吗? 在下方留言。
在kaushikdevireddy.com上了解有关我的更多信息
From: https://hackernoon.com/subscriptions-on-the-blockchain-c037ade68242