diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 5986f8716..35293088c 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -33,7 +33,6 @@ } sendrawtransaction of the above hex. - ./komodo-cli -ac_name=MUSIG getrawtransaction 5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c 1 "vout": [ { @@ -83,7 +82,7 @@ the "msg" is what needs to be signed to create a valid spend 5 args: ind, numsigners, combined_pk, pkhash, message to be signed on node with pubkey: 02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28 - ./komodo-cli -ac_name=MUSIG cclib session 18 '[0,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","c1b34139744f3b54b652dc741ebd0f9d5b53ad28795cc6614dd8ad3aaabf15ae","f5d91999b23b85630a4cbd0baea3736529411b052cf5f1f4345c5d181af12825"]' + ./komodo-cli -ac_name=MUSIG cclib session 18 '[0,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' { "myind": 0, "numsigners": 2, @@ -221,7 +220,9 @@ struct musig_info secp256k1_musig_partial_signature *partial_sig; //[N_SIGNERS]; int32_t myind,num,numcommits,numnonces,numpartials; uint8_t msg[32],pkhash[32],combpk[33]; -} *MUSIG; +}; + +std::vector MUSIG; struct musig_info *musig_infocreate(int32_t myind,int32_t num) { @@ -412,23 +413,33 @@ UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n,myind,num; char *pkstr,*pkhashstr,*msgstr; uint8_t session[32],msg[32],pkhash[32],privkey[32],pub33[33]; CPubKey pk; char str[67]; + UniValue result(UniValue::VOBJ); int32_t i,n,myind,num,musiglocation; char *pkstr,*pkhashstr,*msgstr; uint8_t session[32],msg[32],pkhash[32],privkey[32],pub33[33]; CPubKey pk; char str[67]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 5 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 5 ) { myind = juint(jitem(params,0),0); num = juint(jitem(params,1),0); if ( myind < 0 || myind >= num || num <= 0 ) return(cclib_error(result,"illegal myindex and numsigners")); - if ( MUSIG != 0 ) - musig_infofree(MUSIG), MUSIG = 0; - MUSIG = musig_infocreate(myind,num); - if ( musig_parsepubkey(ctx,MUSIG->combined_pk,jitem(params,2)) < 0 ) + if ( n > 5 ) + musiglocation = juint(jitem(params,5),0); + else if ( n == 5 ) + musiglocation = 0; + //printf("number of params.%i musiglocation.%i\n",n,musiglocation); + if ( MUSIG.size() > musiglocation ) + { + for (int i = 0; i < MUSIG.size()-1; i++) + musig_infofree(MUSIG[i]); + MUSIG.clear(); + } + struct musig_info *temp_musig = musig_infocreate(myind,num); + MUSIG.push_back(temp_musig); + if ( musig_parsepubkey(ctx,MUSIG[musiglocation]->combined_pk,jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing combined_pubkey")); - else if ( cclib_parsehash(MUSIG->pkhash,jitem(params,3),32) < 0 ) + else if ( cclib_parsehash(MUSIG[musiglocation]->pkhash,jitem(params,3),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( cclib_parsehash(MUSIG->msg,jitem(params,4),32) < 0 ) + else if ( cclib_parsehash(MUSIG[musiglocation]->msg,jitem(params,4),32) < 0 ) return(cclib_error(result,"error parsing msg")); Myprivkey(privkey); GetRandBytes(session,32); @@ -458,15 +469,17 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * my_index: index of this signer in the signers array * seckey: the signer's 32-byte secret key (cannot be NULL) */ - if ( secp256k1_musig_session_initialize(ctx,&MUSIG->session,MUSIG->signer_data, &MUSIG->nonce_commitments[MUSIG->myind * 32],session,MUSIG->msg,&MUSIG->combined_pk,MUSIG->pkhash,MUSIG->num,MUSIG->myind,privkey) > 0 ) + //fprintf(stderr, "SESSION: struct_size.%li using struct %i\n",MUSIG.size(), musiglocation); + if ( secp256k1_musig_session_initialize(ctx,&MUSIG[musiglocation]->session,MUSIG[musiglocation]->signer_data, &MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind * 32],session,MUSIG[musiglocation]->msg,&MUSIG[musiglocation]->combined_pk,MUSIG[musiglocation]->pkhash,MUSIG[musiglocation]->num,MUSIG[musiglocation]->myind,privkey) > 0 ) { memset(session,0,sizeof(session)); result.push_back(Pair("myind",(int64_t)myind)); result.push_back(Pair("numsigners",(int64_t)num)); for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",MUSIG->nonce_commitments[MUSIG->myind*32 + i]); + sprintf(&str[i<<1],"%02x",MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind*32 + i]); str[64] = 0; - MUSIG->numcommits = 1; + if ( n == 5 ) + MUSIG[musiglocation]->numcommits = 1; result.push_back(Pair("commitment",str)); result.push_back(Pair("result","success")); return(result); @@ -483,18 +496,22 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; size_t clen = CPubKey::PUBLIC_KEY_SIZE; - UniValue result(UniValue::VOBJ); int32_t i,n,ind; uint8_t pkhash[32]; CPubKey pk; char str[67]; + UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32]; CPubKey pk; char str[67]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) { + if ( n > 3 ) + myind = juint(jitem(params,3),0); + else if ( n == 3 ) + myind = 0; if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) + else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) return(cclib_error(result,"illegal ind for session")); - else if ( cclib_parsehash(&MUSIG->nonce_commitments[ind*32],jitem(params,2),32) < 0 ) + else if ( cclib_parsehash(&MUSIG[myind]->nonce_commitments[ind*32],jitem(params,2),32) < 0 ) return(cclib_error(result,"error parsing commitment")); /** Gets the signer's public nonce given a list of all signers' data with commitments * @@ -512,16 +529,18 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * number of signers participating in the MuSig. */ result.push_back(Pair("added_index",ind)); - MUSIG->numcommits++; - if ( MUSIG->numcommits >= MUSIG->num && secp256k1_musig_session_get_public_nonce(ctx,&MUSIG->session,MUSIG->signer_data,&MUSIG->nonces[MUSIG->myind],MUSIG->commitment_ptrs,MUSIG->num) > 0 ) + //fprintf(stderr, "COMMIT: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind); + MUSIG[myind]->numcommits++; + if ( MUSIG[myind]->numcommits >= MUSIG[myind]->num && secp256k1_musig_session_get_public_nonce(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,&MUSIG[myind]->nonces[MUSIG[myind]->myind],MUSIG[myind]->commitment_ptrs,MUSIG[myind]->num) > 0 ) { - if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG->nonces[MUSIG->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) + if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG[myind]->nonces[MUSIG[myind]->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) { for (i=0; i<33; i++) sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]); str[66] = 0; - MUSIG->numnonces = 1; - result.push_back(Pair("myind",MUSIG->myind)); + if ( n == 5 ) + MUSIG[myind]->numnonces = 1; + result.push_back(Pair("myind",MUSIG[myind]->myind)); result.push_back(Pair("nonce",str)); result.push_back(Pair("result","success")); } else return(cclib_error(result,"error serializing nonce (pubkey)")); @@ -538,18 +557,22 @@ UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n,ind; uint8_t pkhash[32],psig[32]; CPubKey pk; char str[67]; + UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32],psig[32]; CPubKey pk; char str[67]; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) { + if ( n > 3 ) + myind = juint(jitem(params,3),0); + else if ( n == 3 ) + myind = 0; if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) + else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsepubkey(ctx,MUSIG->nonces[ind],jitem(params,2)) < 0 ) + else if ( musig_parsepubkey(ctx,MUSIG[myind]->nonces[ind],jitem(params,2)) < 0 ) return(cclib_error(result,"error parsing nonce")); result.push_back(Pair("added_index",ind)); /** Checks a signer's public nonce against a commitment to said nonce, and update @@ -563,9 +586,17 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * with `musig_session_initialize_verifier`. * In: nonce: signer's alleged public nonce (cannot be NULL) */ - for (i=0; inum; i++) + MUSIG[myind]->numnonces++; + //fprintf(stderr, "NONCE: struct_size.%li using_struct.%i added_index.%i numnounces.%i num.%i\n",MUSIG.size(), myind, ind, MUSIG[myind]->numnonces, MUSIG[myind]->num); + if ( MUSIG[myind]->numnonces < MUSIG[myind]->num ) { - if ( secp256k1_musig_set_nonce(ctx,&MUSIG->signer_data[i],&MUSIG->nonces[i]) == 0 ) + result.push_back(Pair("status","not enough nonces")); + result.push_back(Pair("result","success")); + return(result); + } + for (i=0; inum; i++) + { + if ( secp256k1_musig_set_nonce(ctx,&MUSIG[myind]->signer_data[i],&MUSIG[myind]->nonces[i]) == 0 ) return(cclib_error(result,"error setting nonce")); } /** Updates a session with the combined public nonce of all signers. The combined @@ -586,20 +617,20 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) * adaptor: point to add to the combined public nonce. If NULL, nothing is * added to the combined nonce. */ - MUSIG->numnonces++; - if ( MUSIG->numnonces >= MUSIG->num && secp256k1_musig_session_combine_nonces(ctx,&MUSIG->session,MUSIG->signer_data,MUSIG->num,NULL,NULL) > 0 ) + if ( secp256k1_musig_session_combine_nonces(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,MUSIG[myind]->num,NULL,NULL) > 0 ) { - if ( secp256k1_musig_partial_sign(ctx,&MUSIG->session,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + if ( secp256k1_musig_partial_sign(ctx,&MUSIG[myind]->session,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) { for (i=0; i<32; i++) sprintf(&str[i<<1],"%02x",psig[i]); str[64] = 0; - result.push_back(Pair("myind",MUSIG->myind)); + result.push_back(Pair("myind",MUSIG[myind]->myind)); result.push_back(Pair("partialsig",str)); result.push_back(Pair("result","success")); - MUSIG->numpartials = 1; + if ( n == 5 ) + MUSIG[myind]->numpartials = 1; return(result); } else return(cclib_error(result,"error serializing partial sig")); } else return(cclib_error(result,"error making partial sig")); @@ -610,24 +641,29 @@ UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,ind,n; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; + UniValue result(UniValue::VOBJ); int32_t i,ind,n,myind; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; if ( ctx == 0 ) ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) + if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) { + if ( n > 3 ) + myind = juint(jitem(params,3),0); + else if ( n == 3 ) + myind = 0; if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG->pkhash,pkhash,32) != 0 ) + else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG->num ) + else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) return(cclib_error(result,"illegal ind for session")); else if ( cclib_parsehash(psig,jitem(params,2),32) < 0 ) return(cclib_error(result,"error parsing psig")); - else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG->partial_sig[ind],psig) == 0 ) + else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG[myind]->partial_sig[ind],psig) == 0 ) return(cclib_error(result,"error parsing partialsig")); result.push_back(Pair("added_index",ind)); - MUSIG->numpartials++; - if ( MUSIG->numpartials >= MUSIG->num && secp256k1_musig_partial_sig_combine(ctx,&MUSIG->session,&sig,MUSIG->partial_sig,MUSIG->num) > 0 ) + //fprintf(stderr, "SIG: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind); + MUSIG[myind]->numpartials++; + if ( MUSIG[myind]->numpartials >= MUSIG[myind]->num && secp256k1_musig_partial_sig_combine(ctx,&MUSIG[myind]->session,&sig,MUSIG[myind]->partial_sig,MUSIG[myind]->num) > 0 ) { if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 ) { @@ -640,7 +676,7 @@ UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *param } else { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG->partial_sig[MUSIG->myind]) > 0 ) + if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) { result.push_back(Pair("myind",ind)); for (i=0; i<32; i++) diff --git a/src/musigtest.py b/src/musigtest.py new file mode 100755 index 000000000..a452b7e97 --- /dev/null +++ b/src/musigtest.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 +import platform +import os +import re +import json +import random +import base58 +import binascii +import hashlib +import sys +import time +from slickrpc import Proxy + +# fucntion to define rpc_connection +def def_credentials(chain): + rpcport = ''; + operating_system = platform.system() + if operating_system == 'Darwin': + ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo' + elif operating_system == 'Linux': + ac_dir = os.environ['HOME'] + '/.komodo' + elif operating_system == 'Windows': + ac_dir = '%s/komodo/' % os.environ['APPDATA'] + if chain == 'KMD': + coin_config_file = str(ac_dir + '/komodo.conf') + else: + coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf') + with open(coin_config_file, 'r') as f: + for line in f: + l = line.rstrip() + if re.search('rpcuser', l): + rpcuser = l.replace('rpcuser=', '') + elif re.search('rpcpassword', l): + rpcpassword = l.replace('rpcpassword=', '') + elif re.search('rpcport', l): + rpcport = l.replace('rpcport=', '') + if len(rpcport) == 0: + if chain == 'KMD': + rpcport = 7771 + else: + print("rpcport not in conf file, exiting") + print("check " + coin_config_file) + exit(1) + return (Proxy("http://%s:%s@127.0.0.1:%d" % (rpcuser, rpcpassword, int(rpcport)))) + + +# generate address, validate address, dump private key +def genvaldump(rpc_connection): + # get new address + address = rpc_connection.getnewaddress() + # validate address + validateaddress_result = rpc_connection.validateaddress(address) + pubkey = validateaddress_result['pubkey'] + address = validateaddress_result['address'] + # dump private key for the address + privkey = rpc_connection.dumpprivkey(address) + # function output + output = [pubkey, privkey, address] + return(output) + +CHAIN = 'MUSIG' #sys.argv[1] + +rpc = def_credentials(CHAIN) + +pubkeys = [] +address_info = [] +ret = input('Do you want to generate new pubkeys? ').lower() + +if ret.startswith('y'): + numpks = int(input('Enter number of pubkeys to combine: ')) + if os.path.isfile("list.json"): + print('Already have list.json, move it if you would like to generate a new set.') + sys.exit(0) + while len(address_info) < numpks: + addressinfo = genvaldump(rpc) + address_info.append(addressinfo) + f = open("list.json", "w+") + f.write(json.dumps(address_info)) +else: + if os.path.isfile("list.json"): + with open('list.json') as list: + address_info = json.load(list) + else: + sys.exit('No list.json you need to create new pubkeys!') + +for addressinfo in address_info: + pubkeys.append(addressinfo[0]) + +ret = rpc.setpubkey(pubkeys[0]) +ret = rpc.cclib("combine", "18", str(pubkeys)) +pkhash = str(ret['pkhash']) +combinedpk = str(ret['combined_pk']) +print('Your combined pubkey is: ' + combinedpk) +print('Your pkhash is: ' + pkhash) +amount = float(input('Enter amount to send: ')) +if amount == 0: + sys.exit('Cannot send 0 coins. Exiting.') +tmp = str([combinedpk, amount]) +hex = rpc.cclib("send", "18", tmp)['hex'] +senttxid = rpc.sendrawtransaction(hex) +print('Your senttxid is: ' + senttxid) + +print("Waiting for tx to be confirmed") +while True: + confirmed = int(rpc.gettransaction(senttxid)["confirmations"]) + if not confirmed: + time.sleep(10) + else: + print('SentTX confirmed') + break + +scriptPubKey = rpc.getrawtransaction(senttxid,1)['vout'][1]['scriptPubKey']['hex'] +print('Your scriptPubKey is: ' + scriptPubKey) +tmp = str([senttxid, scriptPubKey]) +msg = rpc.cclib("calcmsg", "18", tmp)['msg'] +print('Your msg is: ' + msg) + +i = 0; +commitments = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + tmp = str([i, len(pubkeys), combinedpk, pkhash, msg, i]) + commitments.append(rpc.cclib("session", "18", tmp)['commitment']) + i = i + 1 + +print("Created commitments sucessfully... Sending to all signers.") + +i = 0 +nonces = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + n = 0 + for commitment in commitments: + tmp = str([pkhash, n, commitment, i]) + ret = rpc.cclib("commit", "18", tmp) + try: + nonces.append(ret['nonce']) + except: + x = 1 + n = n + 1 + i = i + 1 + +print("Created nounce's sucessfully... Sending to all signers.") + +i = 0 +partialsigs = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + n = 0 + for nonce in nonces: + tmp = str([pkhash, n, nonce, i]) + ret = rpc.cclib("nonce", "18", tmp) + try: + partialsigs.append(ret['partialsig']) + except: + x = 1 + n = n + 1 + i = i + 1 + +print("Created partial sigs sucessfully... Sending to all signers.") + +i = 0 +combinedsigs = [] +for pubkey in pubkeys: + ret = rpc.setpubkey(pubkey) + n = 0 + for partialsig in partialsigs: + tmp = str([pkhash, n, partialsig, i]) + ret = rpc.cclib("partialsig", "18", tmp) + try: + combinedsigs.append(ret['combinedsig']) + except: + x = 1 + n = n + 1 + i = i + 1 + +print("Created combined sigs sucessfully... Verifying.") + +tmp = str([msg, combinedpk, combinedsigs[0]]) +ret = rpc.cclib("verify", "18", tmp) + +if ret['result'] != "success": + print(ret) + sys.exit('Could not verify signature.') + +print('Verified... Attempting to send.') + +tmp = str([senttxid, scriptPubKey, combinedsigs[0]]) +ret = rpc.cclib("spend", "18", tmp) + +if ret['result'] != "success": + print(ret) + sys.exit('Could not create spend transaction.') + +try: + ret = rpc.sendrawtransaction(ret['hex']) +except: + sys.exit('Could not send transaction.') + +print('Spent txid: ' + ret) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0ed2f866c..0e0ab9906 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5308,7 +5308,7 @@ UniValue setpubkey(const UniValue& params, bool fHelp) char Raddress[64]; uint8_t pubkey33[33]; - if ( NOTARY_PUBKEY33[0] == 0 ) + if ( NOTARY_PUBKEY33[0] == 0 || (strcmp(ASSETCHAINS_SYMBOL, "MUSIG") == 0) ) { if (strlen(params[0].get_str().c_str()) == 66) {