然後會出現這樣一個視窗:
現在在平臺上可以質押一些通證。首先,需要點選確認,然後就可以向智慧合約傳送ERC20通證。一開始需要在錢包中充一些測試網LINK通證,你可以點選此處獲得Kovan LINK。
點選兩次確認後,就可以開始交易了。完成後,重新整理頁面可以看到最新的質押通證餘額。
然後可以回到終端,發放獎勵通證。可以在這裡檢視LINK/ETH匯率。平臺會發放與我們的ERC20通證總值相等的DAPP通證(注:以以太幣計價)。在我寫這篇文章時,1個LINK價值等於0.03348個以太幣,因此平臺將收到0.3348個DAPP。那麼執行以下命令發放通證:
truffle exec scripts/issue-token.js --network live
操作完成後,你可以看到收到的DAPP通證數量。
你還可以一鍵轉換通證型別。程式碼庫包含Kovan測試網的三種預設ERC20通證,即:LINK、FAU和DappToken(由你來部署!)
專案執行機制
專案主要功能包括兩個智慧合約,它們的前端都由react實現。
DappToken.sol
TokenFarm.sol
如果你剛開始學習truffle,不知道Migrations檔案是什麼,請先檢視truffle文件。
我們先來做DappToken.sol,因為它最容易做,只是一個簡單的ERC20通證。
幾乎不用寫什麼程式碼就可以部署一個ERC20通證:
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract DappToken is ERC20 {
constructor() public ERC20("DApp Token", "DAPP") {
_mint(msg.sender, 1000000000000000000000000);
}
}
安裝openzepplin作為智慧合約框架。匯入的ERC20.sol包含Dapp通證作為ERC20通證所需的所有功能。在建構函式中給它命名,然後首次發行通證,進行部署。在演示中,我們使用了1,000,000個DAPP。(記住,末尾要加18個0,因為solidity/以太坊不帶小數點。)
部署合約時,將1,000,000個DAPP通證全部發到TokenFarm智慧合約中,平臺使用者獲得的獎勵全部來自這個智慧合約。這些行為定義在migrations檔案3_deploy_tokenfarm.js中。
const tokenFarm = await TokenFarm.deployed();
await dappToken.transfer(tokenFarm.address, "1000000000000000000000000");
tokenfarm.sol檔案重要性更高,其中包含質押、取消質押以及檢視使用者餘額等所有程式碼邏輯。為了追蹤所有使用者的質押資產餘額和ERC20通證總額,我們將使用者地址對映生成包含通證地址和通證數量的資料結構,並命名為stakingBalance。我們還可以對映生成以下資料:
· 使用者質押了多少獨特的通證
· 某一通證對以太幣的價格資料
· 平臺支援的通證名單
· 使用者/流動性提供方名單
mapping(address => mapping(address => uint256)) public stakingBalance;
mapping(address => uint256) public uniqueTokensStaked;
mapping(address => address) public tokenPriceFeedMapping;
address[] allowedTokens;
address[] public stakers;
使用者可以呼叫stakeTokens和unstakeTokens函式在平臺上質押或取消質押通證。不過更有意思的是getUserTotalValue函式,這個函式會接入Chainlink去中心化預言機,獲取可靠的價格資料,計算質押資產總值。
function getUserTotalValue(address user) public view returns (uint256) {
uint256 totalValue = 0;
if (uniqueTokensStaked[user] > 0) {
for (
uint256 allowedTokensIndex = 0;
allowedTokensIndex < allowedTokens.length;
allowedTokensIndex++
) {
totalValue =
totalValue +
getUserStakingBalanceEthValue(
user,
allowedTokens[allowedTokensIndex]
);
}
}
return totalValue;
}
getUserStakingBalanceEthValue函式可以獲取某一使用者的某一質押通證價值。
function getUserStakingBalanceEthValue(address user, address token)
public
view
returns (uint256)
{
if (uniqueTokensStaked[user] <= 0) {
return 0;
}
return
(stakingBalance[token][user] * getTokenEthPrice(token)) / (10**18);
}
getTokenEthPrice函式可以獲取Chainlink價格資料。
function getTokenEthPrice(address token) public view returns (uint256) {
address priceFeedAddress = tokenPriceFeedMapping[token];
AggregatorV3Interface priceFeed = AggregatorV3Interface(
priceFeedAddress
);
(
uint80 roundID,
int256 price,
uint256 startedAt,
uint256 timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
return uint256(price);
}
需要新增通證對以太幣的價格資料,以計算正確的價值。
歡迎大家使用這個程式碼庫進行開發或發PR。智慧合約開發者如果想要在專案中新增流動性挖礦功能,這是一個很好的起點。
現在,你的DeFi專案就可以接入Chainlink去中心化預言機了!