private Pb.PreExecWithSelectUTXOResponse PreExecWithSelectUTXO( string bcname, string address, AccountPrivateKey privkey, BigInteger amount, string contractName, string method, SortedDictionary <string, byte[]> args, ContactVMType.Type contractType, string initiator, List <string> authRequire) { var header = GetDefaultHeader(); var req = new Pb.PreExecWithSelectUTXORequest { Header = header, Bcname = bcname, Address = address, TotalAmount = (long)amount, NeedLock = false, Request = new Pb.InvokeRPCRequest { Header = header, Bcname = bcname, Initiator = initiator, }, }; if (authRequire != null) { req.Request.AuthRequire.AddRange(authRequire); } var invoke = new Pb.InvokeRequest { ModuleName = ContactVMType.GetNameByType(contractType), MethodName = method, }; if (contractName != null) { invoke.ContractName = contractName; } foreach (var item in args) { invoke.Args.Add(item.Key, ByteString.CopyFrom(item.Value)); } req.Request.Requests.Add(invoke); var res = client.PreExecWithSelectUTXO(req); if (res.Header.Error != Pb.XChainErrorEnum.Success) { Console.WriteLine("PreExecWithSelectUTXO failed, error code=" + (int)res.Header.Error); return(null); } return(res); }
// Invokes contract method with given args // TODO: multisig is not supported /// <param name="contractName">the name of contract to invoke</param> /// <param name="method">the method name of contract to invoke</param> /// <param name="args">the arguments of contract</param> /// <param name="authRequire">add more address if multisig needed, otherwise keep null</param> public Response InvokeContract(string bcname, string contractName, string method, SortedDictionary <string, byte[]> args, List <string> authRequire = null, string desc = "", ContactVMType.Type contractType = ContactVMType.Type.WASM) { // pre-execute contract var execRes = PreExecWithSelectUTXO(bcname, this.Account.Address, this.Account.PrivateKey, 0, contractName, method, args, contractType, this.Account.Address, authRequire); if (execRes == null) { Console.WriteLine("InvokeContract: PreExecWithSelectUTXO failed"); return(null); } // check contract response var contractResult = new Dictionary <string, string>(); for (var i = 0; i < execRes.Response.Responses.Count; i++) { if (execRes.Response.Responses[i].Status >= 400) { Console.WriteLine("Contract execute failed. res=" + JsonConvert.SerializeObject(execRes.Response.Responses[i])); return(new Response { Error = new XChainError { ErrorCode = Errors.Success, }, }); } contractResult.Add(execRes.Response.Requests[i].ContractName + ":" + execRes.Response.Requests[i].MethodName, Encoding.ASCII.GetString(execRes.Response.Responses[i].Body.ToByteArray())); } // assemble transaction var tx = AssembleTx(execRes.UtxoOutput, this.Account, authRequire, "", 0, execRes.Response, desc); if (tx == null) { Console.WriteLine("InvokeContract: AssembleTx failed"); return(null); } // post transaction var postRes = PostTx(bcname, tx); if (postRes == null || postRes.Header.Error != Pb.XChainErrorEnum.Success) { Console.WriteLine("InvokeContract: PostTx failed"); return(null); } var res = new Response { Error = new XChainError { ErrorCode = Errors.Success, }, Txid = XConvert.ByteArrayToHexString(tx.Txid), Data = contractResult, }; return(res); }