Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。2 E" C4 o- ^6 F
) `6 u2 W( Q! ~$ K$ P6 H% }# N, ^
若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。6 [0 ]- Y2 z8 ~! U! `' M

$ v) X" ]  G9 C, L4 r3 q若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:
9 L: [  I( @' w4 r: W“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。
' d* u) `6 o9 z) Z2 _
' R$ S3 R" ^9 |/ p4 v$ k+ K
若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。
$ S; T# _, F  _# D* C
- I/ d  a2 |! c9 B【核心智能合约简单描述】2 n4 \2 ?! s+ E3 T# F: I: f7 z
1,contract BancorConverter
8 B1 h0 X. `! ?& |功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。7 u- l5 v+ \3 \- K+ Y1 v' A+ U/ \, g
2,ITokenConverter7 F" ^$ L9 q- ^( R% [
功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。& V7 v, z0 \6 m: T$ c* j3 K  s/ d0 j
3,SmartTokenController4 `5 b8 J& q0 \' |0 Q# ^! M; R$ h
功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。
/ ]) ]5 Y$ G- ~8 X, \4,Managed
& e" q/ h$ k& L  |0 |- [) b" M功能说明: BancorConverter的父类之一,提供协议管理的支持。) T3 X# R  g8 `  D
5,IBancorConverterExtensions
# V/ ~2 t1 T/ Y功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。
& f( G5 R/ y& s$ R* o7 ^- n#4,核心函数分析$ {) C+ n6 G* l" b
##4.1 convert(…)函数
8 i7 _6 y+ C  A7 S7 m4 \* ^1 vconvert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:
/ }0 {. s0 s& n

6 z9 z. C8 h+ i# N/*** z8 h6 Y9 g: m- H. B6 h
        @dev 将一定数量的_fromToken 转换为 _toToken: _& S8 ?1 }( Y3 O$ T; F( f6 I# R# }
        @param _fromToken  用来转换ERC20代币) F! F* k" K) v6 B* E' O
        @param _toToken    被转换到的ERC20代币
1 U# M+ ^* u8 Q2 ]        @param _amount     转换的数量,基于fromToken  K# T) z1 ~( y# ^1 q
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消. N2 |+ E- r3 b4 J. ^( ?
        @return conversion 返回数量* O* m* [' S4 |% \% z
    */. ^0 q2 n3 @  M/ j) f- N/ D
    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {' [' ?( i% {( C9 l0 y# x/ i4 c
            convertPath = [_fromToken, token, _toToken];& L6 v0 Z7 `3 T- N
            return quickConvert(convertPath, _amount, _minReturn);$ P( o+ q. P5 L, g
    }
( n/ H' ?3 e6 Y$ O( I: r/**8 U7 h. a# W- i* w2 o
        @dev 通过之前定义的转换路径来转换代币' G( H2 }2 }) O
        注意:当从ERC20代币进行转换,需要提前设置补贴' ^8 |% l" C0 l, W& l8 l
        @param _path        转换路径
" `% f* O6 |1 x) p% }) p        @param _amount      转换的数量
! U- n7 }- X. E- D        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
  W4 J& w2 P' o$ D7 V        @return 返回数量1 M2 J9 w2 ]+ @! C: h# v* |( M
    */
( o- V+ {9 G, M    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)
. n: M- ?& ?0 r% S+ f! d  r( W        public/ C& s8 M# \8 R7 B. e
        payable
4 M5 v4 [# t+ m( @        validConversionPath(_path)- s% H( z2 v) X1 g( B6 {9 s) w2 G* y
        returns (uint256)7 K3 w0 S1 z7 I: k
    {  o  x( v. J( a, v
        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);
$ D2 m: w: o1 s% c& e8 `! i    }
( d- E' z: n% e5 m2 Z! G+ x: \/**
; c  k  v# F! @- E; X  L        @dev 通过之前定义的转换路径来转换代币
, S6 E; B! o; P" Q        注意:当从ERC20代币进行转换,需要提前设置补贴8 c1 y& J! i5 y
        @param _path        转换路径
' f( r/ C3 H) l* g        @param _amount      转换的数量9 W: a- W) K' K2 R  P4 h1 H; ]
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消' [! Q: |+ Y' x
        @param _block       如果当前的区块超过了参数,则取消
. Q' A* V; @0 w" g6 J        @param _nonce       发送者地址的nonce
: R( ]9 A4 ]# Q3 _2 g        @param _v           通过交易签名提取' P  Y( B. _/ l7 g4 k4 l) `3 l. R$ P
        @param _r           通过交易签名提取$ ]6 o5 B- [: i; I9 b9 z
        @param _s           通过交易签名提取' B) {7 s6 Y6 O1 G1 O+ G
        @return 返回数量# s! c6 ^! j9 R% o# i0 h
    */8 E: ^) h/ t7 i0 `( w, Y
    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)& G. ]$ r# K; B: z
        public- z  ^8 r( Y% n; f* u5 b; i
        payable
: O/ y8 _# w9 {/ u/ ~        validConversionPath(_path)
3 {! p% y, H, A4 [+ P        returns (uint256)
; ^4 o  @# @, A7 P    {, T3 h& d6 K. `4 p
        IERC20Token fromToken = _path[0];
9 r) U( {$ C( S4 e! L3 L- y" g; s$ f        IBancorQuickConverter quickConverter = extensions.quickConverter();7 S. }/ V# r; |+ n, v0 K
        // 我们需要从调用者向快速转换着把源代币转化9 H5 U' y+ L0 F7 b/ B: {' I' y6 j
        // 因此他能基于调用者进行转换
4 k7 F+ |* s+ h5 v: B9 [        if (msg.value == 0) {
( O: @  a' J2 J( [            // 如果不是ETH,把源代币发给快速调用者
* L. g8 A  Z3 x6 _, K            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者4 M% E  a* t# O
            if (fromToken == token) {" O$ h# T/ b% E8 w6 N1 c
                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币
, M; P! p5 T( g2 x                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者
; F8 R) c) `. P6 L, q            } else {
; O4 N/ B6 R) I# O* B3 H. ]+ [                // 否则,我们假设有了补贴,发给快速转换者5 S* i, e3 o1 z# U
                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));
5 {: G/ I4 g( b% c4 p  f            }( x) B  n4 E8 H% W6 q9 s3 q
        }1 x1 C5 x1 D6 O! O6 c' C' M
        // 执行转换,把ETH转回! ^8 E8 o: V. w/ ~( S) W* s
        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);) M! n2 O- q7 W  [" W
    }6 L: F; N, [; k( g7 G5 G

* {; Z$ |: f, y* n/ h; I* i##4.2 change(…)函数! _( o( P/ w' ~7 ~' I
** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:5 R- L3 H; A# e* P
: Y7 g& x: |# {1 `9 V# }
既然是过期代码,源代码就不放了。' j, N' Q0 Y: [6 F
##4.3 getReturn(…)函数  U' ~$ y7 I- l) Y: i( b0 ^

% x8 C: D6 w: ]/ p8 ^) Ofunction getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)
% q( ]+ I% {. P+ [& V) I

0 L8 A3 E& ?# U1 g0 N* G8 x2 ?+ r" p功能3 N6 q  `# l6 V
返回从一个代币转换为另一个代币的预期数
源码:( s3 _$ K4 Y& K* ^' c

' S* F! @: z  t9 U/ e/**; \4 ^; a! J4 N1 G4 q0 ]
        @dev 返回从一个代币转换为另一个代币的预期数量
1 B' ~. X) S$ |" [% \& W  B( E/ {        @param _fromToken  ERC20 被转换的代币0 p8 B+ N2 ?" x. m- Q
        @param _toToken    ERC20 转换成的代币& E' a: t* t. Y) U' b, I+ N6 B
        @param _amount     转换的数量; y9 N% s/ _5 a$ j! y, u9 {
        @return 与其转换的数量
3 N7 a' @9 p" J1 w    */
8 F& h- U" T5 p# a) d    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {# A" H5 R1 e& V9 b7 _1 n8 {
        require(_fromToken != _toToken); // 验证输入$ \! S1 n" c' @2 `4 X* }
        // 基于当前代币转换
, J$ Y2 C2 D3 X# P        if (_toToken == token)1 Z" D8 t3 b4 I- H0 y
            return getPurchaseReturn(_fromToken, _amount);& Q  R' K0 x' l% b/ v( L
        else if (_fromToken == token)
6 B, q, V  R3 e* S& i            return getSaleReturn(_toToken, _amount);7 a) v: a+ k2 a$ ]# T9 I3 I) K* F
        // 在两个连接器之间转换
% L' Z/ i) y- H' S  F        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);
" P7 {% N1 M5 R: Y6 O        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));9 K# d! }. s9 i4 |0 I1 L
    }
* @4 ?  J5 K  l/**7 W& r2 C4 T: q3 b
        @dev 返回通过一个连接器代币购买代币的预期结果. |. C  E2 s) F7 v1 N9 `
        @param _connectorToken  连接器代币协约地址6 L& x+ j% L4 b. ~0 Z  O1 q
        @param _depositAmount   买入的数量. R0 `5 f( Z) u' z0 h9 z1 D
        @return 预期的数量
- L  G( v0 h2 s) Q* e    */
! j% c7 T  g1 |4 G2 c- \' ?1 K. B" B    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)
0 u$ u$ l& V4 T0 }        public
8 }; ^( g. g" z, ]% ?- }; x        view
5 F1 A- O8 W) Z. |3 t        active2 }: C0 M- a; p6 b7 d5 F
        validConnector(_connectorToken)0 O3 e8 O5 g4 z8 u
        returns (uint256)/ G6 Z( [3 u- g& i
    {' L- }) |. ^  J8 L
        Connector storage connector = connectors[_connectorToken];
) f0 A% M/ L$ U  u        require(connector.isPurchaseEnabled); // validate input3 Z. ?7 P2 }9 ?# q9 Q; c# V
        uint256 tokenSupply = token.totalSupply();
/ O' d5 c. O9 B* I        uint256 connectorBalance = getConnectorBalance(_connectorToken);
, L; \. x2 |$ F/ H% B6 N% k6 ~        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);* P6 i+ h6 N- W9 A! ^, x5 ~
        // 扣除费用# V; p# T7 Z- t: x8 w% Q/ g' p
        uint256 feeAmount = getConversionFeeAmount(amount);
6 S& l  l# W# i8 `4 o3 L' u3 k        return safeSub(amount, feeAmount);
1 J+ D! o( E8 S' _    }( ^2 a; |2 I# w: c$ d5 ?4 m- Z
/**2 D; X& u# i! N! u) Z7 R
        @dev 返回通过一个连接器代币卖出代币的预期结果
4 y+ n: F' a. R9 @; g3 F! ~        @param _connectorToken  连接器代币协约地址# @( ]' l+ b, P' v- T2 }  N
        @param _sellAmount      卖出的数量
" x: n- @) _8 \' u, k0 o- E        @return 预期得到的数量8 u5 |( |- v3 u/ E8 o+ x
    */' t/ k1 Y" ^. E# G
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {9 X5 @) Y, u9 E% P: D9 @& e# v0 Y
        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());
6 k! I) z0 Y9 R9 n, g+ k    }
" f  r/ [' `; g$ K; \/**4 h5 M; p% I3 I6 N1 r) n
        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回# X7 Q( \# |) H/ w) j
        @param _connectorToken  连接器代币协议地址
& M. P& Z8 p) @' R        @param _sellAmount      销售的数量
: v# j2 U' X: T  h        @param _totalSupply     设置总供应量+ G4 z5 k0 |$ s) J/ U
        @return 返回的数量
( \; V5 y; Z# h; D. L    */
- C( {: G- U. W, D" S* `, k% t    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)
9 Q+ g/ d( f: \3 \' Z        private
1 [* I+ }' h9 @1 l- @( W        view
! c- ?5 `2 o. k( H2 ?4 c6 A        active
9 q2 a9 @* F+ N+ a$ ~( }        validConnector(_connectorToken)" i) _2 O, c4 z, q  S, ^
        greaterThanZero(_totalSupply)
6 B# f% N; D- Y6 Y. h1 ^; ]        returns (uint256)
# j. ~  `1 L: }7 O. y    {  C5 B5 |" U: S
        Connector storage connector = connectors[_connectorToken];- i- Z1 |# G, D8 E1 I1 |3 v' G
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
! X  O% I. }$ \        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);
* J: [9 }1 Z" u; q+ |; {2 ?1 R        // 从返回的数量中剪掉费用
% x6 ~% f. v* F) n0 g7 ^        uint256 feeAmount = getConversionFeeAmount(amount);
4 c5 d' E0 W* C        return safeSub(amount, feeAmount);
7 E' T! n8 @2 R5 }    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14