DAPP与智能合约
用户和系统之间在去中心化应用程序(DAPP)上发生的大多数交互都是由智能合约提供支持的,一定程度上来说,DApp是通过智能合约构建起来,DAPP智能合约开发,币安智能链o智能合约3DAPP搭建,智能合约钱包开发DAPP源码,这种合约是去中心化的,难以篡改。DAPP实现用户体验,还需要UI交互界面,通过RPC与后台对接,那么DAPP就是包含完整的智能合约+用户UI交互界面。
Uniswap
Uniswap是所谓的Decentralized Exchange,它允许个人或称为流动性提供者,将Token汇集到智能合约中提供流动性。
它包含两个Token: 一个用于我们正在交换的Token(第7行),另一个是治理Token(第11行),称为流动性池(LP)Token。该池将BSV直接存储在UTXO中(以satoshis为单位),将Token存储在对应的公钥哈希下(第3行)。
contract Uniswap{
//pool's public key
PubKey poolPubkey;
//the main token
state
ERC20 token;
//the liquidity pool governance token
state
ERC20 lpToken;
...
}
Uniswap合约源代码
增加流动性
任何人都可以通过调用函数addLiquidity向池中添加流动性。有两种情况(在第9行检查):
首次增加流动性:可以存入任意数量的BSV和Token。
添加更多流动性:BSV和Token存入的比率必须与池中的现有比率相匹配(第22行)。
//add bsv and token to liquidity pool
public function addLiquidity(PubKey sender,Sig senderSig,int tokenAmount,int senderBalance,int senderKeyIndex,int oldTokenBalance,
int lpSenderBalance,int lpSenderKeyIndex,int newBsvBalance,SigHashPreimage txPreimage){
require(checkSig(senderSig,sender));
int oldBsvBalance=SigHash.value(txPreimage);
//mint new lp tokens for the liquidity provider
if(oldBsvBalance==0){
//initialize pool
//initially,just mint new lp tokens per the amount of new bsvs deposited
int lpMint=newBsvBalance;
require(this.lpToken.mint(sender,lpSenderBalance,lpMint,lpSenderKeyIndex));
}else{
//add more liquidity
int bsvAmount=newBsvBalance-oldBsvBalance;
//deposit ratio must be the same with current pool ration
//i.e.,oldBsvBalance/oldTokenBalance==bsvAmount/tokenAmount
require(oldBsvBalancetokenAmount==bsvAmountoldTokenBalance);
//mint new lp tokens,proportinal to the amount of new bsvs deposited
int lpMint=this.lpToken.totalSupply()*bsvAmount/oldBsvBalance;
require(this.lpToken.mint(sender,lpSenderBalance,lpMint,lpSenderKeyIndex));
}
//transfer tokens to the pool
require(this.token.transferFrom(sender,this.poolPubkey,tokenAmount,senderBalance,senderKeyIndex,oldTokenBalance,senderKeyIndex));
require(this.propagateState(newBsvBalance,txPreimage));
}
存入BSV后,新的LP Token在第26行按比例铸造给流动性提供者。Token在第30行转移到池子对应的账户。
例如,如果池中有10个BSV和100个LP Token,而Alice又向其中存入了5个BSV,则将向她铸造50个新的LP Token。
移除流动性
流动性提供者调用函数removeLiquidity来提取他们的资金,包括BSV和Token。
//remove bsv and token from liquidity pool
public function removeLiquidity(PubKey sender,int lpAmount,Sig senderSig,int oldTokenBalance,int senderKeyIndex,int senderBalance,
int lpSenderBalance,int lpSenderKeyIndex,SigHashPreimage txPreimage){
require(checkSig(senderSig,sender));
int oldBsvBalance=SigHash.value(txPreimage);
//withdraw amount
int bsvAmount=oldBsvBalance*lpAmount/this.lpToken.totalSupply();
int tokenAmount=oldTokenBalance*lpAmount/this.lpToken.totalSupply();
//burn the lp tokens
require(this.lpToken.burn(sender,lpSenderBalance,lpAmount,lpSenderKeyIndex));
//transfer tokens from pool to the sender
require(this.token.transferFrom(this.poolPubkey,sender,tokenAmount,oldTokenBalance,senderKeyIndex,senderBalance,senderKeyIndex));
//transfer bsvs to the sender
int newBsvBalance=oldBsvBalance-bsvAmount;
require(this.propagateState(newBsvBalance,txPreimage));
}