isExist = false;
function getEvidence(bytes32 _hash) public view returns(bytes memory content, uint256 timestamp) {
let ptr := mload(0x40)
/**
对存证的所有请求,都通过节制层举办转发,节制层将请求通过署理转发给逻辑层,逻辑层凭据业务逻辑处理惩罚后通过数据层举办数据上链。架构图如下图所示。存证数据的相关变量都被界说为internal范例,限制为只能合约内部会见。
•合约EvidenceVoteSaveHandler担任自无审核方的基本存证合约EvidenceBaseSaveHandler和存储审核方信息的Caller合约。•存证方提倡存证后会先存储到待上链的voteEvidence中,等审核方投票,投票数高出阈值后才可存储到存证数据中。•saveEvidenceToChain要领并没有加权限校验,因为只有大于便是阈值的存证才气最终上链。
owner: msg.sender,
uint timestamp;
}
voteEvidence[_hash] = VoteEvidenceObject({
threshold = _threshold;
require(voteEvidence[_hash].voters[msg.sender] == false, “Already voted!”);
1、合约陈设
署理合约的焦点代码如下所示。
*/
}
function () payable public {
contract EvidenceVoteSaveHandler is EvidenceBaseSaveHandler, Caller {
timestamp: now
}
如需将逻辑层合约进级为有审核方的合约,此时需要
/**
bool internal _initialized;
return (evidence[_hash].content, evidence[_hash].timestamp);
setOwner(owner);
•EvidenceData存证焦点布局,包罗存证内容content、所有者owner和存证时间timestamp•evidence存证hash与存证布局的mapping变量•evidenceAmount用于统计总的存证数
2、合约进级
if (evidence[_hash].owner != address(0)) {
二、需求阐明
returndatacopy(ptr, 0, size)
mapping(address => bool) voters; // 审核方投票记录
}
}
isExist = true;
}
voteEvidence[_hash].voters[msg.sender] = true;
function checkEvidenceExist(bytes32 _hash) public view returns(bool isExist) {
3、节制层
contract EvidenceData {
References
});
// 看待上链的存证举办投票
function voteEvidenceToChain(bytes32 _hash) public isCaller {
struct VoteEvidenceObject {
address owner;
let size := returndatasize
1.0版 struct EvidenceObject {
2.2 有审核方审核的逻辑实现
default { return(ptr, size) }
bytes content;
for uint256;
}
switch result
function createSaveEvidence(bytes32 _hash, bytes memory _content) public onlyOwner {
// 存证方提倡存证,会先存储到待上链的voteEvidence中
voted: 0
审核方认真对存证方提倡的存证内容举办审核,只有审核通过的内容才气够上链。
}
}
此时,已完成了逻辑合约的进级。
address _impl = implementation();
基于需求阐明,我们按照最小可利用原则,设计第一版存证合约框架,如下图所示。
}}
此时,通过署理合约,已可以或许挪用EvidenceBaseSaveHandler合约中的相关要领。
content: _content,
在公链的情况中,审核方一般由第三方公信机构接受,存证内容的真实性由公信机构认真审查。
* @dev Tells the address of the implementation where every call will be delegated.
说明:合约架构图中的各个层级只列出了该层级的焦点成果点。 在存证合约架构1.0版本中,只需要两个合约,一个用于权限节制的Owner合约,一个用于存证业务的Evidence合约。假如说存证合约任何用户都可以或许挪用,举办存证内容上链,权限节制都可以不需要。 存证作为的一个重要应用场景,在各个公链中都有已落地的应用和处事。本文将先容在上的一种可进级的存证合约的设计与实现。 3.0版 郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
•存证方认真将需要确权的数据举办上链;•取证方在需要时可以在区块链上查询到存证内容和该内容的所有者。
address owner;
});
*/
require(!_initialized);
assembly {
一、存证业务模子
function saveEvidenceToChain(bytes32 _hash) public {
// 对高出投票阈值的存证提倡上链
bytes content;
三、合约设计
}
五、合约陈设
calldatacopy(ptr, 0, calldatasize)
voteEvidence[_hash].voted++;
require(voteEvidence[_hash].owner != address(0), “Evidence not exist!”);
节制层利用的是OpenZeppelin提供的“非布局化存储实现可进级”的署理框架。署理模式的具体内容可阅读我之前写的另一篇文章《以太坊智实现智能合约进级的三种署理模式》[1]
require(_impl != address(0));
}
}
function setThreshold(uint8 _threshold) public isCaller {
mapping(bytes32 => EvidenceObject) internal evidence;
function initialize(address owner) public {
using SafeMath
function createSaveEvidence(bytes32 _hash, bytes memory _content) public isCaller {
3.0版本与2.0版本在架构上是一致的,焦点区别在逻辑层。3.0版本在逻辑层增加了存证审核方的业务逻辑。
1.陈设EvidenceVoteSaveHandler合约2.挪用OwnedUpgradeabilityProxy合约中的upgradeTo要领,将新陈设的逻辑合约注册到署理合约中。
require(keccak256(_content) == _hash, “Invalid hash!”);
require(uint256(voteEvidence[_hash].voted).mul(100).div(callerAmount) >= threshold, “Insufficient votes!”);
四、 存证合约实现
假如是在同盟情况中,审核方也有大概是取证方,同盟内的成员对本身审核通过并已上链的内容自然认为是可信的。
require(checkEvidenceExist(_hash) == false, “Evidence exist!”);
假如存证的内容自己可以或许自证真实性(如电子条约,已有相关参加方的签名),这种业务模子是可以满意需求的。
createSaveEvidence(_hash, voteEvidence[_hash].content);
1、数据层
合约说明:
}
按照上边的存证业务模子先容,存证合约需要可以或许满意以下需求。
2.1 无审核方审核的逻辑实现
mapping(bytes32 => VoteEvidenceObject) private voteEvidence; // 存证方提倡的存证
uint8 public threshold; // 投票阈值,高出该阈值则说明存证内容可上链
数据层焦点界说了以下数据:
整体上较量简朴,但有几个需要说明的处所:
function implementation() public view returns (address);
owner: msg.sender,
evidenceAmount++;
}
case 0 { revert(ptr, size) }
1.只有存证方可以或许提倡存证内容上链2.链上的存证数据应该包括存证内容和内容的所有者3.可以对已上链的存证举办检索4.审核方需要看待上链的存证投票,投票数满意必然条件后存证才气上链
let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
uint internal evidenceAmount;
require(keccak256(_content) == _hash, “Invalid hash!”);
function getEvidenceAmount() public view returns(uint256 amount) {
* @return address of the implementation to which it will be delegated
* This function will return whatever the implementation call returns
存证业务的焦点是确权,业务逻辑相比拟力简朴,一般分为存证方和取证方。
* @dev Fallback function allowing to perform a delegatecall to the given implementation.
•之所以需要有initialize要领来为权限合约的owner赋值,是因为署理合约在署理逻辑合约之后,逻辑合约自身通过结构函数初始化的值是无法获取到的,因此需要有一个要领可以或许为初始参数赋值。•createSaveEvidence建设存证合约时,参数_hash为 _content的hash。假如存证的内容自己就是一个文件的hash值,,那么参数_hash相当于是hash的hash。
require(voteEvidence[_hash].owner != address(0), “Evidence not exist!”);
contract Proxy {
接下来会具体讲授存证合约的实现。完整实现代码可会见:https://github.com/six-days/ethereum-contracts/tree/master/evidence
content: _content,
在第二版中,我们回收了雷同MVC布局,将数据和逻辑疏散,而且引入节制层。
require(checkEvidenceExist(_hash) == false, “Evidence exist!”);
2、逻辑层
由于回收了节制层的署理布局,对付业务逻辑进级时,只需要陈设新的业务逻辑,然后将新合约的地点注册到署理合约中,即可完成合约进级,而且对外提供处事的合约地点稳定。
require(evidence[_hash].owner == address(0), “Evidence exist!”);
evidence[_hash] = EvidenceObject({
1.先陈设节制层的署理合约OwnedUpgradeabilityProxy2.陈设无审核方的逻辑层合约EvidenceBaseSaveHandler3.挪用EvidenceBaseSaveHandler合约的initialize为初始化参数赋值4.挪用OwnedUpgradeabilityProxy合约中的upgradeTo要领,将逻辑合约注册到署理合约中。
2.0版
[1] 《以太坊智实现智能合约进级的三种署理模式》: https://learnblockchain.cn/article/1102
uint8 voted; // 赞成票个数
可是大大都存证场景的存证内容并不可以或许自证真实,好比你正在阅读的文章,并不能证明作者就是六天,那么为了担保存证方上链的内容是可信的,这时候就需要引入第三个脚色审核方。
}
require(voteEvidence[_hash].owner == address(0), “Vote evidence exist!”);
return evidenceAmount;