Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。6 s3 X. ]) W$ L3 G6 Q: p7 R( G

7 }8 h- A; g; m2 ]# X若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。  r; N" }7 ]( e

1 h' F- j" c: Z若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:8 u0 ^( s" y9 E# h. K, E) I7 N3 j* i
“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。" E- N& V! [. z2 H5 Q& H

$ H, [5 t+ R+ v若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。+ @+ ^2 X3 |, }
4 H# ]& q5 l+ i1 Z' B. M0 S7 X: X
【核心智能合约简单描述】5 _0 K: ^" ], r; H6 r* ?
1,contract BancorConverter
5 H2 M: ]* b/ y1 c; z2 g. K* Q6 A- K; l功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。
  k2 A% ~: I4 |# i2,ITokenConverter" y; J% o* y$ W
功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。
7 Z+ Q! R) l/ q- Z1 K- @3,SmartTokenController$ R; @! ?' f0 k$ g9 ^0 ~% r8 ^' p
功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。
3 N/ L6 |+ H+ ^+ j& M5 x$ w4,Managed
# U8 d$ O$ X0 `+ L' `  b- |功能说明: BancorConverter的父类之一,提供协议管理的支持。1 y, [5 t/ G" e; f% @5 J; p1 ~5 E6 l
5,IBancorConverterExtensions3 W$ e6 D( a- f' r, M7 @
功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。
7 }2 }0 W( U: w! i% p0 E. `0 M#4,核心函数分析
) L1 `! P/ F3 D, x$ S  k##4.1 convert(…)函数
7 S, ~9 C0 _" R! |convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:9 O* v  K: c7 X: G, s' r. m

  a3 c! d) O- m) \/**6 H& }6 k1 D2 [& r4 c
        @dev 将一定数量的_fromToken 转换为 _toToken) `0 C7 j# c7 V0 y
        @param _fromToken  用来转换ERC20代币
' A& m, k. q/ m( R4 `        @param _toToken    被转换到的ERC20代币; |! h4 }- Y2 d- a4 i6 _# k( a1 a4 u
        @param _amount     转换的数量,基于fromToken
9 r) s1 X: w  t, ?, T        @param _minReturn  限制转换的结果需要高于minReturn,否则取消
) t  E$ r7 t$ A        @return conversion 返回数量, P1 F  O" u. p6 t3 K1 {: k6 w& r2 W
    */
3 x. `; W5 r. B/ |. x1 W    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {! [0 K6 Q. J  H0 z$ K5 ]
            convertPath = [_fromToken, token, _toToken];
( s, u8 T( L/ E+ u            return quickConvert(convertPath, _amount, _minReturn);5 R+ e2 w- v/ S
    }# G3 u& O; M4 q8 P
/**) {: n9 ]4 J7 \
        @dev 通过之前定义的转换路径来转换代币3 w7 b& r% E% l9 E
        注意:当从ERC20代币进行转换,需要提前设置补贴
5 ?2 d2 [" b% N" K        @param _path        转换路径# R& T4 ]; ~, J) m# U8 l. g- j4 m
        @param _amount      转换的数量7 ~* E- |) q0 K  |" Y
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消2 F1 I# r& c; F5 \  h  H: X/ U
        @return 返回数量
3 ^, m! W& e/ ^9 h- j    */2 e! W) b& {. n3 m( f( z* W4 o
    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)# I. I2 O4 e% G% d( X
        public" y# w0 T0 ^, e5 ]& o
        payable* U" ]3 _: l5 [3 i
        validConversionPath(_path)) o$ W# o% M' Z0 l9 q5 s! I
        returns (uint256)8 U# f( l& W) c/ d
    {
1 ^* m% F' D7 H1 D1 U        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);3 y/ {0 P! A0 i0 v6 }6 ~6 q
    }  P1 N2 N  O8 C: v* H# L9 G
/**
; n$ u% f; u6 n4 @: h; V        @dev 通过之前定义的转换路径来转换代币: {2 W* C+ K6 |7 J) _5 Y
        注意:当从ERC20代币进行转换,需要提前设置补贴
: W4 x% g) X5 \& H: _/ m        @param _path        转换路径
2 q( k) P: k1 d5 }' Q! }+ w( K        @param _amount      转换的数量% @$ k# E% K* ]  I: x, w! Y
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
# e3 @+ h$ X. m. M+ k' _        @param _block       如果当前的区块超过了参数,则取消
; V- }) t5 N) i        @param _nonce       发送者地址的nonce8 h* n& z' |4 \
        @param _v           通过交易签名提取/ G. h3 L+ s, e% C  R
        @param _r           通过交易签名提取% ^% c/ s* |, l+ K- Z* |9 a+ O7 h, E
        @param _s           通过交易签名提取
# b" b6 Z; C* ?! a; ~. ]        @return 返回数量$ u% S  p0 ^$ J9 N0 b
    */
( _7 S* \3 P0 N2 B: w0 Q' x    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)
# D) Q& b" V# e" `        public
/ P- U% T7 B8 y3 G1 h0 h% W        payable# z/ [8 B- e8 `2 Z. q+ e
        validConversionPath(_path)6 x& Y$ Z+ i- K9 m8 r; G% U. Q7 g
        returns (uint256)
- t+ j3 E' |) y6 R; O5 d    {/ Z! W5 P/ U" g4 A
        IERC20Token fromToken = _path[0];% F7 `+ F! |5 R/ a: H2 h$ G! Y
        IBancorQuickConverter quickConverter = extensions.quickConverter();  {) S5 R- I& y  `
        // 我们需要从调用者向快速转换着把源代币转化9 m; Y" E# F1 ~' i7 m6 G0 g
        // 因此他能基于调用者进行转换9 Z( B4 R/ Y, h$ S" v: p
        if (msg.value == 0) {; }7 L+ g1 b9 v: i5 @& X; Q( B, P
            // 如果不是ETH,把源代币发给快速调用者
$ ]* A: }6 t1 Y3 q            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者
. q5 n) |* e" ?; v+ e% x            if (fromToken == token) {
- n' F- K* y* C" Z3 P: S                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币
# ^5 F% ^& v9 t6 a) o  Q                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者! L: A. ^) U+ V- _! A  W4 k
            } else {
$ O8 ^& O! |0 v+ \; z                // 否则,我们假设有了补贴,发给快速转换者& @& Q7 i' m0 V
                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));- Y: m0 W: c5 _5 f' s5 b9 Z9 b9 D
            }
" e* i; V! j3 R+ E        }$ }! j; L" q, @: b, [$ G
        // 执行转换,把ETH转回, e$ H6 m( v9 h( @7 ]
        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
. O6 @9 N7 q! i$ X3 o    }* z& L+ g3 u' P- T4 z& j

; j# O7 _* ^6 K& t##4.2 change(…)函数
( T0 J) w# Q" E' z** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
1 [9 [; I8 }" ^- y/ P3 e8 N% C7 V

0 w1 @' n3 v6 D既然是过期代码,源代码就不放了。
, r: P" {* n2 I; s3 q##4.3 getReturn(…)函数
+ B9 ~. G- G9 N# W
6 x. B2 b4 l3 z0 U$ V" c3 zfunction getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)1 `" g7 \5 R# [: W0 E# D" |, _  _7 D
. T3 }4 h% \/ w5 m' T
功能
9 y, ?% L9 k/ Z* S返回从一个代币转换为另一个代币的预期数
源码:
! s1 F9 n( l2 K" n, B6 O- I. @& e
+ o( k3 j( W. \2 v! [
/**
4 S8 b, H; O4 v! F; s/ W# `, J* U        @dev 返回从一个代币转换为另一个代币的预期数量8 p, i7 Z& [6 y( v5 G" w2 t4 ^
        @param _fromToken  ERC20 被转换的代币, C6 ?! }9 I' {- ]. W
        @param _toToken    ERC20 转换成的代币
3 A1 _: q( {+ i/ k) Z7 z& f& R( [        @param _amount     转换的数量! e$ ?4 @7 D1 k, _' l: I
        @return 与其转换的数量
3 R3 h. z1 V' ~! ?6 @9 P. @% t    */
8 \' g* ?5 {$ Z    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {
- }, D2 [0 X$ \" h        require(_fromToken != _toToken); // 验证输入. W, h* n: K& k! X. |
        // 基于当前代币转换2 M% ?* E( _, e) J
        if (_toToken == token)- S2 ?  {; Q, [* p2 c, s* {
            return getPurchaseReturn(_fromToken, _amount);! m% Q. H" G# n- r
        else if (_fromToken == token)
& k0 j/ w8 r5 x3 ~* [- @) q2 I( L            return getSaleReturn(_toToken, _amount);
! W6 l2 y+ N9 j! h( A# B" w        // 在两个连接器之间转换  w3 U) `' A% q  O7 P
        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);/ @6 b  S4 J2 S6 t
        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));: w# A) |$ c3 c& m0 L8 B& {/ l
    }$ F8 `4 q& B9 N+ u
/**; D2 C7 H3 ^! c" R4 X
        @dev 返回通过一个连接器代币购买代币的预期结果/ a/ R% c" Y( l2 `% m9 Y. F* D/ _
        @param _connectorToken  连接器代币协约地址/ V5 I% |; ?# F2 z3 D' X
        @param _depositAmount   买入的数量4 f$ N, y# v" _3 }/ L
        @return 预期的数量
  b" q* W/ j# s$ i0 k" I    */" E$ ?7 G& U( f3 W# }3 i7 {
    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)
$ o, Y# ^6 [" k4 a2 ]8 B7 j        public( u. c# F8 a3 c* M- J: ^
        view: ~+ O; A: |2 f! V8 T( {
        active
( O1 R7 }5 s# p/ V9 m: x9 ?; Z        validConnector(_connectorToken)
0 w* ^4 W7 r. f( ?7 F! ~        returns (uint256)8 \. S, [" V1 u1 ?% Y2 d9 |0 M
    {2 J* a" n$ x" Y
        Connector storage connector = connectors[_connectorToken];( r- q: ?$ g& ?4 c( c
        require(connector.isPurchaseEnabled); // validate input' k% a3 }+ ]0 M2 l
        uint256 tokenSupply = token.totalSupply();
9 @+ |& G8 N* L3 Y& D        uint256 connectorBalance = getConnectorBalance(_connectorToken);! O  V# d7 N. x
        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);
# E4 B/ h# m4 m" j2 f6 H        // 扣除费用( y- N* O0 ~, Z
        uint256 feeAmount = getConversionFeeAmount(amount);
( H7 G! e# o! D0 e. |- {        return safeSub(amount, feeAmount);% C: `' N# J: P3 d( @! U
    }
& h5 i* G$ [0 w( l/**
0 @" v) O9 H3 \% s4 f7 t$ @        @dev 返回通过一个连接器代币卖出代币的预期结果
: N1 p  D3 x8 s( t* k' E        @param _connectorToken  连接器代币协约地址' _  P5 V4 C8 a1 u" l
        @param _sellAmount      卖出的数量
' Z9 n. h2 w/ w        @return 预期得到的数量* Z# p- J2 S, N* d" ^/ M
    */
" Y6 u8 T  j* T3 v4 I; S' n    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {
) P2 I- o  w  k- n. o# L        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());
" ?5 p( B$ D) K" [; ?. Z! ?    }# S$ O0 B! S* j
/**, N& z& \' V3 M# o
        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回0 \8 ?6 I" Z' k2 S4 ?4 ^" @1 C
        @param _connectorToken  连接器代币协议地址9 H3 Z; o; u  O: c4 y* Z6 V6 ?. Y9 G
        @param _sellAmount      销售的数量
. P/ O! [0 \% @  y        @param _totalSupply     设置总供应量# Q9 F# A/ h. {/ x$ }+ s; d: z1 f
        @return 返回的数量) e, f# z( ]3 @6 I
    */% D+ ]/ A) B( p7 T
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)2 p; O, T0 a; z) _" E2 r
        private3 j. g% p& W* }' P9 ^+ `
        view, G% U3 f, i0 @- [: N9 z. `( r
        active  y# q' f* K3 O# W
        validConnector(_connectorToken)
/ \9 p: E) q4 D% `1 o# y* d        greaterThanZero(_totalSupply)
/ C/ Y. C; u* C& G0 l, d1 K        returns (uint256)
; _7 A1 n) e$ Y: W* q5 K' p5 S" \    {% p& q! ?) ^# x
        Connector storage connector = connectors[_connectorToken];
$ `2 t3 f1 c. Y+ W' e        uint256 connectorBalance = getConnectorBalance(_connectorToken);
' w$ F! S. s# ]7 O. a% u        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);
. c6 n8 }# F! t: L0 ]# D        // 从返回的数量中剪掉费用5 S4 w  N: u9 d7 i
        uint256 feeAmount = getConversionFeeAmount(amount);
7 q9 y7 k- K$ ^! ^/ S( C        return safeSub(amount, feeAmount);
; T& ~# k* d' d. M  o8 ~    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14