本文提供了在Solidity中共享分散数据的另一个示例解决方案,Solidity是以太坊区块链的智能合约的开发语言。
背景
Alice和Bob已经在他们选择的数据仓库中共享数据,而智能访问控制着用户访问,这些访问都通过互联网链接在一起。
Alice和Bob也想下棋。
他们都有属于自己的棋盘和棋子,他们只需要在数据仓库中保存一份移动记录就行。我们还可以在状态机中对轮到谁的代码进行编码,用户可以通过直接调用智能合约来对其进行影响。
国际象棋数据共享示例
本示例旨在为Alice和Bob提供解决方案。所需的任何功能都可以编码到智能合约中。
在此示例中,智能合约可以由任何用户(智能合约所有者)创建。可能是Alice、Bob或其他人。
在任何情况下,只有智能合约所有者可以在合约允许的情况下终止合约。终止的合约将向智能合约所有者释放任何剩余资金,并将删除数据仓库。
某些对象允许用户访问,而其他对象则禁止用户访问
上图中,两个用户Alice和Bob可以分别将数据读和写到数据保管库中自己的文件夹中。他们还可以从其他用户的文件夹中读取邮件,但不能写入该文件夹。
如果不是合约所有者(如果不是Alice或Bob)无法访问任何人的数据。
用户还可以将一个包含棋子移动的新文件附加到上图中的共享文件夹-3中。
设计
我们将account1和folder1分配给Alice,将account2和folder2分配给Bob。
我们将国际象棋移动文件记录在folder3中。每个用户可以依次添加一个新文件。
这是智能合约的UML逻辑状态机图:
国际象棋数据共享示例智能合约的UML逻辑状态机图
这里我们有3个并发状态机:合约所有者可以随时终止智能合约;数据可以像[如何在区块链上实现去中心化数据仓库共享-part2](http://bitoken.world/wp-admin/post.php?post=2134&action=edit "如何在区块链上实现去中心化数据仓库共享-part2")中那样共享数据。用户轮流将国际象棋移动文件附加到folder3(Await1和Await2机器状态)。
数据仓库使用图表中数据共享部分中显示的函数来确定对对象的允许操作。
图中wait部分显示的done函数是一个用户函数。仅当指定用户轮到该用户时,它才能成功使用,这取决于机器状态。在Await1状态下,只有account1(Alice)可以调用完成。在Await2状态下,只有account2(Bob)可以调用完成。
以下是每个角色允许的其他操作:
Object Role State Permitted Operations
contract account1 Await1 done - move to Await2
contract account2 Await1 done - move to Await1
folder3 account1 Await1 read, append new file
folder3 account2 Await2 read, append new file
创建智能合约
这是我们将要部署到以太坊区块链的ChessDataShareSDAC智能合约:
import "DataShareSDAC.sol";
contract ChessDataShareSDAC is DataShareSDAC {
bool turn2;
constructor( address _account1, address _account2 ) public
DataShareSDAC(_account1, _account2) { }
function getPermissions( address account, uint object )
public view override virtual returns (uint) {
if (!terminated) {
if (object == 3) {
if (account == (turn2 ? account2 : account1)) {
return DIRECTORY | APPEND_PERMISSION;
} else {
return DIRECTORY | READ_PERMISSION;
}
}
}
return DataShareSDAC.getPermissions(account, object);
}
function done() public {
require(msg.sender == (turn2 ? account2 : account1));
turn2 = msg.sender == account1;
}
}
此智能合约包含一个函数getPermissions,该函数重写基类中同名的函数。调用此函数,并可以选择是否调用基类函数。它会这样做,而不是确定新棋步文件夹(对象3)的访问权限。
done函数可由任一用户(实际上,任何以太坊用户)调用。但是,它确保只有轮到用户才能更改机器状态,并通过require(msg.sender == turn)防止其他任何用户。该函数使turn2变量指示它是另一位用户的回合。
部署智能合约
请参阅[如何在区块链上实现去中心化数据仓库共享-part2](http://bitoken.world/wp-admin/post.php?post=2134&action=edit "如何在区块链上实现去中心化数据仓库共享-part2")中的这一部分。
更新数据仓库
我们无法更改将哪个智能合约附加到数据仓库。这是一个深思熟虑的设计决定。我们认为用户不太可能愿意更改控制其数据的合约。
但是可以编写一个更复杂的智能合约,该合约可以更新如下:
但是目前,我们必须创建一个引用新智能合约的新数据仓库。
创建数据仓库
创建部分请参考上一篇文章,这里就不重复操作。
我们可能需要将现有文件从以前的数据仓库复制到这个新的,然后终止以前的智能合约。
无论如何,我们都需要为共享文件夹添加一个新的环境变量。
Smart Contract Owner Terminal
$ export C=folder13
使用国际象棋数据共享
设置智能合约是为了让Alice首先执行。在指定了自己的举动之后,Alice必须直接与智能合约进行通信,以告知她已经完成了自己的举动并转换了机器状态(使用UML和智能合约中的操作):
Alice Terminal
$ datona writeVault $contract $vaultUrl $vaultSrvId --file $A/msg10
“Are you Ready for a game? I go first"
$ datona writeVault $contract $vaultUrl $vaultSrvId --file $C/move01
“e4"
$ datona transactContract $contractCode $contract done
这些移动将写入到folder 3中的文件中。我们在下面为文件名提供了序号,但是在完整解决方案中将由DApp管理。
Bob Terminal
$ datona writeVault $contract $vaultUrl $vaultSrvId --file $C/move02
“e5"
$ datona transactContract $contractCode $contract done
$ datona writeVault $contract $vaultUrl $vaultSrvId --file $B/msg21
“Your go"
Alice或她的DApp可以监视下一个移动文件的存在:
Alice Terminal
$ datona readVault $contract $vaultUrl $vaultSrvId --file $C/move02
VaultError - File does not exist
$ datona readVault $contract $vaultUrl $vaultSrvId --file $C/move02
e5
$ datona writeVault $contract $vaultUrl $vaultSrvId --file $C/move03
“Nf3"
$ datona transactContract $contractCode $contract done
游戏可能会以同样的方式继续。
我们上一篇文章中的共享去中心化数据解决方案中的示例描述了数据仓库上用户之间的交互,该交互由智能合约控制。
这个例子还演示了用户和智能合约之间的直接交互。
智能合约功能可供用户和数据存储库使用
结论
Alice和Bob以及其他许多人都希望能够以分散的方式共享数据。这可能会使数据更安全、更私密、更可控。
我们已经展示了一个实用的解决方案,它使用智能合约和数据仓库的组合来实现这一点,这些都符合datona-lib中描述的接口规范。
--------------------------------------------
原文作者:Julian Goddard
译者:链三丰
译文出处:http://bitoken.world
---------------------------------------------