Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

EOS智能合约的多索引表table

西门幻雪雪vj
113 0 0
建多索引表是一种为了在RAM快速访问的方法,主要用来来缓存状态和数据。多索引表支持创建、读取、更新和删除(CRUD)业务,区块链不行(它只支持创建和读取)。, k+ D# Q4 \8 |
    多索引表提供了快速访问数据存储接口,是一种存储智能合同中使用的数据的实用的方法。在区块链记录交易信息,你应该使用多索引表存储应用程序数据。. Q9 b3 z& P) L( P! W# f
    使用多索引表,因为他们支持为使用的数据建立多个索引,主索引必须是uint64_t类型和唯一的,但其他的索引,可以有重复的,你可以使用多达16个,类型可以是uint64_t,uint128_t,uint256_t,doubleorlongdouble。2 K" V2 z1 S5 R2 v% _. U2 E5 O- Y
    如果你想你需要使用一个字符串做索引,需要转换成一个整数型,将结果存储在随后索引的字段中。
) M/ Z2 Q  c7 |) Y+ o( o    1.创建一个结构
; Z# Y. t1 s3 t" {    创建一个可以存储在多索引表中的结构,并在要索引的字段上定义getter。
& F( T- u- h" a: U, [$ ~7 ?* d    请记住,这些getter中必须有一个命名为primary_key(),如果没有这个,编译器eosiocpp将产生一个错误…"itcan’tfindthefieldtouseastheprimarykey"即它找不到任何一个字段被作为主键。
+ p( ~; x: J, T: e8 a' t    如果你想要有一个以上的索引,(最多允许16个),然后为你想要索引的任何字段定义一个getter,这时这个名称就不那么重要了,因为你会把getter名称传递给typedef。
1 {+ K1 c; Y7 X# ~+ C    ///@abitable: a$ U3 P' D7 a1 S" R- P! l
    structmystruct: V& H1 X1 F; \3 M  O$ L$ h9 y
    {7 D' D! e0 I* W8 e# X
    uint64_tkey;! n  Z; E8 C1 S
    uint64_tsecondid;
! R) P: ^. h; v9 g    std::stringname;
, h  G8 @! `" F5 U1 J    std::stringaccount;
( N- z2 K! |& T  ]$ I    uint64_tprimary_key()const{returnkey;}//getterforprimarykey+ v+ P& }( x3 G
    uint64_tby_id()const{returnsecondid;}//getterforadditionalkey+ m0 Q# u" F! w5 U8 u
    };7 f7 I5 G# |. S3 n' w
    这里还要注意两件事:/ H: Q! H* L. z
    1.注释:$ {. K0 u" Y, }5 y
    ///@abitable' f/ o  `8 W$ V2 w0 b
    编译器需要使用eosiocpp来识别要通过ABI公开该表并使其在智能合约之外可见。0 D) q/ Y; r6 |8 l5 f
    2.结构名称少于12个字符,而且所有的字符都要小写字母。
8 r2 s) B# B3 N5 A0 V    2.多索引表和定义索引9 U. L; @4 V7 v8 n
    定义多索引表将使用mystruct,告诉它要索引什么,以及如何获取正在索引的数据。主键将自动创建的,所以使用struct后,如果我想要一个只有一个主键的多索引表,我可以定义它为:
8 a0 L4 S5 k% q  _) ^    typedefeosio::multi_indexdatastore;
* ?$ M8 ?6 k' d( o# E0 p& A/ @    这定义了多个索引通过表名N(mystruct)和结构名mystruct。N(mystruct)会对结构名编译转换到uint64_t,使用uint64_t来标识属于多索引表的数据。. w2 {& b9 x; a0 L' b/ P7 B
    若要添加附加索引或辅助索引,则使用indexed_by模板作为参数,因此定义变为:
0 W8 S$ `; Y' f" b3 l, Q6 N    typedefeosio::multi_index>>datastore;6 ?. C" y+ ]! i
    注意:- i1 j# R- n/ R# N) M
    indexed_by>
2 U2 B4 C' H' q$ V9 e. O; _    参数:* i2 Z7 v' w: j% B/ O
    字段的名称转换为整数,N(secondid)- F$ X6 r& k$ q
    一个用户定义的密钥调用接口,const_mem_fun
5 h- z+ L2 K) G& `, x    来看看有三个索引的情况。, u8 ~- q& L& A* ]  R( u
    ///@abitable. X! f4 A% x0 S& n! \! S
    structmystruct
* I# k3 o/ m5 g9 h- e, f. D    {3 Y% h; |& J) i/ d1 L) K7 F6 u7 H
    uint64_tkey;
2 n6 f, ~; Q; g# E8 R    uint64_tsecondid;
8 ^. o) p' _6 t9 L    uint64_tanotherid;3 p9 j0 c4 i5 |1 ~3 {) N
    std::stringname;
! o  O6 X  v# Q+ S! L0 A    std::stringaccount;
& s2 ?  ^7 X) j+ G9 L    uint64_tprimary_key()const{returnkey;}, e- e- v0 R) {
    uint64_tby_id()const{returnsecondid;}+ \( y( p( n0 U
    uint64_tby_anotherid()const{returnanotherid;}( G. ?3 a4 K' ?0 ~0 j
    };4 F* R& M1 I2 S: [6 c+ K
    typedefeosio::multi_index>,indexed_by>>datastore;
* ]% H  H, Y5 K+ R& `, F6 b    更多的就不列了。
( y5 }& ?2 `, c: |. I' u. G2 \7 M    这里要注意的一个重要事项是,结构名与表名的匹配,并且将出现在ABI文件中的名称遵循规则(12个字符,所有都是小写的字母)。如果它们没有遵循这个规则,则表不会通过ABI可见(当然可以通过编辑ABI文件来绕过这一点)。
" c: D3 E7 f* l1 ~9 \    3.创建定义类型的局部变量
2 |. U# A& m! K" m9 Z2 N; v9 n  w    //localinstancesofthemultiindexes. f0 H+ T4 K. j' V6 s( s2 V1 u
    pollstable_polls;
  w( \5 B3 a6 ]1 P    votes_votes;0 t. P5 O2 T/ @
    现在我已经定义了一个带有两个索引的多索引表,我可以在我的智能合约中使用它。
7 Z  q0 F, N# k/ g( \/ D9 f    如下是一个智能合约使用两个索引的多索引表的例子。在这里你可以看到如何遍历表,如何在同一合约中使用两个表,我们未来将增加额外的教程,利用多索引表。
1 ^, @7 j$ S7 I: q1 M- ]( u    #include
2 d/ V# b) }) N7 ^8 A/ v, \/ j    usingnamespaceeosio;# E7 K+ ?+ n9 f0 y: l
    classyouvote:publiccontract{
' t' v" e) T$ X) r6 S  e    public:' w% J. ^2 I$ X. n+ P% c  k& C
    youvote(account_names):contract(s),_polls(s,s),_votes(s,s)7 C9 b* ~- O9 ^4 Q  a
    {}/ x- m& c9 u: ?) _
    //publicmethodsexposedviatheABI
& c8 W8 ^- w# a" B8 [' G) _    //onpollsTable% t2 _" c$ j: R
    ///@abiaction5 y, L' B4 @. T
    voidversion()8 c" N- N8 g2 V* T; \( `) \9 k8 H
    {* {8 l5 |+ Y* V' P0 I
    print("YouVoteversion0.01");
0 o5 u+ G! C3 P6 {    };& C; Z5 J. |1 d. t: c, V" F" w# Y
    ///@abiaction' [" n2 y& |. \
    voidaddpoll(account_names,std::stringpollName). W! |7 b; @6 z$ x" x4 \( K
    {
9 l! {/ y9 o1 Q1 c) ~5 O    //require_auth(s);9 b. q% B% H: A- |
    print("Addpoll",pollName);
! b# S( D* p5 O1 @; e1 Q# U    //updatethetabletoincludeanewpoll
' v2 i: |2 z2 T7 r    _polls.emplace(get_self(),[&](auto&p)
$ `8 L  L( F0 d. H, |8 W    {
+ u& \- A8 x' t# ~/ L2 t    p.key=_polls.available_primary_key();  m5 v, N0 J* r. f. Z2 y8 f& F
    p.pollId=_polls.available_primary_key();
9 C& x2 d" Z3 V" Q' `    p.pollName=pollName;
& g. c4 M0 T0 q8 q6 ~2 o' G+ {- `3 y5 Y    p.pollStatus=0;
; B4 H) u5 r) @) i6 e    p.option="";
4 t( x( L4 V# G( K1 t    p.count=0;: }- V1 k8 G( x. a  }( [
    });# Y/ g) d" I+ {: R, j  B' [: Z
    };4 Q* o4 s. c7 W( e  x" h
    ///@abiaction0 _- @) K& y0 _8 F
    voidrmpoll(account_names,std::stringpollName)' L: T/ o; o; v9 O1 \  S
    {
  S. Z  y* u" k: M' ]& ~    //require_auth(s);
+ Y" W5 {5 Z( \6 |6 Q! q' o# z$ o, M    print("Removepoll",pollName);$ D2 Q" \4 d" d# l
    std::vectorkeysForDeletion;
$ b/ `$ F) L1 l1 k2 ?    //finditemswhichareforthenamedpoll
& {& x, ^3 x) S8 P9 Z    for(auto&item:_polls)
: ?8 `1 P4 ~+ |' |) o    {
( l3 }# X$ j. }- t: B    if(item.pollName==pollName)
: h6 H# r2 X; L2 @    {
: _" [5 |5 B. N- d2 T    keysForDeletion.push_back(item.key);
1 s, x! A% A2 J( C' b3 N% x    }
  {- y; }* |* x  u5 t# X6 W    }! c% x' M/ b& ?
    //nowdeleteeachitemforthatpoll
% h* a+ P( L1 Q    for(uint64_tkey:keysForDeletion)* c1 h! P6 H4 G" J' n7 H4 g9 C
    {
4 O3 V( s! K8 ^/ v( K5 X    print("removefrom_polls",key);9 ?! ]* n1 X# n. {
    autoitr=_polls.find(key);
$ ~! ?* t% v# c4 I    if(itr!=_polls.end())
4 E/ E# q# X7 d* u% _) ]    {& L2 n* Q" ?* |- O
    _polls.erase(itr);
' n+ G7 }6 s& _9 I    }
! P$ t1 S& M" N) k2 `    }9 G. T( C' {8 H5 M% c! b3 p
    //addremovevotes...don'tneedittheactionsarepermanentlystoredontheblockchain$ F0 q# O: w% ]3 x  U. `
    std::vectorkeysForDeletionFromVotes;' `' G* q; N5 I
    //finditemswhichareforthenamedpoll
6 B8 ]" h# r- B: Z    for(auto&item:_votes)
, r9 F5 t8 _+ g! K' }# V    {
+ ?! ]. {7 |1 a- [    if(item.pollName==pollName)- E, ~. O$ s, X1 ^8 N
    {( [5 K  K6 D! [! H; c
    keysForDeletionFromVotes.push_back(item.key);' N* B( U6 k. ?1 J) D3 y
    }1 W; j* \8 z4 F/ b0 Q. A
    }
# Q. A+ L$ M) h- C8 Q( L    //nowdeleteeachitemforthatpoll
) N5 ]9 N5 a: T/ a; r2 O; C    for(uint64_tkey:keysForDeletionFromVotes)
5 K1 q$ w+ x  H& t. N    {
4 {7 q  e/ G4 f% z    print("removefrom_votes",key);) A. v( A/ C, j8 S& r! o
    autoitr=_votes.find(key);
+ Q8 U2 \6 e4 {0 S3 ^0 e8 c3 n+ u    if(itr!=_votes.end())
) z4 y+ [. }. {/ I7 G3 {0 S& l    {0 P' e' d2 r, F% p9 S3 k
    _votes.erase(itr);
: J$ v$ d9 V8 y$ z0 R8 L) Q8 T$ S    }2 M8 A) l7 [; V8 B! r
    }5 J7 w* K, j0 w3 K4 k" v; c
    };
+ f0 s( \- \- X- R/ _  c6 N, u    ///@abiaction; m. s- U& B$ `8 P/ O: K; a: B
    voidstatus(std::stringpollName)6 H( o7 F# e# q( x8 W
    {) r$ E3 P+ P1 r& o  z8 P
    print("Changepollstatus",pollName);# a+ k0 B* z4 w- l1 L& [* ?
    std::vectorkeysForModify;
% |5 S3 d* f: {6 s  V! k    //finditemswhichareforthenamedpoll
# i/ Q/ h9 v3 N8 J0 b/ v6 e    for(auto&item:_polls)& n( D6 q- ^! L9 H! \
    {4 d# K. v) w9 J% ~7 j
    if(item.pollName==pollName)0 D" Y8 g9 X7 j5 N* A* V  X
    {2 h9 y- r/ P; A( L  K0 x
    keysForModify.push_back(item.key);
. d  n( u$ v( o0 L3 c. Q    }
7 q# y! Z! d  q& H. C    }
9 F" e2 B! V0 Z& s6 J    //nowgeteachitemandmodifythestatus; j$ e* K; |  n$ M2 q9 f
    for(uint64_tkey:keysForModify)
, C5 j/ P( ]3 i. {) I- C2 P5 n8 y1 c    {! h: f3 g, I! I  }1 J
    print("modify_pollsstatus",key);/ D# W: Z4 }: v6 a+ {: s
    autoitr=_polls.find(key);$ c" u! r4 M) D  q
    if(itr!=_polls.end())
0 A8 E& \0 @1 M& j    {
3 }' W9 D( A" Q' n2 k    _polls.modify(itr,get_self(),[&](auto&p)4 ~: S' B2 h+ Q2 M8 r
    {
3 b$ y, i" \8 T, P# W6 x6 C    p.pollStatus=p.pollStatus+1;9 |$ g  _1 O2 g, J2 u& o$ R
    });
# J# F: j  m- W$ F. p: H    }7 C! @, X7 A; _
    }
2 G3 A" C- N: _- G, @% v* @2 T4 \    };  Z  o# x$ k& D' W
    ///@abiaction$ B% J3 J# m& O. m' ^
    voidstatusreset(std::stringpollName)* v$ q' R- Q. j2 _. \
    {
: f, `! @$ s% m& J    print("Resetpollstatus",pollName);1 E. q- \- k. i7 g/ ?+ h
    std::vectorkeysForModify;3 S) x& H$ U* D# u
    //findallpollitems: w4 s4 e" W, m
    for(auto&item:_polls)' M' z+ A% N7 }: A2 Y5 z
    {; J, F* T  A8 @) w; d
    if(item.pollName==pollName)
( Y2 r$ ~: E' i# D9 ]* V6 S    {
) `9 ]8 `4 Y! @% a9 h. C    keysForModify.push_back(item.key);- {; q+ I. m6 V' J0 M+ J2 ~* @
    }4 v% f/ x" P- |$ ^* Y+ x7 p/ R
    }
6 b% _; U  `% g% T  Y    //updatethestatusineachpollitem, x+ s) [6 P( k  M' v3 F& d6 ]! ~! U
    for(uint64_tkey:keysForModify)- A- |" T5 v/ c+ X7 e
    {, V* Z* ~/ f  c# C
    print("modify_pollsstatus",key);! _) M9 M0 t9 s
    autoitr=_polls.find(key);
9 a3 O/ H1 {9 [0 @: A    if(itr!=_polls.end())
8 s# M8 \: v9 r/ e. Y. r    {$ \1 A% \' Z0 U% D+ ~5 r2 g; u
    _polls.modify(itr,get_self(),[&](auto&p)! Q5 y' H& ?( F$ O( d
    {
0 B- G9 S! A: p) e    p.pollStatus=0;5 c' s* a6 m. b( r; z: B
    });9 o2 f6 b) y6 k! M% e' u) n( j
    }' b; e  Y& V. ?# i1 E% ~8 ]' P
    }
5 H- q6 y8 V0 c4 w1 Y    };
* @( j! U+ s) K    ///@abiaction) ]  ~9 k! N, p" @
    voidaddpollopt(std::stringpollName,std::stringoption)
2 k: x8 ^; \) C, R+ O; x2 |! |. t    {
3 w& p3 k* J1 I- y: q1 c1 o- W    print("Addpolloption",pollName,"option",option);5 T$ Z7 \* g2 m" |* U. F: I
    //findthepollId,from_polls,usethistoupdatethe_pollswithanewoption
7 h+ o$ u. y9 a" R: J8 V    for(auto&item:_polls)
3 A' P# ^. Y; P/ _    {& H+ P  g. ~' e4 K  h
    if(item.pollName==pollName)
* k0 O' ?- W; S    {: n# p* ?. ?1 d: h( o6 c  k
    //canonlyaddifthepollisnotstartedorfinished
$ P$ g6 \4 p# L0 e# N+ D: q7 o    if(item.pollStatus==0)
3 X* E$ {6 I' Q! X, b) }. r! c    {, W2 q2 w2 ~& l. h5 k2 V- v
    _polls.emplace(get_self(),[&](auto&p)
+ ^) I" ?! l# x: j    {1 `$ E4 Z# T- i- }& |& ^  b6 q! \
    p.key=_polls.available_primary_key();! k+ b4 ?/ @" Z
    p.pollId=item.pollId;; b# S4 ?/ u7 G& ]
    p.pollName=item.pollName;
$ T3 M7 p$ J. m0 J% o9 A    p.pollStatus=0;# ]3 J+ \' S4 N: v! P; w
    p.option=option;
! S" o) T8 Z8 p. w$ `    p.count=0;
" ^5 L- x8 r3 {6 U" j( u    });$ N8 N9 S3 Y4 ?8 M& _" |
    }0 U2 H$ [. d* {& y3 L
    else6 S: C$ b1 h: ^4 T0 \( w6 \
    {
* i; B9 }- U, x/ j4 w& a$ ^+ C7 H) m    print("Cannotaddpolloption",pollName,"option",option,"Pollhasstartedorisfinished.");9 z. T* d$ a( O0 V# C
    }" c6 e$ F9 i; M
    break;//soyouonlyadditonce7 A, r5 R' S- ~2 I
    }& A5 B! L* j& ?3 [% `- q, J) E6 b
    }: f: {; c) E1 O( Q4 Q
    };( U0 v- E# s6 }1 t5 ?
    ///@abiaction
) u8 _+ Z% j) V  Y1 P9 ]- P2 y4 c    voidrmpollopt(std::stringpollName,std::stringoption)8 ]! a) N6 g3 n3 z2 K  u" }. I
    {
7 b$ \9 M* R' ~. R$ }    print("Removepolloption",pollName,"option",option);4 `: e6 @1 }! ~6 c
    std::vectorkeysForDeletion;% c+ d% @* {7 I/ k+ |+ b
    //findandremovethenamedpoll
; F/ g& |& J6 t% [6 e/ ]) e% x    for(auto&item:_polls)8 s7 c9 [  R) B2 I! A& Z
    {
3 |7 Y# A1 ?! f7 x$ a- E: K- i    if(item.pollName==pollName)2 n! ]# c$ w7 d8 j3 m5 q/ x0 I
    {2 \+ `6 O! ^. N# j% U! J
    keysForDeletion.push_back(item.key);3 s' H' }7 t2 p1 X3 b; H8 W
    }
4 ?( z+ r$ v  M7 o    }6 P1 E! N, r" L( W/ ]# b$ K2 M
    for(uint64_tkey:keysForDeletion), A' j& \" p! V0 P
    {( C: J! h0 r* i% J( j( a
    print("removefrom_polls",key);
+ t! N3 Y: K# e    autoitr=_polls.find(key);
0 I+ B5 A* K3 w9 @$ H9 r    if(itr!=_polls.end())( k( v0 @1 ?" K/ j) w# k7 y2 P
    {+ k5 N0 ?/ z1 L1 }6 Z
    if(itr->option==option)* V9 m  X  l5 V/ p8 J6 F
    {
( _+ w/ j+ b0 G7 u9 D" Q    _polls.erase(itr);
2 t3 o! |( o( E5 i    }- `0 }4 v. K/ k0 r, M
    }' Y0 s) ^& |" l" J, q! i5 ~* c
    }' S" ?& C2 E, G
    };4 B* l7 @; K9 F; @( K3 X9 T
    ///@abiaction6 A* {1 s- ^9 n0 F8 @4 y) j. M4 N4 x
    voidvote(std::stringpollName,std::stringoption,std::stringaccountName)
. m  P4 k; D- k% f    {* `% o; g0 @3 j! V0 l  \
    print("votefor",option,"inpoll",pollName,"by",accountName);
: }# a4 R) _0 s& e4 G% r7 ?    //isthepollopen
$ R1 Q5 Y4 o/ L    for(auto&item:_polls)" @+ ~8 Y, j  Y* v( U
    {
- W, N' g5 Q5 O7 _    if(item.pollName==pollName)+ }# Z; J) j( @% X& L4 j
    {
! }9 K/ b: D4 d1 t' y    if(item.pollStatus!=1)9 k; e* f! |$ S* b
    {
! r( x& P2 Q# s9 R4 u    print("Poll",pollName,"isnotopen");
7 f' m) l# A4 ~    return;
3 h( M' k, F0 B    }. [9 v2 `8 f4 c7 p3 r) C0 C( }
    break;//onlyneedtocheckstatusonce- m! Q; \  d+ i: i
    }7 \# c2 p- y. p/ O5 |: \5 H
    }
, e) m1 A  `5 P+ k0 `3 ]    //hasaccountnamealreadyvoted?7 V4 V9 \2 M' C& v4 N# P
    for(auto&vote:_votes)" C  {" ]! E% M3 K
    {
; V% i0 _: `2 C" |; `, b# \5 q4 {    if(vote.pollName==pollName&&vote.account==accountName)2 r8 S- c; b, r* {8 ~5 U0 F2 m
    {
2 ^, ^! W8 K0 E$ m, X    print(accountName,"hasalreadyvotedinpoll",pollName);! U4 i& `  N  C- [, A) x
    //eosio_assert(true,"AlreadyVoted");
8 ~5 f+ E  Y5 h: m8 R    return;+ h4 b- A. l& s
    }
% H: L; }1 o+ W: `    }
' G1 P+ c  b" l) U5 {  V    uint64_tpollId=99999;//getthepollIdforthe_votestable) ~" `% l0 X$ G3 u; B0 @
    //findthepollandtheoptionandincrementthecount& y1 l& \7 H! h1 q4 S
    for(auto&item:_polls)) e8 A, g7 H8 x
    {0 e5 v% ?2 z- m4 F2 }6 i
    if(item.pollName==pollName&&item.option==option)1 ^, a' n/ L2 m- G8 O, v
    {
0 g' p, W/ O% Z% a0 L7 U# i; k    pollId=item.pollId;//forrecordingvoteinthispoll8 v3 G3 f+ t2 {- [' \( Q
    _polls.modify(item,get_self(),[&](auto&p)0 s5 ?+ l' X, R9 \5 B
    {5 T, V+ o& a- G1 V* D& r! l
    p.count=p.count+1;- x; o9 {6 ?! q1 q+ U. R
    });
: T3 H( q4 l, P( s! a/ q+ J    }& }% W* B- n: R
    }" M+ {% z0 U! ~
    //recordthataccountNamehasvoted3 d) X# N( [+ Q: m+ K( U8 z, F  I
    _votes.emplace(get_self(),[&](auto&pv)
  J' m# o) s4 i# g    {5 v! w$ E( K: ~3 ]6 A
    pv.key=_votes.available_primary_key();9 j$ T" N! K& ?) o7 R/ r
    pv.pollId=pollId;& Q; _$ c* C; e) {8 k1 a& u
    pv.pollName=pollName;3 e$ u$ c8 T2 a& v
    pv.account=accountName;
7 e" i4 v+ g' t' N  W- C; ~' Q    });
3 q) e5 v3 k* k  j# b. Q; K    };
* y8 X  `8 P! D7 {' C    private:4 p0 `; E  x! P
    //createthemultiindextablestostorethedata% u7 X) z) ?8 Z- U
    ///@abitable
0 p% T: H. n' e. D" t    structpoll& D4 P5 l6 N, T1 U( {* G( G) ^
    {
7 `; c' B4 y' `    uint64_tkey;//primarykey
0 ?! g+ ]' t" u% @& F8 ]3 Q    uint64_tpollId;//secondkey,non-unique,thistablewillhaveduprowsforeachpollbecauseofoption- q2 W6 H& g4 q
    std::stringpollName;//nameofpoll* t8 C% j& E$ Q* G; g
    uint8_tpollStatus=0;//stauswhere0=closed,1=open,2=finished3 ]5 h; b( D; O% Y; J; P
    std::stringoption;//theitemyoucanvotefor3 w7 m4 ?  @1 A& s+ o$ G
    uint32_tcount=0;//thenumberofvotesforeachitme--thistobepulledouttosepartetable.' d2 ?& X4 ^+ Q! ^/ a2 M: O
    uint64_tprimary_key()const{returnkey;}
& z$ f- x; u7 D4 s4 l6 m    uint64_tby_pollId()const{returnpollId;}" z0 s/ D- Q, r  q3 n
    };0 u2 e; Y, D8 I, f- o
    typedefeosio::multi_index>>pollstable;- y/ M$ Q$ j' \+ W3 i
    ///@abitable
2 U( J) P5 q& [1 K- `6 W    structpollvotes
0 q2 O1 X1 t  P3 N' h: r    {
/ m4 |! w. a' F/ ^0 D3 b4 G    uint64_tkey;* k' A: x/ k0 a
    uint64_tpollId;& N$ d9 |3 d0 \
    std::stringpollName;//nameofpoll4 Q; X  U1 o/ s
    std::stringaccount;//thisaccounthasvoted,usethistomakesurenoonevotes>16 A8 q& ^8 y) z: S
    uint64_tprimary_key()const{returnkey;}! u: P2 {$ \6 {8 X' T8 u
    uint64_tby_pollId()const{returnpollId;}
8 y$ a) }" z5 p( n    };4 p7 i$ d9 O1 Y1 @8 p6 s2 o$ t: c3 c+ W
    typedefeosio::multi_index>>votes;
5 t  x7 Z4 A6 H+ @    //localinstancesofthemultiindexes' {6 W! I: I) G' ]8 }2 P
    pollstable_polls;
0 W3 q$ E; S/ B( t6 H" }    votes_votes;9 w7 U' C; v% {! `, _4 j# O- S& U
    };3 B& c4 I$ s  q& v4 i$ k+ V6 c
    EOSIO_ABI(youvote,(version)(addpoll)(rmpoll)(status)(statusreset)(addpollopt)(rmpollopt)(vote))+ @3 u3 I9 X; [& z
    注意EOSIO_ABI调用,它通过ABI公开函数,重要的是函数名与ABI函数名规则一定要匹配。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    0

  • 主题

    10