Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。' L, `. ^9 Q' K4 o5 c

* J* \3 u) b5 D若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。, D4 ~; R; l$ ?+ R9 i
6 r8 g7 m" C  r% }5 d) b
若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:
5 i: K' u" G; ~& S“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。1 G9 E4 A0 A5 S" s5 l
2 H$ h2 |+ K; k) `0 K
若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。
# w. O' @" q/ v6 s. b, L* X! f5 ^9 C8 b6 `
【核心智能合约简单描述】6 G! n! q. q& z
1,contract BancorConverter! J9 u- ~. [# R- u" n7 o- W9 a
功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。
: k/ S. ?1 {% T0 c7 F2,ITokenConverter
. ~. _3 a; e# \, X4 H3 m功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。
0 I: e& L! y  w+ k7 x. z$ h3,SmartTokenController
# s5 Q+ @& m2 `& I; z* j' s  D( O功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。
* b  L" y- x$ ]: k& M- A& D4,Managed
0 e+ g& e* L1 @$ ?3 Y9 U1 I功能说明: BancorConverter的父类之一,提供协议管理的支持。
  T+ c2 i/ f* B5 O) i5,IBancorConverterExtensions
9 E4 T. I) G. J" E2 V/ c  |8 J功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。1 J' M, G) l1 ~& c8 G! T
#4,核心函数分析0 Q" V& W7 g* l! l# H; K- G. s7 g
##4.1 convert(…)函数
, s, [8 w# _8 }- lconvert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:1 Y; ~2 R' _; y  r+ T- M3 d

( V( V! l( K. N! m1 k: M/**$ K0 A/ J7 a8 P2 @4 v8 D
        @dev 将一定数量的_fromToken 转换为 _toToken
: Q! t  k* h2 u, j        @param _fromToken  用来转换ERC20代币
$ F7 T, @7 j7 H0 j  {        @param _toToken    被转换到的ERC20代币1 ^# L% c& s6 x$ w: }1 w
        @param _amount     转换的数量,基于fromToken" l( p/ I% Q5 L- K
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消
! B5 o) g$ |: F* R# E2 Q/ ~9 e1 X        @return conversion 返回数量' z6 _$ Q# i2 m2 _
    */
; R, w5 `' u( B7 T0 X    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {
, T5 M: c( \* O4 J            convertPath = [_fromToken, token, _toToken];
$ P9 z$ ?' S0 V/ ^, ~; z6 b            return quickConvert(convertPath, _amount, _minReturn);
+ r/ J, K: Z" i6 o3 z7 m    }# R- {  E4 O. S" u6 P( l
/**$ _7 j+ r/ W% t$ u& n
        @dev 通过之前定义的转换路径来转换代币8 |6 e: A7 K1 T
        注意:当从ERC20代币进行转换,需要提前设置补贴% S9 K( b! C, w$ U
        @param _path        转换路径) D! i( C2 o- U7 B( y3 ]
        @param _amount      转换的数量
% O5 I( s2 L. q6 ^" |        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
2 C. D( Y* M3 ^9 x4 t5 B0 D        @return 返回数量; o! s/ l0 c$ o
    */9 M7 F' `4 d  `( `9 H. A+ N
    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)
0 Q& y6 c. I$ S5 c  L        public
' W; ^0 O9 P+ f; |/ b        payable3 c1 x! K4 z6 K$ O  d
        validConversionPath(_path)) T/ s* a6 l. h- D  W- z% B
        returns (uint256)7 C3 z) \* I3 \
    {
- ?) I, e5 _8 A7 ^5 j" u: }        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);" e* [  o6 i: {+ e4 H0 y" k
    }
" P( Z7 a5 T; s1 h# y9 ?9 Y/**# H$ W' ^: E& s1 b( ^8 ]
        @dev 通过之前定义的转换路径来转换代币
" [) c- i+ `- `! }/ j' o4 X        注意:当从ERC20代币进行转换,需要提前设置补贴
$ ]' K2 V9 ]0 r2 g        @param _path        转换路径
0 }  W7 \% R9 w1 x1 j9 P        @param _amount      转换的数量
3 u8 _$ ~7 q& e8 V0 a0 |        @param _minReturn   限制转换的结果需要高于minReturn,否则取消1 k- K& x9 K8 ?$ }3 @
        @param _block       如果当前的区块超过了参数,则取消0 V! e& _$ i7 A1 ]0 t
        @param _nonce       发送者地址的nonce
& }2 }' f9 o  d  v( j        @param _v           通过交易签名提取
% r3 m* {2 S  f) @2 P0 z$ s- m        @param _r           通过交易签名提取
/ A. n$ g( j! ^3 O1 \4 T1 }        @param _s           通过交易签名提取/ ?1 B- f" a! W% a' j
        @return 返回数量, }% d! ^% L+ x& P: P
    */
* @& t& H. A# ?' t# H8 }    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)% k6 ]! Z. C, R/ {# _
        public9 O5 `& B% }- n, m
        payable7 j4 h7 }) L) P2 V4 T4 p# r
        validConversionPath(_path)
" l1 W" c6 Y& M+ v+ f, s/ W/ x        returns (uint256)
" A" X5 j* ]1 l* o  \# i    {6 C5 i8 X) g! T1 D2 ?9 Q8 N7 z6 v
        IERC20Token fromToken = _path[0];
) p/ O7 ~# W* x( A* O/ N        IBancorQuickConverter quickConverter = extensions.quickConverter();! t5 {- }6 j/ a* W2 X$ I
        // 我们需要从调用者向快速转换着把源代币转化
5 @4 R. T" S: A' N0 j: D# @; P( _        // 因此他能基于调用者进行转换6 b$ y; f0 f& y& E& F
        if (msg.value == 0) {% e/ f0 }9 X0 y+ L$ Z
            // 如果不是ETH,把源代币发给快速调用者5 O. M8 }3 z5 N0 |1 J: _
            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者
; Y  s; ^4 h, V- q$ x" Z3 |            if (fromToken == token) {' J3 [2 L9 k4 h; d" r
                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币
3 e) E" j, L* X/ Y/ Z3 v$ o) S                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者) p2 Z" Q0 `  H# U) B
            } else {
8 y! t: c' \$ [/ r. }  v                // 否则,我们假设有了补贴,发给快速转换者& C& h7 `% g0 T0 k6 U* N9 S0 B
                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));
* \! U4 a+ Y) n7 ^" K$ J            }
; i" X# v- J( N: N" p  p; D        }
" B: R: c9 u1 r9 h4 y$ U( ~6 B" ?7 c        // 执行转换,把ETH转回
3 s. N8 F! |) M/ s        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
* _" Z2 s2 A3 v' t5 b5 h) A6 v; U: }! u1 M    }
# n9 M6 H- D1 x8 H
' @! L8 X+ i. o+ z) ^##4.2 change(…)函数, p, W  [6 ]6 g* {9 D
** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
8 [) g% e, l2 n% V. I; c
( \2 t# E; k: M# Y& E! p
既然是过期代码,源代码就不放了。
6 ^9 [9 I+ Y) ^. Q3 i' T# t( k4 y0 ?' F9 C1 w##4.3 getReturn(…)函数8 @; i, C* o2 r" Z; \
7 F* v2 k9 y. D& E( H( X& |  ^1 {
function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)0 v( H# W: y; \" k) M& W: r

$ q  L6 v% k, Z( \4 X2 o5 h功能
4 `9 [1 ~" ?0 q% T2 o8 m返回从一个代币转换为另一个代币的预期数
源码:! P  o3 n, \. Z  f5 E, b* D' p% k
9 e  i, C; j* u; y5 s& L2 k
/**
5 W8 M* Z: ^! g5 n7 K; P* b        @dev 返回从一个代币转换为另一个代币的预期数量: i! b3 A7 U! n: l5 Q
        @param _fromToken  ERC20 被转换的代币
( j; i1 l& G4 L# F# r. t3 f- m        @param _toToken    ERC20 转换成的代币8 \4 @, P7 Y+ p  w- G! _) X
        @param _amount     转换的数量( S7 x8 O* c. B* Y! J
        @return 与其转换的数量
- d8 S8 A8 n, L4 }/ K2 [. H( R    */  |% j* x  S8 l
    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {
: M  d  p4 `( d# j        require(_fromToken != _toToken); // 验证输入
# i6 e# n% l7 J. n, ]/ @        // 基于当前代币转换
- g6 [% F7 m6 r# @* W- I/ |        if (_toToken == token)7 {) i. A1 Y5 ~" u
            return getPurchaseReturn(_fromToken, _amount);  U, Q2 n9 p  q, Y. m
        else if (_fromToken == token)
9 W+ S) `, \4 b- V& _+ ^            return getSaleReturn(_toToken, _amount);
" U: V# f. |  Z7 H* E" \        // 在两个连接器之间转换
" n8 b. `2 j0 L, [7 k6 U: r" I7 |        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);
; b+ {" b6 Z8 e4 Q        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));$ e: T7 c! K- G( v  ]' a, ]) x
    }
' x! J3 h+ i  O2 ^% X/**
; z0 L! l/ E, @/ k- a        @dev 返回通过一个连接器代币购买代币的预期结果
/ H% }: |0 A- W9 }( v& M6 D        @param _connectorToken  连接器代币协约地址, ]& s$ o/ [4 J8 d0 Q
        @param _depositAmount   买入的数量
7 C  p* l$ V* f' X; k( `        @return 预期的数量% L7 Z7 T& n. j5 X4 F) ^
    */
  o$ ?. Q! w3 G- c. v$ |: S" d    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)
9 d* W# b" r+ W, o* X9 R! u6 N' P        public. y' g8 P6 u# _
        view
* m9 C+ P( U+ ~- b  ?1 c$ K        active
: J- ~+ Z$ |, h4 k+ t        validConnector(_connectorToken)4 ~+ `3 ~# ]. {; w; Q3 ^7 N
        returns (uint256)
5 }2 J4 n* `& X6 P0 O    {5 A4 D" P% s# |+ c3 i
        Connector storage connector = connectors[_connectorToken];
! S% {+ u/ x& D2 Z; s        require(connector.isPurchaseEnabled); // validate input
( B& S" W- u3 B: E" q0 m) l        uint256 tokenSupply = token.totalSupply();
5 w0 R9 }/ i1 j- [4 b+ }        uint256 connectorBalance = getConnectorBalance(_connectorToken);" X; L( L- \* D
        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);( S( n9 Q3 K. J+ u+ f5 M1 ^) p1 Z# G
        // 扣除费用
4 u$ W# _1 x% P' p        uint256 feeAmount = getConversionFeeAmount(amount);' T* \# N, J0 L+ U# y/ e  J/ c
        return safeSub(amount, feeAmount);
5 A6 l$ C  e$ {) Q. f% I% w    }$ [- i" M; A0 O' `2 U
/**
* ^( F$ I4 n/ r& f7 |! J. r        @dev 返回通过一个连接器代币卖出代币的预期结果
- k/ O4 D1 h) P' c. a/ B        @param _connectorToken  连接器代币协约地址
/ o" M( ^5 N4 L9 s        @param _sellAmount      卖出的数量: ~2 \6 G: J8 t9 d( \3 l
        @return 预期得到的数量
6 T$ ?, T) p* f' Y; r& ~( ^* ~    */
+ Q5 ~1 g! H/ `- \" b    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {
( ~6 c% K+ k+ D1 U' `        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());+ R& r% W. W& l1 d) y* @+ }! F
    }
. g, }3 `. \9 i/ M! [/**
6 V* O0 r7 U. |        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回
4 T# P# `: c0 r4 p* G6 q( k# p        @param _connectorToken  连接器代币协议地址0 b/ c, t2 y' @" S7 a" K# d
        @param _sellAmount      销售的数量
7 z" ^& L- L+ T* w        @param _totalSupply     设置总供应量
. T5 x) d8 n- L) X$ p        @return 返回的数量
' b0 s0 e# D7 `; F" Z4 G" Y' |, c/ P9 M    */
1 S  S1 A! R8 b$ ~& W  Q3 v    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)& ^' w: k+ k) O2 Y' z/ B
        private/ X" I( i( S5 A& E
        view
& M. s/ b7 _9 l8 e- m( @2 ^+ ?5 z        active
" d/ \; v4 b, P0 |  G$ p0 f7 H        validConnector(_connectorToken)
6 q) t2 `. H, ^+ L6 T2 P6 A% j        greaterThanZero(_totalSupply)
) C* K* q* r; |9 ^9 m        returns (uint256)
5 u. S: p; @- U2 F5 C' L9 C! i! _. }. ^    {
3 @3 L# i  }5 E  {        Connector storage connector = connectors[_connectorToken];  S8 A7 `+ r4 Q/ z( G& O% b/ V
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
  J5 }# p0 S" s1 U+ r1 K        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);' G8 g( j5 J  c# o1 w. o1 p3 i" n' }
        // 从返回的数量中剪掉费用
) u* F- A' S0 ~6 ~5 l        uint256 feeAmount = getConversionFeeAmount(amount);3 F! N& ]7 L& o$ a# `
        return safeSub(amount, feeAmount);9 F1 j8 ?0 G6 R* m' Q
    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14