Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。1 v/ P' ^" R& l! {' a2 e
3 D* y$ u' P" r2 k8 R$ e7 V4 I) x
若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。
% [) W' F) p2 \% F; R4 G7 |+ o; c: {+ C- ?' ?1 a- {  a
若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:- q: o) h$ i, `
“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。
+ ]  A# n* |! @/ C! S, c6 Y

! h$ S( @, m% J9 [+ x- ~$ ~若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。
9 t7 h% C) W1 J
! A2 s. v2 L) P! n4 o0 k【核心智能合约简单描述】( n8 Y5 P5 L! ~2 [
1,contract BancorConverter
% A8 Z: d9 H9 a3 h2 X; Y功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。! n5 u' i" S: `. E8 g2 ^) d4 _6 S
2,ITokenConverter
' Q5 ?4 ~1 _2 Y. j1 v! A; A功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。9 e: n' G! [* Y: C2 p% \
3,SmartTokenController+ q. ^; V& s2 n0 }. j" M! ~
功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。8 Z5 a; h* I" z
4,Managed* B& G, O* u3 H
功能说明: BancorConverter的父类之一,提供协议管理的支持。
' N! ]  B8 L' O6 s4 ?; ~5,IBancorConverterExtensions
" {$ M, X7 W6 k" {3 b9 C. Z功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。
# j- R. M9 j  x5 ]; o, q#4,核心函数分析
- t. ]) d; K- x. k  q* w##4.1 convert(…)函数
7 H4 ~( e1 _: F/ u, A' {convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:0 X; _% }8 |$ H% G
$ K* T+ b* ~0 c
/**/ t9 t- ^; R( }; n* o7 q# s% ^
        @dev 将一定数量的_fromToken 转换为 _toToken
! X+ b+ j" p0 q% u8 V; }' O        @param _fromToken  用来转换ERC20代币+ F. W. N6 X2 r3 P4 i& ~9 R
        @param _toToken    被转换到的ERC20代币5 K, b* s' J# d2 U# S
        @param _amount     转换的数量,基于fromToken( V3 K, f. |, p- u5 J
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消8 d* V* O0 C3 g+ ?0 P
        @return conversion 返回数量3 A9 L; g# T* a3 }; Y
    */
* K( R" r# b( d' g+ S# r    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {) A( o% l0 |( [' S
            convertPath = [_fromToken, token, _toToken];# @: _/ C8 s# C; u! j
            return quickConvert(convertPath, _amount, _minReturn);9 k5 m' `& o& M: ]% v' @3 X
    }
7 I$ T. ^1 k" N4 N3 h/**7 u/ e8 O7 T2 a4 W7 ~# G) h
        @dev 通过之前定义的转换路径来转换代币3 P! R( n( |7 D4 ^$ G' J
        注意:当从ERC20代币进行转换,需要提前设置补贴: ], w/ C& Z, y2 }
        @param _path        转换路径) {  L: B1 N4 ~% U) r% O& o; e* t
        @param _amount      转换的数量9 |7 ?2 ^# h+ _0 x- u+ n$ h
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消, m- `  g4 z) H; h4 r, \! j7 R3 G( u
        @return 返回数量
5 J# B% @$ v& H3 O    */6 f) a( j$ X1 R9 ?8 {
    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)
5 `! I9 m" M2 n/ [        public
" r. t# ]- `! a/ q        payable0 o- L' [- {* _, n# C+ K* N, e
        validConversionPath(_path); l' B# R( |$ Z
        returns (uint256)# w8 K' v7 \% z8 J, A+ B0 ?
    {( r2 b0 X) b! |# o1 g7 t
        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);8 d. j& J+ N5 e. P; P
    }
7 W7 X2 w3 }) |6 s8 Y5 g; p/**
- f: b4 T8 Q4 f3 i; e) T        @dev 通过之前定义的转换路径来转换代币
$ o% T3 H' }. b2 x, B! U) Z        注意:当从ERC20代币进行转换,需要提前设置补贴
) ]( K' O5 b  u. j        @param _path        转换路径
0 [: v8 N! _0 Z! G  }: j        @param _amount      转换的数量
" l- \5 H, T2 r7 w8 k        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
4 T4 K5 Z1 k/ P$ ?0 R6 K5 X$ K        @param _block       如果当前的区块超过了参数,则取消
1 X5 U7 F0 s7 t2 |/ m        @param _nonce       发送者地址的nonce& Q+ k" m9 ]; a
        @param _v           通过交易签名提取# v! H6 q/ t' {6 \, j
        @param _r           通过交易签名提取  K. G2 J+ Y& V: U
        @param _s           通过交易签名提取  P/ k$ G6 }% O: T5 \  s& C( v6 c& z- a
        @return 返回数量; O9 w8 ^$ }# x/ T
    */3 a0 J/ w8 L5 W( v
    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)0 [' O, v  Q% c  a( d1 g# |
        public
: l! J# V* n4 j" B4 n4 ?3 B. N  l. l        payable
- _0 T# S8 l1 j$ j+ A" c        validConversionPath(_path)' k/ p' K3 z& I, l) u
        returns (uint256)$ H  h1 P4 P: v. r& j7 z  l$ o
    {
8 s8 J- d( Z& m; K$ G# q  z        IERC20Token fromToken = _path[0];
6 P6 E- C5 ?2 s( J        IBancorQuickConverter quickConverter = extensions.quickConverter();
/ e9 t" e# B4 Z' c        // 我们需要从调用者向快速转换着把源代币转化4 k% {' f3 Y4 a) f4 z
        // 因此他能基于调用者进行转换
* l0 K1 h& m& H8 m# e# u9 ?        if (msg.value == 0) {
5 v, o1 S4 F9 Y6 a            // 如果不是ETH,把源代币发给快速调用者6 T$ v) F+ p: m+ m4 k  ?
            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者+ c* I- A% j2 G+ Q6 W7 d* J
            if (fromToken == token) {
. P4 z% L# s" a, E3 f                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币
) M* A" j. s* `! K1 ]" ^! c                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者
" w9 x9 F, u8 D' f            } else {
7 p+ S! G  Z  ^- Q                // 否则,我们假设有了补贴,发给快速转换者$ l9 T) l* t: }6 V3 Y3 k
                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));
' C2 z. @: x" l$ B& ?4 p            }2 e) h- W0 R/ A1 w7 S+ ^
        }4 Q* h% `# X, v4 S( J0 |* m
        // 执行转换,把ETH转回
3 a2 ?" @# U: h$ V) w4 a7 h        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
7 s- a5 e+ o" \    }
8 \( [  c3 f8 [8 j: n& M0 F- f* \$ \. r$ F
##4.2 change(…)函数
4 ^* {+ I( K3 V/ b** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
$ g' T  @. E$ L' I) C

. X6 P8 F# i& N. s既然是过期代码,源代码就不放了。6 E/ O# i% N7 P3 U* K+ B0 d! y4 A& q
##4.3 getReturn(…)函数  A9 u. z  X& g) o( G
4 q# ]. U0 w5 v6 v' J
function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)
0 g2 ^3 \4 G' ~% w: A

  a" K# l- v4 P% O功能" f9 Q- e6 Q" o* m
返回从一个代币转换为另一个代币的预期数
源码:
# S9 ^. X: D4 _7 W1 M+ }
& p( K3 z; h5 e  Z% ~  x" v" K
/**
/ e' d6 N+ c+ J! X' k  N        @dev 返回从一个代币转换为另一个代币的预期数量8 m# \  M+ m7 d5 g
        @param _fromToken  ERC20 被转换的代币# D! R2 f. M" `8 U# e% c
        @param _toToken    ERC20 转换成的代币
8 _3 _8 H$ q0 f! A        @param _amount     转换的数量9 j" T4 `( j  d- g8 C% }0 @
        @return 与其转换的数量# z% I% T! a- @2 q- f/ U
    */
* u2 C$ k/ q) T( Z" [" r& g$ k    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {
- w, Z( f- w6 v1 }) u) Q        require(_fromToken != _toToken); // 验证输入) K; ?+ X# q; `; J9 |
        // 基于当前代币转换  b! [$ _+ X: g. O: n+ l! z
        if (_toToken == token)# \: b' I7 ]6 T6 h0 e( G
            return getPurchaseReturn(_fromToken, _amount);
+ [" A6 Q* V: T- h: Q        else if (_fromToken == token)
- D3 y# z; O& ]: M, y, d            return getSaleReturn(_toToken, _amount);
9 s: k2 R# H" ]1 a        // 在两个连接器之间转换# R% Y7 q# x% V4 d' [
        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);
, {& u9 j2 H- T! M! V        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));
5 d  J8 k9 u# F3 f8 R; W! Y    }1 S2 ^  O5 C% v/ `: q
/**2 s! P5 y! }: d- @$ w
        @dev 返回通过一个连接器代币购买代币的预期结果  R" p5 B. e* i! {, P, W3 O& e
        @param _connectorToken  连接器代币协约地址, n& S1 B  |/ ], V
        @param _depositAmount   买入的数量4 h6 T$ b% \3 k( _+ V9 d
        @return 预期的数量
) Z: {  d; a1 k    */
  m: P& h2 D4 P, [7 n- H/ J    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)
+ H' H0 P- V- f        public! l9 D1 o1 W! i0 g8 ]4 d$ N
        view
5 i: D6 `* K* F, J4 B8 f        active
1 V4 t, S  t! }% n1 P" N# e5 c        validConnector(_connectorToken)7 J, l1 V5 A$ x$ p
        returns (uint256)" b) f  h7 ^$ P' m
    {0 g( p% y3 C5 q# h
        Connector storage connector = connectors[_connectorToken];. ]' t; d1 ~, ?
        require(connector.isPurchaseEnabled); // validate input
( h" i# h( i8 @        uint256 tokenSupply = token.totalSupply();
8 ?5 i+ r% e) B' D        uint256 connectorBalance = getConnectorBalance(_connectorToken);% C6 p* U/ a# @1 ]) \
        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);
4 r& n5 b6 x# H$ |  ~8 T3 E8 T        // 扣除费用
: P6 X+ e  k1 F/ J% k5 y  g        uint256 feeAmount = getConversionFeeAmount(amount);
  T& A7 b+ p- q9 b7 F. l" p        return safeSub(amount, feeAmount);( ^& m6 n' S! k
    }
+ Y. ]- @2 s; z+ n, [3 b/**5 y5 R+ Q! r( C" _  t7 u* b$ M
        @dev 返回通过一个连接器代币卖出代币的预期结果- R$ R) U6 f- p8 ]0 f# L! y& t+ P, q
        @param _connectorToken  连接器代币协约地址
$ Y6 F) h  D' x$ U4 t2 Y        @param _sellAmount      卖出的数量
. M' S" g) R  N5 o3 S( E        @return 预期得到的数量" n! F* n2 g  y! D% q& z  w) h( `
    */0 W9 F$ Q9 ?* H) O0 L% l
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {; E: e4 t6 O: b8 ~
        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());/ V! B3 u1 J, A# \. h9 T, V+ A2 D
    }5 a8 ?9 W( i% Y+ e
/**8 h0 ]6 }# n; h) J0 C: Y+ y
        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回
+ E- j7 T7 f6 G7 r6 i2 A; J        @param _connectorToken  连接器代币协议地址
9 f  M1 G8 k8 P; [5 M8 |6 Q        @param _sellAmount      销售的数量" f9 S0 N8 r3 m/ E5 N' {9 ^
        @param _totalSupply     设置总供应量+ m- E; X- \, }$ D
        @return 返回的数量
% E$ t+ m$ m2 ^' j4 ?    */7 ^, k* X, @! Z) y
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)
* i3 }& B  D2 |8 @  D  |6 B        private
' E/ h/ |- y$ b. ]) F! l        view
* x2 l) v1 J0 o1 J, e2 X" i: j1 v$ i( G        active9 c% j) S0 ?& _4 L4 q
        validConnector(_connectorToken)! }; }9 z2 r5 I% G) ~
        greaterThanZero(_totalSupply)) `# z& f7 C; Q, }
        returns (uint256)# m- o# ^/ j. e& m
    {
. W3 J3 R5 B1 F6 Y        Connector storage connector = connectors[_connectorToken];
- O/ S$ l- i8 i% [: h        uint256 connectorBalance = getConnectorBalance(_connectorToken);" `( Y5 C5 i! z9 N2 e4 G. e/ h0 l
        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);6 l1 W; i1 y, [: k2 h. A. K/ z
        // 从返回的数量中剪掉费用
' n* v& k) ~5 C6 {" T7 _        uint256 feeAmount = getConversionFeeAmount(amount);" f& Q, ~  x2 F$ ?0 J( w
        return safeSub(amount, feeAmount);
5 a* i2 c; ^# u    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14