我们在2019年6月30日发布了MOLDEX α。在这里,我们将总结MOLDEX α系统架构的概述,包括以下三点。希望它对Dapps和区块链的未来发展有所帮助。
· 关于DEX的智能合约
· 关于服务器端
· 关于浏览器钱包
MOLDEX α的结构旨在了解处理性能和非功能性要求(例如可用性,操作和可维护性),用户角度的可设计性以及未来的UX改进。此外,考虑到与区块链的兼容性,MOLDEX α配置了完整的区块服务器。
与MOLDEX α一起使用的智能合约可以用github或Etherscan确认。在MOLDEX α中,我们定义了交易函数(稍后描述),以便任何人都可以交换ERC721和ERC20(甚至与ETH交换)。
在DEX智能合约方面构建通证(token)交换机制时,使用ERC20和ERC721中定义的两个函数approve()和transferFrom()。
· approve()
approve()函数用于允许第三方(在本例中为DEX合约)从发件人的余额中转移通证(token)(在ERC721的情况下,指定tokenId)。通证(token)存储在允许类型映射数据结构中。
// ERC20
function approve(
address _spender,
uint256 _value
)
public
returns (bool)
{
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
// ERC721
function approve(address _to, uint256 _tokenId) public {
address owner = ownerOf(_tokenId);
require(_to != owner);
require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); tokenApprovals[_tokenId] = _to;
emit Approval(owner, _to, _tokenId);
}
· transferFrom()
transferFrom()函数用于由第三方传输通证(token)(在本例中为DEX合约)。第三方(msg.sender)只能提取低于允许的余额(ERC721只能提取指定的tokenId)。
// ERC20
function transferFrom(
address _from,
address _to,
uint256 _value
)
public
returns (bool)
{
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
require(_to != address(0));
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
// ERC721
function transferFrom(
address _from,
address _to,
uint256 _tokenId
)
public
{
require(isApprovedOrOwner(msg.sender, _tokenId));
require(_from != address(0));
require(_to != address(0));
clearApproval(_from, _tokenId);
removeTokenFrom(_from, _tokenId);
addTokenTo(_to, _tokenId);
emit Transfer(_from, _to, _tokenId);
}
· allowance()
allowance()函数是一个视图函数,它返回由approve()函数指定的通证(token)值。在ERC721的情况下,getApproved()函数以相同的方式准备,并且它是一个视图函数,它返回有权从tokenId传输通证(token)的地址(即已批准)。
// ERC20
function allowance(
address _owner,
address _spender
)
public
view
returns (uint256)
{
return allowed[_owner][_spender];
}
// ERC721
function getApproved(uint256 _tokenId) public view returns (address) {
return tokenApprovals[_tokenId];
}
Taker为Token Contract执行approve()函数,并批准转移任意数量的moldcoin(在网站中,它表示为存款但实际上是批准的过程)。
制造商将执行Dex Contract交易功能所需的数据传递给服务器。Taker将执行Dex Contract的交易功能所需的数据传递给服务器。
在服务器端,当收集Maker和Taker的数据时,执行交易功能。在交易功能中,执行Dex Contract允许的transferFrom()。此时,transferFrom要传输的通证(token)必须由approve()函数批准。
执行transferFrom()函数以完成从Taker到Maker的Moldcoin转移,以及将ERC721资产从Maker转移到Taker。
1.准备与批准功能交换
Taker方面使用Moldcoin(ERC20)购买ERC721资产。DEX智能合约批准任何数量的MOLD,使_spender成为Dex合约,以便它可以处理MOLD币。Maker方面出售ERC721。为了允许DEX Contract发送ERC721资产,请将 Dex Contract批准为_spender。
2.发送签名订单数据
必要的订单数据被发送到服务器以执行交易功能。
Maker将散列以下6个元素以生成orderHash and使用密钥对其进行签名。
· Dex Contract Address
· ERC721 Token Contract Address
· ERC721 Token ID
· Maker Address
· ERC20 Token Contract Address
· ERC20 Amount
Taker将散列以下两个元素以生成tradeHash and 用密钥签名。
· orderHash
· Taker Address
3.执行交易功能
服务器端主要执行rawdata verification和签名验证。
rawdata是上面提到的订单数据。从Maker/Taker方面,rawdata+orderHash或tradeHash将被发送到服务器端。在服务器端,哈希函数检查rawdata的内容是否正确。此外,公钥可以根据v,r,s的值和用私钥签名的原始数据唯一确定,因此我们还检查签名是否正确。
在Dex Contract的交易功能中,使用ecrecover(hash,v,r,s)验证签名。如果返回值与订单所有者的地址不匹配,则将恢复订单。
4.执行transferFrom功能
当Dex Contract是msg.sender时,transferFrom函数执行两次以移动ERC20通证(token)并移动ERC721通证(token)。
以太坊最大的好处之一是所有涉及资金转移,所有已部署智能合约以及为一份智能合约完成的所有交易的交易都在区块链上公布和不可变。这意味着无法隐藏或修改迄今为止所做的交易,并且验证以太坊网络上任何节点上所有交易的有效性和状态的能力使以太坊成为一个非常强大的分布式系统。
但最大的缺点是,一旦部署了智能合约源代码,就无法更改。使用集中式应用程序(Facebook,Airbnb等)的开发人员不断更新以修复错误并引入新功能。在以太坊上运行这种传统的发展模式是不可能的。
您无法升级已部署的智能合约的代码,但您可以配置代理智能合约体系结构,该体系结构允许您使用新部署的智能合约,就像主逻辑已升级一样。
由于此Dex合约也是alpha版本,因此预计将来会进行许多修订和升级。那时,您可以通过分离和管理智能合约的存储和逻辑部分来切换到新的智能合约版本。
1. 部署OwnedUpgradeabilityProxy
2. 部署逻辑智能合约的第一个版本
3. 调用OwnedUpgradeabilityProxy 的 upgradeToAndCall函数在代理契约方注册逻辑契约,并初始化代理契约方。
使用与先前逻辑协定相同的变量名部署新的逻辑协定
调用OwnedUpgradeabilityProxy 的 upgradeTo函数来更新逻辑契约
将实现地址分配给适当的散列字节字符串,以将变量的信息存储在代理协定方定义的存储槽中。
//UpgradeabilityProxy.sol
bytes32 private constant implementationPosition = keccak256("org.zeppelinos.proxy.implementation");
function implementation() public view returns (address impl) {
bytes32 position = implementationPosition;
assembly {
impl := sload(position)
}
}
function setImplementation(address newImplementation) internal {
bytes32 position = implementationPosition;
assembly {
sstore(position, newImplementation)
}
}
使用代理协定中定义的非结构化存储槽来存储升级所需的数据。
在代理契约中,通过散列任意字符串来定义为存储逻辑契约地址提供足够随机存储位置的常量。
由于常量状态变量不占用存储槽,因此无需担心代理协议会意外覆盖implementationPosition。根据Solidity如何在存储中列出其状态变量,此存储槽不太可能与逻辑协定中定义的任何其他内容冲突。
通过使用此模式,没有逻辑契约版本需要知道代理的存储结构,但是所有未来的逻辑契约都需要继承其更高版本声明的存储变量。将来升级逻辑智能合约将允许您升级现有功能并引入新功能和新存储变量。
Zeppelin实验室存储库提供的实现也使用代理契约的概念。代理智能合约的所有者是唯一可用于升级或转移代理智能合约所有权的地址。
此代理智能合约的最大优点是逻辑智能合约方不必将其定义为代理的一部分。
对于失去其功能的可拥有智能合约等构造函数也是如此。在部署逻辑协定时,只有构造函数确定的初始状态不存储在代理协定方中。
因此,在逻辑契约中,您需要创建初始化函数等并正确定义所有者。或者,当您使用upgradeToAndCall函数进行Update时,需要调用并初始化作为构造函数的函数。
非结构化存储使用可靠性程序集来存储逻辑契约的地址,因此逻辑契约方最好不需要继承诸如可升级性的契约。除了能够转移所有者权限之外,您还可以定义新变量并将其存储在存储中。
MOLDEX α使用无服务器架构,主要执行三个过程:静态文件处理,API处理和批处理。
静态文件处理用作js文件和图像文件的存储目标,并使用CloudFront作为CDN和S3构建,用于托管静态网站。
使用CloudFront不仅可以启用缓存,还可以启用AWSShield和DDoS保护。此外,仅S3不能将SSL/TLS协议与其自己的域一起使用,但可以使用CloudFront来使用它。
如上所述,CloudFront提供了多种好处,因此我们采用了使用CloudFront的配置,而不是直接访问S3。
ECS使您可以轻松地部署,管理和扩展运行应用程序,服务和批处理的Docker容器。由于容器操作,即使API更改,也可以保持应用程序可用性。
此外,目前不需要同时处理许多请求,但是可以在将来集中访问的情况下轻松扩展应用程序。
访问以太坊不是从前端操作,而是通过API处理,以减少前端不必要的处理。
例如,执行交易功能后的交易历史始终通过参考以太坊区块链中的交易事件保持最新。
此外,如果正在批准的资产转移到另一个地址,则批准Dex智能合约将失效。因此,有必要定期监测以太坊侧的容许量。
它成为上面的通用配置图,但是通过运行Build→test→从circleCI部署,它能够相对平稳地进行开发。
这一次,我们采用了Golang作为API的一部分,并且有很多部分引用了Geth(go-ethereum)的实现。
目前(+微信关注网络世界),以太坊上的大多数Dapps使用Metamask,但MOLDEX α已经实现了应用程序的内置浏览器钱包,而不是使用Metamask。目的是要意识到可以被不熟悉区块链的用户使用的DEX。
我们认为对区块链稍微熟悉的用户像往常一样增加了chrome的扩展,但大多数用户目前不使用元掩码甚至扩展。
我们认为Dapp和其他Dapps的理想是实现平稳和简单的用户体验,以便用户不知道它正在使用区块链。为了使用一个Dapps,有一种方法(对于大多数用户而言)您不需要安装Metamask(在大多数用户中),可以将钱包功能合并到应用程序中。使用MOLDEX α,粗加工时,通过整合浏览器钱包,登录过一次的用户可以使用只有密码的应用程序。
在DEX中,用户完全负责私钥管理,而服务器端没有关于用户私钥的信息。
首次访问MOLDEX的用户需要使用createkey创建新帐户或导入现有的以太坊钱包。
在MOLDEX α中,用户的私钥由会话管理,加密的json密钥文件由浏览器的本地存储永久管理。
当用户离开页面时,会删除由会话管理的密钥(例如,删除选项卡),因此当您再次访问它时,系统将提示您输入密码以解锁存储在本地存储中的加密密钥文件。
另一方面,由于即使当用户离开页面时加密的密钥文件也存储在本地存储器中,当用户再次访问时,用户只需输入密码来解锁它并使用该应用程序。
钱包解锁后,用户可以自由使用该应用程序,直到会话终止。这简化了繁琐(且缓慢)的Metamask流程,每次弹出窗口都会出现并确认。
此外,如果您希望对浏览器进行加密,但又不想保留密钥文件信息,则可以通过删除密钥从本地存储中删除密钥文件信息。在这种情况下,您需要在再次访问时执行导入密钥。
使用MOLDEX α时,请确保导出密钥文件并将其存储在云端或安全位置。
关于DEX的优点有三点。
· 隐私受到保护
· 安全性高
· 操作的可能性很低
让我们看看这些特征是否实际上在MOLDEX α中。
使用MOLDEX α,任何人都可以在应用程序上创建一个帐户并开始交易。此时,由于服务器端不管理用户信息,因此实现了完全匿名的事务。
此外,由于用户的私钥由用户管理,即使服务器端被黑客攻击,也不可能移动用户的资产(游戏项目或MOLD币)。
此外,即使操作方也无法在服务器上非法操纵订单,因为订单是使用用户的私钥签名的,并且签名在Dex智能合约上得到验证。因此,用户可以无信任地交易MOLDEX α(无需信任服务器端)。
从上述观点来看,可以说这个MOLDEX α是一个有用的例子,它展示了MOLDEX的世界观,并且可以特别理解DEX的优点。
考虑如何在P2P上自由快速地交易数字资产,一种方法是使用分散交换(DEX)。但是,从与以太坊的合作开始,如果您尝试将DEX转换为服务,开发成本很高,而且比您想象的更难。此外,生成以太坊的块所需的时间和天然气的成本是降低用户体验的主要因素之一。
在未来,MOLDEX α版本旨在通过添加以下各种其他功能来实现以太坊MOLD的概念。
· 增加ERC721的资产类型
· 使ETH可以交换
· 启用ERC1155资产的交换
· 可以查看发送和接收的交易历史记录
· 添加登录登录功能
· 制作游戏页面
※MOLDEX α是MOLD所有者的测试版。请注意,将来可能会对规格进行重大更改。
与此同时,在MOLD,我们希望建立一个专门从事游戏的原创连锁店,以解决Etheruem在游戏方面的问题。通过在以太坊进行MOLDEX开发以及在原有产业链上进行研发,我们将在快速变化的区块链行业中稳步推进项目。