時(shí)間:2023-03-31|瀏覽:616
來源:W3.Hitchhiker
原文標(biāo)題:《The Billion User Social Graph》
撰文:Jon Stokes
編譯:Dan,W3.Hitchhiker
如何利用區(qū)塊鏈和智能合約技術(shù)構(gòu)建出十億用戶的 Web3 社交圖譜?
隨著埃隆 - 馬斯克最近接管了 Twitter,關(guān)于從大型社交網(wǎng)絡(luò)遷移到獨(dú)立或開放的替代方案的討論已經(jīng)越來越多,但是所有那些剛開始幻想在加入繁榮的 Twitter 前居民社區(qū)的人,很快就會(huì)遇到自 J6 之后的跨平臺(tái)社交媒體大清洗以來,右派一直在努力解決的問題:網(wǎng)絡(luò)鎖定是真實(shí)的。
你可以對(duì)協(xié)調(diào)問題、偏好級(jí)聯(lián)、信號(hào)和其他游戲理論式的概念進(jìn)行理論和策略分析–我不否認(rèn)這些都是理解問題的有用方法–但要理解 Twitter 和 Facebook 對(duì)我們數(shù)億人的強(qiáng)大影響,你真正需要知道的是網(wǎng)絡(luò)時(shí)代初期的一個(gè)簡(jiǎn)單啟發(fā)式方法
梅特卡夫定律指出,電信網(wǎng)絡(luò)的價(jià)值與系統(tǒng)的連接用戶數(shù)的平方成正比(n2)。梅特卡夫定律最初是由 George Gilder 在 1993 年以這種形式提出的,并歸功于 Robert Metcalfe 在以太網(wǎng)方面的工作。大約在 1980 年,梅特卡夫定律最初不是以用戶為單位,而是以「兼容的通信設(shè)備」(如傳真機(jī)、電話)為單位。只是后來隨著互聯(lián)網(wǎng)的全球化,這一定律才延續(xù)到了用戶和網(wǎng)絡(luò),因?yàn)樗某踔允敲枋鲆蕴W(wǎng)連接。
要讓人們放棄一個(gè)大的、密集的網(wǎng)絡(luò)圖,而選擇一個(gè)小的、稀疏的網(wǎng)絡(luò)圖,幾乎是不可能的,唯一的原因是前者有價(jià)值,而后者沒有。
不過奇怪的是,web3 解決了這個(gè)問題?;蛘咧辽偃绻覀兪褂靡恍┖?jiǎn)單的智能合約,將區(qū)塊鏈從一個(gè)巨大的用戶表變成一個(gè)巨大的社交圖譜,它可以解決這個(gè)問題。
區(qū)塊鏈可以而且確實(shí)作為一個(gè)巨大的、共享的用戶表發(fā)揮作用,它是開放的、公開的,不受任何一個(gè)實(shí)體控制。正如我在《十億用戶表》中寫的那樣:
公共區(qū)塊鏈相當(dāng)于整個(gè)互聯(lián)網(wǎng)的一個(gè)單一的、大規(guī)模的用戶表,下一波分布式應(yīng)用將建立在它之上。
取而代之的是一個(gè)由 API 連接的分散的用戶數(shù)據(jù)倉(cāng)網(wǎng)絡(luò),一個(gè)通過開放協(xié)議和分散的存儲(chǔ)節(jié)點(diǎn)網(wǎng)絡(luò)訪問的單一分散的用戶數(shù)據(jù)存儲(chǔ)。因此,身份托管區(qū)塊鏈代表了數(shù)據(jù)存儲(chǔ)實(shí)施層的去中心化,以及數(shù)據(jù)存儲(chǔ)訪問層的再中心化。
想象一下,LinkedIn、Reddit 和 Github 都將他們的用戶表(以及他們的許多專有數(shù)據(jù),如認(rèn)可、積分和活動(dòng)歷史)移植到 BitClout。馬上就會(huì)發(fā)生以下情況:每個(gè) Github 用戶也是 Reddit 用戶、LinkedIn 用戶和 BitClout 用戶。同樣,每個(gè) Reddit 用戶也是 Github 用戶、LinkedIn 用戶和 BitClout 用戶。我可以繼續(xù)說下去,但你會(huì)明白這一點(diǎn)。
每個(gè)建立在同一虛擬用戶表上的公司都能立即獲得該表上其他每家創(chuàng)業(yè)公司的網(wǎng)絡(luò)效應(yīng)。每當(dāng)一個(gè)鏈上公司加入一個(gè)新的用戶,那么你的服務(wù)也有一個(gè)新的用戶。( 從某種程度上說。他們可能還沒有積極使用你的服務(wù),但他們實(shí)際上在你的服務(wù)的潛在用戶)。
先前的那篇文章用 Bitclout(該項(xiàng)目中的鏈現(xiàn)在被稱為 DeSo)作為可以支持這種用例的區(qū)塊鏈的典型例子。但是,盡管我對(duì) DeSo 的整個(gè)事情感到興奮,但它的結(jié)果并不那么好。
這里不適合做 Bitclout / DeSo 的事后總結(jié),但標(biāo)出該區(qū)塊鏈的一個(gè)方面是有意義的,因?yàn)樗鼘?duì)現(xiàn)在的討論很重要。Bitclout 努力將整個(gè)社交網(wǎng)絡(luò)放在鏈上,每個(gè)帖子都被寫在鏈上,作為一個(gè)對(duì)象,可以累積收入(通過 Bitclout 鉆石)。這很聰明,但任何試圖承載實(shí)際內(nèi)容的區(qū)塊鏈都會(huì)看到其數(shù)據(jù)需求隨著用戶和連接的數(shù)量而非線性增長(zhǎng)。
Bitclout 團(tuán)隊(duì)非常熟悉這種無限制的數(shù)據(jù)增長(zhǎng)問題,并花費(fèi)了大量的實(shí)際工程努力來解決這個(gè)問題。但事后看來,我實(shí)際上認(rèn)為他們?cè)噲D同時(shí)做太多的事情。他們應(yīng)該只專注于社交圖的可移植性問題。
用我之前文章中的數(shù)據(jù)庫(kù)術(shù)語來描述,Bitclout 試圖把以下所有的表都放在鏈上(另外還有一些是 Bitclout 特有的):
users
user_follows_user
posts
user_likes_post
最后兩張表總是出現(xiàn)數(shù)據(jù)爆炸,在用戶迅速增長(zhǎng)的情況下都會(huì)變得不容易操作。
因此,我認(rèn)為更好的方法是采用現(xiàn)有的區(qū)塊鏈,它基本上已經(jīng)是那個(gè)第一張表(即用戶),并在其中添加一個(gè) user_follows_user 連接表。( 我們還可以為其他類型的關(guān)系擴(kuò)展連接,如 user_mutes_user,但目前我們還是保持簡(jiǎn)單的。)
這個(gè)用戶對(duì)用戶的連接表也會(huì)隨著用戶數(shù)量的增加而非線性增長(zhǎng),但增長(zhǎng)速度會(huì)比較慢,更重要的是,為了表示它所需要的額外數(shù)據(jù)量(=它所消耗的額外塊空間量)將遠(yuǎn)遠(yuǎn)低于帖子表。
我這樣建議是因?yàn)橛脩艉头劢z關(guān)系構(gòu)成了每個(gè)大型社交網(wǎng)絡(luò)平臺(tái)鎖定的主要來源。如果你的整個(gè) Twitter 或 Facebook 的社交圖譜都是開放的,并且可以隨時(shí)提供給其他想要托管帖子和其他更多數(shù)據(jù)密集型的社交網(wǎng)絡(luò)體驗(yàn)的社交平臺(tái),那么這些平臺(tái)的鎖定性基本上為零。
想象一下,我的整個(gè)推特圖是在鏈上體現(xiàn)的–包括實(shí)際的賬戶和追隨者關(guān)系。為了查看該圖中的 Twitter 帖子(以及相關(guān)的喜歡、轉(zhuǎn)發(fā)、引用 - 轉(zhuǎn)發(fā)等),我需要用我的錢包連接到 Twitter.com。但是,假設(shè)我想跳轉(zhuǎn)到 tribel.com,或 gab.com,或其他一些有自己特殊傾向和節(jié)制政策的社交平臺(tái)–如果他們能從區(qū)塊鏈上讀取我的社交圖譜,那么我可以在那里連接我的錢包,看到同樣的連接,并看到他們?cè)谶@個(gè)其他網(wǎng)站上的任何帖子。
這聽起來可能沒那么有吸引力,但考慮到這樣一個(gè)事實(shí):如果我在 Tribel 上關(guān)注一個(gè)新的人,那么我現(xiàn)在也在 Twitter 和 Gab 上關(guān)注這個(gè)人–以及在其他所有使用相同鏈上圖的用戶和關(guān)系的社交平臺(tái)上。取消關(guān)注和屏蔽的工作方式也一樣–在一個(gè)地方做一次,你的圖譜的變化就會(huì)立即反映在所有地方。
現(xiàn)在,那些在閱讀時(shí)想利用這一點(diǎn)的已經(jīng)意識(shí)到,在一個(gè)如上所述的世界中,將不可避免地發(fā)生什么:有人會(huì)制作一個(gè)全能客戶端,讓你通過一個(gè)界面從任何或所有這些網(wǎng)絡(luò)中閱讀和發(fā)布信息。那么,擁有獨(dú)立的服務(wù)就沒有意義了,他們都會(huì)倒閉……或者他們會(huì)嗎?
我所描述的世界已經(jīng)以一種原型狀態(tài)存在,以競(jìng)爭(zhēng)性信息協(xié)議的形式存在,這些協(xié)議都與你的電話號(hào)碼相聯(lián)系,并從你的聯(lián)系人數(shù)據(jù)庫(kù)中填充自己。電話號(hào)碼系統(tǒng)是億萬用戶表的原型,而分布式的聯(lián)系人應(yīng)用程序都可以讀寫標(biāo)準(zhǔn)的 Vcard 格式,構(gòu)成了建立在該表之上的關(guān)系圖。
有許多信息傳遞協(xié)議都是借助于這種電話號(hào)碼 + 聯(lián)系人的組合,其結(jié)果有點(diǎn)像我在這里描述的社交網(wǎng)絡(luò)。例如,當(dāng)你第一次登錄 Telegram 時(shí),它會(huì)掃描你的聯(lián)系人,然后你立即在這個(gè)新的應(yīng)用程序中擁有你現(xiàn)有的網(wǎng)絡(luò)。
其結(jié)果是,你可以選擇通過 Signal、Telegram、WhatsApp、iMessage 或傳統(tǒng)短信與相同的電話號(hào)碼交換信息–這一切都在于你和你的網(wǎng)絡(luò)中的其他人想使用哪種信息協(xié)議。
還有一個(gè)永恒的循環(huán),就是消息應(yīng)用的去中心化和再中心化,這從 ICQ 時(shí)代就開始了,在 WhatsApp / Signal / Telegram / Facebook / 等的時(shí)代仍然在發(fā)生。你可以找到任何數(shù)量的多合一消息客戶端,在一個(gè)窗口中支持許多這些平臺(tái)。
這些信息應(yīng)用都沒有受到損害,因?yàn)樗鼈兌紡耐粋€(gè)開放的電話號(hào)碼系統(tǒng)和可互操作的聯(lián)系人應(yīng)用和服務(wù)生態(tài)系統(tǒng)中獲取身份–它們都共存并帶來不同的東西,而且我們中的許多人在它們之間切換,與我們聯(lián)系人中具有不同需求和偏好的不同子圖交談。如果我們把社交圖譜移到鏈上,我希望這種動(dòng)態(tài)會(huì)持續(xù)下去。
不同的平臺(tái)有不同類型的社交連接,用戶可以相互之間的連接。Facebook 有朋友、關(guān)注和屏蔽。Twitter 有關(guān)注、靜音和屏蔽。這些對(duì)于這些平臺(tái)來說是很好的,但我們可以改進(jìn)它們,使它們更適合區(qū)塊鏈,使它們更具有可組合性。
可組合性是一個(gè)計(jì)算機(jī)科學(xué)術(shù)語,大概意思是,你可以混合和匹配這些小的、離散的、明確定義的工具,以獲得不同的效果和功能。
考慮到 Facebook 的「朋友」–這是它自己的連接類型,但它也意味著「關(guān)注」,因?yàn)楫?dāng)你把某人加為好友時(shí),你會(huì)自動(dòng)關(guān)注他們。在 Twitter 上,「封殺」意味著「靜音」,因?yàn)楫?dāng)你屏蔽某人時(shí),你基本上是在讓他們靜音,同時(shí)也阻止他們看到你的帖子。
對(duì)于我自己的兩個(gè)社交圖譜的建議,下面,我想建議跟隨,更干凈和可組合的社交圖譜關(guān)系集:
關(guān)注: 你可以閱讀你所關(guān)注的人的帖子。
靜音: 你不能閱讀你已經(jīng)靜音的人的帖子。
屏蔽:你屏蔽的人不能閱讀你的帖子。
在這個(gè)方案下,一個(gè)封殺是一個(gè)「靜音」加一個(gè)「屏蔽」,所以它是對(duì)同一個(gè)目標(biāo)地址的兩個(gè)操作,一起組成的(例如,如果我想封殺 annoyinghater.eth,我就把這個(gè)地址靜音,再把它的屏蔽)。
如果我想看到某人的帖子,但又不想讓他們看到我自己的帖子,我可以關(guān)注他們,再加上屏蔽?;蛘?,如果我想保留通過導(dǎo)航到他們的內(nèi)容或定期取消他們的靜音來閱讀,我可以關(guān)注加靜音。
我試圖以這種方式理清關(guān)系,因?yàn)樗刮覀兏菀淄评斫酉聛淼恼鹿?jié)中的合約和關(guān)系。
在本文的其余部分,我提出了兩個(gè)將社交圖譜分層到十億用戶表中的建議。
第一種,On-Chain Graph(OCG),更加開放和簡(jiǎn)單,但在費(fèi)用方面也更加昂貴,所以有些人會(huì)喜歡它,有些人不會(huì)。
第二種,鏈?zhǔn)綀D(CLG),更復(fù)雜但更便宜,而且提供更多的控制和隱私,所以我預(yù)計(jì)大多數(shù)人會(huì)更喜歡它。不過,平臺(tái)可以同時(shí)支持這兩種方式。
要真正理解這兩個(gè)提案,你需要對(duì)以下概念有一些基本的熟悉:
不可拆分的代幣(NFT)和不可拆分不可轉(zhuǎn)讓的代幣(NTFT,也叫靈魂綁定的代幣)。
以太坊域名服務(wù)
智能合約
了解一點(diǎn) Solidity(以太坊的智能合約編程語言)也會(huì)有所幫助。如果你對(duì)上述一項(xiàng)或全部?jī)?nèi)容模糊不清,我試圖以一種你應(yīng)該仍然能夠掌握基本知識(shí)的方式來寫這篇文章。
對(duì)于這兩個(gè)提案,我假設(shè)我們使用 ENS 作為身份的根,并向其添加新的地址記錄,其中包含一些相當(dāng)標(biāo)準(zhǔn)的 ERC721 NFT 合約的地址,這些合約分別代表我上面概述的三種類型的社交關(guān)系(跟隨、靜音、屏蔽)。這三個(gè)合約的作用從一個(gè)提案到另一個(gè)提案都非常不同,但把它們的地址放入三個(gè)特殊的 ENS 地址記錄的基本想法保持不變。
我還想為社交用戶數(shù)據(jù) URI 提出一個(gè)額外的 ENS 記錄,這樣你就可以更新你的社交數(shù)據(jù)而不需要消耗 gas。一個(gè)擬議的 profileURI 記錄將鏈接到一個(gè)藏在某些第三方平臺(tái)上的 JSON 對(duì)象,看起來像這樣:
curl https://jonstokes.com/jons-profile.json
-H "Accept: application/json"
{
"name": "jonstokes.(eth|com)",
"bio": "Writer. Coder. Doomer Techno-Optimist. Cryptography Brother.",
"website": "https://jonstokes.com/",
"location": "Austin, TX"
}
檔案 JSON 中的一些內(nèi)容與現(xiàn)有的 ENS 字段是多余的,但這沒關(guān)系;這樣做的目的是為了給社交平臺(tái)提供一些可以顯示的東西,并讓用戶能夠?qū)λ麄兊纳缃粰n案進(jìn)行修改,而無需花費(fèi) gas 來更新 ENS 記錄。
On-Chain Graph 的想法使用 NTFT 來表示上述的三種關(guān)系。對(duì)于以下三個(gè)社交合約,持有 ENS NFT 的同一個(gè)錢包也應(yīng)該擁有這些合約,它們的三個(gè)對(duì)應(yīng)的 ENS 地址記錄應(yīng)該指向這些合約:
OCG 追隨者: 當(dāng)你從我的 OCG 追隨者合約中存入一個(gè) NTFT 到你的錢包,那么你就跟隨了我。我們中的任何一個(gè)人都可以銷毀這個(gè) NFT,使你取消對(duì)我的關(guān)注。
OCG 屏蔽: 當(dāng)我從我的 OCG Ghosted 合約中空投一個(gè) NTFT 到你的錢包中時(shí),我就對(duì)你產(chǎn)生了屏蔽。只有我可以銷毀這個(gè) NTFT 來解除對(duì)你的困擾。
OCG 靜音: 當(dāng)我從我的 OCG 靜音合約中空投一個(gè) NTFT 到你的錢包時(shí),我已經(jīng)把你靜音了。只有我可以銷毀這個(gè) NTFT 來解除你的靜音。
這三種情況的語義基本上都是:「相對(duì)于我,即合約所有者,你是 X」,其中「X」是追隨者、屏蔽、靜音的一種。
這里有一個(gè)追隨者合約樣本:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract OCGFollower is ERC721, ERC721Enumerable, Pausable, Ownable, ERC721Burnable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("OCGFollower", "OCGF") {}
function _baseURI() internal pure override returns (string memory) {
return "https://jonstokes.com/ocg/follower";
}
function relationship() public {
return "ocg follower";
}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
function safeMint(address to) public {
//Prevent anyone but the owner from minting
//a token to an address they don"t own.
require(isOwner(_msgSender()) || (_msgSender() == to), "Unable to mint to this address");
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
function _beforeTokenTransfer(address from, address to, uint256) pure override internal {
//Disable token transfers.
require(from == address(0) || to == address(0), "Cannot be transferred.");
}
// The following functions are overrides required by Solidity.
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
如果你熟悉 Solidity,你可以看到這個(gè)非常簡(jiǎn)單(而且未經(jīng)測(cè)試?。┑暮霞s試圖做什么。
首先是擴(kuò)展:
ERC721Enumerable 擴(kuò)展被包括在內(nèi),因此代幣持有者可以被社交網(wǎng)絡(luò)客戶端列出來,而不必掃描整個(gè)鏈。
我使用 Pausable 是因?yàn)槟銘?yīng)該能夠暫停造幣,以便基本上鎖定你的賬戶一段時(shí)間,即停止接受新的粉絲。
Ownable 是必不可少的,因?yàn)橛行┦虑橹挥泻霞s所有者應(yīng)該做。我認(rèn)為沒有必要使用更強(qiáng)大的角色功能。
ERC721Burnable 在這里,因?yàn)槟阈枰軌蜾N毀代幣,以便刪除關(guān)注關(guān)系。這里面包含的標(biāo)準(zhǔn) burn() 函數(shù)有我們需要的權(quán)限,即只有所有者或令牌所有者可以銷毀代幣。
我包含了Counters,這樣 tokenID 就會(huì)自動(dòng)遞增,這很方便。
現(xiàn)在對(duì) OpenZeppelin 向?qū)У妮敵鲞M(jìn)行修改:
safeMint() 被修改后,只有合約的所有者可以將代幣鑄幣到其他人的地址。對(duì)于所有非所有者,你只能向你調(diào)用合約的地址鑄幣。
_beforeTokenTransfer() 被重寫,這樣它就基本上禁止了轉(zhuǎn)讓代幣的能力,創(chuàng)造了一個(gè)簡(jiǎn)單的靈魂綁定的代幣。
relationship() 函數(shù)是一個(gè)方便的方法,確保有一個(gè)簡(jiǎn)單的方法來查詢合約并確認(rèn) NFT 代表什么樣的關(guān)系。我并不贊成包括這個(gè),但它似乎很有用。
這一切真的很簡(jiǎn)單,對(duì)于 OCG 的屏蔽和 OCG 的靜音變體,你要做以下小改動(dòng):
改變合約名稱和符號(hào)
改變 relationship() 和可能的 baseURI() 的返回值,以反映你所代表的關(guān)系(即,「muted」或「ghosted」)。
把 safeMint() 和 burn() 都變成 onlyOwner 函數(shù),這樣只有合約所有者可以調(diào)用這兩個(gè)函數(shù)。
顯然,這將取決于平臺(tái)是否以正確的方式履行這些合約(即關(guān)注、屏蔽、靜音)。不過,這沒有聽起來那么有威脅性和不穩(wěn)定,因?yàn)槿绻粋€(gè)特定的社交平臺(tái)不履行你所關(guān)心的合約,就不要使用它。
你可以在 safeMint 中加入 payable,然后使用 setMintRate 來設(shè)定人們必須為以下內(nèi)容向你支付的價(jià)格。因此,類似于這樣的內(nèi)容:
uint256 public mintRate = 0.01 ether;
function setMintRate(uint256 mintRate_) public onlyOwner {
mintRate = mintRate_;
}
function safeMint(address to) public payable {
// Require pay-to-follow
require(msg.value >= mintRate, "Not enough ether to mint");
//Prevent anyone but the owner from minting
//a token to an address they don"t own.
require(isOwner(_msgSender()) || (_msgSender() == to), "Unable to mint to this address");
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
我相信我還能想到許多其他的調(diào)整和功能來添加到這個(gè)建議中,但最好從簡(jiǎn)單和容易理解的東西開始。
上面描述的 OCG 合約足夠簡(jiǎn)單,但該方案有一些特質(zhì),可能會(huì)使很多人產(chǎn)生分歧:
所有的東西都是公開的,在鏈上的,包括屏蔽和靜音。你不能這樣做鎖定賬戶,但解決這個(gè)問題的辦法可能是使用一個(gè)替代賬戶。
每一個(gè)行動(dòng)都要花費(fèi) gas,這意味著你必須對(duì)你關(guān)注的人、屏蔽和靜音做出真正的選擇。但如果 gas 費(fèi)用足夠高,那么這可能會(huì)使網(wǎng)絡(luò)無法使用。
對(duì)于一個(gè)網(wǎng)絡(luò)或一個(gè)特定的賬戶來說,付費(fèi)關(guān)注可能是也可能不是一個(gè)理想的功能,但你會(huì)有這樣的選擇。
鑒于不是每個(gè)人都會(huì)喜歡這個(gè)建議的這些特質(zhì),我想提出一套替代的社交合約,給用戶和平臺(tái)更細(xì)化的控制,特別是誰能看到什么樣的信息,而且使用成本更低。
鏈?zhǔn)芥溄訄D(CLG)的基本思想: 我們不通過 NFT 直接在鏈上表示社交關(guān)系(關(guān)注、屏蔽、靜音),而是在鏈下存儲(chǔ)這些關(guān)系,并使用鏈上代幣來發(fā)現(xiàn)和訪問這些關(guān)系。
發(fā)現(xiàn): 該合約提供了一個(gè) listURI() 函數(shù),該函數(shù)返回一個(gè) JSON 列表的鏈接,該列表中的 ENS 名稱是你打算聲明某種社交關(guān)系的(即,我關(guān)注他們,我讓他們靜音,或者我屏蔽他們)。
訪問: 如果 listURI() 返回的鏈接是令牌控制的,那么合約的令牌就會(huì)授予持有者對(duì)元數(shù)據(jù)中發(fā)現(xiàn)的鏈接的讀取權(quán)限。
那么該社交關(guān)系就不是直接在鏈上的,而是通過一組合約和 URL 與鏈相連。
與 OCG 一樣,三種社交關(guān)系中的每一種都由智能合約來管理,但 CLG 的語義不同:
關(guān)注:包含一個(gè)鏈接到你正在關(guān)注的 ENS 名字的 JSON 列表,由它發(fā)出的令牌授予對(duì)該關(guān)注列表的讀取權(quán)限。
靜音:包含一個(gè)鏈接到你正在靜音的 ENS 名字的 JSON 列表,由它發(fā)出的令牌授予對(duì)該靜音列表的讀取權(quán)限。
屏蔽:包含一個(gè)鏈接到一個(gè)你正在屏蔽的 ENS 名字的 JSON 列表,由它發(fā)出的令牌授予對(duì)該屏蔽列表的讀取訪問權(quán)。
因此,CLG 令牌的語義是:「這是對(duì)我 X 賬戶列表的讀取權(quán)限」,其中「X」是「關(guān)注」、「靜音」或「屏蔽」。
你可以把我在這一節(jié)中提出的建議看作是我為信息應(yīng)用描述的電話號(hào)碼 + 地址簿組合的一個(gè)近似物。你的電話號(hào)碼是(準(zhǔn))公開的,當(dāng)你把一個(gè)新的消息應(yīng)用程序連接到它時(shí),你可以授予或拒絕該應(yīng)用程序?qū)δ愕穆?lián)系人的讀取權(quán)限。
在我的 CLG 社交令牌計(jì)劃中,你的 ENS 名字就像你的電話號(hào)碼一樣是公開的,你發(fā)行和撤銷令牌,以便授予和拒絕閱讀與你有某種關(guān)系的人的名單。如果你愿意,你可以把這些令牌授予隨機(jī)用戶,但主要是你要把它們授予社交平臺(tái),以便這些平臺(tái)知道誰的帖子要顯示給你,誰的帖子要隱藏(或誰不應(yīng)該看到你的帖子)。
( 對(duì)構(gòu)成你的社交圖的列表的寫入權(quán)限可能由你正常的 ENS NFT 控制–如果你的錢包里有你的 ENS 名字,你就可以對(duì)列表進(jìn)行寫入 / 更新 / 刪除的修改。一個(gè)可能的替代方案是有第四個(gè)社交合約,授予 NTFT 持有者列表寫入權(quán)限,這樣你就可以將列表管理外包給一些第三方)
在鏈下托管這些列表,同時(shí)從鏈上指向它們,有幾個(gè)好處:
你可以通過在托管列表的端點(diǎn)上使用認(rèn)證來鎖定你的關(guān)系,不讓公眾查看。或者你可以讓它對(duì)公眾開放,這樣任何人都可以閱讀它。
更新一個(gè)鏈下列表不需要花費(fèi) gas。
這個(gè)方案使得與社交供應(yīng)商互通的社交圖譜托管服務(wù)市場(chǎng)得以建立。
任何人或服務(wù)都可以輕易發(fā)現(xiàn)你的列表。
實(shí)現(xiàn) CLG 合約的關(guān)鍵創(chuàng)新是代幣訪問控制。代幣訪問控制背后的概念是,除非你用含有特定訪問代幣的錢包連接到主機(jī),否則你不能訪問主機(jī)上的特定數(shù)據(jù)。
例如,你可以對(duì) IPFS 上的內(nèi)容進(jìn)行代幣訪問控制,這樣只有用錢包中的特定 NFT 連接到端點(diǎn)的讀者才能查看特定的文件。
CLG 使用令牌門為我們的社交合約增加了一些間接性,因此,社交 NFT 不是代表一種特定類型的關(guān)系–關(guān)注、靜音或屏蔽–而是代表對(duì)你的社交圖譜的一部分的讀取權(quán)限。
很明顯,為了使代幣門檻發(fā)揮作用,平臺(tái)必須尊重它。據(jù)推測(cè),如果平臺(tái)不尊重代幣訪問控制,你會(huì)把你的關(guān)系列表轉(zhuǎn)移到其他平臺(tái),并改變你的合約,必要時(shí)重新發(fā)布任何 NFT。
另外,要清楚的是,有些人的名單在某些時(shí)候會(huì)泄露。我們生活在一個(gè)個(gè)人數(shù)據(jù)泄露的世界,所以如果數(shù)據(jù)被托管在某個(gè)地方,那么有些數(shù)據(jù)就會(huì)被泄露。我將在后面的章節(jié)中討論一些可能的緩解措施。
下面的合約將是一個(gè)標(biāo)準(zhǔn)的 ERC721 NTFT 合約,與上述 OCG 的合約非常接近:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract CLGFollows is ERC721, Pausable, Ownable, ERC721Burnable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("CLGFollows", "CLGF") {}
function _baseURI() internal pure override returns (string memory) {
return "https://jonstokes.com/clgfollows/";
}
function listURI() public {
return "https://jonstokes.com/clgfollows/list";
}
function relationship() public {
return "clg follows";
}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
function safeMint(address to) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
function _beforeTokenTransfer(address from, address to, uint256) pure override internal {
//Disable token transfers.
require(from == address(0) || to == address(0), "Cannot be transferred.");
}
}
所有的擴(kuò)展都與 OCG 相同,只是我沒有包括 ERC721Enumerable,因?yàn)椴磺宄欠裼腥讼胱屗麄兊?CLG Follows 代幣被列舉出來(另外它提高了鑄幣的 gas 成本)
至于函數(shù)方面,我對(duì) OpenZeppelin 向?qū)У妮敵鲎隽艘韵滦薷模?/p>
relationship(): 與 OLG 一樣,它返回社交合約的類型。同樣,對(duì)于 Solidity 合約來說,這可能沒有必要,我也沒有見過這樣做,但盡管如此,我覺得我想讓合約自我報(bào)告它的類型。所以我不知道–如果這冒犯了你,請(qǐng)忽略。
listURI() 返回一個(gè)指向 JSON 對(duì)象的鏈接,該對(duì)象是你正在關(guān)注(或靜音或屏蔽,取決于合約類型)的 ENS 名稱列表。我們希望這個(gè) URI 能被標(biāo)記為隱私,但這并不是必須的。
大多數(shù)情況下,你會(huì)使用 CLG Follows NTFT,把它發(fā)布到社交平臺(tái)擁有的地址。這樣,該平臺(tái)可以讀取你的關(guān)注列表,并向你展示正確的帖子。
但你也可以把這些 NTFTs 發(fā)給追隨者,以便你的追隨者可以發(fā)現(xiàn)其他追隨者。你可以通過空投給追隨者,或者通過解禁造幣,讓任何人造幣來實(shí)現(xiàn)。
所有其他合約的工作方式與上述完全相同,但有不同的名稱和符號(hào),并從 relationship() 和 listURI() 返回不同的值。
如果你擔(dān)心你的列表從不同的服務(wù)中泄漏,那么把 listURI() 變成更像 tokenURI(uint256 tokenId) 的東西是非常直接的,即簽名是 listURI(uint256 tokenId),它把 tokenID 連接到一個(gè)基本 URI 的末尾,這樣每個(gè) token 持有者就可以得到自己的列表 URL。這個(gè)功能與列表主機(jī)上的一些邏輯相結(jié)合,可以讓你把列表隔離開來,使不同的令牌持有者得到主圖的不同子圖。這樣一來,如果一個(gè)平臺(tái)被擁有,那么只有我的圖的那一部分被泄露了。
和 OCG 一樣,你可以把 safemint 變成一個(gè)可支付的函數(shù),并向訪問你的列表的人收費(fèi)。請(qǐng)看 OCG 部分的代碼,以了解這個(gè)例子的情況。
你可能希望能夠更新 tokenURI() 和 / 或 listURI() 返回的 URLs,在這種情況下,你需要將這些 URLs 存儲(chǔ)在變量中,在構(gòu)造函數(shù)中初始化它們,并為更新它們提供 onlyOwner setter 函數(shù)。這將增加你的鑄幣成本,但如果你只打算把它們給服務(wù)而不是個(gè)人,這可能并不重要。
這里概述的兩個(gè)建議都提供了一些集中式托管服務(wù)的地方,即使它只是一個(gè)權(quán)宜之計(jì),在生態(tài)系統(tǒng)過渡到像 IPFS 這樣的分布式系統(tǒng)之前。
最明顯的服務(wù)類型是托管由 URI 功能之一返回的任何東西–配置文件數(shù)據(jù)、NTFT 元數(shù)據(jù)和代幣控制的 JSON 列表(在 CLG 的情況下)。
另一個(gè)有用的服務(wù)是一種專門的 Infura 版本,通過 API 暴露鏈上的社交數(shù)據(jù)?;蛘撸琁nfura 可以為社交數(shù)據(jù)提供一個(gè)專門的 API。
最后,可以有第三方服務(wù)來驗(yàn)證賬戶,以滿足用戶和組織的需求。
我不知道我是否期望我的鏈上社交圖譜建議會(huì)以我在這里描述的形式被采納。我提出這些想法,更多的是為了引發(fā)對(duì)話,討論我們?nèi)绾螐哪壳巴耆i定平臺(tái)的狀態(tài)有效地過渡到更便攜的狀態(tài),即你擁有你的圖譜,并可以輕松地將它隨身攜帶。
上述內(nèi)容有一部分看起來有點(diǎn)像 web5 的提議,但關(guān)鍵的區(qū)別在于,我的兩個(gè)想法被設(shè)計(jì)得更簡(jiǎn)單,并利用了智能合約和現(xiàn)有的鏈上身份提供者(ENS,但也包括其他鏈上的類似提供者)。
如果你從這篇文章中沒有其他收獲,我希望我至少已經(jīng)說明,在一個(gè)分布式賬本技術(shù)和智能合約的世界里,我們?nèi)魏稳硕紱]有必要在 2022 年被鎖定在一個(gè)社交網(wǎng)絡(luò)里。解決這個(gè)鎖定問題的工具是廣泛存在的,我們只需要拿起它們并使用它們。