Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。
$ h/ r0 |; r% ?  q9 w  Q- ^1 {# j7 C9 E, J" V
若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。+ e0 \1 ]4 v% j$ S2 Z

  a- t2 f/ N0 }: l# N若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:
7 k7 C. T) o- _3 A( F& x/ A“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。
# C% H7 w1 [/ Q: W

, o7 h/ d  H6 q2 B3 L若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。& s  ]: i0 H2 h* E9 F' m- D( Q

, q: {) b8 G  P9 q4 S' H5 n【核心智能合约简单描述】
9 W. d4 s; a  d5 E% Q( U1,contract BancorConverter, Z! D' v$ f( x5 J
功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。7 R+ Q8 b# J" c3 n5 m
2,ITokenConverter
% W7 x  Y0 W- F/ Q6 U功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。
. o6 ^0 ~, Z1 s3 _5 w3,SmartTokenController
, @9 ~1 q2 \; z) D7 _, W9 o功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。
! G9 j8 z- `; V) ^/ A4,Managed
- ?: q0 k: Q& ?& j$ e% z* J# Q功能说明: BancorConverter的父类之一,提供协议管理的支持。( q) z- X2 R9 X3 h; f
5,IBancorConverterExtensions
5 p6 c$ y1 e5 b* [* K$ e; w- G功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。  F* s0 w# }) \0 m( k/ C
#4,核心函数分析
4 Y6 j1 U' k3 x# B& R##4.1 convert(…)函数& I# a: S+ z% K
convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:
; a" f. y7 t. `9 A, l* |& u$ H

# m+ ^3 _! M7 H; h, J+ f/**
- J3 N3 d8 E! l% u7 G) B        @dev 将一定数量的_fromToken 转换为 _toToken
% Q, h( ^0 ~- X, K: D# k' T        @param _fromToken  用来转换ERC20代币# w: X2 r' |$ K' [. r! T
        @param _toToken    被转换到的ERC20代币
( q! S7 l$ E: S        @param _amount     转换的数量,基于fromToken- c0 n4 d- d1 ], t
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消
  J( ~, a" y- i/ b% B5 l        @return conversion 返回数量- m- d  K9 K' Q. T2 {
    */, u$ G+ B2 K, }6 N: L2 U
    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {
# g; N4 u9 q; p. G: n            convertPath = [_fromToken, token, _toToken];
; e" v5 K+ y1 O$ g8 X* G            return quickConvert(convertPath, _amount, _minReturn);8 p% l/ D+ P9 u7 n
    }1 V7 U9 X+ }6 E2 u4 L5 {6 P
/**
# u; D/ j4 f6 o        @dev 通过之前定义的转换路径来转换代币: i* I' ^5 D. v9 O9 x* M
        注意:当从ERC20代币进行转换,需要提前设置补贴& Q2 E4 B8 a6 l
        @param _path        转换路径
5 k0 s% N' E! q5 E. i6 M- T        @param _amount      转换的数量  s& O. y+ x7 T, O% Z2 B
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消; m, e4 w; q6 p6 B
        @return 返回数量$ A+ k3 L& Y; z8 q7 N- w, d3 W
    */
4 W0 w9 c8 l* n! k8 d    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)
; H) `( N, @3 D  |" f2 b/ K        public
: C( D6 G3 n$ s$ U6 V, L1 B        payable) l8 x4 P; T* o' ?( I& \4 b6 g
        validConversionPath(_path)/ {/ K# E8 y. Z2 _! j# \
        returns (uint256); O) [2 x2 t! W% v
    {
: X* `& U$ `4 z/ Q) s3 _+ p# O        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);: Z9 L9 _1 r; U/ E' C7 F
    }
, ~' h- [4 X& S  i. V/**) }3 E, B# z- z& C" Z
        @dev 通过之前定义的转换路径来转换代币/ _" R6 {1 b! C( O! P; c
        注意:当从ERC20代币进行转换,需要提前设置补贴
! Q: U/ d; M  h8 O1 {        @param _path        转换路径
6 i7 n0 ^' F9 @0 H* L0 @        @param _amount      转换的数量, F8 m5 x, C& s+ G5 B% H1 L6 K
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
* H2 z4 s+ v' p) s        @param _block       如果当前的区块超过了参数,则取消% A9 ~+ O  ~# x/ R: g( P
        @param _nonce       发送者地址的nonce
/ i; B. D% B9 S" M8 [. V  \        @param _v           通过交易签名提取5 d6 j0 f% `$ I5 u
        @param _r           通过交易签名提取
' w+ k/ M! H& @7 B4 q) y        @param _s           通过交易签名提取3 _8 I. ]# h! s: n8 g3 O# P
        @return 返回数量' |" s+ D$ t8 E4 _; T8 w2 u
    */; I. @4 |2 I) O: q$ G3 [, i; t+ ~+ {
    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)
8 v7 g! _& N5 y  N/ }" W        public
( s. O6 R  f' n5 P% ~7 m# `# B        payable
! i2 t# R( w& t        validConversionPath(_path)
1 O! i$ h! B$ k2 g  w        returns (uint256)
8 P# g, F5 i6 J  Q; |5 U    {
: ]$ z+ z% i! e3 u        IERC20Token fromToken = _path[0];
& ~  M) M3 ]7 j8 d' v9 ]        IBancorQuickConverter quickConverter = extensions.quickConverter();
! f4 }5 g' U! c7 J9 F        // 我们需要从调用者向快速转换着把源代币转化) R6 t! _7 G7 m+ b# i+ |
        // 因此他能基于调用者进行转换
* s( }2 ~: m$ B1 E1 [' L        if (msg.value == 0) {
/ m8 r+ d8 l, i3 T# S5 z            // 如果不是ETH,把源代币发给快速调用者: o6 y1 B/ N" n- u
            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者- u' B( `; T+ x" t* M
            if (fromToken == token) {
$ }: b* ?2 }* \- F1 [" Q/ v7 w                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币- t. v4 d8 A( q, ~
                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者
7 l1 Z/ G$ a" K& d            } else {; f5 b5 K4 ]1 ^/ I3 |7 V& Z
                // 否则,我们假设有了补贴,发给快速转换者
2 H4 {7 a1 c2 x# _# y% v: a                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));/ u6 Y  d' u+ y& A
            }6 N" R; K0 R9 }' \
        }
0 }) \4 p) t' y* E' d9 ^        // 执行转换,把ETH转回. Z, B* A/ |6 U9 s5 R
        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
. `- C3 }3 s: I    }9 o# L* }. L! J

3 o0 r  p2 [- L8 s( r##4.2 change(…)函数
+ {9 Q9 _' Y8 [1 ~" N. R+ R9 h** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
' b9 M" N, _8 D
: v- o$ V* Z; r8 S7 N
既然是过期代码,源代码就不放了。9 p7 }% q' m' W1 s
##4.3 getReturn(…)函数; s7 a' q1 I( p
4 R! Y1 d5 h( S$ a. K1 w6 Z
function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)) y$ k6 n6 @! z7 P
% b  ^) P$ o2 n6 }* s) S: C8 h% \
功能
* q4 O8 k8 q7 ?$ X# T$ W返回从一个代币转换为另一个代币的预期数
源码:
- }( n( P" w' F8 Q8 @
6 c4 W" C; M( N& G+ c; J: c: x
/**& j1 f  u# Y) l5 q- h# r  p
        @dev 返回从一个代币转换为另一个代币的预期数量
- q5 U8 a* r) g# w; f. V& z        @param _fromToken  ERC20 被转换的代币
5 d$ f8 D7 H0 j        @param _toToken    ERC20 转换成的代币, O# [; k3 ^( o* k( u' P6 E
        @param _amount     转换的数量/ g: P0 ^& i! c' B
        @return 与其转换的数量
) v0 _$ K: s3 W& L8 T; k9 v' W    */- P# Z/ v9 ^4 n! S/ ~8 `
    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {- u$ b* \% R6 o& q! j, R
        require(_fromToken != _toToken); // 验证输入( A" u% C2 _/ z" c- ^* ~, H3 \
        // 基于当前代币转换
  K) B! I9 q0 k4 c0 D/ h. R8 `        if (_toToken == token)
( b) ^) |, O# x: k, F            return getPurchaseReturn(_fromToken, _amount);4 [5 f4 Y2 i( [: u) C7 U- X0 f
        else if (_fromToken == token)# _; k# J" s8 C0 v' Y0 ~" }
            return getSaleReturn(_toToken, _amount);
* X' ^+ _. X+ I* C! @8 C  `' w        // 在两个连接器之间转换: M. a& k) o$ v( L
        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);! I$ q  ?; {' J5 P
        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));8 U+ R0 J# G0 ]- \  @; o
    }
! O( D/ t4 d, R0 `% q+ _/ ?; q/**' H. I+ y- z: H6 w3 Q- p) m- I
        @dev 返回通过一个连接器代币购买代币的预期结果. W( Z$ X) v) f% ^; E  h6 h
        @param _connectorToken  连接器代币协约地址
( e! q  y& `0 R1 i- K        @param _depositAmount   买入的数量. s5 n! M$ o) r7 A) j% ]) H# H% x
        @return 预期的数量! K; I7 ^- h! `- Q& ?+ {( ^: e
    */0 @4 n6 c' A& F7 B. Y& d& ?* R5 B; `/ z5 S
    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)
* l1 l+ z' a! ]5 C. |9 ~+ E/ L' F        public
  F5 S% t% G* m        view
  a9 Y% u' y4 N! T. P        active4 t6 U2 S- H  a0 l2 P7 Z; E; i
        validConnector(_connectorToken)
5 [) t$ A0 n+ f6 |# G& ]4 {        returns (uint256)* ]5 w# f9 h3 N! C& i' `
    {7 i3 R, d- s* [4 O/ x* A
        Connector storage connector = connectors[_connectorToken];+ `4 e# T9 B9 ]
        require(connector.isPurchaseEnabled); // validate input9 Y: a9 u8 n: ?7 h+ \7 H
        uint256 tokenSupply = token.totalSupply();
0 `# @  S- G$ z  ?        uint256 connectorBalance = getConnectorBalance(_connectorToken);' A: O! T' R! z4 D) P
        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);0 d3 q+ v  a; R
        // 扣除费用* H+ s& n$ W7 U& ~
        uint256 feeAmount = getConversionFeeAmount(amount);
. ?$ G, ]% P' m6 y, K# x        return safeSub(amount, feeAmount);4 E- @) }- B% I8 r% B- u* ?
    }3 ~0 L% x0 o3 G4 _3 A
/*** f3 f# x5 n! z
        @dev 返回通过一个连接器代币卖出代币的预期结果& r6 q" z; P$ {' ?& U
        @param _connectorToken  连接器代币协约地址* }* \. [. R4 ~! I% m2 Y
        @param _sellAmount      卖出的数量. h* z# R1 t1 x
        @return 预期得到的数量; W% _8 p. B. l) i- o1 f$ y3 Y0 H
    */
# e) c' m7 C4 k% {% t; x. l% O  l    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {
9 b% M8 c1 O# }$ l2 x        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());
. o' Q! l! K: I, {    }1 ?2 L9 k- r1 [7 _/ L4 g5 {' C
/**
/ h: p$ j/ J  O: I3 n        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回
! c: @$ A" N7 Z" f- ?+ q% J        @param _connectorToken  连接器代币协议地址
: ?6 f, b6 y/ n6 v* i0 p        @param _sellAmount      销售的数量" s8 ]( n) O  @! d# O" V  S/ `& w# f. j
        @param _totalSupply     设置总供应量$ u' H  _- P0 {+ `7 O* f: i; M
        @return 返回的数量: W' G* ^+ k; D& p
    */
" [+ p" D" k/ a: A3 B    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply): E1 i9 s2 _& ^. j8 N
        private
0 x7 a; S8 A" Z+ d* N/ g        view
/ N+ D' j8 ^8 e9 j! W' ]! |        active0 Q. Y) ]9 L* C5 y: V( N* Q# y2 x
        validConnector(_connectorToken)
  w. m/ m5 v3 g        greaterThanZero(_totalSupply)
6 L3 r) `8 H4 f2 Y! E# A: |        returns (uint256)
, A6 h& y  o/ ~2 }  n6 V7 _# A    {* ?8 e- P: w- D6 x& o' G
        Connector storage connector = connectors[_connectorToken];
: E8 ]" r2 }7 M0 l6 ?4 d/ m" n        uint256 connectorBalance = getConnectorBalance(_connectorToken);) @/ ~9 K1 |) m2 j) Q$ I
        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);, Q$ q: V5 L3 Y* g) t3 B
        // 从返回的数量中剪掉费用$ ?! C& I  a$ Q0 h! S$ w
        uint256 feeAmount = getConversionFeeAmount(amount);
# ?; z2 k- F) r* K& K7 ]        return safeSub(amount, feeAmount);! }* e% c# \, ]" N6 [& K. v
    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14