Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在以太坊上发行的大量ERC20-Token是没有价值锚定的,其价值完全依赖于项目方的技术与运营能力,若项目失败了,则通证(TOKEN)价值就很可能归零。
8 S) ~- n9 q4 l" H0 w' T, I* ]' A) E$ s2 K
若利用智能合约的强大而灵活的“资金流转控制”能力,在通证合约中控制着一定量的储备金,让通证与储备金之间拥有一定的兑换能力,那么Token的价值就可以储备金为锚定物,而不完全依赖于项目方。通证持有者也就不用承担项目失败或者项目方可能诈骗跑路的风险。; e% ^0 f9 ?% M( X  G) x
* U& m8 ]* p, J- O
若通证与锚定物之间的兑换算法采用了Bancor算法,又符合ERC20标准,则被称为智能通证(Smart-Token) 。为了简单起见,以下的论述以ETH作为锚定物举例说明。购买与售卖Token的过程如下:
  h) a$ I+ e. R7 @“购买者”发送一定量的ETH到Token合约地址,触发了合约代码自动执行"购买功能代码",获得对应数量的Token;“售卖者”发送一定量的Token到Token合约地址,触发了合约代码自动执行“售卖功能代码”,获得对应数量的ETH。8 ^' c+ j4 K( a! v

' a/ v3 z( L- |, {  p若AToken与BToken都是以ETH为锚定物的智能通证,那么Token持有者无需通过交易所,仅仅凭借智能合约提供的买卖与兑换功能,就能实现AToken与BToken的自由兑换,比如AToken–>ETH–>BToken,多种智能通证之间通过共同的锚定物串接起来,就形成了一个价值网络(Bancor Network)。
8 Z  c0 X5 X8 [( l: q) X/ D0 w) ?7 C. K/ D4 \) t3 e- `5 d, }
【核心智能合约简单描述】: _7 g0 \/ S, ?9 c" [
1,contract BancorConverter! K& \- E0 v! x6 ~. R+ H
功能说明:代币转换器,允许一个智能代币和其他代币之间的转换,ERC20连接器的余额可以是虚拟的,从而不需要依赖于真实的余额,这有助于避免在一个协约中有大量金额的风险。转换器可以升级。/ l- H: Q- y5 Q. P! B
2,ITokenConverter
/ q8 ]( E4 [5 z9 d1 ^. U6 @功能说明:BancorConverter的父类接口之一,EIP228 Token Converter接口,用于智能代币的买卖和数量计算接口。
; p2 z. z: x: P1 m3,SmartTokenController. ?2 \; n5 V! b( }2 Z
功能说明:BancorConverter的父类接口之一,智能代币管理器。智能代币管理器是一个可以升级的模块,从而允许更多功能和问题修复。当它接受了代币的所有权,它会成为代币的唯一管理器,执行各个功能。0 m4 j: ?! _9 G: c. v
4,Managed
; w/ u$ J# \5 }功能说明: BancorConverter的父类之一,提供协议管理的支持。- J! `9 Q! }* R& [' [. a
5,IBancorConverterExtensions' T% ?' i. D2 G! F6 d' _- u. j- u
功能说明:BancorConverter的公开变量类,bancor converter extensions 协议。能返回formula,gasPriceLimit,quickConverter等3类接口合约。
7 f/ s0 ^4 t: l0 r/ z) A7 K% p#4,核心函数分析; I) _0 J  h7 j1 [
##4.1 convert(…)函数! p9 J9 U5 _* s+ U4 D
convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken;源码:7 N. `1 c* v$ Q6 C4 \

% I9 ~/ `# Y, G. l% S2 f/*** ?8 D1 q& z/ R+ f. i4 W
        @dev 将一定数量的_fromToken 转换为 _toToken. H/ R1 ]4 Q; D& Q
        @param _fromToken  用来转换ERC20代币5 e- w( Z  p" V+ F1 u5 J, ]
        @param _toToken    被转换到的ERC20代币: Z- m5 t7 S% {! x$ H4 G' H
        @param _amount     转换的数量,基于fromToken2 }# E6 Z. p  E0 {2 M
        @param _minReturn  限制转换的结果需要高于minReturn,否则取消
. x; R  G1 S! K6 r8 |  i* V        @return conversion 返回数量
" _  ]$ {. O* o3 P( N7 u; [3 n+ K    */7 Q3 B/ Q4 o( E- k
    function convert(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256) {
5 P: c# ]- ^! d& B            convertPath = [_fromToken, token, _toToken];
0 ^! V. `1 @1 b2 o+ k            return quickConvert(convertPath, _amount, _minReturn);8 I! a" f2 D6 J" V
    }) z+ O+ I3 o. ~  v4 R/ t
/**0 |4 f; P+ f; a9 r! {/ {$ Z$ ?
        @dev 通过之前定义的转换路径来转换代币/ R% [/ B4 N. j# n8 m1 r( G
        注意:当从ERC20代币进行转换,需要提前设置补贴
' _. w) v5 g8 V  l; r1 M1 @        @param _path        转换路径
2 I7 y6 y; T7 O% y6 u& P        @param _amount      转换的数量
: q4 u& V- n, D  r- t9 i        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
: @. U1 Z/ f0 l. l: Y; R        @return 返回数量1 J4 s- Y# T  `) `
    */
6 W2 L4 ^: m: D$ h7 r1 H/ E' `    quickConvertfunction quickConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn)+ ?: y1 i' {1 Z# X
        public& {  q1 h; T" C5 U- M& T0 Y+ G7 a
        payable
8 T- Q- m2 V) F1 j+ h: N        validConversionPath(_path)) ^, x5 L; d6 r
        returns (uint256); f. n: N  n1 G+ e
    {
# ]5 y- z/ Y- C/ w        return quickConvertPrioritized(_path, _amount, _minReturn, 0x0, 0x0, 0x0, 0x0, 0x0);9 n, Q* H5 T! o
    }5 Y! B% y, ?' W8 a& u
/**
- m5 f& {7 b1 F1 V" k        @dev 通过之前定义的转换路径来转换代币' b! e, N6 s8 d& V
        注意:当从ERC20代币进行转换,需要提前设置补贴7 N8 R" }& e/ e
        @param _path        转换路径7 s6 @/ t* S5 @8 O2 V
        @param _amount      转换的数量
; u7 N% P$ d: g$ G5 o8 f3 z        @param _minReturn   限制转换的结果需要高于minReturn,否则取消
& E2 l) b2 e/ Z/ Q5 ~. F7 ^        @param _block       如果当前的区块超过了参数,则取消' b- `/ D& [. b) i! n
        @param _nonce       发送者地址的nonce) H( G3 V; i0 j; [) n: i
        @param _v           通过交易签名提取: G8 |9 w9 V' v3 D2 d0 _
        @param _r           通过交易签名提取  T0 A  y) P- w
        @param _s           通过交易签名提取
5 G% e* ~  N! h1 ]        @return 返回数量
* G6 \0 Z8 ^5 H8 E5 a4 I    */3 l" ?1 w9 H" l) f+ W
    function quickConvertPrioritized(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, uint256 _block, uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s): }9 Q0 r' |. O& q3 l3 k
        public+ l0 x. v  p$ s  g2 [1 q
        payable
; J6 N6 O0 ]& R% b5 G        validConversionPath(_path)
3 I. |/ o9 a% _, L1 Y! r        returns (uint256)
0 Z; A+ K2 _& g# ]    {
6 l' v: B7 m- K2 F- L9 @' Q) c, G        IERC20Token fromToken = _path[0];$ M5 B% \: x7 S5 P( u
        IBancorQuickConverter quickConverter = extensions.quickConverter();8 J8 ^: x8 j1 {  a/ S* X
        // 我们需要从调用者向快速转换着把源代币转化
9 U5 E' }' f& U, k) a0 Q: z        // 因此他能基于调用者进行转换
$ n- n6 e% e/ k" m        if (msg.value == 0) {# O% ?4 E# t6 W' I% T1 S
            // 如果不是ETH,把源代币发给快速调用者- U( ^9 P( [( Q! w$ w+ A
            // 如果是智能代币,不需要补贴 —— 销毁代币,然后发给快速转换者* r. Z: K6 w" I: o- a  d" F5 }" a" O
            if (fromToken == token) {
3 S! `7 B" f) M# u- M  i                token.destroy(msg.sender, _amount); // 销毁调用者的_amount代币+ f6 r- A6 v0 K$ l/ ^/ F
                token.issue(quickConverter, _amount); // 把_amount的新代币发给快速转换者6 {+ h* u  _, L" ~+ _
            } else {
2 k2 n9 B9 r$ B# }* J9 S                // 否则,我们假设有了补贴,发给快速转换者6 z& U" x1 d' L3 J
                assert(fromToken.transferFrom(msg.sender, quickConverter, _amount));
* p4 ]: r/ f( N3 f! O8 P            }
) j: C, P, r* t/ z        }
+ E  {& ^2 }; G" e" ]9 `        // 执行转换,把ETH转回
, d% c, Y6 ^$ |/ p; M7 D        return quickConverter.convertForPrioritized.value(msg.value)(_path, _amount, _minReturn, msg.sender, _block, _nonce, _v, _r, _s);
, b' M. j, e) k) @( ?    }
9 T1 f. S: P2 k) \4 Z) b8 t# d8 f5 y, |  K) s
##4.2 change(…)函数, h3 Q: u' ^! V/ D+ a+ N
** function change**(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256)功能: 将一定数量的_fromToken 转换为 _toToken。弃用了,向后兼容。设计思路和源码结构挺好的代码:
4 ^9 l7 `0 g6 I/ ^( x

$ Q0 X' Z  E9 H* `5 \% Y) q既然是过期代码,源代码就不放了。
8 M; \1 y; n* c( v: H  f##4.3 getReturn(…)函数; E; y: g6 W, u( h4 n
; x# L; V4 F0 n' A, F" U$ W& ]& R/ e5 m
function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256)7 V/ x3 P! F" i( ]

. c3 j! D$ W( |. n7 `+ a, h功能6 J# b4 ~: A6 b4 V% p, F9 G! Z
返回从一个代币转换为另一个代币的预期数
源码:( |/ r, T9 w, t1 H8 _: G

: g0 ^5 H) d* t, T0 x3 l$ K/**
( J# p- L; S2 T% z# _        @dev 返回从一个代币转换为另一个代币的预期数量
2 H3 Q3 {4 s% N0 E        @param _fromToken  ERC20 被转换的代币$ D- P7 W2 z! O( I
        @param _toToken    ERC20 转换成的代币
% b; V# {+ ~: Y* W' ~4 O. ^        @param _amount     转换的数量8 o2 _. Q! G  b0 M8 @4 A! Y
        @return 与其转换的数量
9 P# x9 l0 W- Z2 D$ a- z8 h    */, F9 t5 Y! P/ q+ s" x- t
    function getReturn(IERC20Token _fromToken, IERC20Token _toToken, uint256 _amount) public view returns (uint256) {
3 }0 S9 t5 o& |+ n3 F        require(_fromToken != _toToken); // 验证输入
7 b' ]9 j# s, h. D4 ~! e        // 基于当前代币转换- D5 e4 z0 V- Q" n  f
        if (_toToken == token)
/ ^; `2 l1 ]) t! J            return getPurchaseReturn(_fromToken, _amount);9 s. R) [" u  E, R! [  n, ^
        else if (_fromToken == token)
9 \6 X  N3 s7 V8 a8 H, R. u! k, V            return getSaleReturn(_toToken, _amount);
" I  r1 x% g% M        // 在两个连接器之间转换
3 i% p  Y1 J9 I( b. g        uint256 purchaseReturnAmount = getPurchaseReturn(_fromToken, _amount);
0 `0 ]4 r/ x% Y! H: C        return getSaleReturn(_toToken, purchaseReturnAmount, safeAdd(token.totalSupply(), purchaseReturnAmount));- A6 G1 r9 X1 h  d" x" S/ E$ e
    }
5 d( d- D! f5 ]5 i. }5 `- t. a/**
) n; i7 l; e. X" L5 u9 M/ p5 O        @dev 返回通过一个连接器代币购买代币的预期结果
- G: i$ D! O. J- g4 A        @param _connectorToken  连接器代币协约地址
1 _# @6 `% u2 B* \; V8 d# n7 e        @param _depositAmount   买入的数量
  H% t' h* K3 `' x7 N% R        @return 预期的数量0 v/ x% }4 a! z& i
    */* X# n9 M2 j" z6 q
    function getPurchaseReturn(IERC20Token _connectorToken, uint256 _depositAmount)- q1 M$ Q+ D, s# E; V0 m% H6 ?  P
        public8 R) @! y8 b4 L) i
        view
4 i+ B6 X+ v2 c! J, `- i        active
/ Z1 e% d7 P& c. w4 t& x        validConnector(_connectorToken)
% N1 c1 z) G- r1 N        returns (uint256)9 o/ {% O9 e; Z$ I5 o( O
    {
6 M6 q! Q% i) h- M+ m! p" v        Connector storage connector = connectors[_connectorToken];
% K( j, }6 [  ?5 J; K        require(connector.isPurchaseEnabled); // validate input
" F- ?& u9 x4 R7 O8 s        uint256 tokenSupply = token.totalSupply();( p3 |& y8 d( p7 F* h7 k
        uint256 connectorBalance = getConnectorBalance(_connectorToken);* p( z$ ^; [# Q: x
        uint256 amount = extensions.formula().calculatePurchaseReturn(tokenSupply, connectorBalance, connector.weight, _depositAmount);
- s! z$ f1 Q3 b$ E, R9 Y        // 扣除费用
8 A" N! g) x/ K7 ^- h        uint256 feeAmount = getConversionFeeAmount(amount);7 f6 R2 ^: l* n/ F
        return safeSub(amount, feeAmount);
& ?  ^( a# M9 L" @    }
9 F1 p( S- i) \3 P8 c/**2 q! f0 k, Y/ Y9 l4 I# H
        @dev 返回通过一个连接器代币卖出代币的预期结果
: L6 o# N  p; g& J+ X        @param _connectorToken  连接器代币协约地址! U' Q& ~* j# R( _4 T
        @param _sellAmount      卖出的数量
( ?' t6 }  K6 G: V4 r$ @        @return 预期得到的数量+ M3 O+ Q( `# C3 d& u: P1 V5 |
    */% q; Q; a$ J' m) i2 U
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount) public view returns (uint256) {& q: d' O0 E+ X- J4 T+ L" `
        return getSaleReturn(_connectorToken, _sellAmount, token.totalSupply());4 [. F# u( K) k6 T# I
    }8 v  j% a- N" p1 S" X
/**
' d$ R2 m  ~3 `        @dev 工具,基于一个总供应量,返回基于一个连接器代币来卖掉代币的期待返回- i1 N& R3 C" S
        @param _connectorToken  连接器代币协议地址9 R& X6 q% i6 _& x+ ?% u! Z# ?4 M
        @param _sellAmount      销售的数量
+ |, a% ?8 S8 ~$ n7 ^        @param _totalSupply     设置总供应量
2 u+ E4 [2 Z9 j' B, g1 e" |! [; v        @return 返回的数量! g& S9 t; e/ j" d2 ?$ |$ \
    */( g% l# c8 P: N! O9 ?
    function getSaleReturn(IERC20Token _connectorToken, uint256 _sellAmount, uint256 _totalSupply)
" `' G$ y' B# t5 ~0 z( ~/ {        private* U1 }0 U! X, p* U
        view
/ u# R" ~( W  Z) F        active
: a$ x+ q' |( e/ Z8 X2 y        validConnector(_connectorToken)
! |9 G9 f  [# w- p; d* M+ U7 Z: W4 j        greaterThanZero(_totalSupply): L0 H7 T5 h* y$ m
        returns (uint256)
5 F& g7 `* w' L+ }! w    {
0 g' b9 A, V6 V3 ?4 ]        Connector storage connector = connectors[_connectorToken];6 c: {8 r3 {. J8 Q1 m: [+ A$ R: [
        uint256 connectorBalance = getConnectorBalance(_connectorToken);
7 y0 w3 J2 o/ P3 D/ ?        uint256 amount = extensions.formula().calculateSaleReturn(_totalSupply, connectorBalance, connector.weight, _sellAmount);
. z0 G, a) @$ |- q% b2 u        // 从返回的数量中剪掉费用1 d, }5 G. J$ |5 v! N+ ~6 m
        uint256 feeAmount = getConversionFeeAmount(amount);- I$ C/ ]3 x) c  Y" s0 N6 G
        return safeSub(amount, feeAmount);# a( l- C4 L2 C6 H3 t
    }
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14