From 2c0921bf2b55668a2b8a5782d5a953c2ca46d857 Mon Sep 17 00:00:00 2001 From: danielAlvess Date: Tue, 8 Dec 2020 17:19:45 +0700 Subject: [PATCH] feat/#63 add revoke code for new badge --- community/community.abi | 21 +- community/community.wasm | Bin 331679 -> 343541 bytes community/include/community.hpp | 24 +- community/src/community.cpp | 489 ++++++++++++++++++++++---------- 4 files changed, 375 insertions(+), 159 deletions(-) diff --git a/community/community.abi b/community/community.abi index 512ba4c..b8ab306 100644 --- a/community/community.abi +++ b/community/community.abi @@ -553,6 +553,20 @@ } ] }, + { + "name": "revokebadge", + "base": "", + "fields": [ + { + "name": "community_account", + "type": "name" + }, + { + "name": "revoke_badge_propose_name", + "type": "name" + } + ] + }, { "name": "setaccess", "base": "", @@ -1319,6 +1333,11 @@ "type": "proposecode", "ricardian_contract": "" }, + { + "name": "revokebadge", + "type": "revokebadge", + "ricardian_contract": "" + }, { "name": "setaccess", "type": "setaccess", @@ -1429,7 +1448,7 @@ "key_types": [] }, { - "name": "v1.cert", + "name": "v1.certs", "type": "v1_cert", "index_type": "i64", "key_names": [], diff --git a/community/community.wasm b/community/community.wasm index 45183be832ee67cfa4798ecff336fc732f8fcc2e..db52f4be709383f868bb88de19bf27fb993823be 100755 GIT binary patch delta 39942 zcmeIb33!w>*Ec>%?&-9hF4Kj!KnwQ_1R$QKoAQ>2T`ObASy^fP!wbr%3cArD9ZnLl6$68D2UJZyzl?}uImvYlRL@D$;mk< zC&@`Nb7t}{eK$wZp+1vBm&Ee;PMt*1rZqA)*>LYIL1{OJu5O)25C8jmYX*UN2$f z^?LDF|G@7u{___`UgKj8kQun+-{fQp=oiD^#AHtc{E25S{9y^q!)%6~4Ptfc+6A+* zh!o*t-kf}!(`WN;I2Q^W(ahd!(4hX$+J53uJ($hQoY(B(pRz@KKg;2#*$6gZ0w2$I z@?Y38_9MGxHUEPxVN3X7wvC-&#cUJX%fDx<_&&awO=fv~8vlR~?Y~8A72k+$V!QZO zd@p_wJH;;Xqu4E?*Dp*i6b_r~X4iteAEVl5@DZo{)vMR%@164BTm2gT=_&u1>I3+; zQ~q<+-{2#Q{I6%t;!}(KO={H4{G!O_vYD)gu(>0gyp0*rHplue-*!i=&1>`SDe{l3 z(S%BWQbU!#x8^AT$?H(-JA-}auTrlEUw6hoqTWXocPeYR?J5$C_MQ_tR5UyS;|!n`$f~HSt^$qZ$@|aI8ajM(EzP)>I*7`??zUsQf%bTtcRjJ+hI`V!2T)9lt*MZg$N2<|D$`@Wf55FO69tcM`)npV#;{@z)+ zvni|Z|Dknxw%32Q^()3cVMa*jgRGMOt?RBQ3Kd>=W9s=cs?j!+dkbx@$O`cUa{XEV z4Q=`*oCT71dAK+7X4NIdMgIIYsTI!@*|O`{Y#!lV?aTIFV1vCCbo#uX{ioX;rJmmH zT}i5PRx7B5P^4i}PBM6uA6YBe4?sOk}!+)UDaQ>zt2QTGy{gXSVBdeU9$D7Fs zLyb6!%o=Lch}tYn=1tFb75M9R8AFu&s7rGSe(TbX?>U>-=8oqC;kD}Sm3F@IjK9VG zrhjVpS^DSq!TQ=g(1GpG^FQEY?4UoX=dJ9gyq-NjXKm5@-RB5%o z4_mp3E;1oY+)81OERi9*9~80vuG#hR0d%V?b2kHi-84q<{kyX%BZ3V7&HWVFp6l1H z9Pk zl>a5)>*zdxM$SNX%>PQx2zER#aaax2f>y(45(c}6wEoXDFt z+NUyQjJ?NH(&M$eqhm6mIM5D{-89<8CdMR?7)?HzH)-rSL!(AtODsl17wjN$ATfBKqfSIXwE zyY>0J*wt~I{p#=a`HWJv=Xp0IU0Soh+M3s{2yx;k&-;B}UolT!-K`jl!&{m+?3@3! zx)fE{?Jk3=|B<%6S9o#T*wMuQ89J)o%RYMxCtmvC*X|Vhlh4&5w!8jZii+O%NA>7q zzd=Vph+Zkq8}~;OrM1`n)fhuZ-k*OB=X_DI)+jrQ<%P*?A|G>3*5GX09Y0iyVm|gF z{dM4PGX8R36`Oaj=;yI#VwiJPf}rM$Y|=e20^0hTh+Kit)HP$F<_padC`nzi&1~L4^2iKqqPAF@W zQdY@nFM13iQei?;gBj72{+5ycD?bI8H_ zc#`ah8G@`F!7^E~ydi?!j-YQOt0VIx*uWa5nM72wnTgcnHZy@b+-9Z*!3Dd0h3w{F z?pmOW>2xh;o+?>921pX(}>GX`HE1cAVk5lh`GQP&27P0TDHkc z(onHOr%}g5X16VRXW`s8SAY23y*f`0lbxbiT68`G!$dYgwQ_J2>(Xh1jdG&`DrRPT zoLO9phUsX`Z$(}N?Gf0$$k~_=Qa^!AW4-|*;@tp&0H@fpUGD=hfXIYs*0h2LtgHo0 z(V58Wjv!hT%SWPFgGjW&jA_gbIV+k~sc)DLz%w8wuxngqgbAy_g<%H$4{SV+8)GRy z5J5&)N2i$}e~V^qS%PftWEt{aCu;?oO>wfO%#>T4%w4C5%Ep+Eex4Ywqk|%Di26mK zzC(2p!LK2TWaSv<@f9;qMB57&F3ekW=w1Ih+g+#<(~<>?m%Tc2>&}%vnC@ztGUeSf zN4C7*2(yD=vdWG)W)XTK^R|Y7K2`BCUu}Hr$dq4gR*{@3?=C(5#g4CRn0V0KC&v5C zU~gnQnH$6G(IF&P$kj2d97GkRpalyzfxVPQA-*kCt<&X7x2-VLHuQz&7|riGmX_^t zYsS}c6a1ulN#z9>*dWm!j}k3VylwNGoQ;`sB$*uJ4if0VURTu8GSky zlWitwk|W8LZKj4I$=PN~C<56o7mB23o5?C-CN<`nss>=(n41bD{@Ee2T^}oPsUd(k z)9Pe9ddNmBmIz9izBn`yKXjU6C`wDgT+Yh|lZ27vlXMZ`+*M6YPwMUV?nufSX@;nI zZulgWF7R{d3)l5Pj zm&4=m+S@H_=}3%*Wpz(A^ohrb-r;R5SYSv`b@_D? zYv`jyw}aGz)9rAY)lDaHiPn%M-I}VqRTU30w53xOhZBCmf}vb4C2v~us$5{tP%g8I zH!IuIpo*E#Jgv|J!82XOUEZ9k=2_DN(Y8TDMtTSA3 zx%4PIIFVJ%aF|Z8!)+dvg}NZFg^of73X;{(TPs;5C6^j{(N>JUH1@i}#@=N4TOwypcd6&YI-_`L#)qq(_^ zPG=1g@?jTb@nq9>lNyQf`L=Xc9}^Lolg@6Y@T+vzlESDA)`71*C-2T+eJQ>sgWW)J zMd{wvdV^yIBpkDA3x?rZS2T z+brtHh$^gdC~{|bWKMXb$ciLnvWAfhMFrEA#na@^RnYn%q&G5IIz?7wGA}<5WAL!3 zM)5VNQ{ z=3rJYa4wTI;m9E;ZsUCj_M6pNHL(aqYi{Q`#&5!O_$&7?<=5MJR$xLF+pMVGt0vo* z{u#^Soy-Vtv8|Nh4aV89MLtlAJxcwvp%%IrVM=ZGFrZzjm_@u3YPp)BIc)4{- z;qHZ<2F)7OxUy<}b}L&iAFs~_A*(!CpLORuw+7laV1Kc4pO;zWu7<2Lip+1wUc)R^ zwrIpgvJG-gBPQ7wvRh+Tm3=9FjoI|%uc)pKmL`nwPQb5?fqG4tV39kwDt15OKQ;bo ze@^S_L=~*hz5+7H>}G5fAf0K(>as5bRhqMDYW;6b3$WR`GlAPz@HtFQZpCJ5V%L}V zw`D)^e;Kmlbr6W-BoLWwec-q2*tJA$THP$2WrvkT9={&FGr|Zwc>{YGOQ=R**NyBi z&W9UvS9?~$`6V-9fM;>T^<{wF477oc{T7y`x}|OhHrM=&c_OJ}1T`)w5NMg6!><2E zp6Q^bw}Jk*f}V0mCoKA*gM7EMl*F^&Afwk-$Cjp7*1y^&=iiPd%I)$83Xg1;u^pM4 zzw@oE*O8Uu`@fa#I-*C{%le(z{8s22C?s^Jz}OS)PC$eT0mvI+e;YJ?#thjTR+C!U zM@{8Av$j@EH7hZ_a(-kxikmK4%(i=ZJB<};pWT^Nq1xAXX2*2xDRM&>);4TSLMGpV z`SoX@nI?r9>H1pUa0i>nHp*}BV6(&5CtkgiO{VpUYIk8y`lWpGF18nRz58x9NzwKA zJ*;JH*h0XR?_{H{5GIiAov!Re3fdj5+8yD|Ct)zqK%~9fjon|aK&7<@*Qq45pOPxy z%eqS0jU^L|R}e9`l$DRV%}GUO?U45S*t=YZ3uO21tP|S(ZgLy6d2eHd*>e8`avdPBKgC?|jH z&E5ohfuRpGC$0I&m;110PKTO+kog%Szv{!5Mde@_z-1cV5%Q%+S*^R(SgegP!;EPn zdYT3j_tLzy4SrxWHi!~rk$J@sjEk;sFne;78D?N2?}?-VHqr}I7j>ACFuOWebVmoA zeOVkK5vbS?+hEa-CL&UqTMn5qfVH879s}4g&PGXghBtL!tBPzr|J1xko%KvdPz-2= zG^M6x1xC1F@-Yu;RXM=-=o!VW2A1tjJ6a-(&hS*Zc`)-+4ZR;{Cuz-9-Z_Ll#I^@k z41oj^VZ>AH+H&YX3__TOdvi(dG&tGeDRv_jdF?6o4Er|Ve46E}BAcFJ4N{=~Pz3T~ zCjy1alzSF~(w?({`<`V{jD06jsG`gn%AR98;nMsj$uR;wV zWZxJ`(j0BX1{S@_?otfMC$bOHtv-q{ndztq1Ir-2qPE$9&bEoHYRYTBXq|&G#l(gh zs2iE>+AZT>W8IU{OBiRVmm*6D?t6`SVz-c{P#YaK*B-e9pUMWbR~{ljkn76;DhLC# zFEG;2nv`n$H-^v!#(qmROMkhMk{culgSr3(0`Ub#S*Y3N<*gMr_&=CW-rdzK>R zcdU}!najpwFM~Cf*Ue&X!r5Zcu*MHq#?sjVIdK-do2YY{3H?4 z&SA~uAG0ya2frN(;9HUi@8{bMr{81aFH551WK;wN@nXsp%5zIu5Bd30JxnTU9g$;} zvBp-zGv$=!7y^&Vf;`w-ni$r%WAv@L{P=x#4@7tHTP)QuBV6lc-4EDJkgb{lR$I>b z0LIDju*3r@F@VI5rPyG?3ibxkvi65CQBO*CnDs<(;X@VlT&cu%@@b$N^HFJvUTwj^ zx>cCH0p`Rt3g*B96|A{Iq{`K+SwpA=3AJF#{7>0^fkF9ympL%&(~u5XPQ-s?9oEGW zrmttiqb2Vu~RD3 zRU*IuVzMH+{R`II0)owwpQX70_TP>mtnFVBtN>u$U5c=yH?e0gA!z(JilDOlH|&o~ zNK#Os6En8J;49fUmH#%RK%ea_LX8WM;rBqJ`4C^$7LCPvglcRFTas?WVCjHGxxz5N7`&kRHnt70wmw_Fuvov?GB+I4X5-9TUe&&&Pe$VQ& z_484L#eDxgAk&_Q_xtZmY4Eon()dlD285 z*-Mv5TL}e5hLi1Y^7fDu&tiH;gWWHB;uA#^A8emUbDfvbf0P1v;1AXsWb&M66Abp(`+3~p>@T^3^WWf^A(skX5vwYj1g{)Ev-wr< zdNnY!@qTJ^r^XB*vjt5yqg-DzZ%usZPhYZN!e;T>t}kUrgRf^B11WX@V}Au2MDRNW z%~@diD%~*l_tCRZTe?dwly%{#h)x?NL-uDyCjUo z=&3x?^!oVZUjvhq`4eiA>`dWrDgBw7%10-j{}ECT67ZY#gz=-@fevXLT7MXqZx%# z_zX5K(5F6!gVQV0-H<=WUX{}u@*Zq_;LnEqGdut2H`!vWQC{wBj_w-yoBX*sPo*%r z1z%pu&EkWWJfoB=LIBPrt1h+00T}?$3@g_-_0m0rmJq zcW~iJ`CWJ39CM+v)=|}pX*Am-m+ljl!`#F0{dW<^UJLwjKVLy25qQ4`oJfhqv5Zkw ze%A|~h)7W{-i=L^w>-!P5LeWBl=qOm9|4Qid59O%m$7}pCw|#^FwY3Q+ncvioY=D; zBtm3!x6JL$qXXj~;aCW>inG@#b20&ll}jGwJA+Upe++QP59Cn+cXl|Sp#yoPz_0!I zq7V$(X|P5iTDl+Odx8+yR03Tq@b*AnFN6nsBS7^LZ$I)BSM!j9r}z_5Z*mM}u!IWa zzJ5GO_IR4V2u9!iG_UI@#Z_0!wUTBKfvx{S)##GabLjx)(ii#VTs5=)Q@B^lqgRC6 z>UDTsyDsKJdBb^c4PNxGhnR#DsRf)-y4`QmG@;SGdL|4&Z1;2A%#YXj5mSF zOxfp6ejoMz+Bf; z%iFjr(`r&zJ!}Bzmgzi;&6B@R2Q$7co6g|7+5AB2Oumd^XXMLSd~C&q97_sdBd6L6 z!eSJ5AMp>?5#Eu5X7eu5SVz{)S}ixu=8M^!z_WAslcg*j`&{lV7w$(%n>$+Md#z;k z_q63>0IJS^`Y1yaFV)Yf1JNjC%n7cUI zux|-p9oo|QCYP6oOrOZ*!`XbQ@~-f@b}i-2LA>@C;ECI58P6fE*}9B3VEd&#kH0}H zIPlWFnL;?|R+2rZ8>wMiKQ)(ga$5~Nv7Fz|NyTYj#lWc#c+HEK*86j|An?&j4)<_W zVqe8)mkXKc(RFOKv0@0@?YF)1qg5EoKienIt%CA>X}^5_6JEW-VouZ(+Km;v`O(1@ zp?3qTJ^>kd@$SHZ)jYYBy|Km+&6CRLI~ive5ER+fE_z5~EvI!sIdv`n=-LoQSn96r zWtyMY?k9%CY=WF-xM|c76S(U=uJ9dsK)$?=-&rCDMmQtOpV#qvJm;XSvYy{pEy(Le z*fxot*wnGPu>M68w1R_j?s`6;VlJnxFj{F1$`s{9hA}_M+Mn}kBvp5Q&O5TDa_;AR z3R@;yZQ#{nigzQM%D4VNVBiMcnSmeHe8D@hn|3D%4kx{6a?+c{`+1B^(Ay0+TJl@d zW0^soTgA*YXum!OEv1e6Q3yj$a78jX+vMSmyryd#GqG!@g{Rb=ASYHMR?*g^k3_ldCaAQ$C7U5bsZWDhn5h>WaP^*-1umc+`nEW-b z)EJ*Zj7iLcc}q(T0JNaK(%ghkX=?L0+M+TMAx+--HE$i6rrVt^-}su>j!VZDF`=4H zn5M~X$idR(mV>;CBZz&g&AhsQsXrxIZ>6iAnqU!TihN}=uhk2B82Bj9Nh4e-D^??1 zfDrO%$4QEp_)RKI3+Z@5Xn%l~^_?hz4#fTdp^jNX0k2ybLRc30BQ^D7WS;_FqfLxO z{1^=-i$|irA~m7m-ALRAe@CJ*930~jG|h%zrr~W#4t<8Vp)4rio;#>-0fAgY6pIqo z2vybR-YFQM(Btq}q@9RJy%Ry=3L;M9dS4yWLfVCZ&xYQLaLSm&d{6}H07^1{3$NTh zpLwEV9WjwkFQW!4RAY@8J2f6O>V^F;?0|r7`d2~d7lsq{iI@)i|MK`3+>{Z8yaB{g zjz7ZF;aWhzNy3TQ0A{Uxw2;5R^5vmI?rw(#UFH6v*%k}p{{^2uKEZE!PV2K5`Gd5dW{PD%V$s>%)OLyLfjN+!LToAQT~mUVJ~0yqmWt zjd}kbekbc0u1u9$MK(BWptBGCU!_Z1U#dno@4E^$+G#&;a20Cwt^I)YUo{$J+5emx z{q84T|8Lc3^+UYYf7R&!RciFzBmA0hBl`3aelMBow;$!Nk>cEcR4LA=WBf)n4eNBA zzt^HZ1cZzMJU}%Oc7_v}C9gz>6#JSXf>~M+?%vgcJ11rUb$EI=t0#=l5 zt`9L6cdd}$o#G7}uEg;NGfJUrO%YW!q(xmH(VU&iH0BE^TcnjuURT7+v5y0H74Z(F zUT6Od^~%>DkiVVgD`{wn`-Qs`pt&*V!A&kGY4WEt{BHhAv21mgZ@zrCK$~Cqe#RyT zs{Fb;*&js%jps1O>MlrJj{ zOlsHrlfd;t^eHthy&7z~{gN6PJflOQ3x8q!=h)$_j}tl!Cv;-GD-6r{k0GOf0lYoP z#>+*hjs94ic%cZwS%xxSV$E3DV=YgGpEEpfZRqD1?-V23jMFx!iUhk*ab1iz7iSmL zcWrd44<%Noit1CbA+s|Uzu;g3lg$(FGU1vM;~fRBa5xDoA5g-_CngAB8}2zjiawwj zQz%3;W+9|<-~-ExJ`P^=3HZ1{xluQ-vE zX8ptwn)239nBsJ(rclt4q8M*6!gPcM;FK6TJfwdn`{)3X28km{m93w!+)Y6&fmtP3 z0tW{OX__*dvE;$?ly|7dE1QhbsaR0(iWpF+|GRRwN~p~VcG=qs%uh%FSH zZJTz#?`x#aA}UppFT5_SCd5%Gn;92gS0peX(aN-xPa+V6le+F`?^>uAtIy-WKw9(A z5sRR-c}+}}gIo-PVS)=D%R&|(DGJ3U2#G^XK-i(V2GXWkP&Z$*Cb2N$#6fFFlK?9h zIkhWjo;XeS0w4r9XarF+9)pOhqT8c$<%?i0Lfco8O%o+Y6Bp+*74;OcAWI|_MC1*I zMI*(wicU(Pa27@#5K#Cl5egD$12qQJS&N|qXA9z$1_;sChmKTr#ar^Kn@6o04K;{q zvq8klLUA`7=M@g4s7HZQ4#$#03jU(|-DzrIN;c#A>E^|GjVC?HUb^anb&MsAI*Mm| z(m;{hJc(wq*T6ynjsOw=5#wR0ONArIXi?Sa%00<|=Vch=Oq4=tI&4TuBe)rtO`V4y zY1E}D^fiaO(@0no-D!j@Q5ac>$BBEO8q}#Hg^OlcUyOGfQmhf}V)pf1iG6c&X1((r z$e_pv?PT#Ct=g$kO7Y)Ds#Y-{c*2uhiuVY6-<5c;Nb@07sHF~20QGT z<41}ajZ+vN*Jsp=DewpNz*!k128MI3ztgl5LQ=X;@}V35RlAH|qLB0%b!M2@%dnKV?PJO~#VqyUaeg(#p0q!g3JA`)qwLsvpXQl8?D zbDC+oYX~8YMy{r$g~oCNdPbv>Tm~AqTX-lmbX^c3tFBz5q^@MDD@EgFH9p6looS0F zq;jw=M{81-Iav}sOcLFUj;COk%0_2Y)WMQa%tgmcLb2phu{760IkCE^MKfF6lydP+ zC$#?~7i5WBE|acrLh+5S%mnQ`6d3(Hv6y^d$+x*}rhyPAt7lP&^J6n8jBX|-Q0Tq3NtUonL=QX#jGe(VK1E5;CN zXUP;8nPO=$ELcA7qx@!+f%YrarwP;jbF5ElD`BbHOreItLa+cAP?(bwJob#0d88M> z?2g5#?3x1L_yzJ|;Kp1fwyhnbEJ8ZbKg+<-f!{QI$I@g7|K@^^)+-dvSn}Z)q+^g5 zWkh{j)=2t|G6GBWFi}U2=%mt7a3+~5FuU+`FO3#J13zccR~Lc8yvRoug+l9dKyb&A z0HL!~hF~!Z0^zG6peZ;#r+}#{(n{c_<0pfF>W&~RP7G3qVQ)+kfocRa2SK&L zXmeQG8z3KyAZ%a25K^5_nQm0KTOp3A8U7`!Nn;l4U5w%RP4xUl#e535-hnW&{*dN@ z!#$9|kwWcmYCwbOjfav3(Hc(aKd5GbQh}a${9LSm(s~VV0~PBa6$=8`JlGqvnNB)~ zFR%y`ZwjAf%u~x~u8M`8_J9D1E4^( zLVQR} zITV!#ITYN0-ouVBaT0Nh#X>Qflah6ij`oAiaG)G{8uQwk+v@4Wrut(W#bydLH3(uU zTwj*OWh5G)@vS9HhJi=*1=!5uvRu_M;aujsDmEj+Yd(bRYhqD<4~<+RF|hVkBQKSh>n{MS4t;eMq1DhCDO9v5^4FT!V;7f^t9Re5@DHMhOk(gI3yqcqvB!7rCPDk z(m^f@YA$t^(&6xF1pfolVTq^Bn!Q~m0{=nr)CgpeqctXt|NHgFVQdW34ml;-VZ>#% zgW{V)yu1{jYflyglxI+e_L03!x29{i>{tJTw(J&4W^vs=N8B`R_h>}L#I;TFZet0Teh!0cj^_4s9UB$#qNE;|vlQW0bw zrN@-{jjb7s{xtIjSLFz0(^`XW2z@va>zTI*TBmAT5LCCJoEr5Vst)aSV+u9>hNZ4r z>=q&YZe1LJ<&wuU9}hiT#AJ!9vaia1(OH5x&yOrT;^)V z{|!2X)g=Zx=C36dI_zl+$>K01@%l8+HBnUgmeZ3S9hWx15g2gU}|S&o31NP=bI^=B)Y0;{smAO{i$X$UzM z1h6^Hwl2!sN#|{^^L9l5iRg)s3MYNe99T6~2|iH|p}HhY-2z6p0g=xb{xQ{5S2ZXL zc`&i1Bv@qngu2RLO>3dtVmuKvl)>79Baxcb;%62dd%`ERgag(dNztK58@QTc{z@=i zo7E-?$UwRVi89g@bt940YV!vD8?KGy z$Eath5kwa`w2v?`i9v5El6W_$5gaQ3I8CEnD^0jv**xe#1tfyzp|D90qI$HzpnLx4 zMhTk-o{QcUEGW*{W2R{+oW&IK#0Q1&z9gXVn1gGjhI1527TROABhA8mltR`MN$nq}e@6uk z=qM6uv=y^!8X-Yp_;R66+)EG~A<+orCYb`OY1fJH0TMH7%)x6A&(a+zYK+9BbDJ6? z877?(YL}ae`e3v~kU<>|%N87LfjZnd+=||WxrO~+n=<*M0pOtiSqAdTH8F%de4B&F zM{DHKaX{Xu{W(I|n{+QW-Miri1LE>9R8dgU0zGXm)dI*M8h~lDhNr=WH2~UB^-$1n zLoKB!(FH+;%eMvWMiiuF3fERdXi^oStzRV*yEOk2&tM2r{J$Z@|Lsc+&BXJH&$S!@ zH6?EN3MK+C>Pa<-Pm^kr0Uje?n2o!*6h3srlM?a>*EeO!00?4&Ep9Cl0VM?Jff6Ao zRNX;i+CLM52-K{_1gb>q1G@MDU$qb@)k89XS+bUaQY93HBdm!rIdDSxU|tN<2Z-p= zEW)ei#mc=Csbs5$QhiWI)?C>t3>hj(rc^ywwo)-y4yB^=m4pHNEB4f&EA&(%F+l0A zlG(FaJM@c62=xmF=Sy|dW%>nTUD7WT{!Qgnn##1)1J~Cu_B&QMgGd&!|CHJB z53CMYEKuQOxa6RFE$dq83RnoLp&%v3x=sjSqJT{)@86gmC02*Jgz@rLM+Cf4{s+ts z%j(#E6;{X1mdWyeZg$9leMGHGZH;fslIQ>08vnI5LQC}jQCs6Xuv^I1z>b$z&i_B# z8sC>C1D6@o{%dRe@7WqZ{DXe^udNZXQ)s~cf6>;6D{X7YRW(FD`G;FCXUL^B#jQct z?T7>F9x=J)MsXAFv&4nkXC!Xza?h{XUoiP-9TB>uAb?jjS_Lma2;emhM=6i%8TG_t z`qG2>3H1dhPw_Rki9tApJK|b>A=dZT3OueMuWKky{q5}t8=B%0&@kuoE8eknxeK%0 zt;C!#Ab}rRi3lDYI`CRvo?5`WmK+{_qm2ljA*RdWT6@K|utUUjg&gwISz@{)3fDfF z@|qjPee5+k=0;I9tRA@@aWBK_g@-1tG~FgIhBM!OpC*x&^ z)b=Hv6?_6EGVn`#ks9o^k~dJ~{q;o6aGd{1_w|&wb^P~B|9$7rY$(QGkwfrI%4Nvj z@nW*)4?ptmkK`$GwPZKxzF}LN#8N629j8D})v-WSPk{>?*T})W#dU$M z4~jI-KBdSrY<1vhZ_$nMrN`xskBEl2WoPIkqBHwZZhS-xrPJW;`-q3w?!e+cqB+0h zdf|{0SgUYHuYcqOCMr0Gm(m1bn)N|>b3d`#(yRe!)=8ya@aZLQcuZ`*w9gX5>)a?sNvgB_HwK3!V8H$N>}uqo2{jJTgjnf;9Dg6OJe#J6mpob;?{6txJi z^w0wO1iAHD@nC06nmG=s%6H#exp3^;#`6=z1^BBsue;5-$1UBN?*p&7Kj zQ-GDFL%c!^d|grJ&M|K<`u*GQ+uo(BoVopzw@>}>21Qkk^Mj9S$N@t|4IhrK;0_Sw zK&IgC09-8ZYq*%zyAA_xWd%3vc@B-ce0MuM<{RB*p*}^oymKtBfk#WM$2z*iR?;mv zNHxKgX)i)*!Cus~z!$7)0jerQRh3j#^S6AmedEax&KFki*|q2dMHP{DSqHL@~)%k7auyN zOKe3A`8+|!(hj^A735+-PO~6mQHQXuXaQa`P9YUU8c13%p`>aq%E_^i#zq+-y^BC& zS$&5EdIvz)18C5nocCPE02{ZY^0udf57$_r7g#;fITmi2#Gfm+kKBCdwl1;dc^i|p z&Dl6+Zk~FhM6VAP;e|1{#i}}wQ=QnwEwt(^M4cpfsM2*D^_53`zP1xWB4JhW%`ayU z9y|z<=n`wW-K`}+uu$_YK=}aF-l7W@i52U^y&mX=y%=MmyZ-eNQ;Ec>8mF@aD!MU; zqbUB=5WXV7GA&rxHaY>kQWYrhuj1~`vB^Qmio{)FQ#2^N1SPz9L4kZB2~;k)3<_Lx z8J4kKCjl!(!^+qE+c`ESNJQf9F0tjXiA&uBKULwyy8t-|304latXvi-951JyFBim0 zvug+x^u=uGlP*A0f%+H#ys=Oe2niG&!{}sz!d8Im6ky@tgzC#P-_{}iv|ugRzIo#I zMTAz826dcT2tRx{3n);9(luNp`;x5EpK2cL9Geg%ki~O}x;VVHg%^8|`Bw3K5D1Gy znm`*spr3(CA^{7%mee^`!Co+W-4arwT>x6shZ^MqeGr0VAP`zLDhLZJx~|iJm0&R* z4mt=g9(vh;kTP#T<~CNnFl$_Akk@79okV%zjSde(m3IR2K4ay@-jC}n^2S?vr%{8F zWYZiG=PL?Uj+IT-Kk&v@s4gdf@D|Ut0OkT?PtCxoSyes? z-5zP>#m?fd$Ql#Glj?@g{{&4;9CQRVi-SlM1Bu^|8z-X_VA=)u;&mHr1}eY>$h;z$ z89RMSWTLIiizzdXH7u|)FF@wK!OVND%u&J2)V%Uo+Ff9^ZvooZ)53W#+E)xTBCX74 z333HUn+3TDkf#J8PXXj}$cz_8G%+Z1MG(WvJPMg}wBx_d@pMq%%Mc3+Dph+|M|n-O&&oRrd2@o0agxP# z0hzIUt}-8_%x(;pR_49PoMi#dLife<3fSax^+ql@z+~EFi}B(GGVxZ97tJXAWxV(< zb{IVP)fzDF^ZxnG?rMg^Km@g~PT zcF3K^@UU-LND$s+)l8Co7K=aGC<1NDbIU|^x%geNE@gC?r2;Q65!sBr6l!A!*&|oX zOnJHN+{sIEM-~yQ*D^5}ua^e4EfWbWWn|g8|Hu>V7@I52HR6t&J1WYJ0yBfEVnlBMe-Venxhkn)j8 zG;k%D0@;4GD5^ZCOlUz;y(RC-7aL^T_wlG&{HNlU3K2F?))C&lYM+L%ed1HGiW=VF zGtn@4tl|)lQD&?K3iE9x`$cA(oh5Km@K7s)ZC9X0SG zA-7EcO0&vDsncuX4cT}u=58Rq;m5pajH+Ftfm`K@Nuo7(UPQC1bHtbO$2SG;j(AJl z$zw_-=LYIatn;wf1E6UdlTGtQa-v3rq-H$sY=Ha-nK4ofr+%J2Qfq}>BgO8Ew8G#* z(SWkxg`2wa)^)-|5jP* z?ykeQ2dYMqa7Mya0WJ_oJomYn3c-?-Hi(JL9;o((aH+ygzZBgp(0C*AOOcxSPS|0i z7*}}A<$4>}G)dwfwwBfX7RjLu2eJJbwaaY1Fk3~n9!|MuCTO*Dn^YaA_Y1Xh|kp=yG%r4 zBwd&5_FmJY-lxM4;&o;Z#)mdl0z$ zDUkjH5jDal>mJ9YWS{L6y{MKeGRR%}^+Y_?ZDh;N)9}DU-5%7{+vvlFv5`}-0Lk?g~5dhR1N=r85fv2n*A~iDj z8m0XCfF|9b-|(zb--DvQRa=P&pt-eVg`b3*Qj|Pg+=Wk;g<+~JI3>!)pYVgIj~SPv?{+8;WSzAOU)m^I!S)9+enf9k7!XI z_7kf5;K=2xQhek{#GHdh1${D*#9(1y>{0O~gW#~^VssEu`QdSqsUjJusm%#A+<8Lj z33`7^eQ6e+jDEhK+aq8GWxMiZ?g^~*E|*77hz`W6@VH5c3A8#Xl7j+Ws_PYD)w@`r zpkn*WQ?i`=yeQPA?Mu`VO4OE5AJP~Gi>FF-P5DxpYRcHtxN3KfOg{}1ZEj%tY4MW? zHu_=_yuPF;1TslB`c3Ovu-1K428>jyA!RDc-o>H^WiCPL6dXqBOVT;31J4X;dOrc8}Azfz#kUJ=X9jl@i{12WC^M`ER%k)%;E!jQa9{1S6GT)vjPP zq)3F^V;Twc1<4iU?gT@<)fSP6V@-L1_K8Lkiy&3&`c(ExG6oYm+mej;!b#zfdy_;lxUYlHWijLyeUnYsJL! zxP%dApW!VZ8plEAI7GQzzDUUHJ z`1G#8^Nxcm=?CwYRMDtyt72S3s45idXBsaiey>p=n3(9nn|Zcmm5hhWYS()`am)FH zszxFu9&3)?`=qKd$?>Drh?si15k)nPHk4yeJsrC18^?$bd(}2zuk2^ieY4SD?x|xq z2;(=K7%$88hQ>%La^<3j%PKnX8sm|&kgZnNs88R!)ioA7PW&SjPnT8C)uH&yrA1F% zj9pL!_f#=b5+f9E49qTh+gaM1={{=I%y`d%MF}NS$C_zgyT7?^)`aFpZ36sBb1k~) zj-`ozl=LMGSM=os+2(p<1m#(9)iQQcWszQ^c37XsZc42gj^ z7;PzQjaG(w5%Omgq4*LV4;*i0VD}crsP86Y5A|-(cE%ly=Wv;jCi+Y1HE^@L2)NrC zZ>a$Y^{ev#b5&2fwCYMsesPQDEJ#)xOF6cx0Oh!>gW(nsC0R4k$bdG6;<-N1o#K%HM-O7Mhyy|yWO~!!ra@9w;f9?ZFhf1-7~>V!Jf(Lqf!7Ra+8HSMe+LD`g-pLI6MQC&2yI6km)Jl92wSj-(-v~It{=s=m?yaU>E zVc^F*j0omfWo15kr?Hq4r`)Bxa@SqZ-iUkdR`I|icUxUJ@E+BLvQt-8WuQ-2D`8MK zozVGSLm6&E?p4eXSaz?0=cQH$+H^N?cRsrL_xp|BYCO1D6+&gG(eZFkSrzA^$*;yRe@lX=6=RxCfDu2gAS|VP0NYi_{74CmXOGbQe9k%Rk zC^PSID?YQgp=L6Ly^T5qC-q?+@A7 z;!!9>L^?i-!4o%hd+T2#tM!FA;o9z7`Wl1PHQj^Xfe~Mj4Pqc?WIvD*;oz4LtPFYtj{Bx4KSXel)M2(T~-h{Fu$JSj ze#>YkzZ#|uwa>MkC4#*cI6KoAhsT=au-V3T&aG_>9C=HKlbo5K` ze5XdgY{<F4C%f*&0eXP@)nc7v&pqVj*@w z_F3Gs_XDH(6$Gfh@rvPGD!0r)FAom@+0s2r(}uvP70^(+OGgIeN({m!m;`{y_+a;h z%(%Ra?ewRn(I8wi?$FP<#wB zVwOC()u>1xVba`YVST+7uP;{*F;Yr^0e+T@*%r!gl1_*X-2EhUpq%)9NNqKf#p{eX z;z{;{(Ku=vi6KV)X@NFB7`v6Ifc{F~BfXX!nhV7;ZJo?Am4E{3yx?SND{0 zQnGGz?H&vPNG|yje?ZTnO1>yAK&KHG&`e0~HSki?e;npeCTIQx>kc&~9l{VXLb76! zT(Vp?`;aj6t3NKVfmSM+@yD7`}$F*VYIbjSXfuC^#*w2@) zlX`%A@+9;C@X0%A+<|ke*y_m1x49m!5byLJ|J3HX7lzV`)}sTJel~I(&OSGG>C(J; zmmBZy*g>`^HhRR*DZpbar9W1Py#C?GhxC1Gz?-hT?+zt;LcKY4u&hgCplHZXJ54y8IU>M;+_j~^^ZlVX> z=lo%`q9@h&{egiAFPv98Z#1Kq#Jin0y4h##usJ)*?&pmfa_@N~%YF)RubgrMIyCJCR{)q4=>(!0dYLF`0538=lLJyj~6hz`)K#;RqSo;xc}T)S5@=+i}nn> zIQ9B;`y@OmC9h@ncJ|-)+MKt_Uff<;&S3Vs^b*i!W^Yd~0d4u&NR{=ty*6LFUp~O? zH`zxX2(@4pN9Oehc%Wv!zb& z9AU4?ewTF|_6BlEguNw)H|I4D`vCh_$863=WPOLdt1NcdUF5iVJi^|FA3rXmBkf+k z;Do#_(%#6vr$PzaPRT`4_Qn|_ zi)_y1zK=cCtAF3#<`d5jcyM5U^RZq79!A-zMe?sGd!w7aK$eszo_uh~_R>xVS8P|L71gzpB`E0bk0iXA?d^g(Ood58%JQ8hhQ~CAN!2HR_dOg_xVROhp z^O3%f^)~xG{47c=KuR_Fe6-yiW#RMnY5BMlOfd0`{Mc!4cHg=)HfO}skM|uy$ZkX= zrV0p@iN95eP~IK%sTzJ&$KNdV=^%ZofuA+;x0d=;M4xKoXC3^#Mty<PhZwQ#5X@rQf$MjdPM+vxM~5d6fC4J~c9{|`%l@q+*W delta 34686 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 S2A;*8gYU;99^CC6j{gS*Ka)QI diff --git a/community/include/community.hpp b/community/include/community.hpp index 51c5897..1e4f8b7 100644 --- a/community/include/community.hpp +++ b/community/include/community.hpp @@ -61,6 +61,7 @@ CONTRACT community : public contract POSITION_DISMISS, BADGE_CONFIG, BADGE_ISSUE, + BADGE_REVOKE, }; enum BadgeIssueType { @@ -247,6 +248,8 @@ CONTRACT community : public contract ACTION issuebadge(name community_account, name badge_propose_name); + ACTION revokebadge(name community_account, name revoke_badge_propose_name); + ACTION setconfig( name community_creator_name, name cryptobadge_contract_name, @@ -260,6 +263,25 @@ CONTRACT community : public contract ); private: + void create_issue_badge_code( + name community_account, + uint64_t badge_id, + uint8_t issue_type, + uint8_t issue_exec_type, + RightHolder right_issue_sole_executor, + RightHolder right_issue_proposer, + uint8_t issue_approval_type, + RightHolder right_issue_approver, + RightHolder right_issue_voter, + double issue_pass_rule, + uint64_t issue_vote_duration, + name ram_payer + ); + + void create_config_badge_code_for_admin(name community_account, uint64_t badge_id, name ram_payer); + + void create_revoke_badge_code_for_admin(name community_account, uint64_t badge_id, name ram_payer); + bool verify_approver(name community_account, name voter, uint64_t code_id, bool is_ammnend_code); bool verify_voter(name community_account, name voter, uint64_t code_id, bool is_amend_code); @@ -552,7 +574,7 @@ CONTRACT community : public contract } }; - typedef eosio::multi_index<"v1.cert"_n, v1_cert, + typedef eosio::multi_index<"v1.certs"_n, v1_cert, eosio::indexed_by<"badgeid"_n, eosio::const_mem_fun>, eosio::indexed_by<"owner"_n, eosio::const_mem_fun>> v1_cert_table; diff --git a/community/src/community.cpp b/community/src/community.cpp index 491c78c..13b6b42 100644 --- a/community/src/community.cpp +++ b/community/src/community.cpp @@ -32,12 +32,14 @@ const name BA_Create = "ba.create"_n; const name BA_Issue = "ba.issue"_n; const name BA_Claim = "ba.claim"_n; const name BA_Config = "ba.config"_n; +const name BA_Revoke = "ba.revoke"_n; const name BA_Adopt = "ba.adopt"_n; const name BA_Discard = "ba.discard"_n; const name badge_update_action = "updatebadge"_n; const name badge_create_action = "createbadge"_n; const name badge_issue_action = "issuebadge"_n; +const name cert_revoke_action = "revokecert"_n; struct createbadge_params { @@ -73,6 +75,14 @@ struct issuebadge_params bool require_claim; }; +struct revokecert_params +{ + name issuer; + uint64_t cert_id; + name owner; + string reason; +}; + void community::transfer(name from, name to, asset quantity, string memo) { if (from == _self) @@ -504,7 +514,7 @@ ACTION community::execcode(name community_account, name exec_account, uint64_t c packed_params_datastream >> packed_refer_id; check(code_itr->code_type.refer_id == packed_refer_id, "ERR:INVALID_BADGE_POSITION_CODE::Please use correct code to execute badge/position action"); } - else if (execution_data.code_action == "issuebadge"_n) + else if (execution_data.code_action == "issuebadge"_n || execution_data.code_action == "revokebadge"_n) { name packed_proposal_name; packed_params_datastream >> packed_proposal_name; @@ -522,6 +532,18 @@ ACTION community::execcode(name community_account, name exec_account, uint64_t c check(cb_data.issuer == community_account, "ERR::ISSUE_BADGE_PROPOSAL_INVALID::Issuer in issue badge proposal not the same with community account"); check(cb_data.badge_id == code_itr->code_type.refer_id, "ERR:INVALID_BADGE_POSITION_CODE::Please use correct code to execute badge/position action"); } + + if (action.account == _config.cryptobadge_contract_name && action.name == cert_revoke_action) + { + auto cb_data = unpack(&action.data[0], action.data.size()); + + check(cb_data.issuer == community_account, "ERR::REVOKE_BADGE_PROPOSAL_INVALID::Issuer in issue badge proposal not the same with community account"); + + v1_cert_table _badges(_config.cryptobadge_contract_name, cb_data.owner.value); + auto owner_badge_itr = _badges.find(cb_data.cert_id); + check(owner_badge_itr != _badges.end(), "ERR::REVOKE_BADGE_PROPOSAL_INVALID::Certification does not exist"); + check(owner_badge_itr->badge_id == code_itr->code_type.refer_id, "ERR:INVALID_BADGE_POSITION_CODE::Please use correct code to execute badge/position action"); + } } } } @@ -1951,8 +1973,8 @@ ACTION community::createbadge( RightHolder right_issue_approver, RightHolder right_issue_voter, double issue_pass_rule, - uint64_t issue_vote_duration) -{ + uint64_t issue_vote_duration +){ require_auth(community_account); v1_global_table config(_self, _self.value); @@ -1999,6 +2021,80 @@ ACTION community::createbadge( std::make_tuple(cryptobadge_contract, badge_propose_name, ram_payer)) .send(); + create_issue_badge_code( + community_account, + badge_id, + issue_type, + issue_exec_type, + right_issue_sole_executor, + right_issue_proposer, + issue_approval_type, + right_issue_approver, + right_issue_voter, + issue_pass_rule, + issue_vote_duration, + ram_payer + ); + + create_config_badge_code_for_admin(community_account, badge_id, ram_payer); + + create_revoke_badge_code_for_admin(community_account, badge_id, ram_payer); +} + +ACTION community::configbadge( + name community_account, + uint64_t badge_id, + uint8_t issue_type, + name update_badge_proposal_name) +{ + require_auth(community_account); + + v1_global_table config(_self, _self.value); + _config = config.exists() ? config.get() : v1_global{}; + const name ram_payer_system = _config.ram_payer_name; + const name cryptobadge_contract = _config.cryptobadge_contract_name; + + auto ram_payer = community_account; + if (has_auth(ram_payer_system)) + ram_payer = ram_payer_system; + + if (update_badge_proposal_name != name("")) + { + multisig_proposals proptable("eosio.msig"_n, cryptobadge_contract.value); + auto &prop = proptable.get(update_badge_proposal_name.value, "proposal not found"); + transaction trx; + datastream ds(prop.packed_transaction.data(), prop.packed_transaction.size()); + ds >> trx; + for (auto action : trx.actions) + { + if (action.account == cryptobadge_contract && action.name == badge_update_action) + { + auto cb_data = unpack(&action.data[0], action.data.size()); + + check(cb_data.issuer == community_account, "ERR::CREATE_BADGE_PROPOSAL_INVALID::Issuer in update badge proposal not the same with community account"); + check(cb_data.badge_id == badge_id, "ERR::CREATE_BADGE_PROPOSAL_INVALID::Issuer in update badge proposal not the same with config badge id"); + } + } + + action( + permission_level{community_account, "active"_n}, + "eosio.msig"_n, + "approve"_n, + std::make_tuple(cryptobadge_contract, update_badge_proposal_name, permission_level{community_account, "active"_n})) + .send(); + + vector action_permission = {{community_account, "active"_n}}; + if (ram_payer == ram_payer_system) + action_permission.push_back({ram_payer_system, "active"_n}); + + action( + action_permission, + "eosio.msig"_n, + "exec"_n, + std::make_tuple(cryptobadge_contract, update_badge_proposal_name, ram_payer)) + .send(); + } + v1_code_table _codes(_self, community_account.value); v1_code_sole_decision_table _code_execution_rule(_self, community_account.value); @@ -2009,11 +2105,167 @@ ACTION community::createbadge( v1_position_table _positions(_self, community_account.value); - auto getByCodeName = _codes.get_index<"by.code.name"_n>(); - auto ba_create_code = getByCodeName.find(BA_Create.value); + name issue_badge_code_name; + if (issue_type == BadgeIssueType::WITHOUT_CLAIM) + { + issue_badge_code_name = BA_Issue; + } + else if (issue_type == BadgeIssueType::CLAIM_APPROVE_BY_ISSUER) + { + issue_badge_code_name = BA_Claim; + } + else + { + check(false, "ERR::BADGE_ISSUE_TYPE_INVALID::Badge issue type is invalid"); + } - vector code_actions; - code_actions.push_back("issuebadge"_n); + auto getByCodeReferId = _codes.get_index<"by.refer.id"_n>(); + uint128_t issue_badge_reference_id = build_reference_id(badge_id, CodeTypeEnum::BADGE_ISSUE); + auto issue_badge_code_itr = getByCodeReferId.find(issue_badge_reference_id); + uint64_t issue_badge_code_id; + + // save new code to the table + if (issue_badge_code_itr == getByCodeReferId.end()) + { + vector code_actions; + code_actions.push_back("issuebadge"_n); + auto new_issue_badge_code = _codes.emplace(ram_payer, [&](auto &row) { + row.code_id = _codes.available_primary_key(); + row.code_name = issue_badge_code_name; + row.contract_name = get_self(); + row.code_actions = code_actions; + row.code_type = {CodeTypeEnum::BADGE_ISSUE, badge_id}; + }); + issue_badge_code_id = new_issue_badge_code->code_id; + } + else + { + getByCodeReferId.modify(issue_badge_code_itr, ram_payer, [&](auto &row) { + row.code_name = issue_badge_code_name; + row.code_type = {CodeTypeEnum::BADGE_ISSUE, badge_id}; + }); + issue_badge_code_id = issue_badge_code_itr->code_id; + } +} + +ACTION community::issuebadge(name community_account, name badge_propose_name) +{ + require_auth(community_account); + + v1_global_table config(_self, _self.value); + _config = config.exists() ? config.get() : v1_global{}; + const name ram_payer_system = _config.ram_payer_name; + const name cryptobadge_contract = _config.cryptobadge_contract_name; + + auto ram_payer = community_account; + if (has_auth(ram_payer_system)) + ram_payer = ram_payer_system; + + action( + permission_level{community_account, "active"_n}, + "eosio.msig"_n, + "approve"_n, + std::make_tuple(cryptobadge_contract, badge_propose_name, permission_level{community_account, "active"_n})) + .send(); + + vector action_permission = {{community_account, "active"_n}}; + if (ram_payer == ram_payer_system) + action_permission.push_back({ram_payer_system, "active"_n}); + + action( + action_permission, + "eosio.msig"_n, + "exec"_n, + std::make_tuple(cryptobadge_contract, badge_propose_name, ram_payer)) + .send(); +} + +ACTION community::revokebadge(name community_account, name revoke_badge_propose_name) +{ + require_auth(community_account); + + v1_global_table config(_self, _self.value); + _config = config.exists() ? config.get() : v1_global{}; + const name ram_payer_system = _config.ram_payer_name; + const name cryptobadge_contract = _config.cryptobadge_contract_name; + + auto ram_payer = community_account; + if (has_auth(ram_payer_system)) + ram_payer = ram_payer_system; + + action( + permission_level{community_account, "active"_n}, + "eosio.msig"_n, + "approve"_n, + std::make_tuple(cryptobadge_contract, revoke_badge_propose_name, permission_level{community_account, "active"_n})) + .send(); + + vector action_permission = {{community_account, "active"_n}}; + if (ram_payer == ram_payer_system) + action_permission.push_back({ram_payer_system, "active"_n}); + + action( + action_permission, + "eosio.msig"_n, + "exec"_n, + std::make_tuple(cryptobadge_contract, revoke_badge_propose_name, ram_payer)) + .send(); +} + +ACTION community::setconfig( + name community_creator_name, + name cryptobadge_contract_name, + name token_contract_name, + name ram_payer_name, + symbol core_symbol, + uint64_t init_ram_amount, + asset min_active_contract, + asset init_net, + asset init_cpu +){ + require_auth(_self); + + v1_global_table config(_self, _self.value); + _config = config.exists() ? config.get() : v1_global{}; + + _config.community_creator_name = community_creator_name; + _config.cryptobadge_contract_name = cryptobadge_contract_name; + _config.token_contract_name = token_contract_name; + _config.ram_payer_name = ram_payer_name; + _config.core_symbol = core_symbol; + _config.init_ram_amount = init_ram_amount; + _config.init_net = init_net; + _config.init_cpu = init_cpu; + _config.min_active_contract = min_active_contract; + + config.set(_config, _self); +} + +void community::create_issue_badge_code( + name community_account, + uint64_t badge_id, + uint8_t issue_type, + uint8_t issue_exec_type, + RightHolder right_issue_sole_executor, + RightHolder right_issue_proposer, + uint8_t issue_approval_type, + RightHolder right_issue_approver, + RightHolder right_issue_voter, + double issue_pass_rule, + uint64_t issue_vote_duration, + name ram_payer + ) { + v1_code_table _codes(_self, community_account.value); + + v1_code_sole_decision_table _code_execution_rule(_self, community_account.value); + v1_amend_sole_decision_table _amend_execution_rule(_self, community_account.value); + + v1_code_collective_decision_table _code_vote_rule(_self, community_account.value); + v1_ammend_collective_decision_table _amend_vote_rule(_self, community_account.value); + + v1_position_table _positions(_self, community_account.value); + + auto getByCodeName = _codes.get_index<"by.code.name"_n>(); name issue_badge_code_name; if (issue_type == BadgeIssueType::WITHOUT_CLAIM) @@ -2029,6 +2281,9 @@ ACTION community::createbadge( check(false, "ERR::BADGE_ISSUE_TYPE_INVALID::Badge issue type is invalid"); } + vector code_actions; + code_actions.push_back("issuebadge"_n); + auto getByCodeReferId = _codes.get_index<"by.refer.id"_n>(); uint128_t issue_badge_reference_id = build_reference_id(badge_id, CodeTypeEnum::BADGE_ISSUE); @@ -2124,8 +2379,23 @@ ACTION community::createbadge( }); } } +} - code_actions.clear(); +void community::create_config_badge_code_for_admin(name community_account, uint64_t badge_id, name ram_payer) { + v1_code_table _codes(_self, community_account.value); + + v1_code_sole_decision_table _code_execution_rule(_self, community_account.value); + v1_amend_sole_decision_table _amend_execution_rule(_self, community_account.value); + + v1_code_collective_decision_table _code_vote_rule(_self, community_account.value); + v1_ammend_collective_decision_table _amend_vote_rule(_self, community_account.value); + + v1_position_table _positions(_self, community_account.value); + + auto getByCodeName = _codes.get_index<"by.code.name"_n>(); + auto getByCodeReferId = _codes.get_index<"by.refer.id"_n>(); + + vector code_actions; code_actions.push_back("configbadge"_n); uint128_t config_badge_reference_id = build_reference_id(badge_id, CodeTypeEnum::BADGE_CONFIG); @@ -2148,7 +2418,7 @@ ACTION community::createbadge( else { getByCodeReferId.modify(config_badge_code_itr, ram_payer, [&](auto &row) { - row.code_name = issue_badge_code_name; + row.code_name = BA_Config; row.code_exec_type = ExecutionType::SOLE_DECISION; row.code_type = {CodeTypeEnum::BADGE_CONFIG, badge_id}; }); @@ -2181,60 +2451,7 @@ ACTION community::createbadge( } } -ACTION community::configbadge( - name community_account, - uint64_t badge_id, - uint8_t issue_type, - name update_badge_proposal_name) -{ - require_auth(community_account); - - v1_global_table config(_self, _self.value); - _config = config.exists() ? config.get() : v1_global{}; - const name ram_payer_system = _config.ram_payer_name; - const name cryptobadge_contract = _config.cryptobadge_contract_name; - - auto ram_payer = community_account; - if (has_auth(ram_payer_system)) - ram_payer = ram_payer_system; - - if (update_badge_proposal_name != name("")) - { - multisig_proposals proptable("eosio.msig"_n, cryptobadge_contract.value); - auto &prop = proptable.get(update_badge_proposal_name.value, "proposal not found"); - transaction trx; - datastream ds(prop.packed_transaction.data(), prop.packed_transaction.size()); - ds >> trx; - for (auto action : trx.actions) - { - if (action.account == cryptobadge_contract && action.name == badge_update_action) - { - auto cb_data = unpack(&action.data[0], action.data.size()); - - check(cb_data.issuer == community_account, "ERR::CREATE_BADGE_PROPOSAL_INVALID::Issuer in update badge proposal not the same with community account"); - check(cb_data.badge_id == badge_id, "ERR::CREATE_BADGE_PROPOSAL_INVALID::Issuer in update badge proposal not the same with config badge id"); - } - } - - action( - permission_level{community_account, "active"_n}, - "eosio.msig"_n, - "approve"_n, - std::make_tuple(cryptobadge_contract, update_badge_proposal_name, permission_level{community_account, "active"_n})) - .send(); - - vector action_permission = {{community_account, "active"_n}}; - if (ram_payer == ram_payer_system) - action_permission.push_back({ram_payer_system, "active"_n}); - - action( - action_permission, - "eosio.msig"_n, - "exec"_n, - std::make_tuple(cryptobadge_contract, update_badge_proposal_name, ram_payer)) - .send(); - } - +void community::create_revoke_badge_code_for_admin(name community_account, uint64_t badge_id, name ram_payer) { v1_code_table _codes(_self, community_account.value); v1_code_sole_decision_table _code_execution_rule(_self, community_account.value); @@ -2245,108 +2462,63 @@ ACTION community::configbadge( v1_position_table _positions(_self, community_account.value); - name issue_badge_code_name; - if (issue_type == BadgeIssueType::WITHOUT_CLAIM) - { - issue_badge_code_name = BA_Issue; - } - else if (issue_type == BadgeIssueType::CLAIM_APPROVE_BY_ISSUER) - { - issue_badge_code_name = BA_Claim; - } - else - { - check(false, "ERR::BADGE_ISSUE_TYPE_INVALID::Badge issue type is invalid"); - } - + auto getByCodeName = _codes.get_index<"by.code.name"_n>(); auto getByCodeReferId = _codes.get_index<"by.refer.id"_n>(); - uint128_t issue_badge_reference_id = build_reference_id(badge_id, CodeTypeEnum::BADGE_ISSUE); - auto issue_badge_code_itr = getByCodeReferId.find(issue_badge_reference_id); - uint64_t issue_badge_code_id; - // save new code to the table - if (issue_badge_code_itr == getByCodeReferId.end()) + vector code_actions; + code_actions.push_back("revokebadge"_n); + + uint128_t revoke_badge_reference_id = build_reference_id(badge_id, CodeTypeEnum::BADGE_REVOKE); + auto revoke_badge_code_itr = getByCodeReferId.find(revoke_badge_reference_id); + uint64_t revoke_badge_code_id; + + // save revoke badge code to the table + if (revoke_badge_code_itr == getByCodeReferId.end()) { - vector code_actions; - code_actions.push_back("issuebadge"_n); - auto new_issue_badge_code = _codes.emplace(ram_payer, [&](auto &row) { + auto new_revoke_badge_code = _codes.emplace(ram_payer, [&](auto &row) { row.code_id = _codes.available_primary_key(); - row.code_name = issue_badge_code_name; + row.code_name = BA_Revoke; row.contract_name = get_self(); row.code_actions = code_actions; - row.code_type = {CodeTypeEnum::BADGE_ISSUE, badge_id}; + row.amendment_exec_type = ExecutionType::SOLE_DECISION; + row.code_type = {CodeTypeEnum::BADGE_REVOKE, badge_id}; }); - issue_badge_code_id = new_issue_badge_code->code_id; + revoke_badge_code_id = new_revoke_badge_code->code_id; } else { - getByCodeReferId.modify(issue_badge_code_itr, ram_payer, [&](auto &row) { - row.code_name = issue_badge_code_name; - row.code_type = {CodeTypeEnum::BADGE_ISSUE, badge_id}; + getByCodeReferId.modify(revoke_badge_code_itr, ram_payer, [&](auto &row) { + row.code_name = BA_Revoke; + row.code_exec_type = ExecutionType::SOLE_DECISION; + row.code_type = {CodeTypeEnum::BADGE_REVOKE, badge_id}; }); - issue_badge_code_id = issue_badge_code_itr->code_id; + revoke_badge_code_id = revoke_badge_code_itr->code_id; } -} - -ACTION community::issuebadge(name community_account, name badge_propose_name) -{ - require_auth(community_account); - - v1_global_table config(_self, _self.value); - _config = config.exists() ? config.get() : v1_global{}; - const name ram_payer_system = _config.ram_payer_name; - const name cryptobadge_contract = _config.cryptobadge_contract_name; - auto ram_payer = community_account; - if (has_auth(ram_payer_system)) - ram_payer = ram_payer_system; - - action( - permission_level{community_account, "active"_n}, - "eosio.msig"_n, - "approve"_n, - std::make_tuple(cryptobadge_contract, badge_propose_name, permission_level{community_account, "active"_n})) - .send(); - - vector action_permission = {{community_account, "active"_n}}; - if (ram_payer == ram_payer_system) - action_permission.push_back({ram_payer_system, "active"_n}); - - action( - action_permission, - "eosio.msig"_n, - "exec"_n, - std::make_tuple(cryptobadge_contract, badge_propose_name, ram_payer)) - .send(); -} - -ACTION community::setconfig( - name community_creator_name, - name cryptobadge_contract_name, - name token_contract_name, - name ram_payer_name, - symbol core_symbol, - uint64_t init_ram_amount, - asset min_active_contract, - asset init_net, - asset init_cpu) -{ - require_auth(_self); - - v1_global_table config(_self, _self.value); - _config = config.exists() ? config.get() : v1_global{}; + auto revoke_badge_code_sole_decision = _code_execution_rule.find(revoke_badge_code_id); + auto revoke_badge_amend_code_sole_decision = _amend_execution_rule.find(revoke_badge_code_id); + if (revoke_badge_code_sole_decision == _code_execution_rule.end()) + { + _amend_execution_rule.emplace(ram_payer, [&](auto &row) { + row.code_id = revoke_badge_code_id; + row.right_executor = admin_right_holder(); + }); - _config.community_creator_name = community_creator_name; - _config.cryptobadge_contract_name = cryptobadge_contract_name; - _config.token_contract_name = token_contract_name; - _config.ram_payer_name = ram_payer_name; - _config.core_symbol = core_symbol; - _config.init_ram_amount = init_ram_amount; - _config.init_net = init_net; - _config.init_cpu = init_cpu; - _config.min_active_contract = min_active_contract; + _code_execution_rule.emplace(ram_payer, [&](auto &row) { + row.code_id = revoke_badge_code_id; + row.right_executor = admin_right_holder(); + }); + } + else + { + _amend_execution_rule.modify(revoke_badge_amend_code_sole_decision, ram_payer, [&](auto &row) { + row.right_executor = admin_right_holder(); + }); - config.set(_config, _self); + _code_execution_rule.modify(revoke_badge_code_sole_decision, ram_payer, [&](auto &row) { + row.right_executor = admin_right_holder(); + }); + } } bool community::verify_voter(name community_account, name voter, uint64_t code_id, bool is_amend_code) @@ -2432,8 +2604,9 @@ bool community::is_pos_candidate(name community_account, uint64_t pos_id, name o for (int i = 0; i < _required_badge_ids.size(); i++) { v1_cert_table _badges(cryptobadge_contract, owner.value); - auto owner_badge_itr = _badges.find(_required_badge_ids[i]); - if (owner_badge_itr != _badges.end()) + auto get_cert_by_badge_id = _badges.get_index<"badgeid"_n>(); + auto owner_badge_itr = get_cert_by_badge_id.find(_required_badge_ids[i]); + if (owner_badge_itr != get_cert_by_badge_id.end()) { return true; } @@ -2491,8 +2664,9 @@ bool community::is_pos_voter(name community_account, uint64_t pos_id, name owner for (int i = 0; i < _required_badge_ids.size(); i++) { v1_cert_table _badges(cryptobadge_contract, owner.value); - auto owner_badge_itr = _badges.find(_required_badge_ids[i]); - if (owner_badge_itr != _badges.end()) + auto get_cert_by_badge_id = _badges.get_index<"badgeid"_n>(); + auto owner_badge_itr = get_cert_by_badge_id.find(_required_badge_ids[i]); + if (owner_badge_itr != get_cert_by_badge_id.end()) { return true; } @@ -2548,8 +2722,9 @@ bool community::verify_account_right_holder(name community_account, RightHolder for (int i = 0; i < _required_badge_ids.size(); i++) { v1_cert_table _badges(cryptobadge_contract, owner.value); - auto owner_badge_itr = _badges.find(_required_badge_ids[i]); - if (owner_badge_itr != _badges.end()) + auto get_cert_by_badge_id = _badges.get_index<"badgeid"_n>(); + auto owner_badge_itr = get_cert_by_badge_id.find(_required_badge_ids[i]); + if (owner_badge_itr != get_cert_by_badge_id.end()) { return true; } @@ -2726,4 +2901,4 @@ community::RightHolder community::admin_right_holder() #endif EOSIO_ABI_CUSTOM(community, - (setapprotype)(setvoter)(setapprover)(setaccess)(transfer)(createacc)(create)(initcode)(inputmembers)(initadminpos)(execcode)(createcode)(setverify)(createpos)(configpos)(nominatepos)(approvepos)(voteforcode)(voteforpos)(dismisspos)(setexectype)(appointpos)(proposecode)(execproposal)(verifyholder)(createbadge)(issuebadge)(configbadge)(setsoleexec)(setproposer)(setvoterule)(setconfig)) + (setapprotype)(setvoter)(setapprover)(setaccess)(transfer)(createacc)(create)(initcode)(inputmembers)(initadminpos)(execcode)(createcode)(setverify)(createpos)(configpos)(nominatepos)(approvepos)(voteforcode)(voteforpos)(dismisspos)(setexectype)(appointpos)(proposecode)(execproposal)(verifyholder)(createbadge)(issuebadge)(configbadge)(revokebadge)(setsoleexec)(setproposer)(setvoterule)(setconfig))