Compound学习 README.md
Posted Zero_Nothing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Compound学习 README.md相关的知识,希望对你有一定的参考价值。
Compound学习(一) README.md
Compound 是 DeFi 的明星项目之一,定位于去中心化的借贷协议。可以称之为“去中心化的算法银行”。Compound 协议是为了开放金融系统而为开发者构建的开源协议,基于 Compound 协议可以开发一系列新的金融应用程序。
终于要学习Compound了,躲不过去了。
我们知道,Compound是以太坊上的一个借贷协议,当然和Uniswap一样,也是明星项目。关于Compound的介绍在知乎上有一篇文章,我也是看得这篇文章:https://zhuanlan.zhihu.com/p/150553592,因此我们直接跳过项目介绍这一传统篇章,直接进行学习。
学习一个项目(源码)从哪入手呢?除了刚才提到的介绍(包含白皮书,说明文档),我想应该从项目自带的文档README.md开始。
我们在github上clone一下Compound的master分支到本地,打开项目根目录,会发现一个README.md。顾名思义,读我,那我们就从读它开始了。
Compound在github上的地址为:https://github.com/compound-finance/compound-protocol
README.md
我们使用vscode打开Compound项目根目录,找到README.md并打它开,映入眼帘的是md格式各种控制标签,没关系,我们在右边栏目右键点击README.md
标签,再选择打开预览,我们就能看到MD文件的正确显示了。
一、介绍
README.md的第一段是介绍这个Compound项目是做什么的,英文好的同学直接看上面链接的白皮书,不好的同学就看我在开头提到的那篇介绍。
二、Contributing
这个基本和我们没有关系,没有能力贡献这个代码(不排除部分读者可以)。
三、核心合约分类
该MD的第三段是核心合约分类,这个是我们需要着重关注的。
3.1、CToken,CErc20和CEther。
本段第一句的意思为Compound Tokens是自完备的借贷合约。CToken 里面是核心逻辑,而CErc20 和 CEther分别是Erc20和Eth的公共接口。每个CToken都包含了利息和任务模块,它允许用户来提供资产、赎回资产、借资产和归还资产。CToken也完全兼容ERC20,它的余额代表着该市场的份额(这里每种CToken对应一个市场)。
那么它的合约具体有哪些呢?打开左边contracts
目录,密密麻麻的很多,不要慌。既然这里提到了三类合约,那么所有以CErc20打头的合约(.sol)及 CToken.sol
和CEther.sol
就是本类合约了。
3.2、Comptroller
任务模块合约,它用来验证用户行为权限。当用户不满足特定任务条件时,便会关闭该行为。例如,Comptroller 强制用户在借款时必须持有足够的保证金。
对应的具体合约为所有以Comptroller
打头的合约和Unitroller.sol
。
3.3、Comp
这个很简单,Compound发的币,用来进行治理的。代币合约为Governance
目录下的Comp.sol
。
3.4、Governor Alpha
用来进行运维管理的时间锁定合约。持有Comp的玩家可以发起一项提案或者对已有提案投票。通过后的提案会排队并在一定时间后执行。所有的DAO都是类似的。
对应的合约就是在Governance
目录下(这个不是重点学习的 内容)。
3.5、InterestRateModel
利息模块。这个模块根据当前市场的的利用率来计算相应的利息。
注意:左边InterestRateModel.sol
为一抽象合约,其中一个实现为WhitePaperInterestRateModel.sol
,顾名思义,就是根据最初的白皮书实现的。
3.6、Careful Math
数学库,这个跳过
3.7、ErrorReporter
用不同的返回值代表不同的错误情况,一般0代表成功(这就是一般会验证Compound类合约用户相关操作后的返回值为0的原因)。见左边ErrorReporter.sol
。
3.8、Exponential
用来处理固定精度十进制数的库,可以跳过。
3.9、SafeToken
用来和Erc20合约安全交互的库。很多DEFI都会用到,也较常见。
3.10、WhitePaperInterestRateModel
上面已经介绍过了,注意这里提到了它的构造器中包含两个参数,一个是基准利率,另一个暂切叫着斜率参数吧,这里先记下来,以后有用的着的。
四、安装依赖库
按提示安装就可以了,这里笔者遇到了使用yarn
安装失败的情况,于是使用了npm install
五、REPL、Testing、Code Coverage
主要是测试相关,暂时我们用不上。
六、Linting
这里可以跳过。
七、Docker 与 Console
这部分介绍怎么在Docker部署并显示相关合约,我们挑重点看:
7.1、部署基础合约
找到文档中的Deployed goerli contracts
,它会部署如下合约:
comptroller: 0x627EA49279FD0dE89186A58b8758aD02B6Be2867
comp: 0xfa5E1B628EFB17C024ca76f65B45Faf6B3128CA5
governorAlpha: 0x8C3969Dd514B559D78135e9C210F2F773Feadf21
maximillion: 0x73d3F01b8aC5063f4601C7C45DA5Fdf1b5240C92
priceOracle: 0x9A536Ed5C97686988F93C9f7C2A390bF3B59c0ec
priceOracleProxy: 0xd0c84453b3945cd7e84BF7fc53BfFd6718913B71
timelock: 0x25e46957363e16C4e2D5F2854b062475F9f8d287
unitroller: 0x627EA49279FD0dE89186A58b8758aD02B6Be2867
这里列出了8个Compound要部署的合约,虽然只是部分并不完整。
comp: 项目的治理代币合约
comptroller:comptroller的实现合约
unitroller:comptroller的代理合约。左边点击打开comptroller.sol
,会在注释里看到这么一句话:
Storage for the comptroller is at this address, while execution is delegated to the `comptrollerImplementation`.
CTokens should reference this contract as their comptroller.
也就是该地址用存储数据,执行委托调用comptroller的实现合约。所有的CToken应该设置comptroller为本合约(Unitroller)。
这里可以看出使用了一种代理委托的可升级模式。
governorAlpha: 提案管理合约,防止使用个人账号进行管理。
timelock:时间锁定合约,成功的提案在锁定一段时间后才会执行,给大家留出准备时间。
maximillion:有来处理CEther的合约
priceOracle:这里打开左边PriceOracle.sol
,可以发现它为一个抽象合约,相当于定义了某些接口和数据结构。SimplePriceOracle.sol
是它一个简单实现,所以这个地址可以为SimplePriceOracle.sol
地址。
priceOracleProxy:项目中没有相应的合约,不过我们可以在CreamFi团队Fork的compound-protocol的合约中找到一个实现参考。它是价格预言机的一个较完善版本,能获取多种DEFI中的代币/LP价格信息。
7.2、部署CToken
前面的命令部分我们可以跳过,我们先看下面这段代码:
npx saddle -n rinkeby script token:deploy '{
"underlying": "0x577D296678535e4903D59A4C929B718e1D575e0A",
"comptroller": "$Comptroller",
"interestRateModel": "$Base200bps_Slope3000bps",
"initialExchangeRateMantissa": "2.0e18",
"name": "Compound Kyber Network Crystal",
"symbol": "cKNC",
"decimals": "8",
"admin": "$Timelock"
}'
这里,红色部分就是初始参数了。在这里要提及一个概念,就是每个CErc20/CToken
对应一个市场,每个市场其实都有一个底层货币(ERC20),也就是underlying
,在本例中,底层代币就是KNC。
这里要提及一下,CErc20/CToken
其实也是采用了代理委托这种可升级模式:
代理合约为:CErc20Delegator.sol
。
实现合约为:CErc20Delegate.sol
。
接下来我们看一下CErc20Delegator
的构造器函数:
/**
* @notice Construct a new money market
* @param underlying_ The address of the underlying asset
* @param comptroller_ The address of the Comptroller
* @param interestRateModel_ The address of the interest rate model
* @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18
* @param name_ ERC-20 name of this token
* @param symbol_ ERC-20 symbol of this token
* @param decimals_ ERC-20 decimal precision of this token
* @param admin_ Address of the administrator of this token
* @param implementation_ The address of the implementation the contract delegates to
* @param becomeImplementationData The encoded args for becomeImplementation
*/
constructor(address underlying_,
ComptrollerInterface comptroller_,
InterestRateModel interestRateModel_,
uint initialExchangeRateMantissa_,
string memory name_,
string memory symbol_,
uint8 decimals_,
address payable admin_,
address implementation_,
bytes memory becomeImplementationData) public {
// Creator of the contract is admin during initialization
admin = msg.sender;
// First delegate gets to initialize the delegator (i.e. storage contract)
delegateTo(implementation_, abi.encodeWithSignature("initialize(address,address,address,uint256,string,string,uint8)",
underlying_,
comptroller_,
interestRateModel_,
initialExchangeRateMantissa_,
name_,
symbol_,
decimals_));
// New implementations always get set via the settor (post-initialize)
_setImplementation(implementation_, false, becomeImplementationData);
// Set the proper admin now that initialization is done
admin = admin_;
}
这里需要提供的构造器参数为10个,上面红色部署为8个,少了实现合约地址和初始编码数据。
由此可见,我们需要先部署一个实现合约,也就是CErc20Delegate.sol
,这里只用部署一次就可以了,因为委托合约不包含数据嘛,只负责逻辑。这样我们就得到了缺少的第一个参数:address implementation_
。
从CErc20Delegate.sol
合约中的_becomeImplementation
函数我们可以看到,那个becomeImplementationData
其实是没有用到的,因此我们简单的将它输入0x
即可。
这样,10个参数我们就全部拿到了,我们可以部署CToken合约了(记住这里comptroller是Unitroller合约的地址,前面讲过的委托代理可升级模式)。
建议读者可以在以太坊Kovan测试网上自己尝试部署一下Compound,不过,这里还要做一些准备工作,把一些常用的ERC20代币从以太坊主网上搬到Kovan测试上去(重新部署一次),例如USDT、DAI、WETH等。部署几个测试用就可以了。
我们可以多部署几个CToken合约,把常用的代币例如USDT,USDC,DAI之类的市场全部建立起来。记住,实现合约只用部署一次,那个实现地址参数都是相同的。
具体部署的过程下次再研究了。
对于Compound的学习必须先掌握Solidity合约的委托代理这种模式,切记!
八、写在最后
Compound合约第一眼看上去多又复杂,笔者也忍不住打了退堂鼓。然而学习就是一个从难到易的过程,只有用功夫去努力学习,你才能慢慢理解它的结构和细节,最终你会觉得也许并没有那么难。
自己也是边学边写,欢迎读者留言指正错误或者提出改进建议。
以上是关于Compound学习 README.md的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android Studio 的 README.md 文件中禁用代码检查错误
API接口自动化测试框架搭建(二十六)-框架README.md设计