当前位置:网站首页>钻石标准--Diamond Standard
钻石标准--Diamond Standard
2020-11-06 20:21:00 【怎当她临去时秋波那一转】
钻石标准主要是为了对应以太坊上智能合约大小24K字节的限制。同时也可以应用来处理智能合约的无缝升级问题。钻石合约是这样的一个合约:它将函数调用代理调用(delegatecall)到外部已经部署的合约。这样的外部已部署合约被称为钻石面(facets)
标准
钻石标准定义在EIP2535中。标准文本在这里。https://github.com/ethereum/EIPs/issues/2535
例子实现
概览
diamondCut 函数是用来合约升级的函数,可以增加,替代和删除钻石合约里的任意函数 。它接收一个bytes[]类型的参数输入,指明修改内部映射表所需要的方法-钻石面对。比如,调用diamondCut函数可以一次性在一个交易里增加2个新函数,替换3个函数并且删除4个函数。同时diamondCut函数可以触发事件,记录所有的增加,替换和删除。
放大镜(The Loupe)是用来查询钻石合约的内部状况。钻石合约提供4个函数来提供钻石合约当前存储的函数和钻石面。这些函数被统称为放大镜。所有的钻石合约都必须实现这些函数
例子解释
下面我们以diamond-1为例来说明
数据结构
在IDiamondCut.sol, 有如下的数据结构:
struct FacetCut {
address facetAddress; // 当前钻石面(Facet)的地址
FacetCutAction action; // 当前DiamondCut的操作,增删改查
bytes4[] functionSelectors; // 该钻石面(Facet)所支持的函数选择子的集合
}
在IFacet.sol, 有如下的数据结构:
struct Facet {
address facetAddress; // 本钻石面(Facet)地址
bytes4[] functionSelectors; // 本钻石面(Facet)所支持的函数选择子的集合
}
IDiamondLoupe.sol中定义了需要实现的4个函数:
/// @notice Gets all facet addresses and their four byte function selectors.
/// @return facets_ Facet
function facets() external view returns (Facet[] memory facets_);
/// @notice Gets all the function selectors supported by a specific facet.
/// @param _facet The facet address.
/// @return facetFunctionSelectors_
function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);
/// @notice Get all the facet addresses used by a diamond.
/// @return facetAddresses_
function facetAddresses() external view returns (address[] memory facetAddresses_);
/// @notice Gets the facet that supports the given selector.
/// @dev If facet is not found return address(0).
/// @param _functionSelector The function selector.
/// @return facetAddress_ The facet address.
function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
在LibDiamond.sol中,定义了下面的数据结构
struct FacetAddressAndSelectorPosition {
address facetAddress;
uint16 selectorPosition;
}
struct DiamondStorage {
// function selector => facet address and selector position in selectors array
mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition;
bytes4[] selectors;
mapping(bytes4 => bool) supportedInterfaces;
// owner of the contract
address contractOwner;
}
包装合约
Dianmond合约是标准的入口。Diamond合约中除了一些初始化的工作以外,最主要的下面的Proxy功能。
下面的程序要点:
- ds.slot是内联汇编,意思是获取状态变量ds的Slot(存储槽)位置。见https://solidity.readthedocs.io/en/v0.7.4/assembly.html
- 通过调用的传递过来的函数选择子获取facet的地址
- 通过Delegatecall汇编指令来调用相应钻石面(facet)里的函数
fallback() external payable {
LibDiamond.DiamondStorage storage ds;
bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
assembly {
ds.slot := position
}
address facet = address(bytes20(ds.facetAddressAndSelectorPosition[msg.sig].facetAddress));
require(facet != address(0), "Diamond: Function does not exist");
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
参考文献
- https://medium.com/1milliondevs/new-storage-layout-for-proxy-contracts-and-diamonds-98d01d0eadb
- https://dev.to/mudgen/understanding-diamonds-on-ethereum-1fb
- https://learnblockchain.cn/article/1398
- https://naturaldao.io/collaboration/blog-cn/113-eip-2535%E5%8D%B3%E9%92%BB%E7%9F%B3%E6%A0%87%E5%87%86%E4%BB%8B%E7%BB%8D.html
- https://medium.com/1milliondevs/solidity-storage-layout-for-proxy-contracts-and-diamonds-c4f009b6903
- https://hiddentao.com/archives/2020/05/28/upgradeable-smart-contracts-using-diamond-standard
- https://hiddentao.com/archives/2019/10/03/upgradeable-smart-contracts-with-eternal-storage
- https://hiddentao.com/archives/2020/03/19/nested-delegate-call-in-solidity
- https://hiddentao.com/archives/2020/05/28/upgradeable-smart-contracts-using-diamond-standard
版权声明
本文为[怎当她临去时秋波那一转]所创,转载请带上原文链接,感谢
https://my.oschina.net/gavinzheng731/blog/4704491
边栏推荐
- Menu permission control configuration of hub plug-in for azure Devops extension
- Use of vuepress
- Cos start source code and creator
- 使用Asponse.Words處理Word模板
- PPT画成这样,述职答辩还能过吗?
- WeihanLi.Npoi 1.11.0/1.12.0 Release Notes
- 遞迴思想的巧妙理解
- 嘗試從零開始構建我的商城 (二) :使用JWT保護我們的資訊保安,完善Swagger配置
- Why do private enterprises do party building? ——Special subject study of geek state holding Party branch
- Details of dapr implementing distributed stateful service
猜你喜欢

JetCache埋点的骚操作,不服不行啊

How to demote a domain controller in Windows Server 2012 and later

有关PDF417条码码制的结构介绍

Gradient understanding decline

(1) ASP.NET Introduction to core3.1 Ocelot

读取、创建和运行多个文件的3个Python技巧

DTU连接经常遇到的问题有哪些

Can't be asked again! Reentrantlock source code, drawing a look together!

Anomaly detection method based on SVM

“颜值经济”的野望:华熙生物净利率六连降,收购案遭上交所问询
随机推荐
高级 Vue 组件模式 (3)
“颜值经济”的野望:华熙生物净利率六连降,收购案遭上交所问询
The practice of the architecture of Internet public opinion system
嘘!异步事件这样用真的好么?
Aprelu: cross border application, adaptive relu | IEEE tie 2020 for machine fault detection
nlp模型-bert从入门到精通(一)
How do the general bottom buried points do?
使用NLP和ML来提取和构造Web数据
01 . Go语言的SSH远程终端及WebSocket
Jmeter——ForEach Controller&Loop Controller
03_ Detailed explanation and test of installation and configuration of Ubuntu Samba
Analysis of ThreadLocal principle
Every day we say we need to do performance optimization. What are we optimizing?
3分钟读懂Wi-Fi 6于Wi-Fi 5的优势
GDB除錯基礎使用方法
数字城市响应相关国家政策大力发展数字孪生平台的建设
Details of dapr implementing distributed stateful service
词嵌入教程
網路程式設計NIO:BIO和NIO
[performance optimization] Nani? Memory overflow again?! It's time to sum up the wave!!