Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。- `9 c- E$ Y! g7 ~' c
0 f/ O8 R' Z3 f8 y; K: q
若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。
$ Q9 v3 I6 J/ Z
' c, l8 M6 Z9 v2 W& L, `0 e1 W若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:, c2 ~2 ^' X4 v+ R
“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。
. }* G# {; D- H/ H9 y: b8 R+ `

1 K' H* k; K5 X5 u* t若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。7 L; Q6 z4 h9 C. S& L
$ [1 q; b8 U( O5 e
【核心智能合约简单描述】$ D( W% m1 a! B% g$ v1 U4 q
1,contract BancorConverter- D7 x9 O$ y9 D; |1 w* V0 B- o
功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。
7 W8 Q- }5 t# k9 b2,ITokenConverter
) y4 r" z  k0 T3 L. k+ _' [( A3 _功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。9 v) t  q1 P1 V! }+ x( B
3,SmartTokenController
4 z  s2 V6 a' G6 n功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。0 B4 Q9 F. h3 h
4,Managed2 P  g" L- P6 G' \
功能说明: BancorConverter的父类之一,提供协议管理的支持。
" ?3 i8 l: W. a8 `6 J$ R5,IBancorConverterExtensions% h# \. G/ J1 }
功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。
2 r2 e3 u; X( j  F: o#4,核心函数分析
0 l  d2 t6 Q) V$ [. ^##4.1 convert(…)函数
3 E9 X) S( E2 x. ^9 P/ x# Fconvert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:* U1 l! W# [+ y0 @9 H/ V
! b' L. @3 F9 o9 P4 `
/**
' |+ @0 B/ X  o6 J' x+ }        @dev 将一定数量的_fromToken 转换为 _toToken
$ _* U# h8 q1 i8 K- H: N: ]+ M        @param _fromToken  用来转换ERC20代币+ X! _2 J) l6 S5 k) g- \9 L* O
        @param _toToken    被转换到的ERC20代币
' q* |: v% c  |        @param _amount     转换的数量,基于fromToken: ~6 w5 |3 z$ T& r* V
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消! i' B! K# p- P- s2 `
        @return conversion 返回数量
/ D7 G: S/ z( E: j3 Y* H    */
" T1 f0 @2 w. |; e- L1 G8 T    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {0 F8 M5 s& R: q+ g9 W3 ~
            convertPath = [_fromToken, token, _toToken];
; {2 A7 f2 x( |4 [            return quickConvert(convertPath, _amount, _minReturn);# ^: X/ K4 ?) D  F5 p8 x6 s
    }
) z  G# n3 O3 t/**
. h9 G9 a8 T4 _$ o        @dev 通过之前定义的转换路径来转换代币
  X2 W! {# g6 u' P        注意:当从ERC20代币进行转换,需要提前设置补贴/ S6 v; L; a7 N( i+ h
        @param _path        转换路径4 ^; [) A8 |1 h0 S& }2 R: v
        @param _amount      转换的数量1 ]! I( ^6 E4 @: W7 M+ j
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
: @1 y- H3 Z" x        @return 返回数量
4 v0 V* {, I! Z2 U    */
2 ]2 J9 D; _6 l6 \6 Y! o7 q    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)
& |& c; V0 T5 S& V( M* k        public2 L9 g# J  x* Q% N; O
        payable
8 K& M4 h" f1 R- g' @: m9 f        validConversionPath(_path)
/ N+ `( u0 c* W! }' e0 T        returns (uint256)% i# o$ b% ]% N6 o
    {! @: O5 u9 u( o9 @
        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);( N. D: ~' e5 _% E- |2 M
    }
9 x8 `4 p: t# x) A: J) M/**! t( D4 F$ v& P/ d( P. z' G7 X
        @dev 通过之前定义的转换路径来转换代币
+ e' U/ |  z3 D1 \; I* v) f- K, Q        注意:当从ERC20代币进行转换,需要提前设置补贴
' `0 H3 ], h$ u( P9 s+ A6 i        @param _path        转换路径
3 Q3 M$ S7 |9 {$ a        @param _amount      转换的数量7 r$ N& v: ?& n$ k) j; `
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
) Y  T1 q6 O2 M+ E8 |2 W        @param _block       如果当前的区块超过了参数,则取消
- o& B: \3 |( Z9 d8 x- f2 |  M        @param _nonce       发送者地址的nonce
+ Y8 {$ K$ i! x5 h        @param _v           通过交易签名提取
; Z8 d% E5 {& w( V. B: `  i' w* Q) [        @param _r           通过交易签名提取
9 I  n/ v0 I2 m! g: w! [  f  e7 B        @param _s           通过交易签名提取
2 o4 N! A3 E, n1 l5 u        @return 返回数量
8 a* l; I/ V' s0 P/ l7 a    */
+ f$ \# ~- C# p% n2 P- g1 Z! J    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)) v4 v* [# P7 J6 D, _: M
        public
" w8 x- o/ V- h% T        payable! o- @- i3 @8 L
        validConversionPath(_path)
. f# M# z  l, d, v1 |, _, ?2 A        returns (uint256)6 N5 i1 p$ r# d8 x
    {
* u, m3 q7 T8 K2 i* g0 M        IERC20Token fromToken = _path[0];
+ i. f8 e. R: }        IBancorQuickConverter quickConverter = extensions.quickConverter();5 Z& n" `: H2 m/ x! n0 n" V
        // 我们需要从调用者向快速转换着把源代币转化
: k1 _+ B$ F! F6 t. Z        // 因此他能基于调用者进行转换5 c  o* e+ Y8 d* \. U  P& l: I
        if (msg.value == 0) {' K2 n' C* R9 Y
            // 如果不是ETH,把源代币发给快速调用者
2 X) G; `" p. Y2 C$ J0 V9 u            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者
; p  e5 W4 k" X* A, k- b9 ^            if (fromToken == token) {$ n0 i8 e% M7 M! R
                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币* l2 n. T' z) Y" V0 e, K6 W+ O" q
                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者3 }+ T( o$ b- {3 P+ p* P3 |
            } else {' k# g: [5 K( ]# R- ]4 \
                // 否则,我们假设有了补贴,发给快速转换者
3 _4 s+ M. }4 ~: K( v                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));2 G* Y# ]: r, w% m6 N  c3 @
            }
' c2 s( n, {. S8 h% t. o2 b4 a3 o        }
. d' P0 r, A! h: ~1 |% q        // 执行转换,把ETH转回/ g( d; O- R3 T+ X# F
        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
  u: l& i% A- S, P$ l- N" b    }6 m, }. \+ {3 V$ o
. Y6 U. e0 h5 i. m4 f7 d
##4.2 change(…)函数8 ?2 ]* u4 c3 J7 S: C1 Z& T  E$ N
** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
( F3 _6 n& v- G7 y/ E. P

% e$ r  F# ?2 f7 w$ C) O* h5 ^既然是过期代码,源代码就不放了。2 F+ R- L" d3 q
##4.3 getReturn(…)函数# }9 @2 P( h3 }$ D1 f
! Z* E5 k6 l, [$ S2 Z
function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)
! y; W5 V# A: g3 ?' L1 K& b2 ~

! G0 C9 \  r' W) s  C9 s* Z功能2 b: T& p  n( T  w1 Q
返回从一个代币转换为另一个代币的预期数
源码:$ ~! G4 z0 P* u* n6 `* J$ N( u0 T9 |

5 B4 `; F8 u/ Y/**' h! r7 {" v! h+ F+ A
        @dev 返回从一个代币转换为另一个代币的预期数量
: t0 ]$ N2 ?$ ]        @param _fromToken  ERC20 被转换的代币
5 d) U- E8 C) ^        @param _toToken    ERC20 转换成的代币  a7 I" `7 V: o
        @param _amount     转换的数量
, J7 P, M: f6 i% S& s' b6 w, L        @return 与其转换的数量- M; a8 c6 L: _7 y+ J
    */% X* I9 V7 M# E0 K+ ~, d2 W
    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {
9 i9 ^& V3 G6 D        require(_fromToken != _toToken); // 验证输入
9 N( {- ^2 K7 B! w1 x7 e) j        // 基于当前代币转换
0 X' G' p- b+ a& b  x        if (_toToken == token). o- D  j2 @! k" ^
            return getPurchaseReturn(_fromToken, _amount);4 }( ?  F# a% j3 U
        else if (_fromToken == token)/ x/ y( t6 J. H9 _5 ~3 L+ E8 Z: i
            return getSaleReturn(_toToken, _amount);6 ]" u; Z4 {! n
        // 在两个连接器之间转换9 E8 I! y/ E! v
        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);; b+ {8 \9 o- k9 W7 k( ]
        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));
; W$ @8 \& l, W5 l/ Z    }
; G0 i3 A$ Y( B/ ]/**
  c; s$ K. {/ o/ V        @dev 返回通过一个连接器代币购买代币的预期结果
! F3 `8 V* R, k: d3 R& K" l* \        @param _connectorToken  连接器代币协约地址
+ T  T4 k& {! W# V# z        @param _depositAmount   买入的数量$ j9 s6 [6 f2 m; W; u6 T9 z; _( I# }" q
        @return 预期的数量
8 K: Q5 k! t* T5 r/ l    */
( m& |; p/ T; B9 g' h& [% O6 ]    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)3 R: h* e& T+ {* O) _1 H
        public) _7 B. _$ ~: O" o/ }; H% ]7 B& F
        view
1 U  ]; W- v( s) A        active
' O# L! s; G5 \! k! u" T        validConnector(_connectorToken)8 y( X$ ?& }  ]% k
        returns (uint256)) j, i" v/ A' W& T4 F4 R/ @$ ]
    {/ k% Z  ?  Y" m7 H2 y
        Connector storage connector = connectors[_connectorToken];
9 q8 H' G1 T2 o2 F3 Q' `# u3 F% z        require(connector.isPurchaseEnabled); // validate input- f# N3 v8 R' ?& c" M( Q2 V
        uint256 tokenSupply = token.totalSupply();, k! H' g! `0 e; u
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
# T5 f( f3 _- S4 Q! N+ `/ Z        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);# ^3 X( A* C4 X2 a6 W# d
        // 扣除费用
, m! m6 _$ ?7 d, T        uint256 feeAmount = getConversionFeeAmount(amount);
4 E* F2 z+ T- O( b: l        return safeSub(amount, feeAmount);6 H  v* S$ x! x+ [/ U; e" H
    }" q1 t) f4 {  v5 u& E3 K8 I7 _/ i
/**$ Z: U$ X( D: }" a
        @dev 返回通过一个连接器代币卖出代币的预期结果, u% p& b$ v: p& Z( h
        @param _connectorToken  连接器代币协约地址5 {+ e! M5 a) T- o+ C6 f, K
        @param _sellAmount      卖出的数量
9 V. n' Y: C: E+ X- R" e  r        @return 预期得到的数量
$ `, f! _& O- z! x3 B  b' t    */+ P! V" o0 `1 g- r* e' @  b
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {
. \2 N' u- ~  l& p! k        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());2 j( X" W$ ]' f8 R
    }- T; W) w! V0 [5 @+ `, F
/*** q, F  }( `) u! c) O! O/ i
        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回. c+ v' N! B& d6 O
        @param _connectorToken  连接器代币协议地址
* o! j/ ]4 ]/ z9 b# a        @param _sellAmount      销售的数量
( O) R" W' Y% k0 F  b' K# J- y: k        @param _totalSupply     设置总供应量6 i9 U/ {  X( Z' l
        @return 返回的数量
! Y- |/ r2 J  _" d) z    */, k( k  X3 |  v* Q
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)
1 h( f% D$ `+ t4 a" }        private
! H( f, F: q& j$ d( V        view
, i* k% }4 M% x* G0 d9 r        active
  o, I* T' A8 s: O* E9 X: S        validConnector(_connectorToken)  h  q& p6 B% \! a* w$ p
        greaterThanZero(_totalSupply)- T5 M, u% E0 D3 L6 H, w, T; @; K
        returns (uint256)
9 k! W" y6 q3 _' o, H% O    {
- i& u# M9 W) M& V0 L! t/ f        Connector storage connector = connectors[_connectorToken];+ T9 C# D8 E7 r9 ]
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
$ `* c- C8 _7 O# q9 x& ]        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);
3 k  W/ S3 [, |* ^& v! g+ F  T8 m        // 从返回的数量中剪掉费用; Z' ~; r: m) f" u
        uint256 feeAmount = getConversionFeeAmount(amount);
% k& ]5 }5 x1 D        return safeSub(amount, feeAmount);
8 F  |8 u6 {. E# @4 s/ g- |    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14