From 56914ff8169005b0b64c8d6b955dd115ef0c4146 Mon Sep 17 00:00:00 2001 From: chenfei Date: Sat, 28 Jul 2018 16:41:28 +0800 Subject: [PATCH 1/8] modify rpc tokenaddress --- .../src/rpc/rawtransaction.cpp | 32 ++++++++++-------- Token_Wallet_API.pdf | Bin 196535 -> 196432 bytes 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp index 0ff4c29..b7f3941 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp @@ -1708,7 +1708,7 @@ UniValue tokensearch(const UniValue ¶ms, bool fHelp) return result; } -UniValue GetAccountTokenAddress(const std::string &account) +UniValue GetTokenAddress(const std::string &account, const std::string &token) { LOCK2(cs_main, pwalletMain->cs_wallet); assert(pwalletMain != NULL); @@ -1733,19 +1733,22 @@ UniValue GetAccountTokenAddress(const std::string &account) const CScript &pk = out.tx->vout[out.i].scriptPubKey; if (pk.IsPayToToken()) { - UniValue entry(UniValue::VOBJ); - CTxDestination address; - if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) - { - entry.push_back(Pair("address", EncodeDestination(address))); - } int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - + + if (tokenName != token) + continue; + + UniValue entry(UniValue::VOBJ); + CTxDestination address; + if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + { + entry.push_back(Pair("address", EncodeDestination(address))); + } entry.push_back(Pair("token", tokenName)); entry.push_back(Pair("amount", tokenAmount)); result.push_back(entry); @@ -1756,18 +1759,19 @@ UniValue GetAccountTokenAddress(const std::string &account) UniValue tokenaddress(const UniValue ¶ms, bool fHelp) { - if (fHelp || params.size() != 1) + if (fHelp || params.size() != 2) throw runtime_error( - "tokenaddress \"account\" \n" + "tokenaddress \"account\" \"token\"\n" "\nList the addresses that contains token.\n" "Returns address list.\n"); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR), true); - if (params[0].isNull()) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, argument must be non-null"); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VSTR), true); + if (params[0].isNull() || params[1].isNull()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameters, arguments must be non-null"); std::string account = params[0].get_str(); - return GetAccountTokenAddress(account); + std::string token = params[1].get_str(); + return GetTokenAddress(account, token); } void ListTokenTransactions(const CWalletTx &wtx, diff --git a/Token_Wallet_API.pdf b/Token_Wallet_API.pdf index 34442c78b83a72a129ea287aa06fe9e33a44a331..d01169c09f4189e189754dd7c3de3b00285fbf76 100644 GIT binary patch delta 8064 zcmZXZbxhsM)`rny#Y%CCQ?$s&Hf)@YOL2-*DDLk3aCa^4?q0MMXBVe96o=x_ja$ES zZ*KDCoHKt+-aJ{E^=2hAYckXJ2W#pXE8*$|m=nwm=1qKf^FNhLi71T7o2-wR1kmKY zcy#nGRGYm}vhDC&?t)atDQ5CN9p#GHmUA9JYC6kA`Oi`*4#H0l;+5=wNtr~Kt#{nO zPDoU55t!0$0t#cYnR*y)YG(En>-h*4xww}i@sv>xMwuo3$zV8)NH^lps`6k(lCU?Q z*Wj`OLho3HLR7iF2aiYACBV7@fhf|4MMDV3a_a~#?@&g5WU98spl9f9Qa}s^sf}g^ zcM+`hFyb{qYZc-4A`LQI)NC&gGr#i*_7?Rg99`*Ip}5kJ%m>b05uLeG+%ajHp<3H> zyr4-=ILuq}Ba#vg6IEAEF5D8dpcjce_lBCi4Sue!Wl_ooIbqD5k{B8TtW#xXU@}2Q zX+ELC)qt{3SMfM^y@A63s_7M!q!FWrsA`d&fD)Yw>Pby@&H~;U%^{>cGeSdbTsh4i zU1|%m{-vDne+NGMOuf7=^jZ&(_;Mi(45fad1xQN-OEqIoTH;$>E9ojkW-dQOz@|%I zQrnY!g6`z{HMQQFB1hIiiFFI43%sb6O+eRwOmtK_*#p2 zl0IdN`*dc3Y_&UEQ=Y6`?Oej=u2Bi1R!W?4&ZimcizYcUu1Qs;W8gwpQ#1q;zaew* zY^YkdDvhO}MaW_SPoH}@h@%>5X0bqrL$UPNpr|5;`G}+(MJ`az5G~mr-l~kIE>+@q z72GxX-D;-1aCB-uyl^G|mvU)tm8Kn9v-NSnOcE{z?Pmo%@%|!50->=6O!=jyVClZ& z%TP{Nna>*>Ig-%SxQ1Xw(iIozVQRGOj?G6Ri)mH;$+x+RlTA8A1D)cpTO(+%7l$IF ztJosy1gz5fJko%uNY7LP)qy9`ZA6I-bQ!Q?c}(`t)~{^mwlQ7}UR zOR&GP@sL5TzF7kN?s}PZvmt?+K&6PdO_v`J$EzHy_Nc*-0js5(wiH*Y3Q-6-?Ea?zjT-*Vvx~XeCRc%`=)tp z$i4}AUT_xpxz%NkuPUTB&OOrccH@LJH?5aFCSKvFC~}UM%U2Plf`dtl{bX%#U?RXK z)nu_CDtg?cnZ#gc=4K+|d6%xb&03j{ODB0Em?0e$&;cF$VIeYz zMa@Q$L<1eJ4sURX=B?2J#g+<+j?=OXzN%n!H_(MUinZe#yJpvLdQmgJitoWj86%MB zKODo|A#w=qdhtB8| zB{hL}30MOL*@am#wUzz9z4Hpb??^wWlwpj0ah8>ew;c(qh{kA-4&fPw|5gZx#S1dR zQIaNUjCn{xsOZCcDIZ+wP}rjqEEnfpXo?tgdG}!#&oSMWicv{q>&}h_IVQI#laXP4 z(`-T&y-axCyaViU;tL8mXFX!0CmCj21A)L7>w^L~lCpFS_6-kBnINKjdmn8<{5S1Y zdq$G22&Bx{uM*^(s4d{Ed3cgrL2h#hnwysK=;yUBV=gHdP2IQ%!yD0{=v5ePX4N)z z^pxv??e<4yD$7+iSabK*==zC+DZ?AvYd*PJvWSW{QyN@QvaoE7Sd?A2? zRhH+L>1orOykx_j$Ue;6nN>zZrlVj7uj!TMoU+)?3^Y2MD^N@wR%Zxl_ic52|BtjA zQ*ze3B@xu9#7VpPmQhi^`5T%ez7~l28^=DQAo%TF@t=>6*~^0kgl}XhXMM8nI}+mw zzKX24WFh1}>^<|vdwIW!!Z|xC@yrHpbGL<(pwU9uTWS}#`fqzIkZtC-HWDuQf`{qR z2>s3)-^{>ctXO`Bsd~_xcB+3(aBCa4^PQ7v6!y4V;@bXZ=KZMHX{G3_o<}flG~u=P zG3#J>%;F%6E73nU_heW^e`w?yGT#0@FL3;Hkts|9hTRYw2R~Yo|JG8It=j|`x-a3Z zkU|(Tz<*NYPN8~aok=or)qRFlAKMIe)*!tPV{V02J%$&Lb48F;TZfa~x%4Z|KUp2L z>~Iu1yBM8Rhm4#%AI0%?72&<8sIMOPni`LrJG&|L6!Zr6-5An!Hm9CA8iW&GCMzyN zaz4VzCGCmGPFKAOsDGL=AG84gjke6q9-AQ|KvS*pv&eFPScZ}OUmM;GK?&Tb^4h}c)3qCBj;A-la{Q?Iy-vT zH!LLaEQj>KXBn|?+GwpI_8e%pGFX((EleHRQs~`7>&bpa=zTz3p8%WdhhB8u9;u%} z)JJJ}u4TWj$#TXW2YN`~ZM}a~Hv4FY z>6v|!`~!m>Fzhh1wE_3H|8|DXAwG4hUdG3FJnYVH#s|BseA$!|43d` zP6~wpL*!nAEhSapZjO$*^Km2)ud{b4uxDXKG3cx=HglsCPKskp*tOg`VAOW`QeEr| zgU(2#)+^0;h2Ki89a8Q&^y=a-kI}}OE70Y?(k4C#T-WV=c5FO)T?Y4e#7^62?5&{D z4%|+wq^XyDrwx5d&d1`H0p2@7enVCCb1WtIGIFs~V@7=Sfu?GZ@`i;>DQ-quu2SQN zGOrjlpIreE)ltS<)lkjxa4Gi;#VGbo-=wc5rbe!QIc8mDv5+s21A`SWZ8q`!>Z8}8LAEMRh=g6L znveSfjv7Q(+fDmH4CY5&30=1D3BFyIr}D{KL{F#TD*+xC7^Q9v9WWu4Gkf`!P{_8zV5@yP|7=thjp27-{RwMMXlSxidQPUPz zLuQ_%qWXLnU6(}PJ^fR-{%hx@XlDL2Uj$vrd|h#v$*1m;@z@8*SWsvB~s>k&sML(HJpFS1;^_}mf zi5nfzF;mzOU86Ei! z=9Tock6|y`G!oP%hgEeuQlXLl09Fj()FXM>N8J0Yn*J4L5b0dNYEBxjf4?mJU{AqH z^);)R+);OE&kKXHYhd67kn)(B>RbI1K}=0|B*yCC7Rp=bsmKj2e0K- zU4dMP78>hRH~eGAdW+{hkiWr-j4C>_Zq&gpKb9GylVNg^v}{kOXfY&-m)hAS?PId zEGV>FREx2GxPI8PDXIQr{&2lAbQS}ju2+uldTJgI0;8`^pnhNe-5B777m{-|uUm=I zjn1P(sPP$<2%|&X*kf9t#*zrIts1h(yj>9qYUn+-pIk^ za?ED*Poi1$e)IU7?N}V8`b`x~typ`aa3vn;!qRb;=R>KJuij;c)-q9@B$b3VVo`mM z-RobtpqWIE3A7dJUO}3LWy7FM1G22GEw=ntPr_pc@9ejB5ovTOgQ4DlMG@%um`xzE zV>F9d!&iZT$*XYF4sDD0E%ujEW32xiw#f}N8U{6nVJdpBXGf@}S`YJ6=&T6!>Bm!L zV4O6umX-nqVx9fD##5>pKC(6g_X3Ke!tbY2#ud9)550=p`9pXOXWT|q%?3;{&~^pN zS{^%q>KudpCigk|&-fxETU7igwnDvCO8Uii965elJ7Rtv@i zpOY?hvAgtOIYx10 zlaK?8f_f-neh*G7Sh2=gD3Q0d5v#Jq!?j0y8s)LrJf-ogIF4xWeHH%Gy)9~I(jC9} zM}=2rp5zFsq>9*<(J#=a8SowV_6tQ`R}AUejh? z*c!_HgKxYEFo6Vqu2PeBX#&+T-46!Bcz9}p)PYi_;!{@xMCf!q$eNUi)U`zV>2Xz3 z*@uH9xIx`#BH2NPhf(ccB-np?jqmnl-DG*`>?Dwy9c-Ux8&HO5K!f%5vB{F%V{_Ir z6R${1Vi%T~8y@C(vwuhk>uZ${(D~tcP72n@;f`<47;hKI(avn z%Rz{zg(B!s|9EDjXy;I6=*@evJ_9s{@ZE^|y}*c(G!x2hPH1p<9Lk!-uVj4W#$STp zOQmu!C4iA$doBOz#x&u^YDvEL=cKY~Lq@ID>bSMMd?p4B$7a{EX(aRS+kcuV?YoPk z!NSK{h7kJw@E{KXakM^xFFa0;{cM7|T1Pc4rh_JqolTWc74>7F9>zuPB@t6S)Oa~+ zIxV{yFk2Ook8OHrF3fZFxpNVLY#zCE&aeR55 z$faY7dMBE%5ZY;WfL`-kE!k#UwI#H$FroW!c3BAi@4+UhSz0p$JFtZ)@-8KQRTyz%_c(w3T;m4cYFg`U8kKFZdl$o)7%%a$m#A! zX$G3-?M>u$IJH}cQ-$`NbIiZp+QoI~Bs&)#l$(*C>w3<3q~B5g7NZh5bA191`*Cr% z3fAoqGmgq|jl60_67l)y%=@zTbuQT}*6e zgnvzWkWkd6LpBNF8q_5>WH9!?BUmp~izDk?RL+=-&z}W_2%LzCMB;X|xGS#$XlrV6 z7adLsLs+exy=TW7@L2^FswZnPZ`GJv$hV>pjA2+Gh~Xqu(DkM+g}HBMI@-!@u5-b) z6S90{1(6-BXnOidwjX#kd}x-M^A~-ms5#h0j55cuQyvOuRtF^VNK%Ie4Uo(#{573! zX@7K~^DUvk_!9>mkIfT3R0s{&;HspqqWPf>b#+~f$RR~7=aP%YnPL>4cxl5Kf(Zq1JD-(TY z@-Llb%t*#Rl&5co_*yTgqkDX&jnKs+*g;Kr8kHYm9tXL~riVxBd92}pDy!bcy0I8G z$Z4kc(@fuey-A3@xj6Rk)l+J5^=vnaGxfnJvRse8pjTy17*U1V6vHqZa4byo$KV=?WuReB}+}ZXEV^YDaEl>t*V-qbX)t+wNn>cBr5=Lp?43>bpck&?jb&-JcaK zc|9xzgM>1pxlh@0Wg_xvDT<<3nnM`Qb;RwT4%DQhm1jvphjmW@h}Hh2!mfrv-|9_s zDU`Ugu9jJn1M?OnC!V^otkg;;t8u-( z%yk(}n19!MO}Bwut(HGtt4AB=2i`T0T4vo95!m%!k5c@Z<6MXLr%`PaKcq=;SKc$t zp~E*qSQiy4a4-)r*0oZf`oeA^i+^J{aj@28O$MiZMZ#mN?7?2ALf2>6j5@=GYB~!O z=C1XxQ+Y0UAPP}$li(OU*z)ATSw&wF1H#j!712wh3H~*K#=^Ul9+JRr(GvX@?$F3K^(bMdvI(TPl#Ay|97ZJk{dSa`&*sNt4i-j!Hxe~i)-kwx#p z7Ge5?0$}_5-~ZSNcQ9h75{=yZZbZDg?`oNX8XqHCMjEI9m(*Wg=b)0A4v@IJt!oE* zdW)+awu-GzjX2h^3i@%!pKhYqJKArTksEp#x}KZFLGMv!F{!#RzIQ3Y zD|wgY&i1?tEJZA9ia(&|MX#eiW)`4R zHL28uy^0AzALKUuepn~wm<8Cn;lVz1t4OP9lb9B}@#=kmVZEt?IQweAB4#{gFjgb#^F=~w#0dS6 z3=mm4B0ceH{)~;0@4&cmZJ4`oEveMlNG2iXJhfB9YgHanctU73PIUm<&3D}5ED3fT ziY@_@NTQrHr)dehbq)n}Rk0skr|t%Q4^7<-C2dH_@N*kaahL&e4N+`{4T85=3DNVZ9xd?CXbJ_U*L&z*0jcsqWnIMl?9wh}ExvNi4;&-;elM({&c* zTC5=o{cU~#%PWHRmiz*%Z(CIHN`u}eZS4V{)k{-G7jjr7jT4Ey<5Kt0tIreZUdou& z=l4;Pwwi7R1pMXhIfB=r=-|~TE<(@lH+QDkKE^R_=2)Kfa-Hi z%c6uR_%|3h*Rk4T3I2^x#gMg@?qlMkrxbY6=u9P(P%RF z4vUoJ52eIsykEcE_zVm5ph}vBIO|rdI7sbrKN}(TaQ2s6mL*iDiJiB$Db_U&a4SYb%zDmAcSlGKV30wI8xA%! zcM+MYO6Di_;Ue^EA*FOM^V~a^4z0tw_+SkCr0c7AWF3MsjN$dRxgQ=QgZa(*-OIcp z8I!XhHU_KR<(@Y=~m!$&qU>> z7}n9ey>};c!YyS2GN7kEfPDABf0|*5GgeF_!RD({IERSL27Ya{3ka6DX77k_8MyH) zFh!Ei{_cj4E-5jMf`;|Bhbx!FTqc6nlyyd78dvv&!%eJ)~~UeNoa@xLJe&^29rE;|AJ>nAf+AwPzzY556g+#==$l=ygs)f~ z$O!uIO$DQ5Wi;*Rzo6R$UyA6<*0%)l7a>I#t1)J{&?sIBcD)&Dp5N!a_2c1)=5$~9 zKoj@)N zSWR>V9-_c@R*a>K@;t(UGif0%YVCVrynI|8(QHWpF<)m;&If$*G;v%9#dihU&2g9BTUV^kuqqKrq>basXRIy(eer4v|rP~45VAgb6!?;pzoqN+; z#iIR{lu-V@30UhBH8OKgUD&eaSJM$_7Ft2o(7>rNjJ5qEu{*U_Qho{SdLDlAAi{sI z9Ty%w)06c4SBolk4%x+obnh)EtGnl^YEcz^n9U<`BHBFJj{b$V*GLrUhRQuiqa6Fz zTq4NqBK`u-kFZ#njcI28>3>hXe<=qOYfL`s;AoogXd1+}Xd0xiE9vzQNT}((4@ivZ zflo-b02ejqe+IQZHRgW>Cl3!V|34WYn3Lz949p|I{V&GL!}%}9$Hn(A1_u2v4*37X zVDP^a3;f60e|`OboB%%<{13*($;tf>gIpjk9=?AV}yni(p0X+$6@GxaSCmW!$IMwI1@Q}tSy_JDunK3Ot)b#q4w3fooc%h>k{j8! zQ3EhXN9xhosrZCw9$;(2#+C*jRy?PhWc*416G+Mx?Lr&_9DONB=6gfB4Q$temAMPT9Iqx8FVOO8kkg2XWe8r)(b@xN1iB4io zsjmq4ql2DsdUS}j zvbvsV+P2bIc=j>>%Mam-ruV6;Yurgt|8I~0YTwY|hRJZ?=ZwSBFq|~J_|4L+!*}r~ zF&GlFV8%Y2Li{G-L{C%VxB;ATFH@k*`!`cBfE10w&XqKbOOI+qw82d%m7P7LoOaLG zNF_m*SUI!_LbQ$|^A&h+P-!ciqh*GgnCv5u*KH7pMnMzuW6LyFOLb&|hL^yy_yOnT%c(URK&x`|OKCPj`#Y$9>x+qDDhME&yi~J6X z0J^x@V-L!hY+f`%{}zIj=1ViMu@}I055AT5wsl!?Vjhul%GP27(_s!M6de%=z_j^ z-IY9gO>)Q=6~41SLf!t6WhPv2Dg6?<>LPVspvQ;*MfaPSlH| zWnf2=-+#oA()m^P?mew(hZbR-Og|W3Gov>^k*H<)th4VZJ8pt?VmRLP@)H^>yn2Rq zpY9y2(EHS>rbb&B4QT|2+M;>w>^Vf?D25swj5rblm%nQlGK>iR?r~>NXOe|Sp>5?y z*X+TuX7MY6IdeuRDu+9u_yXJ)C+XoCuy%~VhN~%3<(M}F&n>lt_|ZuH-J*l#pOKI? z1|>%CEvlurjG&l7J@jiQBRwQ$)-E3j?1KuJJdK>Si+_=kLnD>i1B&i0lc7{BI};5C zm8J+bYn;N&{D%&0;TMzSW&71%L_Iwrdr4%|NdZ$oEgu7%m#G^U@!aNWR^mi+_Ux~0 zG#D_HxeefuYv^lijstvMW|Oe=sp01H4%_)2odwkODO>}QOWhsv%LpCpZxtmw$jfYD z0S0szJ4EZ|u3FT|i!WG)%mOQ6LdqrsNmA@y=2HAhhDt+*?+UJIs=dTor2>xOGJD7}sw4xlP1VheS+W)JCNx|bUn)0Yp!9-CyNnPa@E;B=Krt2r1 zF}F`*>&)$5zlppGEK+(xUHgQDGakTE#P@&|YKaE=?N@<{L|bz^mIF~%q3>3%tD z73peC;IY|rZ1z;u)x-FG|85`bk?QdKJN-Qyyp+hnL*TV2rEWb5YFKnLxd=13{vRV9(=M3vNmkAK=s*;!` zL~%1Z;_mj&PV8YDDBHAYGhz6KW#>L93m{T=2)B35Fy7S0sIuRmOTUNJjk+&QEU^vu z{VrB=VOg13N)mA~Cw|b!ZaZhV+<@P(sv+m5JmR>g#4ZznqZgr-)YLDTOv7a!H z&J8PC2iEarY#Vrji%$ICHdvnr<<|c^9A7O;w8g%CEfIFqa&*1xe0hDlI>lYjmOk%5 zG>iU5cz6?|yWtVCmW@=({pZh3)hI0lCerSUx<1&28!@@MM2^dh{>IZ0FvkbWsTwTq zUBz@Aas5b(Q^razgq+h>{4tCc-VVu0?w>oHjsl06)1rJC;gFVPUD_pzFXro3IvJA9 zJp08@SoKzV_wX)uZ>i5LjifF*;t|WgfYK?uFB?)^tGP2+R$CR3HIU`1v>Scry4Viw zqMyy!c}w0zUg)puC>}Yep}-{VC@vlrxz|m$pL*9j<-xo$lIFp;It-cc^*hOW6NE*7 zG)BvcWb!C;Nwo?i4HERw8DT>7;qR$sEWRvdV##)ynokvDA=d~rXp!(^cUO1WOMI6; zSm)`3l>F5)ZMc@@4Pu!#3mv<76oUwMSzA>6~Z8wmXt}D zepUE$LLR1oT-Qfu;TvgHgG_6wgR~9or05|Z16X|pP-W|@ToG%2DSD@)HOW;rsM#`Go2XGp(p4tc-jXRi^4e2`DXO`I{LTWd+uU(+#^9@l7O)HP z8T5L-6huRI*g;X?io_BBY;O~z@#PLK|)qSQY|C} zt47-#JH4{ojwo0IG-hguQ|I=Fyz28qa`cH7A*Wp`U8eO*I0v>AP$WHfCG zMS}(7IH{Eo5wlI8La>K`DeV>zZv~z^e?15;#h$G1L>8-1#*Fk6d>WVk04NZq88^jM z;6~a*5_HOKC>ja8MbLY|LLlvc30$8Nk0#t%XMaSbKXZ^D<%z zvU`?S$9;W~%~v-Hlr`oASNp;GS9Mq;>o1i9&oQ71=@#~g^|6nLT@4~cc$FEFv?zXm z(r`JN>8es#C*h+OLARvm(QiNegPHtwi1-|JzT17Pv12>{y;})iaomcc&xz%mP<=>7 z(_CFxJ0G+j5+Hy2^vZ@Xo_A0eNFaeTuIAD}2G8~iqMJ%TFcwI-@V|ylCq@`RUcyrw z&|agi;?ODusB=yU$Nuo>P(obY6bODTy=-ql!48$G?QPBqE1npjENF9=d!$;kDJhzD zz>_QQHxr7#vt%++glnYrIjC!b>)mAz zb;0%15my09+(6jEu6fV^JPr8GH;4}VyswisjyZL~?67{ayBc){X%UN?KbV}!sdgJn z8TH%CEL?iMqBK;O+@ zg8hPwmiK(lMc&DV)+m>E1)tjtzOEMMf?jX=uEgkU0?On$oj*!%g<}QI&v#U~Q zcZIKMHDW1hmDlUqTJ}mA{)~OmC`o| z8L7NL_O7L=Gok)f7m`;p<=_j%8J>hCCe)0sm}{VO8ETFoB42v<`_1R%J}0h7Ws4*a zcmF0U&(&_r9jUaOO^0YMrw0L$W;oOlqLO4sc)we@)=;Txww5!N%A#7FfA{SRTUHAA zXV8zdta5MmqHcdcsb4Vs$qz0G_TW4)L6Ftx|0ATV=OWO5VdgS=)?~q$zuW^`9x1nQ zV%4a#9p@(Tt|zl|$(7Jlrs*MR<|IgRI?&kYN2!`as>GiNMoWS<>3#kIk;fEktZ0d| z)oopo!o8fIv5&5qAp)0i3+JNN3aZ!*s0S&{#Z|Ov+Ht7xT;XNc~t+^5(s_q-{ zK@wJWdG1G^;V)lBzNP;-Bl`sVWtaJ3*mkCK3{PFjNnp$Rgcm+5X`-BC?|!2ihw0Rj zol7));jT`<(nV8eHaTxm_q5Q3=p&{)T&)bdU@aB|D(-pPtciR2Qqi~{jm$MP-qc=F zcZQfWb7x*^tHETwGWUfjkv|em{h(*{B&0-(1~q1@v2~8&AV9Ps{S+IfwW7vYFduxX z>a*WR1(WlR(|?#xSw3P?X^SF(0>>aJgnAoY7R^Jjkpu&M} zhsvQagZt=nJGWyWt=_iQ!ZYpLwl|*6Ao`b~CI7w4wN#WBHGL;4G2A~lR4g`@uh^bv zuiTn5Rwoh>~o~V(ZWkhx%a3NU*tqmHtej(NaUi zy~(c)L&E8MhGk9G7K=1P(&6(}9aQ5?8?zEWYq9qYlZ&4#%FiB#kaJGNO;^&sU;p;l z@!Bjg@^Gedoz{|ro-V4Xm<+Mh<({ZL+yskw>NbgL#oP|SQgyY4$0(DJPncxu&>alK zjR@}C&WMi7KI>TUQ3IO1*1NtyPM7D;75JuINT|{{l$L%uEH8u-;gx}g1>~El1p4Ao z+nnXxEOf$1-1Ez;II2#0_-qTF+I9bK8dg|ka%TFK3Hhw?P5jjiyX+w+RXKWqX~6`YIp6dI_Li0 zoUQK9)J~TB(Ga*^GU)wbmVu@rNX(_gUJr*u(#!Q@#oV}-NUi!mCn3kZcF#Xsp;;lX zUZ$S4f1`~1x`bgU3P9*q(lJHmDO*|roDCr@NQC{2D?@TRSg0K(&YdVL3f-D7@^;sr zDYz?2I+f&15T?}db=Qh~-M;nvFY0_FYi#&jal5?2Ptjua~%FlhyxdoU#f9~0*gk|4yhUuDpMlM= zoF?PN^^!*tLwW+)bCH_n@P?3DSv|DSJl-Ebb;HZo+N&!M01kes@r^F-2b$j=ThM9W3i-zd%>k3kC&NK@rRST!`BJ-su*Qq`f0~8Vy z<;7yO4kB*sSX?7!m|{q>ioh6aH82sDW6}wY{Y1kZk%v8vo~TWoO6o?^v%}!YSK!P> zo$9*i(^%16eVaA5(zfB#SXkJbMQE=m@v>BJ!;>ZA5pUl?b$LU`TDydw?oiCbg`=>D z)I|rq!1F@ID^}~dWdFj*-Z=eZ*^aR#`T1?CR0P%(Ck9=l*V1VEj^AR1SAxCG{ogmYVCg2~ROp zW%))Hwsdtk_-)+j`u_HK_1l!s+il-z-e^qBl;dkD3_--LC8u|g7*E&t?@0Sfo zrV|lA-`$jeqp`{+{MP-;!FjWW5G5i6RZ(NZ&n9)tD^QdryqiJ*{}%>*0@6n6_bsYB zr0sM`GByA>WJdOH#%Et!?~!wR4N6RFX-Y9p*p1b<Nu)FM>kLD4 zR3)TEbo%E#NsL)ULa_<{lA}7siZpHr zCt#}5emr5PxbK)x1NOS}{KP*0&dJz=bn~_fQ}OaA6sH@msL><nvd_ ztR0gQD#1t`?9 zKUqfbNe_AYuY@Ft-EdFs*Q5m6IqR|WZWuzFz! zEP?*Ya^sx-9?4rt>_A`_*TtM7IjwS2ZI7mHXd?V$16O&ISK61s3Ip}?H< zGVYC&3L4(H={sGM(0V=&SG>iOMM)!0IC+GsvLy`;wtkv^9nEgID0L<~>t>LU-Nc;n z?6e4G|{*t@bf)wFU;oqJW$l8ADkaZ7Tl=3dx{8SGc-g4V4R zqN*W#C8HY0Z$ER@Rn^Q^OLr~yOgXJ5P7HVQHq{%|@hXSH$WI95&v#$ZV4fA?BVYI$ zcRXsWs?wV(guIIF8wpC>?j#JIGqr1@ru813V%I7rH&&omrdpuJ{5bMD+-;@$dN!lL z4sSaA-5Fqkb)$>{mzP4AOns?a_;a_z*ZNY2kfee91C(j|&O&wEdE3e2(mdMZ$4@fe zUyDBVe`LrvLr3U(^;-~q4~vbn^{#uovr|27s=mLTK-Uyh7W+}Up^2U@aL-tq0!T#z zDQ+tPB)D#MVzzjVPSSpda5SX5Zx#CMAI#%8|Uz=s*>H& zAU~waE_rgJFGda<6VD&@Gr~?V=VhKuZOWL;P&eRA8GB0SlEhU+)b{0{>FK_VyfgF;}b7(8oYtS>$h;p1XLE`?t%Hxm}d?h$BRVu zfX2N+VvFN-cS6yOQP^WM4rVvge8e<r0|OO@GxfzH{xk=9 zA70Vt&94K5{XNtXFs4R^%z%pnx`LY0g6ma8Gzti5vj**I%(C9Q=d1|QK84i9l zeAkO;#{sT3_h)^Hnn={mIh9%m{tO=RDQgCUqh0ZZ6j8LBqtvndG`^X?PxY@v&2_^H z_^7mWWfYvU@>f4;*P@>YT@?7caqYgKG^@oq-9Bv{*a{4O-D}10K|+F6m@MzIHj+{D z17RT4+zdJ6-ln zus3wegYWJ$-q>G!28qy-GpacL7(Q>BxV$DJZqMXS{DZu5XHI@+K!NAuTL1(GFT0#F zA4EwXMoACfOi7P0yNbm}$3v%%@m>}{2jEFDc|qVvq4_`ec@1qJ^t z8o&bp^8aTn00`jY`3NqPw+nr^8mnn0$@-I;$H-5bTC*DgNaGzqwN0x40~Z( From faa81e798668e924065ecba29144b024f54c5ff7 Mon Sep 17 00:00:00 2001 From: chenfei Date: Sat, 28 Jul 2018 20:08:10 +0800 Subject: [PATCH 2/8] token minimum is 1 --- BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp index b7f3941..e87dd09 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp @@ -1413,7 +1413,7 @@ UniValue tokentransfer(const UniValue ¶ms, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( - "tokentransfer \"token\" \"account\" [{\"address\":\"xxxx\", \"amount\":n},...] \n" + "tokentransfer \"token\" \"account\" [{\"address\":\"xxxx\", \"amount\":\"1111\"},...] \n" "\nCreate a transaction to transfer token.\n" "Returns hex-encoded raw transaction.\n" @@ -1478,6 +1478,12 @@ UniValue tokentransfer(const UniValue ¶ms, bool fHelp) return result; } CAmount n = atoll(obj["amount"].get_str().c_str()); + if (n < 1) + { + // amount < 1, return error + result.push_back(Pair("error", 3)); + return result; + } nVoutToken += n; } From 1ba47235b6360483162832363b90e106b83641fd Mon Sep 17 00:00:00 2001 From: chenfei Date: Sat, 28 Jul 2018 23:25:16 +0800 Subject: [PATCH 3/8] tokentransfer sign error --- .../src/rpc/rawtransaction.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp index e87dd09..3904899 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp @@ -1142,7 +1142,7 @@ UniValue getaccountinfo(const UniValue ¶ms, bool fHelp) return GetAccountInfo(account); } -bool SignTokenTx(CMutableTransaction &rawTx) +bool SignTokenTx(CMutableTransaction &rawTx, UniValue &vErrors) { // Fetch previous transactions (inputs): CCoinsView viewDummy; @@ -1188,7 +1188,7 @@ bool SignTokenTx(CMutableTransaction &rawTx) bool fHashSingle = ((nHashType & ~(SIGHASH_ANYONECANPAY | SIGHASH_FORKID)) == SIGHASH_SINGLE); // Script verification errors - UniValue vErrors(UniValue::VARR); + // UniValue vErrors(UniValue::VARR); // Use CTransaction for the constant parts of the // transaction to avoid rehashing. @@ -1393,10 +1393,11 @@ UniValue tokenmint(const UniValue ¶ms, bool fHelp) rawTx.vout.push_back(chargeOut); } + UniValue vErrors(UniValue::VARR); // sign tx - if (!SignTokenTx(rawTx)) + if (!SignTokenTx(rawTx, vErrors)) { - result.push_back(Pair("error", 4)); + result.push_back(Pair("error", vErrors)); return result; } @@ -1573,10 +1574,11 @@ UniValue tokentransfer(const UniValue ¶ms, bool fHelp) rawTx.vout.push_back(out); } + UniValue vErrors(UniValue::VARR); // sign tx - if (!SignTokenTx(rawTx)) + if (!SignTokenTx(rawTx, vErrors)) { - result.push_back(Pair("error", 4)); + result.push_back(Pair("error", vErrors)); return result; } From 8114c4936e369122179a760e84d740901e69a5ed Mon Sep 17 00:00:00 2001 From: chenfei Date: Sun, 29 Jul 2018 14:53:54 +0800 Subject: [PATCH 4/8] if token amount < 17, use opcode --- .../src/consensus/tx_verify.cpp | 61 +++-- .../src/rpc/rawtransaction.cpp | 228 ++++++++++++++++-- 2 files changed, 235 insertions(+), 54 deletions(-) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp index 08d522d..74625d1 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp @@ -246,40 +246,26 @@ bool Consensus::CheckTxInputs(const CTransaction &tx, CValidationState &state, c // Token // verify token CScript prevPubkey = coin.out.scriptPubKey; - if (prevPubkey.IsPayToScriptHash()) - { - std::vector vec(prevPubkey.begin() + 2, prevPubkey.begin() + 22); - CScriptID hash = CScriptID(uint160(vec)); - CScript redeemScript; - if (pwalletMain->GetCScript(hash, redeemScript)) - { - if (!redeemScript.IsPayToToken()) - continue; - - int namesize = redeemScript[1]; - int amountsize = redeemScript[2 + namesize]; - std::vector vecName(redeemScript.begin() + 2, redeemScript.begin() + 2 + namesize); - std::vector vecAmount(redeemScript.begin() + 3 + namesize, redeemScript.begin() + 3 + namesize + amountsize); - std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - if (tokenAmount > MAX_TOKEN_SUPPLY) - return state.DoS(100, false, REJECT_INVALID, "token amount out of range"); - - CAmount temp = mVinToken[tokenName]; - temp += tokenAmount; - if (temp > MAX_TOKEN_SUPPLY) - return state.DoS(100, false, REJECT_INVALID, "vin amount out of range"); - mVinToken[tokenName] = temp; - } - } - else if (prevPubkey.IsPayToToken()) + if (prevPubkey.IsPayToToken()) { int namesize = prevPubkey[1]; int amountsize = prevPubkey[2 + namesize]; std::vector vecName(prevPubkey.begin() + 2, prevPubkey.begin() + 2 + namesize); - std::vector vecAmount(prevPubkey.begin() + 3 + namesize, prevPubkey.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(prevPubkey.begin() + 2 + namesize, prevPubkey.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(prevPubkey.begin() + 3 + namesize, prevPubkey.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } + mVinToken[tokenName] = tokenAmount; if (tokenAmount > MAX_TOKEN_SUPPLY) @@ -306,9 +292,20 @@ bool Consensus::CheckTxInputs(const CTransaction &tx, CValidationState &state, c std::vector vecName(outScript.begin() + 2, outScript.begin() + 2 + namesize); std::string name(vecName.begin(), vecName.end()); - - std::vector vec(outScript.begin() + 3 + namesize, outScript.begin() + 3 + namesize + amountsize); - CAmount amount = CScriptNum(vec, true).getint64(); + + // check opcode or scriptnum + CAmount amount = 0; + std::vector opcode(outScript.begin() + 2 + namesize, outScript.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + amount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(outScript.begin() + 3 + namesize, outScript.begin() + 3 + namesize + amountsize); + amount = CScriptNum(vec, true).getint64(); + } + if (amount > MAX_TOKEN_SUPPLY) return state.DoS(100, false, REJECT_INVALID, "token amount out of range"); diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp index 3904899..59ff3e3 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp @@ -1073,10 +1073,21 @@ UniValue GetAccountInfo(const std::string &account) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } + entry.push_back(Pair("token", tokenName)); entry.push_back(Pair("tokenAmount", tokenAmount)); unspentToken.push_back(entry); @@ -1281,6 +1292,65 @@ void SendTokenTx(const CMutableTransaction &rawTx) RelayTransaction(rawTx); } +opcodetype GetOpcode(const CAmount n) +{ + opcodetype ret = OP_1; + switch (n) + { + case 1: + ret = OP_1; + break; + case 2: + ret = OP_2; + break; + case 3: + ret = OP_3; + break; + case 4: + ret = OP_4; + break; + case 5: + ret = OP_5; + break; + case 6: + ret = OP_6; + break; + case 7: + ret = OP_7; + break; + case 8: + ret = OP_8; + break; + case 9: + ret = OP_9; + break; + case 10: + ret = OP_10; + break; + case 11: + ret = OP_11; + break; + case 12: + ret = OP_12; + break; + case 13: + ret = OP_13; + break; + case 14: + ret = OP_14; + break; + case 15: + ret = OP_15; + break; + case 16: + ret = OP_16; + break; + default: + break; + } + return ret; +} + UniValue tokenmint(const UniValue ¶ms, bool fHelp) { if (fHelp || params.size() != 3) @@ -1367,7 +1437,14 @@ UniValue tokenmint(const UniValue ¶ms, bool fHelp) // build token script CTxDestination destination = DecodeDestination(addresses[0].get_str()); CScript scriptPubKey = GetScriptForDestination(destination); - CScript script = CScript() << OP_TOKEN << ToByteVector(tokenname) << CScriptNum(nSupply); + + CScript script; + if (nSupply < 17) + script = CScript() << OP_TOKEN << ToByteVector(tokenname) << GetOpcode(nSupply); + else + script = CScript() << OP_TOKEN << ToByteVector(tokenname) << CScriptNum(nSupply); + + // CScript script = CScript() << OP_TOKEN << ToByteVector(tokenname) << CScriptNum(nSupply); script << OP_DROP << OP_DROP; script += scriptPubKey; @@ -1410,6 +1487,7 @@ UniValue tokenmint(const UniValue ¶ms, bool fHelp) return result; } + UniValue tokentransfer(const UniValue ¶ms, bool fHelp) { if (fHelp || params.size() != 3) @@ -1549,7 +1627,14 @@ UniValue tokentransfer(const UniValue ¶ms, bool fHelp) std::string address = output["address"].get_str(); CAmount n = atoll(output["amount"].get_str().c_str()); CTxDestination destination = DecodeDestination(address); - CScript scriptPubKey = CScript() << OP_TOKEN << ToByteVector(token) << CScriptNum(n) << OP_DROP << OP_DROP; + + CScript scriptPubKey; + if (n < 17) + scriptPubKey = CScript() << OP_TOKEN << ToByteVector(token) << GetOpcode(n) << OP_DROP << OP_DROP; + else + scriptPubKey = CScript() << OP_TOKEN << ToByteVector(token) << CScriptNum(n) << OP_DROP << OP_DROP; + + // CScript scriptPubKey = CScript() << OP_TOKEN << ToByteVector(token) << CScriptNum(n) << OP_DROP << OP_DROP; scriptPubKey += GetScriptForDestination(destination); CTxOut out(defaultTransferFee, scriptPubKey); rawTx.vout.push_back(out); @@ -1560,7 +1645,14 @@ UniValue tokentransfer(const UniValue ¶ms, bool fHelp) // token charge if (nVinToken > nVoutToken) { - CScript chargePubKey = CScript() << OP_TOKEN << ToByteVector(token) << CScriptNum(nVinToken - nVoutToken) << OP_DROP << OP_DROP; + CAmount n = nVinToken - nVoutToken; + CScript chargePubKey; + if (n < 17) + chargePubKey = CScript() << OP_TOKEN << ToByteVector(token) << GetOpcode(n) << OP_DROP << OP_DROP; + else + chargePubKey = CScript() << OP_TOKEN << ToByteVector(token) << CScriptNum(n) << OP_DROP << OP_DROP; + + // CScript chargePubKey = CScript() << OP_TOKEN << ToByteVector(token) << CScriptNum(nVinToken - nVoutToken) << OP_DROP << OP_DROP; chargePubKey += GetScriptForDestination(chargeDest); CTxOut out(defaultTransferFee, chargePubKey); rawTx.vout.push_back(out); @@ -1579,6 +1671,7 @@ UniValue tokentransfer(const UniValue ¶ms, bool fHelp) if (!SignTokenTx(rawTx, vErrors)) { result.push_back(Pair("error", vErrors)); + result.push_back(Pair("hex", EncodeHexTx(rawTx))); return result; } @@ -1616,9 +1709,22 @@ UniValue tokenlist(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } if (sToken.count(tokenName)) continue; @@ -1673,9 +1779,22 @@ UniValue tokensearch(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } CTxDestination address; std::string issuer = ""; @@ -1744,9 +1863,22 @@ UniValue GetTokenAddress(const std::string &account, const std::string &token) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } if (tokenName != token) continue; @@ -1885,9 +2017,22 @@ UniValue tokenhistory(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - CAmount amount = CScriptNum(vecAmount, true).getint64(); + // CAmount amount = CScriptNum(vecAmount, true).getint64(); + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } if (tokenName != token) continue; @@ -1906,7 +2051,7 @@ UniValue tokenhistory(const UniValue ¶ms, bool fHelp) UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", it.first.ToString())); entry.push_back(Pair("address", EncodeDestination(address))); - entry.push_back(Pair("amount", amount)); + entry.push_back(Pair("amount", tokenAmount)); entry.push_back(Pair("category", "receive")); entry.push_back(Pair("timestamp", wtx.GetTxTime())); result.push_back(entry); @@ -1930,9 +2075,22 @@ UniValue tokenhistory(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - CAmount amount = CScriptNum(vecAmount, true).getint64(); + // CAmount amount = CScriptNum(vecAmount, true).getint64(); + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } if (tokenName != token) continue; @@ -1951,7 +2109,7 @@ UniValue tokenhistory(const UniValue ¶ms, bool fHelp) UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", it.first.ToString())); entry.push_back(Pair("address", EncodeDestination(address))); - entry.push_back(Pair("amount", amount)); + entry.push_back(Pair("amount", tokenAmount)); entry.push_back(Pair("category", "send")); entry.push_back(Pair("timestamp", wtx.GetTxTime())); result.push_back(entry); @@ -2019,10 +2177,23 @@ UniValue tokendetail(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string name(vecName.begin(), vecName.end()); - CAmount amount = CScriptNum(vecAmount, true).getint64(); + // CAmount amount = CScriptNum(vecAmount, true).getint64(); + // check opcode or scriptnum + CAmount amount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + amount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + amount = CScriptNum(vec, true).getint64(); + } + UniValue entry(UniValue::VOBJ); CTxDestination address; if (ExtractDestination(pk, address)) @@ -2050,8 +2221,21 @@ UniValue tokendetail(const UniValue ¶ms, bool fHelp) { int namesize = pk[1]; int amountsize = pk[2 + namesize]; - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); - CAmount amount = CScriptNum(vecAmount, true).getint64(); + // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // CAmount amount = CScriptNum(vecAmount, true).getint64(); + + // check opcode or scriptnum + CAmount amount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + amount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + amount = CScriptNum(vec, true).getint64(); + } UniValue entry(UniValue::VOBJ); CTxDestination address; From 6a266006fa553fdffba4a343c1a1ce3dbbaa93b9 Mon Sep 17 00:00:00 2001 From: chenfei Date: Mon, 30 Jul 2018 12:01:08 +0800 Subject: [PATCH 5/8] serch token list from blockchain --- .../src/rpc/rawtransaction.cpp | 154 ++++++++++++------ 1 file changed, 107 insertions(+), 47 deletions(-) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp index 59ff3e3..520a9f5 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp @@ -1694,58 +1694,118 @@ UniValue tokenlist(const UniValue ¶ms, bool fHelp) UniValue result(UniValue::VARR); std::set sToken; + int height = chainActive.Height(); + CBlockIndex *pblockindex = NULL; - for (auto it: pwalletMain->mapWallet) + for (int i = 100; i <= height; ++i) { - const CWalletTx &wtx = it.second; - if (wtx.IsCoinBase()) - continue; - - for (const auto &out: wtx.vout) - { - const CScript &pk = out.scriptPubKey; - if (pk.IsPayToToken()) - { - int namesize = pk[1]; - int amountsize = pk[2 + namesize]; - std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); - std::string tokenName(vecName.begin(), vecName.end()); - // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + pblockindex = chainActive[i]; + CBlock block; + if (ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + { + for (const auto &tx: block.vtx) + { + if (tx->IsCoinBase()) + continue; - // check opcode or scriptnum - CAmount tokenAmount = 0; - std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); - if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) - { - tokenAmount = opcode.at(0) - 0x50; - } - else - { - std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); - tokenAmount = CScriptNum(vec, true).getint64(); - } + for (const auto &out: tx->vout) + { + const CScript &pk = out.scriptPubKey; + if (pk.IsPayToToken()) + { + int namesize = pk[1]; + int amountsize = pk[2 + namesize]; + std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); + std::string tokenName(vecName.begin(), vecName.end()); + + // check opcode or scriptnum + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } + + if (sToken.count(tokenName)) + continue; + else + sToken.insert(tokenName); + + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", tx->GetHash().GetHex())); + CTxDestination address; + if (ExtractDestination(pk, address)) + { + entry.push_back(Pair("address", EncodeDestination(address))); + if (pwalletMain->mapAddressBook.count(address)) + entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + } + entry.push_back(Pair("token", tokenName)); + entry.push_back(Pair("supply", tokenAmount)); + result.push_back(entry); + } + } - if (sToken.count(tokenName)) - continue; - else - sToken.insert(tokenName); - - UniValue entry(UniValue::VOBJ); - // entry.push_back(Pair("txid", it.first.ToString())); - CTxDestination address; - if (ExtractDestination(pk, address)) - { - // entry.push_back(Pair("address", EncodeDestination(address))); - if (pwalletMain->mapAddressBook.count(address)) - entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); - } - entry.push_back(Pair("token", tokenName)); - entry.push_back(Pair("supply", tokenAmount)); - result.push_back(entry); - } - } + } + } } + + // for (auto it: pwalletMain->mapWallet) + // { + // const CWalletTx &wtx = it.second; + // if (wtx.IsCoinBase()) + // continue; + + // for (const auto &out: wtx.vout) + // { + // const CScript &pk = out.scriptPubKey; + // if (pk.IsPayToToken()) + // { + // int namesize = pk[1]; + // int amountsize = pk[2 + namesize]; + // std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); + // // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // std::string tokenName(vecName.begin(), vecName.end()); + // // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); + + // // check opcode or scriptnum + // CAmount tokenAmount = 0; + // std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + // if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + // { + // tokenAmount = opcode.at(0) - 0x50; + // } + // else + // { + // std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + // tokenAmount = CScriptNum(vec, true).getint64(); + // } + + // if (sToken.count(tokenName)) + // continue; + // else + // sToken.insert(tokenName); + + // UniValue entry(UniValue::VOBJ); + // // entry.push_back(Pair("txid", it.first.ToString())); + // CTxDestination address; + // if (ExtractDestination(pk, address)) + // { + // // entry.push_back(Pair("address", EncodeDestination(address))); + // if (pwalletMain->mapAddressBook.count(address)) + // entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + // } + // entry.push_back(Pair("token", tokenName)); + // entry.push_back(Pair("supply", tokenAmount)); + // result.push_back(entry); + // } + // } + // } return result; } From eb80c95834340b3cbdc9073dac05ba021054440a Mon Sep 17 00:00:00 2001 From: chenfei Date: Mon, 30 Jul 2018 15:11:05 +0800 Subject: [PATCH 6/8] check token balance is enough when transfer token --- BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp index 520a9f5..cc8daea 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp @@ -1575,11 +1575,13 @@ UniValue tokentransfer(const UniValue ¶ms, bool fHelp) for (size_t i = 0; i < utxoToken.size(); ++i) { UniValue u = utxoToken[i]; + if (u["token"].get_str() != token) + continue; + uint256 txid; txid.SetHex(u["txid"].get_str()); CTxIn in(COutPoint(txid, u["vout"].get_int()), CScript(), nSequence); rawTx.vin.push_back(in); - nVinToken += u["tokenAmount"].get_int64(); if (nVinToken >= nVoutToken) break; From c6a562666612ff61ec9f052c3833ed183874c40c Mon Sep 17 00:00:00 2001 From: chenfei Date: Tue, 31 Jul 2018 16:35:19 +0800 Subject: [PATCH 7/8] remove test data --- .../src/consensus/tx_verify.cpp | 6 +- .../src/rpc/rawtransaction.cpp | 71 +----------- .../src/script/standard.cpp | 2 +- .../src/wallet/rpcwallet.cpp | 102 +++++++----------- .../src/wallet/wallet.cpp | 55 ++++------ 5 files changed, 63 insertions(+), 173 deletions(-) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp index 74625d1..35ce575 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/consensus/tx_verify.cpp @@ -219,7 +219,8 @@ bool Consensus::CheckTxInputs(const CTransaction &tx, CValidationState &state, c std::map mVinToken; std::map mVoutToken; - std::vector vTxid; + // verify token issue txid + std::vector vTxid; std::vector vTokenid; for (unsigned int i = 0; i < tx.vin.size(); i++) @@ -266,8 +267,6 @@ bool Consensus::CheckTxInputs(const CTransaction &tx, CValidationState &state, c tokenAmount = CScriptNum(vec, true).getint64(); } - mVinToken[tokenName] = tokenAmount; - if (tokenAmount > MAX_TOKEN_SUPPLY) return state.DoS(100, false, REJECT_INVALID, "token amount out of range"); @@ -342,7 +341,6 @@ bool Consensus::CheckTxInputs(const CTransaction &tx, CValidationState &state, c // if (!issue) // return state.DoS(100, false, REJECT_INVALID, "tokenid must be one of the issuer's UTXO txid"); // } - // verify token end if (nValueIn < tx.GetValueOut()) return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false, diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp index cc8daea..b62333b 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/rpc/rawtransaction.cpp @@ -1198,9 +1198,6 @@ bool SignTokenTx(CMutableTransaction &rawTx, UniValue &vErrors) bool fHashSingle = ((nHashType & ~(SIGHASH_ANYONECANPAY | SIGHASH_FORKID)) == SIGHASH_SINGLE); - // Script verification errors - // UniValue vErrors(UniValue::VARR); - // Use CTransaction for the constant parts of the // transaction to avoid rehashing. const CTransaction txConst(rawTx); @@ -1249,9 +1246,7 @@ bool SignTokenTx(CMutableTransaction &rawTx, UniValue &vErrors) } } - if (!vErrors.empty()) - return false; - return true; + return vErrors.empty(); } void SendTokenTx(const CMutableTransaction &rawTx) @@ -1444,7 +1439,6 @@ UniValue tokenmint(const UniValue ¶ms, bool fHelp) else script = CScript() << OP_TOKEN << ToByteVector(tokenname) << CScriptNum(nSupply); - // CScript script = CScript() << OP_TOKEN << ToByteVector(tokenname) << CScriptNum(nSupply); script << OP_DROP << OP_DROP; script += scriptPubKey; @@ -1757,57 +1751,6 @@ UniValue tokenlist(const UniValue ¶ms, bool fHelp) } } - // for (auto it: pwalletMain->mapWallet) - // { - // const CWalletTx &wtx = it.second; - // if (wtx.IsCoinBase()) - // continue; - - // for (const auto &out: wtx.vout) - // { - // const CScript &pk = out.scriptPubKey; - // if (pk.IsPayToToken()) - // { - // int namesize = pk[1]; - // int amountsize = pk[2 + namesize]; - // std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - // // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); - // std::string tokenName(vecName.begin(), vecName.end()); - // // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - - // // check opcode or scriptnum - // CAmount tokenAmount = 0; - // std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); - // if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) - // { - // tokenAmount = opcode.at(0) - 0x50; - // } - // else - // { - // std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); - // tokenAmount = CScriptNum(vec, true).getint64(); - // } - - // if (sToken.count(tokenName)) - // continue; - // else - // sToken.insert(tokenName); - - // UniValue entry(UniValue::VOBJ); - // // entry.push_back(Pair("txid", it.first.ToString())); - // CTxDestination address; - // if (ExtractDestination(pk, address)) - // { - // // entry.push_back(Pair("address", EncodeDestination(address))); - // if (pwalletMain->mapAddressBook.count(address)) - // entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); - // } - // entry.push_back(Pair("token", tokenName)); - // entry.push_back(Pair("supply", tokenAmount)); - // result.push_back(entry); - // } - // } - // } return result; } @@ -1841,9 +1784,7 @@ UniValue tokensearch(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); // check opcode or scriptnum CAmount tokenAmount = 0; @@ -1925,9 +1866,7 @@ UniValue GetTokenAddress(const std::string &account, const std::string &token) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - // CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); // check opcode or scriptnum CAmount tokenAmount = 0; @@ -2079,9 +2018,7 @@ UniValue tokenhistory(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - // CAmount amount = CScriptNum(vecAmount, true).getint64(); // check opcode or scriptnum CAmount tokenAmount = 0; @@ -2137,9 +2074,7 @@ UniValue tokenhistory(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string tokenName(vecName.begin(), vecName.end()); - // CAmount amount = CScriptNum(vecAmount, true).getint64(); // check opcode or scriptnum CAmount tokenAmount = 0; @@ -2239,9 +2174,7 @@ UniValue tokendetail(const UniValue ¶ms, bool fHelp) int namesize = pk[1]; int amountsize = pk[2 + namesize]; std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); std::string name(vecName.begin(), vecName.end()); - // CAmount amount = CScriptNum(vecAmount, true).getint64(); // check opcode or scriptnum CAmount amount = 0; @@ -2283,8 +2216,6 @@ UniValue tokendetail(const UniValue ¶ms, bool fHelp) { int namesize = pk[1]; int amountsize = pk[2 + namesize]; - // std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); - // CAmount amount = CScriptNum(vecAmount, true).getint64(); // check opcode or scriptnum CAmount amount = 0; diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/script/standard.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/script/standard.cpp index d7e8b1e..86db4b0 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/script/standard.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/script/standard.cpp @@ -96,7 +96,7 @@ bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, vector hashBytes(scriptPubKey.end() - 22, scriptPubKey.end() - 2); + vector hashBytes(scriptPubKey.end() - 22, scriptPubKey.end() - 2); vSolutionsRet.push_back(hashBytes); return true; } diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/wallet/rpcwallet.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/wallet/rpcwallet.cpp index 1aaf075..e6ded2f 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/wallet/rpcwallet.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/wallet/rpcwallet.cpp @@ -693,7 +693,6 @@ CAmount GetAccountBalance(CWalletDB &walletdb, const string &strAccount, int nMi if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) nBalance += nReceived; nBalance -= nSent + nFee; - std::cout << "balance: " << nBalance << std::endl; } // Tally internal accounting entries @@ -768,7 +767,7 @@ UniValue getbalance(const UniValue ¶ms, bool fHelp) list listReceived; list listSent; wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter); - if (wtx.GetDepthInMainChain() >= nMinDepth) + if (wtx.GetDepthInMainChain() >= nMinDepth) { BOOST_FOREACH (const COutputEntry &r, listReceived) nBalance += r.amount; @@ -2807,70 +2806,41 @@ UniValue listtokenunspent(const UniValue ¶ms, bool fHelp) CAmount nValue = out.tx->vout[out.i].nValue; const CScript &pk = out.tx->vout[out.i].scriptPubKey; - if (pk.IsPayToScriptHash()) - { - CTxDestination address; - if (ExtractDestination(pk, address)) - { - const CScriptID &hash = boost::get(address); - CScript redeemScript; - if (pwalletMain->GetCScript(hash, redeemScript)) - { - if (!redeemScript.IsPayToToken()) - continue; - - UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); - entry.push_back(Pair("vout", out.i)); - CTxDestination address; - if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) - entry.push_back(Pair("address", EncodeDestination(address))); - - entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); - entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); - entry.push_back(Pair("satoshi", UniValue(nValue))); - entry.push_back(Pair("amount", ValueFromAmount(nValue))); - entry.push_back(Pair("confirmations", out.nDepth)); - entry.push_back(Pair("spendable", out.fSpendable)); - - int namesize = redeemScript[1]; - int amountsize = redeemScript[2 + namesize]; - std::vector vecName(redeemScript.begin() + 2, redeemScript.begin() + 2 + namesize); - std::vector vecAmount(redeemScript.begin() + 3 + namesize, redeemScript.begin() + 3 + namesize + amountsize); - std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - - entry.push_back(Pair("token", tokenName)); - entry.push_back(Pair("tokenAmount", tokenAmount)); - results.push_back(entry); - } - } - } - else if (pk.IsPayToToken()) - { - UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); - entry.push_back(Pair("vout", out.i)); - CTxDestination address; - if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) - entry.push_back(Pair("address", EncodeDestination(address))); - entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); - entry.push_back(Pair("satoshi", UniValue(nValue))); - entry.push_back(Pair("amount", ValueFromAmount(nValue))); - entry.push_back(Pair("confirmations", out.nDepth)); - entry.push_back(Pair("spendable", out.fSpendable)); - - int namesize = pk[1]; - int amountsize = pk[2 + namesize]; - std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); - std::vector vecAmount(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); - std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - - entry.push_back(Pair("token", tokenName)); - entry.push_back(Pair("tokenAmount", tokenAmount)); - results.push_back(entry); - } + if (pk.IsPayToToken()) + { + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + CTxDestination address; + if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + entry.push_back(Pair("address", EncodeDestination(address))); + entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); + entry.push_back(Pair("satoshi", UniValue(nValue))); + entry.push_back(Pair("amount", ValueFromAmount(nValue))); + entry.push_back(Pair("confirmations", out.nDepth)); + entry.push_back(Pair("spendable", out.fSpendable)); + + int namesize = pk[1]; + int amountsize = pk[2 + namesize]; + std::vector vecName(pk.begin() + 2, pk.begin() + 2 + namesize); + std::string tokenName(vecName.begin(), vecName.end()); + + CAmount tokenAmount = 0; + std::vector opcode(pk.begin() + 2 + namesize, pk.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(pk.begin() + 3 + namesize, pk.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } + + entry.push_back(Pair("token", tokenName)); + entry.push_back(Pair("tokenAmount", tokenAmount)); + results.push_back(entry); + } } return results; } diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp index d98736d..47db2e3 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp @@ -1530,41 +1530,32 @@ std::map CWalletTx::GetTokenAvailableCredit() const if (!MoneyRange(nCredit)) throw std::runtime_error("CWalletTx::GetTokenAvailableCredit() : value out of range"); - if (nCredit == tmpCredit) + if (nCredit == tmpCredit) continue; - tmpCredit = nCredit; - if (txout.scriptPubKey.IsPayToScriptHash()) - { - CTxDestination address; - if (ExtractDestination(txout.scriptPubKey, address)) - { - const CScriptID &hash = boost::get(address); - CScript redeemScript; - if (pwalletMain->GetCScript(hash, redeemScript)) - { - if (!redeemScript.IsPayToToken()) - continue; - int namesize = redeemScript[1]; - int amountsize = redeemScript[2 + namesize]; - std::vector vecName(redeemScript.begin() + 2, redeemScript.begin() + 2 + namesize); - std::vector vecAmount(redeemScript.begin() + 3 + namesize, redeemScript.begin() + 3 + namesize + amountsize); - std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - mCredit[tokenName] = tokenAmount; - } - } - } - else if (txout.scriptPubKey.IsPayToToken()) + tmpCredit = nCredit; + if (txout.scriptPubKey.IsPayToToken()) { - int namesize = txout.scriptPubKey[1]; - int amountsize = txout.scriptPubKey[2 + namesize]; - std::vector vecName(txout.scriptPubKey.begin() + 2, txout.scriptPubKey.begin() + 2 + namesize); - std::vector vecAmount(txout.scriptPubKey.begin() + 3 + namesize, txout.scriptPubKey.begin() + 3 + namesize + amountsize); - std::string tokenName(vecName.begin(), vecName.end()); - CAmount tokenAmount = CScriptNum(vecAmount, true).getint64(); - mCredit[tokenName] = tokenAmount; - } + int namesize = txout.scriptPubKey[1]; + int amountsize = txout.scriptPubKey[2 + namesize]; + std::vector vecName(txout.scriptPubKey.begin() + 2, txout.scriptPubKey.begin() + 2 + namesize); + std::vector vecAmount(txout.scriptPubKey.begin() + 3 + namesize, txout.scriptPubKey.begin() + 3 + namesize + amountsize); + std::string tokenName(vecName.begin(), vecName.end()); + + CAmount tokenAmount = 0; + std::vector opcode(txout.scriptPubKey.begin() + 2 + namesize, txout.scriptPubKey.begin() + 3 + namesize); + if (0x50 < opcode.at(0) && opcode.at(0) < 0x61) + { + tokenAmount = opcode.at(0) - 0x50; + } + else + { + std::vector vec(txout.scriptPubKey.begin() + 3 + namesize, txout.scriptPubKey.begin() + 3 + namesize + amountsize); + tokenAmount = CScriptNum(vec, true).getint64(); + } + + mCredit[tokenName] = tokenAmount; + } } } From 4e746aaa8c3eb373d793ed9c2c000921f85cee4d Mon Sep 17 00:00:00 2001 From: chenfei Date: Wed, 1 Aug 2018 17:47:31 +0800 Subject: [PATCH 8/8] don't use the UTXOs which contains token in sendtoaddress --- .../src/wallet/wallet.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp b/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp index 47db2e3..2f2ce68 100644 --- a/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp +++ b/BitcoinUnlimited-bucash1.3.0.1/src/wallet/wallet.cpp @@ -1495,6 +1495,11 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const if (!pwallet->IsSpent(hashTx, i)) { const CTxOut &txout = vout[i]; + + // Token + if (txout.scriptPubKey.IsPayToToken()) + continue; + nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE); if (!MoneyRange(nCredit)) throw std::runtime_error("CWalletTx::GetAvailableCredit(false) : value out of range"); @@ -2069,6 +2074,19 @@ bool CWallet::SelectCoins(const CAmount &nTargetValue, vector vCoins; AvailableCoins(vCoins, true, coinControl); + // Token + std::vector tmp; + for (const COutput &output: vCoins) + { + if (output.tx->vout[output.i].scriptPubKey.IsPayToToken()) + { + continue; + } + tmp.push_back(output); + } + vCoins.clear(); + vCoins.assign(tmp.begin(), tmp.end()); + // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs) { @@ -2312,6 +2330,7 @@ bool CWallet::CreateTransaction(const vector &vecSend, strFailReason = _("Insufficient funds"); return false; } + BOOST_FOREACH (PAIRTYPE(const CWalletTx *, unsigned int) pcoin, setCoins) { CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;