Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。4 _  {: w4 B8 P2 y7 j) F
) W- m. `# G7 A) ~2 L% j. \
若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。
- \, G/ ?/ Y6 K2 h' `
: x7 \1 r) @! g) j. y3 u2 D若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:
# j2 v7 h* ?5 Y! A- @% {“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。
. r* d/ X' {- k5 |4 Z8 K6 X

. U7 Q# [9 z! q' x9 A( [' X若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。
, J) T) @/ {6 r- N1 K% K. q3 q1 L
【核心智能合约简单描述】# B3 I% L6 Q% n! E. C* Y
1,contract BancorConverter) J! T, ]/ [5 I, D- E3 B' Y* U
功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。
$ s0 o! p; s) M0 D3 @0 q2,ITokenConverter7 D  }  k2 n1 T) b, M
功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。
! |  A3 f* _5 m$ Q" E& E& T! U& g3,SmartTokenController: P: U1 ]  r+ j- T( [
功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。9 I: C% u8 @4 S- I& q3 r
4,Managed: `. V. U4 j7 O+ V1 V) S
功能说明: BancorConverter的父类之一,提供协议管理的支持。
) c, [* t) T% n& b4 y6 M- J' q5,IBancorConverterExtensions! B/ \7 o; O' C5 l; P; h% y
功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。
7 x5 M( {2 W2 s$ J# t#4,核心函数分析# n+ Q9 P" X8 Y! U( G0 i, {9 X
##4.1 convert(…)函数6 `9 {) q& C( Z6 D8 o
convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:4 l4 C( d, {/ S# m
. O; Z6 a2 ^9 k6 A6 Z6 j( s
/**( O9 B; E# p4 C# H$ n% s# N- m1 m
        @dev 将一定数量的_fromToken 转换为 _toToken
9 a0 A9 i& c3 i        @param _fromToken  用来转换ERC20代币' u8 ~' W6 ^: u* Z- _
        @param _toToken    被转换到的ERC20代币
  L) @( L$ k" V6 n& }% m        @param _amount     转换的数量,基于fromToken/ L9 P! Q) w& B, H1 s2 }% ~. D8 w
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消/ b* I3 C+ Y, M9 S
        @return conversion 返回数量
0 Z4 ^! z, @8 U; E, ^    */
( N- ~( n3 \. ?5 R* I    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {& L" ^% M. z* G) S. s" g
            convertPath = [_fromToken, token, _toToken];
, q% ~8 b* J5 K. V) ]9 p+ o            return quickConvert(convertPath, _amount, _minReturn);0 ^' X" S! ]; y5 s5 L
    }
2 L6 w- X. E2 l, A  M/**
; ~' s$ B  v* h2 e        @dev 通过之前定义的转换路径来转换代币8 K0 w4 E4 H4 I" o9 u; f4 o& ~  o
        注意:当从ERC20代币进行转换,需要提前设置补贴
* n) w& k0 N2 c7 D        @param _path        转换路径
6 x$ I- T3 O; R7 n& L  K        @param _amount      转换的数量
; C, E2 p+ L; E        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
6 w$ o- }/ n! d% p        @return 返回数量+ M! [+ s7 m$ H# V4 B  m3 D8 y4 B. J
    */( }. E# T$ ]; c5 H) p% ]/ n
    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)
6 P" H) c5 s; X        public" d2 n" ~2 {  z$ f9 j, v# ?/ R: _
        payable. Q( S, `+ k- M( t, R$ a# a  A
        validConversionPath(_path)
  W% ?0 D( Y! D) u* ~4 Q9 S        returns (uint256)
  G8 ]0 R& }5 q5 M    {; V9 ?1 @  \8 _/ u3 C& l
        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);
- Z0 f; d* C; j9 d    }$ ]6 \1 d0 o5 r& _/ Z& |) i$ w
/**3 X( y+ _& F6 v! Y/ C% O& I* }
        @dev 通过之前定义的转换路径来转换代币6 t: R) m' H* X; [4 l  y9 i, e0 |  L
        注意:当从ERC20代币进行转换,需要提前设置补贴
2 z& J, v, ~8 X3 Z% T- x. X        @param _path        转换路径
6 Z+ ~. s7 V: \& [        @param _amount      转换的数量$ }8 F# U/ b" y8 w1 S
        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
! g- V4 A2 P4 j3 l  X& L        @param _block       如果当前的区块超过了参数,则取消$ s; w; N4 R7 [1 l
        @param _nonce       发送者地址的nonce
  }0 F1 q* N# g0 A" W* Y        @param _v           通过交易签名提取* u7 f/ {/ o% h& l
        @param _r           通过交易签名提取3 Z% \( G; g' p
        @param _s           通过交易签名提取
% g$ P1 u) v4 i: T: }9 g5 _; Q        @return 返回数量
$ f+ G! i, E" K$ A6 W/ g% H    */
, t  v! E9 s" \) C' l    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)
* }0 g) S# y4 u( V) D        public+ D8 r& r" K) L8 Z) p
        payable# c: b8 s, G! c: t; F
        validConversionPath(_path)
, T' Q" M5 S7 b4 t. b6 E5 {+ Z        returns (uint256)1 M$ V0 |* }: g/ L: Y* ^7 a
    {
1 Y3 B* M) c2 q& ]        IERC20Token fromToken = _path[0];" c. P8 b9 W: ^0 `3 N
        IBancorQuickConverter quickConverter = extensions.quickConverter();
0 [8 R+ H# ?& c: ?: g& i- G5 [        // 我们需要从调用者向快速转换着把源代币转化- O* r3 _1 A* Q  A4 m5 e/ z
        // 因此他能基于调用者进行转换
1 ?$ K. `3 F4 G5 i8 C2 B        if (msg.value == 0) {; h! r* L$ ?" `5 V4 T) C
            // 如果不是ETH,把源代币发给快速调用者
7 z. x  m: w* _2 f/ B            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者! G7 v& @; D6 e" I. k1 n
            if (fromToken == token) {+ S1 q' M2 E6 M/ y- f$ s
                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币
0 ^$ h' N. K* }/ |5 \                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者8 `2 q1 _% Z8 k1 \" Z6 Z
            } else {
" p8 h0 o8 x) G2 t4 A9 o7 r- v5 g5 _                // 否则,我们假设有了补贴,发给快速转换者
! T& C/ Z, }* N1 d2 s                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));
# s) Q2 O! S7 W7 {            }" A8 X: W2 Y) B6 `
        }
0 a- V- G* x+ W$ J8 Q        // 执行转换,把ETH转回
& ]; g/ h% m0 V$ m        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);; o( A5 h1 `( I( z  H, {
    }
% E4 E, ]7 M4 l! A, ~# R  p) \; H' a# }6 m
##4.2 change(…)函数& e( d/ f) n1 H. {7 Q$ ]
** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
/ b$ [5 \& C! }& I) L3 w+ \1 M
1 n& c- M3 E: c! m5 B: E
既然是过期代码,源代码就不放了。
6 k9 \& |, U7 L% Q  y##4.3 getReturn(…)函数' ]$ G5 N5 L3 g5 z4 P! f
5 H4 _: K6 }! F# C
function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)  I& V+ ]6 P7 ]* e) ^
. n% V% s& A4 E( }. l+ A
功能
0 W, E7 d9 s* Q* T# [. i2 ?( L返回从一个代币转换为另一个代币的预期数
源码:
2 _: |' {9 Y( j2 Q0 Y0 G: _

5 t: g+ S2 @* C1 p/**: w6 ^3 t6 [" V: F
        @dev 返回从一个代币转换为另一个代币的预期数量
) e8 ?/ r$ e4 f, a) s        @param _fromToken  ERC20 被转换的代币
. X' g  M* s! ~5 h        @param _toToken    ERC20 转换成的代币1 M0 n' Q8 a- g" ]  h: ^" F. w+ x3 C5 n" F
        @param _amount     转换的数量
) x9 W5 [3 T- e8 O        @return 与其转换的数量3 w& \& ~8 N& ], B% q! g8 D
    */4 u. j3 F9 |: a& T+ s: q
    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {" o; ]5 M+ V# E" ]
        require(_fromToken != _toToken); // 验证输入
5 w$ X' U9 ~# n5 ~4 S/ Z# @        // 基于当前代币转换% V/ t/ \- ?# e% `! y8 q) h
        if (_toToken == token)
$ `1 D" ]- ^0 l6 ^3 U2 s' K4 g            return getPurchaseReturn(_fromToken, _amount);; Q* O" ?: e( z
        else if (_fromToken == token)
  V8 A  H3 V4 D# s) H: ]% T  F2 u            return getSaleReturn(_toToken, _amount);
8 H) g5 H  H. M: z        // 在两个连接器之间转换
- m8 c  X/ U  S- @5 h        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);
5 p% w) _- C) Z' g- _# s5 \1 e        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));6 U" F2 j% o+ l1 k: W
    }
1 L" {5 z) D" k+ L$ W& T; ~/**
2 _' E$ u; v" c( ~        @dev 返回通过一个连接器代币购买代币的预期结果
6 j" ?( R) E8 f7 f        @param _connectorToken  连接器代币协约地址
. r( u/ R- h; r  u# M3 r/ @1 A: I        @param _depositAmount   买入的数量
- {9 @/ I$ _$ o/ B2 g        @return 预期的数量; ]: D0 n5 g% h$ z2 G
    *// o8 ]2 p0 V, N) N* H  U9 ]) T' P
    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)% L6 x& Z1 K+ o( m
        public
, J& p6 |. l# `6 g* G7 ~$ }9 j        view: p! y# {: r" m+ j8 q
        active
, E2 X+ E" G) ?. r9 \6 B* `9 U        validConnector(_connectorToken)
: ~4 \" C% ~( [) b. i# N        returns (uint256)* q* N& C8 C% X/ D  V
    {
- D8 y' m" }+ }        Connector storage connector = connectors[_connectorToken];/ ]% k+ h2 {' n4 G* F- E! ~
        require(connector.isPurchaseEnabled); // validate input
6 R+ n  s' x" T3 o: Y) {% O7 z        uint256 tokenSupply = token.totalSupply();$ ^; Q# v; p0 e9 W; z3 m
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
0 V; j2 E; K" D% T; [. F8 F8 U        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);
, N2 y2 A5 ~$ v  f! ?- K        // 扣除费用) q7 ^3 `; I3 R. C  G% T9 U
        uint256 feeAmount = getConversionFeeAmount(amount);) j2 u5 ]# H0 N+ B* Q" D
        return safeSub(amount, feeAmount);$ p0 Q" k. ^* _5 D
    }/ c$ n) W# k3 J# e1 Y' z; q! O$ h
/**
& m/ [. g  L& N, ^        @dev 返回通过一个连接器代币卖出代币的预期结果
5 o6 K5 \+ e) P0 f8 D5 ?        @param _connectorToken  连接器代币协约地址6 r" W+ _& W& E3 j$ v! O+ L  O
        @param _sellAmount      卖出的数量% h5 u" q& L9 H8 K! |2 Q
        @return 预期得到的数量3 t7 p' o" e1 y" m$ @
    */
& {+ U, w+ |7 |, a  ^    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {
( x+ H& i1 D) I+ f! y# @        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());+ h; [$ {& W- l" X8 k
    }6 B4 ]& M! z& Y9 o. ~
/**
% [( l; c" S4 |* e" A9 G' j        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回( i, d- N/ v+ j1 i
        @param _connectorToken  连接器代币协议地址
$ F- `: g7 o3 o& u3 Y        @param _sellAmount      销售的数量
4 [; ?& o8 ~" e4 c0 \' s5 v        @param _totalSupply     设置总供应量
7 `; |2 E+ n" ^& e; ?9 V1 R, }        @return 返回的数量: d+ }: y8 U6 j8 C% ~5 o, I( V. H3 ^
    */: m" k2 }. X( X9 i$ |9 ?
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)* e; m4 j- W7 S5 j  E3 r
        private( K  g$ r  {" M2 @: `/ ^) u
        view
* {/ `/ ]6 e3 T  c, N1 }/ b/ O. @/ G        active$ P$ a: f" f$ l4 {5 w9 s3 K
        validConnector(_connectorToken)+ X7 a- C( P- ?
        greaterThanZero(_totalSupply)* O  J: x% M9 _, ~+ g, p9 K. z
        returns (uint256)3 O+ I; K0 S( }5 S
    {
$ |& k: t1 ?" }1 h        Connector storage connector = connectors[_connectorToken];! y  Z! M9 O: u7 [! O# r
        uint256 connectorBalance = getConnectorBalance(_connectorToken);$ A5 T* y- z6 b8 W, t( [
        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);
, L7 l% [& M, w) q# H1 M        // 从返回的数量中剪掉费用3 F1 C8 C0 A3 d- E2 x
        uint256 feeAmount = getConversionFeeAmount(amount);3 I# u% @# B# D( d
        return safeSub(amount, feeAmount);$ [; ]& h. M4 Q% z9 u
    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14