Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。
( H: L4 X! z3 u/ j! H+ N' e
0 a# t5 b9 Q* N: t5 w7 O- m若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。" J* A  X: @! F) c
5 h$ M; T+ [  K& b$ l
若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:
3 h: w& t" |8 X, ~“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。
  A8 A5 [  |3 A
9 }/ k- g* C' y" K
若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。+ E; B$ b6 X4 V: w7 K
# H" \! e# x. W" v! x* Y% A5 N: w
【核心智能合约简单描述】
! t+ X1 I8 g6 b, R1,contract BancorConverter
7 _& Z  F4 k8 Y0 h功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。/ W' i" `, j2 f, X. F7 `% d
2,ITokenConverter) }' G$ ?8 d3 R/ w: O& _
功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。6 c4 l0 H# G; g/ z  B
3,SmartTokenController) [- P! r+ |) C$ L
功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。/ `) r3 @6 H4 ^3 a0 n) ]- x
4,Managed$ V# T- \1 g7 S* p, S! n+ C
功能说明: BancorConverter的父类之一,提供协议管理的支持。  m, H  @7 J& E, f* T0 c
5,IBancorConverterExtensions
, N% }& I2 z# X. U" e& g4 [功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。, V' F7 O6 ^6 c. ~1 g* H6 Q
#4,核心函数分析0 r( W3 w+ `4 P  K# R
##4.1 convert(…)函数8 S( [; [' _8 w% g8 w
convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:' r/ c/ M9 b3 X
; G" |6 k& I* D, _/ f: K% f& Q8 O/ L
/**
2 t) T5 W0 G) j3 r! f) r6 X        @dev 将一定数量的_fromToken 转换为 _toToken
; x2 v$ A1 F9 e1 B& b9 i9 p        @param _fromToken  用来转换ERC20代币( k! ~! ~- j- d. ?0 H
        @param _toToken    被转换到的ERC20代币8 h  M4 @* k# F. |- \/ `( D/ S  t8 x
        @param _amount     转换的数量,基于fromToken
  ^/ |4 b1 e, b2 y        @param _minReturn  限制转换的结果需要高于minReturn,否则取消
8 m: S) O7 ]7 U( n6 t        @return conversion 返回数量
9 J8 i) G6 k0 m  o: P; T    */% d' t" t  m5 V; A0 w8 }7 j! y
    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {  s4 J; ^- y: i" j
            convertPath = [_fromToken, token, _toToken];
- A  ^0 r8 i$ O; h' l, R: E. w8 V            return quickConvert(convertPath, _amount, _minReturn);
: M2 t; a# n9 j' A$ o. F    }
% O  F5 \9 Y% O% p1 B& c# u* z7 y- g/**7 `' D9 X: l5 H9 S( t$ ~+ M5 U  x
        @dev 通过之前定义的转换路径来转换代币
( ?" H# f: P0 h        注意:当从ERC20代币进行转换,需要提前设置补贴
: G1 k- k8 _6 q+ @& s        @param _path        转换路径, l! J: N7 x+ F, M, d; K# {. Q3 h. W
        @param _amount      转换的数量
; q3 K; o3 N8 y5 ]        @param _minReturn   限制转换的结果需要高于minReturn,否则取消, t8 w1 g$ \. q; Q9 x  _2 ]+ T
        @return 返回数量- }& H5 Z; Z$ v0 m
    */1 p4 Y9 s, A1 {3 r
    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)
4 U. r. [2 F. B# U2 w4 h$ c        public
3 D; Q1 V$ |: ~8 O% k        payable; \1 L0 \; B& L0 M, Q
        validConversionPath(_path)
! B$ b( p7 g3 g0 |  R9 ~. G4 `" i        returns (uint256): ]# S! @% O  F3 S- X+ y
    {+ j! M' c/ f6 \# g) S% i
        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);1 F! ^: O/ F) f& o+ e' }
    }
+ |( @' P; N. ^2 n' I: H/**
/ G9 h/ p6 U( _4 p        @dev 通过之前定义的转换路径来转换代币
; c9 D, h, X: L+ A) Z9 k4 ?. f2 t        注意:当从ERC20代币进行转换,需要提前设置补贴
' j3 u/ L& M; U        @param _path        转换路径
6 A- j8 ~: B* u; D4 N% v4 G: s5 F        @param _amount      转换的数量
5 h4 O6 W6 |% s3 Y* n) Y        @param _minReturn   限制转换的结果需要高于minReturn,否则取消) s" X# ~, }! T5 Y! c( j( v
        @param _block       如果当前的区块超过了参数,则取消/ Y/ l! O) d1 P2 g  J
        @param _nonce       发送者地址的nonce
* y0 ^2 ~: v0 O) B        @param _v           通过交易签名提取2 q7 P- m3 \! E1 J. `" t
        @param _r           通过交易签名提取) k0 _4 p: d$ X1 Q5 A0 q  I% r) u, m
        @param _s           通过交易签名提取% u( f" F6 n( Q5 i
        @return 返回数量
! l. Z! o( e& J( F8 M    */
3 t6 L# a6 d$ \( O: |$ x    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)
( `, B- y6 f; j$ @" @" p        public
0 S3 i: C) v0 ^+ \7 b/ @8 u        payable+ h  S/ e+ D2 H; N1 @3 a9 z# b
        validConversionPath(_path)
9 e# b2 Y& {1 T$ U. X        returns (uint256)2 S. r& P' A6 I' j, o" ^
    {
& ]" X+ G$ O8 B$ a; C        IERC20Token fromToken = _path[0];: b/ }( B4 Y( l) ~, ]6 ~8 B
        IBancorQuickConverter quickConverter = extensions.quickConverter();
3 _4 z8 I, L( S( q2 U) f        // 我们需要从调用者向快速转换着把源代币转化: _$ M' n* l; f+ X5 w7 K, P
        // 因此他能基于调用者进行转换& u. P8 b8 @6 K. Z2 J& f
        if (msg.value == 0) {
* j+ j. K2 ~7 q& Z            // 如果不是ETH,把源代币发给快速调用者# [( Y1 N6 K& f4 \5 w! {; @
            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者
$ Z$ Z; I& z# `, `; k5 a% z8 p+ E/ f            if (fromToken == token) {
; b* f+ d9 t2 U' X1 c* w                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币
$ I  ?8 l0 U# l$ i: O! q( m: |& K                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者
$ G5 G4 H2 b* s+ c" d            } else {
, j$ ^+ ~3 E- u; k0 O: E% G: M                // 否则,我们假设有了补贴,发给快速转换者9 A7 M( D0 Z: {
                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));4 X) M9 m. p: W; `
            }" n* S3 P0 |$ k
        }
1 ~' h( f5 e( e1 {7 @+ L% e4 }  f8 k        // 执行转换,把ETH转回& q1 M5 a+ H$ q) w' C
        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
0 l$ P# H. O6 X& |) S- e    }
$ _2 k5 E1 P" _: x( c1 w
6 z' T$ Y2 a- \+ z* v1 _##4.2 change(…)函数
; @- E# q- f+ E. i8 h- s4 M** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:/ Y4 Z( @# d3 C. J) r

3 d) t: w# g7 u2 M1 ^6 _4 y! b既然是过期代码,源代码就不放了。
! F) f6 s2 s9 ?8 j# U) d##4.3 getReturn(…)函数9 n/ W- y4 V. X) \

6 n. z# S' @9 b; u1 Afunction getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)
0 n9 G" x3 ]" r7 E
. F0 l3 [( ?+ z2 V" ^4 ?7 G2 Q# g
功能' q4 l3 S0 q& V# p3 G' `: i) N6 R
返回从一个代币转换为另一个代币的预期数
源码:
% a) i' K, S1 Q9 k7 G

  D! m& L+ e2 ]. c( ~: Q/**
+ l5 y2 O4 E* J        @dev 返回从一个代币转换为另一个代币的预期数量5 I( b( z- E6 @
        @param _fromToken  ERC20 被转换的代币
- T1 e9 ^2 \( P        @param _toToken    ERC20 转换成的代币  D7 u0 L( r& f% I- _
        @param _amount     转换的数量
4 c8 ?6 {  G6 a: B9 ~% p        @return 与其转换的数量1 z( t3 H. H# C! W- a( w- `! H
    */
& s8 n- [2 g. y    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {
/ e# w# a7 ~: t        require(_fromToken != _toToken); // 验证输入
, U+ T8 E( j$ a) q4 B- ^        // 基于当前代币转换
1 l, b$ U2 ^5 X8 W3 r5 c- ]        if (_toToken == token)5 @# j3 q% q! X; ?, G( G; y7 i2 Z9 m: t
            return getPurchaseReturn(_fromToken, _amount);* Q6 \1 Y& O, x& N3 ?
        else if (_fromToken == token)( ~' g% \' m) j2 D$ l. R' E1 W
            return getSaleReturn(_toToken, _amount);9 J9 i" |$ k- l3 h' f; D+ C1 b
        // 在两个连接器之间转换' O0 Q2 k6 q0 ~; w
        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);
2 ^# w* u) ]+ w6 Y; m* v8 R3 L/ g        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));+ g3 o, x. m( g7 Z
    }$ k# Y5 y/ ~6 p: T6 A  F# d
/**
: ]/ M; C7 h, c; ^; B' d        @dev 返回通过一个连接器代币购买代币的预期结果
. ]' m4 F; J/ f" P! M        @param _connectorToken  连接器代币协约地址% ?( O7 G) q, w0 `, s
        @param _depositAmount   买入的数量3 ~4 w: U1 f2 C0 _
        @return 预期的数量) o5 q& z+ Y( L
    */
7 d3 n/ N# F9 L% Z) ?3 E    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)4 {( j# @! {4 W3 o
        public
4 a& j6 Q! G9 C/ l1 z        view, W( x  {; V/ v$ o
        active. n& C) S0 ~6 i; v
        validConnector(_connectorToken)" v: o' S! W8 l  p
        returns (uint256)
0 ~5 @& i  a4 g( p" G    {/ ]$ w6 q3 A6 B/ e; S3 S- Y( O
        Connector storage connector = connectors[_connectorToken];
" f  s$ d' X( i. ^) @        require(connector.isPurchaseEnabled); // validate input
7 m" h/ _& n. g        uint256 tokenSupply = token.totalSupply();3 w4 x7 m& _9 ?$ d$ U" }  `3 T8 w
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
* E+ Q1 G3 }1 n/ T        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);
/ Z: P. c- F5 t; ~" n        // 扣除费用
5 N" j# i7 }4 D+ |% J        uint256 feeAmount = getConversionFeeAmount(amount);, f* N4 \) r" l( O$ m5 ?
        return safeSub(amount, feeAmount);
! ?1 X) V* Z% P$ o. q7 P    }
, e, T: X. f' H2 K+ {/**
8 q" d4 D. \6 l. n! s        @dev 返回通过一个连接器代币卖出代币的预期结果! A6 _5 x/ K! g5 y9 Y( U
        @param _connectorToken  连接器代币协约地址4 D% x4 {1 o* S  H$ h. b8 Y7 Q
        @param _sellAmount      卖出的数量2 k1 R& b* _3 T, }" C
        @return 预期得到的数量
) j- ^! C( g% e( R/ ~! V    */
0 I+ i  j% w7 y! i$ O0 ]    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {
0 U# p. D4 [) l8 e, A        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());, ^6 _' z. S9 t+ R
    }
; |% F) o, V! s; A8 K/**
" [. g3 J' Q4 n7 F3 x& N        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回
+ f0 x0 `. n& Z4 R5 ]        @param _connectorToken  连接器代币协议地址
- b1 ^# ~6 v0 a7 y        @param _sellAmount      销售的数量
, \8 |! a4 [. d$ `+ M3 T        @param _totalSupply     设置总供应量
$ \% Y/ P/ v) V# D        @return 返回的数量
/ L2 l* ^6 v# {7 D    */$ k5 T* n) w3 Z; m4 [9 n, i
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)
! v8 L% p: k1 l, {+ m3 n3 l* N        private( M! d( z! n2 D$ r) f
        view, p9 v4 n( Z& L! d, K1 K$ k
        active# z% w2 h7 h0 U4 i
        validConnector(_connectorToken)
5 O+ ~" e# `) l* X0 h! B) m        greaterThanZero(_totalSupply)
# z2 z* _. L0 j8 s        returns (uint256)  v: y& l# B1 n% V; a% E; C
    {
# b$ a- o7 g' I7 t, H        Connector storage connector = connectors[_connectorToken];+ r5 ^' J7 T; \, J& S
        uint256 connectorBalance = getConnectorBalance(_connectorToken);# _" ]  A3 ]2 t( v& K% u& H
        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);
- M0 H6 q; m; W6 f        // 从返回的数量中剪掉费用
3 p. A6 x/ P  T        uint256 feeAmount = getConversionFeeAmount(amount);
4 \+ u. n& E2 O2 ]        return safeSub(amount, feeAmount);
& I: X! x, W: a1 l    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14