Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS智能合约的多索引表table

西门幻雪雪vj
111 0 0
建多索引表是一种为了在RAM快速访问的方法,主要用来来缓存状态和数据。多索引表支持创建、读取、更新和删除(CRUD)业务,区块链不行(它只支持创建和读取)。' N# D4 W( L: L3 v% u2 c0 \
    多索引表提供了快速访问数据存储接口,是一种存储智能合同中使用的数据的实用的方法。在区块链记录交易信息,你应该使用多索引表存储应用程序数据。
' ^7 W- X" Z  ^; f' d+ k    使用多索引表,因为他们支持为使用的数据建立多个索引,主索引必须是uint64_t类型和唯一的,但其他的索引,可以有重复的,你可以使用多达16个,类型可以是uint64_t,uint128_t,uint256_t,doubleorlongdouble。' ^4 e  |9 k/ L) D3 J8 l+ I) s
    如果你想你需要使用一个字符串做索引,需要转换成一个整数型,将结果存储在随后索引的字段中。
2 m2 U$ N* a, c2 x( F    1.创建一个结构( g1 [. e6 t' F2 O) y5 p0 u; b
    创建一个可以存储在多索引表中的结构,并在要索引的字段上定义getter。
6 p5 R) m. Q) f# z  d2 d    请记住,这些getter中必须有一个命名为primary_key(),如果没有这个,编译器eosiocpp将产生一个错误…"itcan’tfindthefieldtouseastheprimarykey"即它找不到任何一个字段被作为主键。
/ Y" L4 r" H, m    如果你想要有一个以上的索引,(最多允许16个),然后为你想要索引的任何字段定义一个getter,这时这个名称就不那么重要了,因为你会把getter名称传递给typedef。
6 ~" c" |6 C: z- R8 k: I    ///@abitable
7 p# M" T! |+ o- G9 W    structmystruct- b' m+ l# m# y
    {
4 I6 D' T% U( X9 P" E    uint64_tkey;
, p! n9 K6 u: m3 T    uint64_tsecondid;* K" q1 {8 m( l# q2 _  e
    std::stringname;0 Z! V5 E' r" s2 f% U; s
    std::stringaccount;* n/ ?) H' `* f4 c! i& E0 O
    uint64_tprimary_key()const{returnkey;}//getterforprimarykey3 ~" i/ m3 e: R( ]+ N9 |
    uint64_tby_id()const{returnsecondid;}//getterforadditionalkey( x6 a# t1 P3 u, k* o, X' e8 `
    };
  _( H$ N) v- s2 L, S& d& e    这里还要注意两件事:, h) D+ o5 y: ^$ y
    1.注释:
$ t  q! S+ e; k5 z! n% v, }    ///@abitable
" x( j( [2 j! y7 L7 g# _; l    编译器需要使用eosiocpp来识别要通过ABI公开该表并使其在智能合约之外可见。2 V* N/ _  Z* h+ R) ^
    2.结构名称少于12个字符,而且所有的字符都要小写字母。
/ Y8 V) M; O" z% K2 F    2.多索引表和定义索引
: O6 {2 p; o% }* t  P* r    定义多索引表将使用mystruct,告诉它要索引什么,以及如何获取正在索引的数据。主键将自动创建的,所以使用struct后,如果我想要一个只有一个主键的多索引表,我可以定义它为:
0 _6 I; p5 {  W$ |  M: `    typedefeosio::multi_indexdatastore;
) S, g5 \; K3 M, k    这定义了多个索引通过表名N(mystruct)和结构名mystruct。N(mystruct)会对结构名编译转换到uint64_t,使用uint64_t来标识属于多索引表的数据。' v# R) [& [. C9 L2 W7 q6 j
    若要添加附加索引或辅助索引,则使用indexed_by模板作为参数,因此定义变为:
9 z6 }  d6 q" D9 Q    typedefeosio::multi_index>>datastore;
3 M3 s+ B. i5 A) h; r5 `    注意:# ~( L7 n( [# P- u" J0 a8 G$ a
    indexed_by>1 c8 c$ A1 B, B3 T" |4 R, T
    参数:6 G( I# B/ B0 `, I* \9 v
    字段的名称转换为整数,N(secondid)' V) `$ ]0 t: n* T) n
    一个用户定义的密钥调用接口,const_mem_fun9 z+ v, J3 k, c5 y+ y# J+ T' ?
    来看看有三个索引的情况。
( W& I6 {. {' O; |; |    ///@abitable2 T: U( g( F- b6 o
    structmystruct
( F0 ^3 s9 N5 [$ {5 s7 \- E    {
0 o. u$ o9 r. ]' C' B2 R    uint64_tkey;
( N5 F6 E% M; L  ]# I    uint64_tsecondid;  d2 S! ?1 W/ v7 r" w
    uint64_tanotherid;- J1 K% ?. H5 x- f2 ?  W9 K4 D
    std::stringname;- G( m, }, ]2 d3 L
    std::stringaccount;
2 w: I( s. \# F* D: y    uint64_tprimary_key()const{returnkey;}
3 M7 _5 P0 w" [+ z2 K# l+ E2 l    uint64_tby_id()const{returnsecondid;}, J* x4 k9 o! @! @% U& n
    uint64_tby_anotherid()const{returnanotherid;}
' @. Z2 p+ ]: x8 Y, s; f    };/ J# h! M$ E! t1 n. p7 l
    typedefeosio::multi_index>,indexed_by>>datastore;
! X1 P  `" ~5 X3 k" F& {    更多的就不列了。
3 W( X" |9 G8 k8 N- o# w% K    这里要注意的一个重要事项是,结构名与表名的匹配,并且将出现在ABI文件中的名称遵循规则(12个字符,所有都是小写的字母)。如果它们没有遵循这个规则,则表不会通过ABI可见(当然可以通过编辑ABI文件来绕过这一点)。6 ~, C  \# |4 A. N  d
    3.创建定义类型的局部变量. j* S$ q( |2 R
    //localinstancesofthemultiindexes! H+ I7 N4 m' E: t5 f1 y# C% Y
    pollstable_polls;3 A3 U1 F4 f( }# a
    votes_votes;. z; D* k8 L( X9 s$ ^, |& D* U/ m
    现在我已经定义了一个带有两个索引的多索引表,我可以在我的智能合约中使用它。7 b7 g# o4 e) C0 B4 \$ t
    如下是一个智能合约使用两个索引的多索引表的例子。在这里你可以看到如何遍历表,如何在同一合约中使用两个表,我们未来将增加额外的教程,利用多索引表。
  t/ `! x# L" ?& h    #include3 u. _% W; z" E( P
    usingnamespaceeosio;
* v* U3 O1 c& B: h+ G5 C    classyouvote:publiccontract{
' W+ z% L; O, H3 l    public:0 m& r* o1 z# {; Z, c; ~# C
    youvote(account_names):contract(s),_polls(s,s),_votes(s,s)
4 h4 P9 k  _( S7 v+ r% O* W    {}
+ [. F* _# K$ x4 ~5 x/ H' h7 E1 L    //publicmethodsexposedviatheABI& c- k) I( ]* L' b8 [
    //onpollsTable
) }' ^3 i/ g9 j$ I    ///@abiaction
1 G. H% E8 ^4 E    voidversion()
3 J8 C& W. K4 _' a2 J$ b    {; E; ~3 f2 S7 A- N/ C; @
    print("YouVoteversion0.01");8 X$ r# X5 H; E" ]. d0 u
    };0 x- k) _4 D6 ^
    ///@abiaction) w0 }5 s7 V7 D( M  v+ V
    voidaddpoll(account_names,std::stringpollName)- v5 e+ ]5 L* r; U. i0 O3 I
    {$ r5 ?4 g, d" \" F) H/ X
    //require_auth(s);! ~" H' N/ S; q$ ?
    print("Addpoll",pollName);
6 m1 Q# o3 i/ F1 d    //updatethetabletoincludeanewpoll: i9 ~* G5 `' g
    _polls.emplace(get_self(),[&](auto&p)
% W' q1 S2 y/ a& b" R8 K# y    {
& C* @- J/ T9 U  M2 ?' u    p.key=_polls.available_primary_key();
! \0 }# M' s6 X4 z( c' w    p.pollId=_polls.available_primary_key();4 Q+ [5 V. s8 r5 q; S( A; x2 l4 g
    p.pollName=pollName;" T, b* |. ?4 V. m" g, g* o
    p.pollStatus=0;1 ~- C- I: R( C9 ?; S/ s
    p.option="";
( a! T0 L9 \- W. i1 n6 k    p.count=0;0 s( L  `7 I5 o2 e
    });8 u9 B% Y5 f, A6 ?5 S
    };
1 W- \) R) @' Z+ l    ///@abiaction
% u. Q- K4 W( q" L    voidrmpoll(account_names,std::stringpollName)2 f7 F# p# j' C$ L! G4 R0 V
    {
# k3 V5 l- J- j" _8 o    //require_auth(s);) R. }$ Y1 |- q, L. {0 M: ?
    print("Removepoll",pollName);
9 a3 u  P: g$ @    std::vectorkeysForDeletion;
: b# C8 C. e: w) ~    //finditemswhichareforthenamedpoll
% L! Z+ L1 Q! o  X% n$ ~6 H, {    for(auto&item:_polls)
+ M' q! Y4 q' Z( P4 u; R% m    {7 S. ^7 v9 n2 r$ C# M% X
    if(item.pollName==pollName)& g$ f8 j7 Y+ O% K" C7 z0 K. ^
    {' o* |" d% A6 H; G; W/ ^
    keysForDeletion.push_back(item.key);' P. n6 c  H7 l% {. I' e
    }
. K1 S0 d) ]% S% Z, o+ V- [    }  a4 S7 O- ?( X8 J
    //nowdeleteeachitemforthatpoll# A/ S$ @" `' H* G8 G
    for(uint64_tkey:keysForDeletion)
: Z$ d- ]& R# r2 g7 r" Q( m    {
7 }. Z9 e8 o8 T; W( H' n2 e( }    print("removefrom_polls",key);0 }- X) o9 Q( d/ f4 H* J
    autoitr=_polls.find(key);
& t4 n* ?9 h/ e  E/ c) R5 d* W    if(itr!=_polls.end())
/ e' B4 Y3 a. }4 z' q    {/ k& G- |/ q! M  T5 D( Y3 L+ A
    _polls.erase(itr);
. [$ Z8 T* m5 L3 {    }! A* W- @, @. y3 [  b
    }
- G7 F( b& U* k" a8 y' x7 g8 K    //addremovevotes...don'tneedittheactionsarepermanentlystoredontheblockchain7 D' `& k; `5 C5 y8 G; r
    std::vectorkeysForDeletionFromVotes;' n( J( B# |, X9 \8 q8 Z
    //finditemswhichareforthenamedpoll) A( r* e9 o' s) d) c3 m) A
    for(auto&item:_votes)# o7 @2 V3 m) X7 C( L
    {
+ {; y  o6 Z+ l( b' t    if(item.pollName==pollName)  s4 {) R) b; p
    {
8 m- W& B1 z. g7 O, p, t    keysForDeletionFromVotes.push_back(item.key);4 W+ W6 h, N, d8 f6 k  j$ U
    }4 d, Q5 l7 P/ t% t
    }" J: r. j( W0 q" D' U* a3 ]
    //nowdeleteeachitemforthatpoll
0 }& D5 H7 d0 X& J$ |% \    for(uint64_tkey:keysForDeletionFromVotes)
( w+ n  i; v4 `0 o& O  J    {% }+ n2 s' s) W( ~
    print("removefrom_votes",key);
% f, ~- ?, W5 p) x* z) m2 v    autoitr=_votes.find(key);3 _% }- s( O$ ^! M% b
    if(itr!=_votes.end())
. X) b" J* U; j, }    {+ g: B, u. I! j0 n) f
    _votes.erase(itr);
, y: ?' i: c( v. m$ f) u; l    }$ a% }4 I# t" G4 G
    }
; S* W6 e, n+ b) f) c7 K0 [    };
! M# r2 r% C4 j4 B4 m: D9 s5 r    ///@abiaction
: ^/ I$ h" v; i0 i( k; n$ b    voidstatus(std::stringpollName)
- N% l2 n# o7 {% X    {( K: U: t! l9 B2 B1 I2 k' h0 k  v
    print("Changepollstatus",pollName);
3 ]7 R5 Z7 N/ x8 ]1 ?' b5 @3 w3 u6 L    std::vectorkeysForModify;; c- w! E+ _6 T
    //finditemswhichareforthenamedpoll
8 g4 S0 J8 e7 p/ g7 y    for(auto&item:_polls)
8 l" [3 M  }' z! k' m    {. x% L; U/ V# _+ Y- k
    if(item.pollName==pollName)" K: J* \& x7 ?& o
    {4 q9 }# ?: u0 E
    keysForModify.push_back(item.key);6 t5 k. T6 z7 ~% w( L
    }+ a$ w/ u! X- s( t# X( S
    }# o0 W0 w5 b0 K1 Z, E
    //nowgeteachitemandmodifythestatus; K& p! k5 s4 ^" k- p
    for(uint64_tkey:keysForModify)
9 _; v: O" J& P    {1 f7 x9 X7 M& g
    print("modify_pollsstatus",key);
- j8 N* `% _7 F; \9 i% i    autoitr=_polls.find(key);
# x% k6 O. {" @# y  }0 ]: k    if(itr!=_polls.end())0 n$ p5 p: |0 p" w
    {
: e) f1 f& p6 Q# K    _polls.modify(itr,get_self(),[&](auto&p)
1 W9 L! b- w* }( v+ Z    {, d1 v+ O# f) m7 N( u
    p.pollStatus=p.pollStatus+1;
: y( u2 m( h  \/ N6 {. X    });
) L2 r& i4 }$ f2 ]    }
1 `4 |7 A. O2 v" M4 X    }
; ^2 F1 [  z! X* k2 ~    };
, n1 [4 T' T0 {; n    ///@abiaction" Z1 g5 L& O5 N7 F- {
    voidstatusreset(std::stringpollName)
+ l. a/ `, k# l, U* @2 W    {
( h8 J6 L6 y& u7 R" X6 f5 u. \    print("Resetpollstatus",pollName);
$ ~5 F, O* Y+ y% ~( x$ |# ~    std::vectorkeysForModify;
: s+ o, X: ?+ o0 Z% {6 _    //findallpollitems" Z4 V' x: I9 a
    for(auto&item:_polls)- h( b  s0 G( G. V; A
    {
7 l' ~/ V  X- O& g5 Y" x    if(item.pollName==pollName): p/ D1 Q# E" c# I+ I6 F8 T# R% h
    {/ I+ _, S4 v9 ^# s" G1 b$ _8 X
    keysForModify.push_back(item.key);: i3 j6 M0 }: T* M1 H0 f8 l
    }
* F" b, R- v' z/ J+ N3 Z% Y0 N( z+ k5 I    }9 h- \1 m! g* f$ E- s
    //updatethestatusineachpollitem$ H- N4 @6 p: `2 o" E
    for(uint64_tkey:keysForModify)
8 M/ t0 n0 o) y/ \    {5 z! D3 J, q6 o- r' p
    print("modify_pollsstatus",key);
1 t9 {- M: l, T3 R- n9 q! V    autoitr=_polls.find(key);
/ w, s: M& _$ J/ }- V, V    if(itr!=_polls.end())( P7 ?8 Z* d  \% J$ [4 h& v
    {
; W$ w2 u, p+ X1 x3 y    _polls.modify(itr,get_self(),[&](auto&p)
$ s- I( U" C0 U: W# S, Y$ P    {* G% ?# d/ M& `- ~1 o; w) G
    p.pollStatus=0;
! D6 K4 _/ G: t9 N    });
6 w9 C7 G" O, d) `9 ]    }3 G  Q% \6 ]% i* }( I
    }
+ m' v2 N- E2 F0 @' E    };
' D% U" t- C0 r2 {3 L    ///@abiaction
! t* k1 w# m1 V3 z    voidaddpollopt(std::stringpollName,std::stringoption)* ~$ r% B* _2 d3 b* a0 J) A
    {
+ F( P7 l1 t2 q( q    print("Addpolloption",pollName,"option",option);0 d' k/ {7 j: i! w; G
    //findthepollId,from_polls,usethistoupdatethe_pollswithanewoption
# D* B6 s' H% D1 a2 O7 {    for(auto&item:_polls)
9 u6 u: [: b4 E8 f" q" v: V3 P    {2 J  Q' J2 U, M& e7 k( g9 t6 Y
    if(item.pollName==pollName)
+ }6 Q; `4 o- q, |  k    {
  D$ ^6 e6 v% d# L" S, ?    //canonlyaddifthepollisnotstartedorfinished
3 i& D4 M8 V0 a6 z2 w& C2 m    if(item.pollStatus==0)6 g0 D$ I6 M. b/ ~
    {' I! N& T0 `# c) p6 i0 `. |9 Z
    _polls.emplace(get_self(),[&](auto&p)/ [) `" k. w8 B' n! `9 a! |
    {* {( X% R" C8 g! n
    p.key=_polls.available_primary_key();
  S+ Y+ p3 ~4 v. a6 q$ u9 M    p.pollId=item.pollId;5 i7 j4 U, L" H" G+ H* _( w. H: _
    p.pollName=item.pollName;) t9 i5 ]2 I- A( P
    p.pollStatus=0;
% \) _: T3 o. m7 I6 p/ V* n    p.option=option;
; N# ^2 E# \0 i2 m  V3 q    p.count=0;
/ Z' L" v- r- F% q8 p% g( W: H" L    });8 B4 t; v( _  H5 _2 R& x5 C
    }
; @% p1 N) `* f" b; Z    else  U( y0 `( f) R  l9 D
    {
7 b' W9 z1 u1 K5 b' a4 A    print("Cannotaddpolloption",pollName,"option",option,"Pollhasstartedorisfinished.");3 K1 c& C2 N- g% J! v
    }: i+ l  F) @7 Q/ _
    break;//soyouonlyadditonce
3 |: `5 a$ H- G5 |; a$ r, X    }, {" m- `( F" V- f
    }
4 C1 u4 C' F, W    };
6 S- y' \% A& d! l6 ^) o    ///@abiaction2 C! L, M  w7 C0 p0 D( Y
    voidrmpollopt(std::stringpollName,std::stringoption), l5 _( e5 [: d3 T! v  ]# R
    {' y4 J2 Y3 \2 X* I
    print("Removepolloption",pollName,"option",option);
/ \5 ]2 [* j8 w) x    std::vectorkeysForDeletion;
$ s# n% W3 l, ^9 d& j    //findandremovethenamedpoll
+ e0 J- f& v/ b7 L7 r2 t& l4 ?2 f    for(auto&item:_polls)
0 H5 H% O3 Z1 D" y3 J* {% N2 z    {4 o6 u* ]3 R$ X) F
    if(item.pollName==pollName)
! K) w3 |, n6 o( [$ W    {  L7 R" p" N# A( B9 ?
    keysForDeletion.push_back(item.key);
! D% G  o( a, k) I    }# |# ~$ m2 B& W. B8 y
    }, ^) |% `5 p& V5 W# e
    for(uint64_tkey:keysForDeletion)) w7 `) r+ ?& |0 _1 w) ^% c
    {
2 I/ P6 V+ T* T3 T0 \    print("removefrom_polls",key);
3 e. b, G0 x/ j. b  w    autoitr=_polls.find(key);. u  M0 @1 [( I  s% Y/ O
    if(itr!=_polls.end()). v& u. U. k' B7 Z/ y* r
    {+ m( b, l3 y$ K6 {
    if(itr->option==option)- L1 [  l1 W' h+ u$ w' }8 W
    {  ]) p# G6 J  r0 g
    _polls.erase(itr);
) Y6 p& }9 L8 t5 b  ~    }
8 f. x$ D+ F1 S2 n& U    }
% T( U4 k0 E4 W2 B1 ~    }
' Q) p. u' ~' j6 t    };
' ?- d4 f+ i) j: c7 N/ v    ///@abiaction. }3 Z: s3 x) i. ]- K. e
    voidvote(std::stringpollName,std::stringoption,std::stringaccountName)
! S9 b9 ]0 V, C; H4 ^9 u- q    {, e/ j# C9 a9 c) W  r9 I3 [7 }
    print("votefor",option,"inpoll",pollName,"by",accountName);2 @1 n2 P- `! X. Q7 i
    //isthepollopen
7 ?" B/ T% ]$ u# g. ]$ V    for(auto&item:_polls)
: G+ q* X- j  H$ E- r4 q6 Q9 ^    {
: V; t3 @1 D3 x# }& h    if(item.pollName==pollName)
2 ]5 M8 \4 ]' A    {# n/ Y; a- Q  x" B' s
    if(item.pollStatus!=1)
' s# R) L) u+ M3 \    {
( Q( T7 b9 }. p' e) l, K" {    print("Poll",pollName,"isnotopen");4 H  q- [. l: |. p- w0 c  B& q
    return;
6 `' l* e( e  i& j    }
+ l! h6 E1 t) H' e. \( V' F! G0 E    break;//onlyneedtocheckstatusonce- ^, D9 z- y4 Z' r
    }
3 Y& D0 L& i. R6 p0 b' t8 `. Y    }
  `* a/ m2 w- p    //hasaccountnamealreadyvoted?
$ O+ l/ R! l: f    for(auto&vote:_votes)  K+ W, `6 D4 P; p7 o
    {
8 ^- [$ s" t2 D    if(vote.pollName==pollName&&vote.account==accountName)- W7 ~; h0 E- R9 ~7 n7 t
    {
* K2 K  T- t( O: _    print(accountName,"hasalreadyvotedinpoll",pollName);
  F# L# H( _, j" C$ e* v    //eosio_assert(true,"AlreadyVoted");  @' x2 x6 x+ c8 I
    return;+ n, `+ @( D( F% S
    }2 B7 b& Y9 s! b. r1 Y8 k
    }
8 a( W( h5 M5 M; j% E% A    uint64_tpollId=99999;//getthepollIdforthe_votestable
* ~% D" m: d: D8 A6 R# V( Q% @    //findthepollandtheoptionandincrementthecount8 v& y# A4 B8 G
    for(auto&item:_polls)6 h' ]1 \/ M' L! a/ L4 N4 [% Y
    {" p+ u) y; X; x0 S
    if(item.pollName==pollName&&item.option==option)
% g, R) I$ y$ T3 e$ R* k% h. |    {
7 n6 u( R( e8 T6 ~$ b7 x1 A8 ~) L  ]    pollId=item.pollId;//forrecordingvoteinthispoll( `4 a- l% A5 j0 z$ f6 p5 {
    _polls.modify(item,get_self(),[&](auto&p). O# w9 `; B+ j5 t+ p* t* c9 Y0 Y
    {
1 Y* j; X- d! N$ S; s    p.count=p.count+1;6 a6 h2 p( \6 r7 a! Y. q
    });, Q) Z0 c/ L; F/ B# O" {$ D- p
    }
2 Q" n7 V2 J, w, {7 K1 S1 l  t( t    }) ]* J& h1 K! Q& H9 S9 T
    //recordthataccountNamehasvoted8 c# i8 q7 x5 {. @/ N" |& k  d
    _votes.emplace(get_self(),[&](auto&pv)
2 ^6 V: Q# V* C! K# s    {
* y, X- G) Z- n4 r9 @( q. X    pv.key=_votes.available_primary_key();" S# a3 O$ c7 X4 {9 L3 U
    pv.pollId=pollId;
" s8 P4 L( Q) }& t1 `    pv.pollName=pollName;
" I2 p" G, I4 H0 J3 U( f    pv.account=accountName;
1 r" l8 e- C: [0 m% ?1 f4 |    });" V0 K1 B! `' s7 i: L: _
    };+ `/ C! I& s7 q' x
    private:7 x" P& Z% p6 _5 c8 B6 g* n( M" K
    //createthemultiindextablestostorethedata+ N3 t& z5 e9 U3 H  e2 h
    ///@abitable! |( L6 n  m0 |5 j( W1 v5 n
    structpoll
& g& b) }& W# k$ G0 R* b    {
) ]  f5 h. i# x" `2 Q    uint64_tkey;//primarykey% h, }5 H* z4 ]3 {0 \
    uint64_tpollId;//secondkey,non-unique,thistablewillhaveduprowsforeachpollbecauseofoption
4 G) Z9 u( z6 b+ e: X7 z    std::stringpollName;//nameofpoll
* E4 c+ _3 V; A& `    uint8_tpollStatus=0;//stauswhere0=closed,1=open,2=finished
6 ~6 s1 T' n2 L/ n; n: [% p8 Z( B    std::stringoption;//theitemyoucanvotefor
: K. O3 |; s: `& ~3 I    uint32_tcount=0;//thenumberofvotesforeachitme--thistobepulledouttosepartetable.3 X0 \9 u3 ^& ^: u# k3 z  T8 J  Q! _
    uint64_tprimary_key()const{returnkey;}
' Y( ?2 h4 F/ U  Y* K) S    uint64_tby_pollId()const{returnpollId;}& I. R( V7 S% O3 F# M0 _
    };
% y2 u6 }4 H, i8 d0 @7 B( A1 W; o    typedefeosio::multi_index>>pollstable;) @. W9 B% n7 P" K6 q4 _
    ///@abitable
8 J# x& o1 P$ h0 N+ Z& R    structpollvotes
& \) V! H/ ]( J  d5 k' C% A; q6 a    {$ e) G, D0 k, Q
    uint64_tkey;
/ I& T5 A# \( w# b# i1 {  e    uint64_tpollId;8 ~5 b, G) ?0 d6 d0 o
    std::stringpollName;//nameofpoll4 ~/ i1 |" Z- ?: g0 X
    std::stringaccount;//thisaccounthasvoted,usethistomakesurenoonevotes>1
8 @+ O5 P: `* y, [+ O    uint64_tprimary_key()const{returnkey;}
+ q7 d! j$ Q) h' \. Y5 K' N    uint64_tby_pollId()const{returnpollId;}
- z0 i5 H: W6 X5 K& T" L    };2 L- }! t8 W. v5 i/ v/ |, U, b
    typedefeosio::multi_index>>votes;
3 Z, @1 p4 r$ ]/ p# V* ]5 R6 y    //localinstancesofthemultiindexes) M, d$ H) [% D1 F, U
    pollstable_polls;
$ G" B, x5 _3 k+ |    votes_votes;
& b$ c+ M8 J3 H  \    };
& d& J0 e# w/ Y    EOSIO_ABI(youvote,(version)(addpoll)(rmpoll)(status)(statusreset)(addpollopt)(rmpollopt)(vote))
, U" W  b& R: _. X1 ^    注意EOSIO_ABI调用,它通过ABI公开函数,重要的是函数名与ABI函数名规则一定要匹配。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

西门幻雪雪vj 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10