生態(tài)架構(gòu)
Fountain 的生態(tài)架構(gòu),可以分為四層,即鏈層、行業(yè)協(xié)議層、社區(qū)協(xié)議層和 DApp:
鏈層
位于整個系統(tǒng)最底層的鏈層,可以在現(xiàn)有成熟公鏈如以太坊或 EOS 的基礎(chǔ)上進(jìn)行二次開發(fā)來實現(xiàn)。在必要的時候,再轉(zhuǎn)向 Fountain 的自有公鏈。鏈層提供了整個 Fountain 所需的基礎(chǔ)功能,是 Fountain 可以正常運(yùn)行的土壤。
由于 Fountain 和其它區(qū)塊鏈項目不同,它是有實際業(yè)務(wù)對應(yīng)的,用戶交互也不僅僅是交易轉(zhuǎn)賬,還包括大量社區(qū)交互行為,因此對于鏈的吞吐能力與處理速度都有一定的要求,且記賬所需的燃料費(fèi)也希望趨向于零。
由于 Fountain 的定位,是內(nèi)容行業(yè)的行業(yè)鏈,其上未來可能會不止一個內(nèi)容社區(qū),以及各個社區(qū)的大量用戶,將會面臨包括行業(yè)規(guī)則調(diào)整、社區(qū)規(guī)則調(diào)整、社區(qū)內(nèi)仲裁等等各類不同層次與影響范圍的活動,所以在底層鏈的選擇上,我們將采取一種聯(lián)盟鏈與公鏈的混合方案。
內(nèi)容行業(yè)的各社區(qū)將構(gòu)成一個聯(lián)盟鏈,通過 DAO 的形式來決定行業(yè)鏈上的行業(yè)規(guī)則是否進(jìn)行調(diào)整,而在各社區(qū)內(nèi)也將建立類似 DAO 的組織形態(tài),用來決定各社區(qū)自身的發(fā)展。這樣的組織結(jié)構(gòu)將有利于行業(yè)鏈的生態(tài)形成與演化,同時又能保證行業(yè)與社區(qū)之間不會出現(xiàn)彼此沖突。在同一套行業(yè)規(guī)則下,不同的社區(qū)可以擁有彼此不同的社區(qū)規(guī)則。規(guī)則的設(shè)定是由行業(yè)同盟或社區(qū)管理組來建立,而一旦建立后,所有用戶都在同一個社區(qū)的同一套規(guī)則中進(jìn)行互動。
從技術(shù)上說,我們會在公鏈的基礎(chǔ)上,引入聯(lián)盟鏈的架構(gòu),作為公鏈之上的一種追加結(jié)構(gòu)。新聯(lián)盟用戶將通過聯(lián)盟已有成員的投票來決定是否允許其加入聯(lián)盟。而聯(lián)盟的決議也將通過環(huán)簽名等手段來進(jìn)行確認(rèn)與保護(hù),并在必要的時候?qū)φ麄€ Fountain 的相關(guān)參數(shù)設(shè)置或者智能合約進(jìn)行調(diào)整。
協(xié)議層
協(xié)議層分為行業(yè)協(xié)議與社區(qū)協(xié)議兩部分,分別對應(yīng)了整個內(nèi)容行業(yè)的基礎(chǔ)規(guī)則與相關(guān)服務(wù),以及社區(qū)特有的規(guī)則與服務(wù)。行業(yè)協(xié)議是全行業(yè)都必須遵守的一套規(guī)則,包含一組智能合約與相應(yīng)的基礎(chǔ)服務(wù),而社區(qū)協(xié)議則是內(nèi)容行業(yè)中某個特定內(nèi)容社區(qū)所專有的。從形式上說,它們都是建立在底層鏈基礎(chǔ)上的一組智能合約,以及相應(yīng)的 DApp 可用的網(wǎng)絡(luò)服務(wù)與協(xié)議。不同的 DApp 根據(jù)所在社區(qū)不同,調(diào)用不同的智能合約與網(wǎng)絡(luò)服務(wù)。
DApp
每個社區(qū)都會有自己的 DApp,用于將社區(qū)中的內(nèi)容呈現(xiàn)給用戶。它是整個生態(tài)的展示與交互界面。DApp 可以是社區(qū)自己開發(fā)的官方版,也可以是第三方開發(fā)的私有版,只要遵守行業(yè)與社區(qū)的兩套協(xié)議,就能調(diào)用相關(guān)網(wǎng)絡(luò)服務(wù)與智能合約。我們可以借用軟件架構(gòu)中的 MVP 架構(gòu)來表達(dá)底層鏈、兩個協(xié)議層與各 DApp 之間的關(guān)系:
基礎(chǔ)服務(wù)
在 Fountain 上,有一些基礎(chǔ)服務(wù)是現(xiàn)在與未來所有內(nèi)容行業(yè)都會用到的,比如內(nèi)容的鏈上存儲、內(nèi)容尋址、鏈上 KYC 解決方案、Markdown 和富文本編輯器解決方案等等。
其中,F(xiàn)ountain 主要使用的一項基礎(chǔ)服務(wù)就是內(nèi)容尋址,其本質(zhì)上是一組智能合約,通過一組鏈上可識別的 HASH 表示“轉(zhuǎn)譯”為互聯(lián)網(wǎng)上通用的 URI 地址,從而讓 DApp 可以獲取指定的資源。這是一種鏈-網(wǎng)結(jié)合的方案,對于鏈上無法處理或不便于處理的內(nèi)容放到傳統(tǒng)互聯(lián)網(wǎng)上進(jìn)行處理,而鏈上通過調(diào)用互聯(lián)網(wǎng)服務(wù)的形式進(jìn)行資源獲取。這類服務(wù)的實現(xiàn)方式有多重,可以是服務(wù)器通過 DApp 接入到鏈上,通過接受特定的智能合約 Event 事件來觸發(fā)相應(yīng),也可以是 IPNS 這種分布式域名解析服務(wù)。
準(zhǔn)入制的必要性
包括內(nèi)容社區(qū)生態(tài)在內(nèi)的各網(wǎng)上生態(tài)系統(tǒng)要能健康發(fā)展,依賴于社區(qū)規(guī)則與交互界面( App 或 DApp )的健康發(fā)展。在內(nèi)容社區(qū)中,破壞這種健康發(fā)展的主要手法,有以下這些:
- 不遵守協(xié)議規(guī)范的第三方 App / DApp 對生態(tài)進(jìn)行破壞;
- 利用機(jī)器人等手段偽造多個賬號破壞社區(qū)生態(tài);
- 利用社區(qū)規(guī)則漏洞,進(jìn)行表面合理但目的在于個人利益最大化的交互行為。
- ……
舉個例子:第三方 DApp 可以通過發(fā)布違規(guī)內(nèi)容來擾亂整個經(jīng)濟(jì)系統(tǒng)。違規(guī)內(nèi)容有很多可能性,比如說大量的“抄襲”或者“暴恐”內(nèi)容。這樣的行為會對整個 Fountain 生態(tài)帶來極其負(fù)面的影響。
因此,我們的解決方案是 DApp 的準(zhǔn)入機(jī)制:有行業(yè)聯(lián)盟或社區(qū)管理組來判斷一個第三方 DApp 是否具有準(zhǔn)入資質(zhì),如果具備準(zhǔn)入資質(zhì),則給與它一個特定的令牌 Token 。而在調(diào)用智能合約或者別的網(wǎng)絡(luò)服務(wù)的時候,需要提供該 Token 的 DApp 才有資格調(diào)用該 DApp,比如如下簡化的智能合約( Solidity ):
contract TestContract {
address public owner;
mapping (bytes => bool) public dapps;
modifier onlyOwner () {
require(owner == msg.sender);
_;
}
modifier onlyDApp (bytes32 token) {
token = keccak256(token);
bool got = dapps[token];
require(!!got);
_;
}
constructor () public {
owner = msg.sender;
}
function addDApp (bytes32 token) public onlyOwner {
token = keccak256(token);
bool got = dapps[token];
if (!!got) return;
dapps[token] = true;
}
function removeDApp (bytes32 token) public onlyOwner {
token = keccak256(token);
bool got = dapps[token];
if (!got) return;
dapps[token] = false;
}
function dosomething (bytes32 token, address from, address to, uint amount) public onlyDApp(token) {
...
}
}
在上述這段代碼中,我們可以通過特定賬號為整個社區(qū)添加允許的 DApp 準(zhǔn)入 Token,且可以在需要的時候?qū)⒁粋€ Token 移除,從而來控制被保護(hù)的智能合約函數(shù)。事實上,這樣的方式也可以用來做更復(fù)雜的權(quán)限管理。
對于已經(jīng)通過第三方 DApp 上鏈的內(nèi)容,由于其內(nèi)容未必保存在簡書服務(wù)器上,而只是將 URL 放入了鏈,從而可以通過內(nèi)容尋址服務(wù)找到該特定內(nèi)容的地址,從而進(jìn)行展示(在官方 DApp 上當(dāng)然會做過濾,但在第三方 DApp 上則不會有過濾)。對于這種情況,一個是內(nèi)容尋址服務(wù)中將會把相關(guān)條目刪除(以 IPFS 及其背后的 Kad 與 BitSwap 來說,就是將特定地址對應(yīng)的 route 與 storage 全部清空),另一方面是對鏈上相關(guān)條目進(jìn)行標(biāo)記,標(biāo)記其為違規(guī)內(nèi)容,從而確保在官方以及遵守官方協(xié)議的 DApp 上不會展示內(nèi)容相關(guān)條目。
去中心化的付費(fèi)閱讀平臺
傳統(tǒng)中心化的付費(fèi)閱讀平臺的劣勢是毫無疑問的,大量的收益被平臺所獲得。原創(chuàng)作者理應(yīng)獲得更高的收益。
付費(fèi)閱讀的關(guān)鍵,就是要記錄和驗證指定用戶對指定文章是否進(jìn)行過付費(fèi)購買。我們可以在區(qū)塊鏈中記錄購買信息,并在有需要的時候進(jìn)行檢索驗證,從而實現(xiàn)付費(fèi)閱讀。具體來說,當(dāng)用戶對一篇文章進(jìn)行購買時,我們需要將購買記錄記錄在鏈上。而當(dāng)用戶要閱讀一篇付費(fèi)文章時,內(nèi)容尋址服務(wù)到文章存儲服務(wù)器上進(jìn)行內(nèi)容索取,此時文章存儲服務(wù)器會到鏈上查詢當(dāng)前用戶是否購買了指定文章,如果購買過,則提供文章,否則不提供。
簡單的這類智能合約的大致流程可以寫為(Solidity):
contract MasterPiece {
address public butler;
mapping (address => uint) prices;
mapping (address => mapping (address => bool)) public bills;
constructor () public {
butler = msg.sender;
}
modifier onlyButler () {
require(butler == msg.sender);
_;
}
function setPrice (address article, uint price) public onlyButler {
prices[article] = price;
}
function buy (address article) public payable return (bool) {
uint price = prices[article];
if (msg.value < price) {
msg.sender.send(msg.value);
return false;
}
bills[msg.sender][article] = true;
return true;
}
function check (address user, address article) public view return (bool) {
return bills[user][article];
}
}
在初始階段,我們會使用云服務(wù)器來作為文章的存儲服務(wù)提供方,未來會考慮轉(zhuǎn)用類似 IPFS 這類分布式文件存儲服務(wù),并設(shè)置一個付費(fèi)閱讀秘鑰分發(fā)系統(tǒng),將文章密文保存在分布式文件系統(tǒng)中,而將解密用的秘鑰通過這個秘鑰分發(fā)系統(tǒng)來管理與分發(fā),從而實現(xiàn)付費(fèi)閱讀。
去中心化的 IP 投資平臺
在內(nèi)容創(chuàng)作領(lǐng)域,我們經(jīng)常遇到的一個問題,就是作者有一個很不錯的構(gòu)思,但迫于生活壓力而不得不放棄這篇內(nèi)容的創(chuàng)作而轉(zhuǎn)做其它。一個更健康的去中心化的 IP 投資平臺對作者來說是很有有價值的。由作者發(fā)布作品項目,包括完成作品的時間規(guī)劃,作品完成后的收益分配規(guī)則,而由讀者在作品完成之前,先行為作品付費(fèi),并在作品完成后的一段時間內(nèi)完成作品收益的自動分配。
傳統(tǒng)的IP投資平臺,具備大量信息的不公開透明,應(yīng)用了區(qū)塊鏈賬本的IP投資平臺,將讓更廣大的群眾將更有信心參與其中。
一份這樣的智能合約,其大致形式為(Solidity):
contract WritingProcess {
address public butler;
mapping (address => WritingProgram) public programs;
event NewProg (address author, address article, uint stocks, uint price);
struct WritingProgram {
address author;
address article;
uint public total;
uint left;
uint public price;
uint stockcoinpool;
uint public coinpool;
mapping (address => uint) stocks;
constructor (address _author, address _article, uint totalstock, uint stockprice) public {
author = _author;
article = _article;
total = totalstock;
left = totalstock;
price = stockprice;
coinpool = 0;
stockcoinpool = 0;
}
function buy (address buyer, uint stock) public return (bool) {
if (left < stock) return false;
uint s = stocks[buyer];
s += stock;
stocks[buyer] = s;
left -= stock;
stockcoinpool += stock * price;
return true;
}
function income (uint coin) public {
coinpool += coin;
}
function draw (address a, uint amount) public {
if (a != author) return;
if (amount > stockcoinpool) return;
a.transfer(amount);
stockcoinpool -= amount;
}
function sharebonus (address user) public {
uint s = stocks[user];
if (s < 1) return;
uint p = coinpool * s / (total - left);
user.transfer(p);
coinpool -= p;
stocks[user] = 0;
left += s;
}
}
constructor () {
butler = msg.sender;
}
modifier checkProg (address prog) {
WritingProgram p = programs[prog];
require(!p);
_;
}
modifier checkProgAndPayBack (address prog, uint coin) {
WritingProgram p = programs[prog];
if (!p && coin > 0) msg.sender.send(msg.value);
require(p);
_;
}
function publish (address user, address prog, uint total, uint price) public checkProg(prog) {
p = new WritingProgram(user, prog, total, price);
programs[prog] = p;
emit NewProg(user, prog, total, price);
}
function buyStock (address prog) public payable checkProgAndPayBack(prog, msg.value) {
WritingProgram p = programs[prog];
uint s = msg.value / p.price;
p.buy(msg.sender, s);
}
function rewardProg (address prog) public payable checkProgAndPayBack(prog, msg.value) {
WritingProgram p = programs[prog];
p.income(msg.value);
}
function shareProgBonus (address prog) public checkProgAndPayBack(prog, 0) {
WritingProgram p = programs[prog];
p.sharebonus(msg.sender);
}
}
以上是我們的一些技術(shù)方案探討,我們將根據(jù)項目實際進(jìn)展進(jìn)行調(diào)整和細(xì)化。對 Fountain 來說,能迅速收獲千萬用戶是讓人興奮的事情。同時這也意味著對技術(shù)和架構(gòu)有著更務(wù)實的要求。我們正在招募核心開發(fā)團(tuán)隊成員和去中心化的社區(qū)開發(fā)團(tuán)隊,如果你有興趣加入我們,歡迎發(fā)郵件至:developer@fountainhub.com