Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。
) R1 m6 ]1 E- }
& U" {4 C5 b) l0 H$ R若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。
' l. _2 }( o- S) ~% ^  E% \5 V- [
若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:
1 U; E; ^/ L0 L4 ?“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。+ Q' b4 i$ A* @% A

* V- T* e  [0 c* }) V9 j! X2 b若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。2 k9 ?& B1 Q9 s4 R
4 J8 N4 C/ ^( K* p) M. Q" g
【核心智能合约简单描述】& X1 p1 X- v4 T; K( X* V
1,contract BancorConverter% M8 J# t8 c7 x4 i/ a8 n4 E% y, P4 _
功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。
0 H, q/ _7 E8 ~3 w* p0 n9 s: l2,ITokenConverter
" w+ t8 [. A1 L5 v功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。
/ E1 t7 K* o2 B* P3,SmartTokenController
4 d% e* o& z+ D* Y! O4 r2 s/ U; s* {' n功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。- g5 q" F: w& o1 ^( D
4,Managed4 e! t+ C, v* V' V& n; w- V
功能说明: BancorConverter的父类之一,提供协议管理的支持。
, m9 Q, c1 W6 s% X9 |/ L4 Y5,IBancorConverterExtensions# S, b5 \* C; v) F
功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。! b4 g2 `$ l: k4 {& q  a) W
#4,核心函数分析8 c& _* r: I1 v5 b0 v
##4.1 convert(…)函数' G# N% ?( s+ C1 S7 w6 E
convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:6 T! C2 W* C4 V3 ^9 F# D' E2 B
% m/ g7 E' c* O" h( @
/**
% [  y  W. q' \9 h3 f0 L        @dev 将一定数量的_fromToken 转换为 _toToken8 H7 g  H6 Q5 d: w1 ]
        @param _fromToken  用来转换ERC20代币6 \, Q  Y# q' R
        @param _toToken    被转换到的ERC20代币. |9 ^1 ?0 R/ r) A
        @param _amount     转换的数量,基于fromToken5 {: m4 S2 O3 C& ]( D
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消
% q* [# X0 T. i4 k9 ?9 L  U        @return conversion 返回数量- l4 `" q( L4 B9 h1 A: D1 a
    */
: z6 L/ A& ~1 F5 q2 H* h" d    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {
/ Y, j0 `3 z+ v8 Q5 Y1 ~            convertPath = [_fromToken, token, _toToken];. w/ r0 O* A! o7 [0 f. M1 Q% k4 e3 f
            return quickConvert(convertPath, _amount, _minReturn);. ]' s' l9 `; Q9 x
    }
  K8 |( ~! Y: z  S$ g: g# p/**
. d/ A0 [% `" b2 |% |$ L! R        @dev 通过之前定义的转换路径来转换代币, q, N- y, \# U: M
        注意:当从ERC20代币进行转换,需要提前设置补贴! k/ k  S8 }* a/ W% L
        @param _path        转换路径3 ^7 `7 X! g# a
        @param _amount      转换的数量
# S5 T  B2 I$ x- m. ]        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
4 I* q9 ?, M# Z' B8 v- `/ ~7 x        @return 返回数量
/ w) p) I# \5 e( D$ H) F, a    */
* c# K2 m  x1 }6 T) {3 w    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)% z" ?- P- \# i3 n/ D
        public
& i' P; ~3 b: a9 D        payable
1 U& J" L4 j4 o2 }        validConversionPath(_path)" l0 j/ R9 P8 F, U9 l$ q; S) p$ c8 U
        returns (uint256)) z5 c/ {8 a8 r! R9 C
    {
" ?! [: T; O( Y3 F% x; M0 l% C        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);
0 B. k3 L& s4 M9 {( N    }1 x  r- c8 M/ x  ]
/**
4 Z( H& u3 V8 \' [        @dev 通过之前定义的转换路径来转换代币
2 P7 E. `  ^( h        注意:当从ERC20代币进行转换,需要提前设置补贴
0 F$ ^& v& I5 p& g2 x+ F1 b        @param _path        转换路径" x# Q1 ?1 ^8 N/ \8 m9 Q
        @param _amount      转换的数量
* J( L* k2 e- ~- ^8 V$ l        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
( V6 s& W" R+ i, Q        @param _block       如果当前的区块超过了参数,则取消
$ d+ {% {9 o0 J0 \        @param _nonce       发送者地址的nonce- n' V/ j8 S+ [# [
        @param _v           通过交易签名提取, \# u" T0 Q/ z8 I# ?, i
        @param _r           通过交易签名提取! E- j, U7 N) G$ U) m  C( D1 A
        @param _s           通过交易签名提取7 T( i- y3 l  I; T  Y: _
        @return 返回数量7 m3 H1 r  g; N; Z7 I8 }# n; h
    */
7 r  i& ?- ~* o' b6 |    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)3 z; f% {* L- a4 v3 S
        public
! I0 `$ {  ]. W" |- I        payable; a, i( [: P! R! ~
        validConversionPath(_path)
1 Y) Y5 \9 `7 I8 q        returns (uint256)6 I' h( C6 r( a3 @7 D
    {+ l* l( {. Y) b9 W' n
        IERC20Token fromToken = _path[0];
2 d: X3 l! `# i' A: ]% i        IBancorQuickConverter quickConverter = extensions.quickConverter();
' u% T7 V9 h2 O8 B" g8 v/ U        // 我们需要从调用者向快速转换着把源代币转化
6 W  g  e, M8 j4 D' q        // 因此他能基于调用者进行转换" f8 z5 s" l& ~6 C
        if (msg.value == 0) {
7 H; p8 A- x- q, W" A9 m) r( d            // 如果不是ETH,把源代币发给快速调用者9 _8 {  f* W  [
            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者" \: v1 i1 K: `% u/ D4 `# ?8 [
            if (fromToken == token) {
' Y: s, |7 [; i- h( B                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币
8 `; d; _3 d5 {                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者
3 j( X- H7 x# E* w            } else {
# \6 z& R  C9 y1 j  f                // 否则,我们假设有了补贴,发给快速转换者! d: K' g9 M5 U' c8 X# s% T
                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));  p2 [8 I0 O& U& l$ [6 C
            }
; r4 ]- }2 V" V) t* r6 S        }
4 b) j  V! C7 l  |, ~* W" R        // 执行转换,把ETH转回( t3 Y+ W  \5 W. y, a! z
        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
% I5 d  P/ |6 v7 I! T0 b+ p% s6 s! e2 e    }' E. E1 H0 c- q+ E" a

9 \7 I; ~/ U/ U- @! t6 `; m0 |##4.2 change(…)函数
4 r6 {: E& J) J' [( t' P. J** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
1 i% L5 Q: H$ s+ r4 @

% j$ L  T& D% N$ i3 y: g- R既然是过期代码,源代码就不放了。
8 l( u. C6 O1 w/ Q) o) Q##4.3 getReturn(…)函数- T* [& a7 g- T/ R- ~* Q+ t. Y
6 [, u, J6 ?, a0 T
function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)( S. v1 [( b2 ]- @( \* }# R% H

! ]. ~: f+ G9 Y+ ?7 ?3 I功能
1 O0 V2 c" N# }返回从一个代币转换为另一个代币的预期数
源码:/ Q5 X4 z1 Q0 W2 F7 `& ]8 S" S  ]
9 x& |2 t+ a6 l1 d' H, v' ^
/**1 b- Z2 g8 t' S1 c- O/ j
        @dev 返回从一个代币转换为另一个代币的预期数量* p0 a' x) w3 z. x  n
        @param _fromToken  ERC20 被转换的代币3 d8 Q7 E# W( T* D  F& Y5 \
        @param _toToken    ERC20 转换成的代币
8 Q: B' \! n3 C3 K        @param _amount     转换的数量2 @; `- K: t& f. ^/ O0 B0 g( S' g8 p
        @return 与其转换的数量
, Z! ~: |& t! z2 W! k2 s, A    */
& l4 g3 ~+ |1 ?( `5 @    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {1 q+ N0 K8 ~( {( c
        require(_fromToken != _toToken); // 验证输入
/ V+ z; E; P  y0 O/ T        // 基于当前代币转换
4 }6 r9 H3 Z) ?7 w        if (_toToken == token)
8 j  \4 {$ L$ N            return getPurchaseReturn(_fromToken, _amount);
: l8 ^9 H: R5 g. J7 C$ y% }0 R& G        else if (_fromToken == token)) X% u7 ~/ v0 p6 d# {. _# W
            return getSaleReturn(_toToken, _amount);# [. y" R+ U$ n0 p' [3 V  ]5 l1 R
        // 在两个连接器之间转换
* W& r' [: }$ I( ?" l5 X4 j. L4 f- _# u        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);
5 z1 |" R( h% z4 u* b! m2 @        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));
" C# Y4 w" B+ P# G1 p% z" _8 J6 b7 t& N    }
/ C' A$ H/ F- b/**% w5 a8 c' r$ u2 O5 r/ H* H
        @dev 返回通过一个连接器代币购买代币的预期结果0 \, v1 u( f/ W7 D4 x3 K- ~% I3 f
        @param _connectorToken  连接器代币协约地址2 O. q% C5 k& i9 L( W' S$ \
        @param _depositAmount   买入的数量! j+ k3 z$ |) e. q
        @return 预期的数量
; s. w, A) _# r% E3 J8 F' x    */6 ?6 U4 w+ f5 h( ^- u4 _
    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)! _, j8 Z2 d; O4 F9 g5 {  j1 ^
        public' O6 W* F% l+ ?0 A1 }
        view
; M1 ~9 S0 D. B% U1 h        active: j9 h8 i& u. H' N7 `+ ~  ~
        validConnector(_connectorToken)
0 |3 k  F, @1 D+ J/ {        returns (uint256); u# n4 h6 v8 s
    {& h! G; Q: x; p
        Connector storage connector = connectors[_connectorToken];
$ E7 I3 \' w. \        require(connector.isPurchaseEnabled); // validate input/ M0 q" Q: h* v' @$ f( {* I; C+ O  T3 R, C
        uint256 tokenSupply = token.totalSupply();; u2 S# F# ^- g3 E& O1 x
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
* l, h$ ]( @" P; n8 m; i        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);
9 U6 D: u7 U, K! E' p        // 扣除费用9 @  R/ J) s; q1 a+ V1 k
        uint256 feeAmount = getConversionFeeAmount(amount);
5 {5 x7 j1 A# s$ ?        return safeSub(amount, feeAmount);0 {2 m' ^- Z) i4 e- j: u* O0 J
    }
+ c/ [5 X3 M5 F0 _. \- p; d- |- R/**
; _) c) @5 p  g7 E" B        @dev 返回通过一个连接器代币卖出代币的预期结果
# f5 h$ M5 i! V: U& s        @param _connectorToken  连接器代币协约地址3 I# z4 ~2 I& y; l6 Z6 u0 b
        @param _sellAmount      卖出的数量
6 q% ?. C4 L3 e6 C, |        @return 预期得到的数量& K! S3 N' G" p7 Q9 i
    */! B* \- q2 X+ \# q
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {: S! R# L8 I0 J: {' M
        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());( n* B' {3 p7 M5 L9 y- s) {  `
    }: w) Y" b) z5 M& T
/**2 L# A2 L1 W7 B, `/ Q( _9 T, E
        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回, Z7 X8 c' l- f5 W& u. M
        @param _connectorToken  连接器代币协议地址: d  [; P1 ^  D, U* s
        @param _sellAmount      销售的数量, T( F8 O' a9 G' ~! u
        @param _totalSupply     设置总供应量6 F0 h3 M4 c  L+ ~6 O7 F; g; S. u
        @return 返回的数量
4 C! N  l+ N  p4 W    *// L! P! }; C  x+ M: q: C" }
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)$ G% }5 P$ ]3 ~  T
        private
3 E0 }- o- a9 z- j# S* |        view, G# }+ P! x# c+ x5 `6 E- r
        active
0 F3 o# S/ c4 H6 n& R7 U        validConnector(_connectorToken)
) X. `" U( b# f. o; \3 P        greaterThanZero(_totalSupply)# y1 Z) s2 V% D8 R
        returns (uint256)+ K" T0 G% m' m' X+ }
    {
6 ^5 Y8 c' q  s+ ]) F4 [        Connector storage connector = connectors[_connectorToken];
# w" ?2 Z, V* M4 ?8 H$ \/ B        uint256 connectorBalance = getConnectorBalance(_connectorToken);! z' M7 ^5 W4 B
        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);
6 Q( N& d8 F2 J4 K4 R  I        // 从返回的数量中剪掉费用
# S( ?0 o+ u! N5 q, V) G        uint256 feeAmount = getConversionFeeAmount(amount);5 |: K- a5 c: t
        return safeSub(amount, feeAmount);, J  P2 K9 o) b7 {; N+ G  A
    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14