Example #1
0
 // Initialize XChainClient, must call this method after XChainClient instance created.
 /// <summary>Initialize XChainClient, must call this method after XChainClient instance created.</summary>
 /// <param name="keypath">the folder contains user's address and private key</param>
 /// <param name="targetHost">the GRPC endpoint of xuperchain node, e.g. 127.0.0.1:37101</param>
 /// <returns>the balance of given address</returns>
 public bool Init(string keypath, string targetHost)
 {
     try
     {
         AppContext.SetSwitch(SwitchName, true);
         var channel = GrpcChannel.ForAddress("http://" + targetHost);
         this.client  = new Pb.Xchain.XchainClient(channel);
         this.account = new XCAccount();
         return(SetAccountByPath(keypath));
     }
     catch (Exception e)
     {
         Console.WriteLine("Init failed, err=" + e.ToString());
         return(false);
     }
 }
Example #2
0
        private Transaction AssembleTx(Pb.UtxoOutput utxo, XCAccount account, List <string> authRequire,
                                       string to, BigInteger amount, Pb.InvokeResponse contractInvoke, string desc)
        {
            var tx = new Transaction();

            // check param
            if (amount < 0 || account == null)
            {
                return(null);
            }
            // if have utxo, assemble utxo input/ouput
            if (utxo != null)
            {
                // assemble TxInputs
                tx.TxInputs = new List <TxInput>();
                var total = BigInteger.Parse(utxo.TotalSelected);
                for (var i = 0; i < utxo.UtxoList.Count; i++)
                {
                    var utxoItem = utxo.UtxoList[i];
                    var input    = new TxInput
                    {
                        FromAddr  = utxoItem.ToAddr.ToByteArray(),
                        Amount    = utxoItem.Amount.ToByteArray(),
                        RefTxid   = utxoItem.RefTxid.ToByteArray(),
                        RefOffset = utxoItem.RefOffset,
                    };
                    tx.TxInputs.Add(input);
                }

                tx.TxOutputs = new List <TxOutput>();
                // Assemble utxo Output for transferring to
                if (amount > 0 && to != "")
                {
                    // utxo check
                    if (amount > total)
                    {
                        Console.WriteLine("Utxo use greater than utxo selected" + ", selected=" + total + ", use=", amount);
                        return(null);
                    }
                    var output = new TxOutput()
                    {
                        ToAddr = Encoding.ASCII.GetBytes(to),
                        Amount = amount.ToByteArray(),
                    };
                    Array.Reverse(output.Amount, 0, output.Amount.Length);
                    tx.TxOutputs.Add(output);
                    total -= amount;
                }

                // Assemble contract fee
                if (contractInvoke != null && contractInvoke.GasUsed > 0)
                {
                    var gasUsed = new BigInteger(contractInvoke.GasUsed);
                    if (gasUsed > total)
                    {
                        Console.WriteLine("Utxo use greater than utxo selected" + ", selected=" + total + ", use=", gasUsed);
                        return(null);
                    }
                    var output = new TxOutput()
                    {
                        ToAddr = Encoding.ASCII.GetBytes("$"),
                        Amount = gasUsed.ToByteArray(),
                    };
                    Array.Reverse(output.Amount, 0, output.Amount.Length);
                    tx.TxOutputs.Add(output);
                    total -= gasUsed;
                }

                // charge utxo to user
                if (total > 0)
                {
                    var chargeOutput = new TxOutput()
                    {
                        ToAddr = Encoding.ASCII.GetBytes(account.Address),
                        Amount = total.ToByteArray(),
                    };
                    Array.Reverse(chargeOutput.Amount, 0, chargeOutput.Amount.Length);
                    tx.TxOutputs.Add(chargeOutput);
                }
            }

            // Assemble contracts
            if (contractInvoke != null)
            {
                if (contractInvoke.Inputs.Count > 0)
                {
                    tx.TxInputsExt = new List <TxInputExt>();
                }
                if (contractInvoke.Outputs.Count > 0)
                {
                    tx.TxOutputsExt = new List <TxOutputExt>();
                }
                if (contractInvoke.Requests.Count > 0)
                {
                    tx.ContractRequests = new List <InvokeRequest>();
                }
                // TODO: transfer within contract is not supported
                foreach (var input in contractInvoke.Inputs)
                {
                    var inputExt = new TxInputExt
                    {
                        Bucket    = input.Bucket,
                        Key       = input.Key.ToByteArray(),
                        RefTxid   = input.RefTxid.ToByteArray(),
                        RefOffset = input.RefOffset,
                    };
                    tx.TxInputsExt.Add(inputExt);
                }
                foreach (var output in contractInvoke.Outputs)
                {
                    var outputExt = new TxOutputExt
                    {
                        Bucket = output.Bucket,
                        Key    = output.Key.ToByteArray(),
                        Value  = output.Value.ToByteArray(),
                    };
                    tx.TxOutputsExt.Add(outputExt);
                }
                foreach (var request in contractInvoke.Requests)
                {
                    var invoke = new InvokeRequest
                    {
                        ModuleName   = request.ModuleName,
                        ContractName = request.ContractName,
                        MethodName   = request.MethodName,
                    };
                    foreach (var arg in request.Args)
                    {
                        invoke.Args.Add(arg.Key, arg.Value.ToByteArray());
                    }
                    foreach (var limit in request.ResourceLimits)
                    {
                        invoke.ResourceLimits.Add(new ResourceLimit
                        {
                            Type  = (ResourceType)limit.Type,
                            Limit = limit.Limit,
                        });
                    }
                    tx.ContractRequests.Add(invoke);
                }
            }

            // Assemble other data
            tx.Desc      = Encoding.ASCII.GetBytes(desc);
            tx.Version   = 1;
            tx.Coinbase  = false;
            tx.Autogen   = false;
            tx.Initiator = account.Address;
            if (authRequire != null && authRequire.Count > 0)
            {
                tx.AuthRequire = authRequire;
            }
            var digestHash = XDigest.MakeDigestHash(tx);
            var sign       = XCrypto.SignHash(account.PrivateKey, digestHash);
            var signInfo   = new SignatureInfo()
            {
                PublicKey = account.PublicKey.RawKey,
                Sign      = sign,
            };

            tx.InitiatorSigns = new List <SignatureInfo>();
            tx.InitiatorSigns.Add(signInfo);
            if (authRequire != null && authRequire.Count > 0)
            {
                tx.AuthRequireSigns = new List <SignatureInfo>();
                tx.AuthRequireSigns.Add(signInfo);
            }
            var txid = XDigest.MakeTransactionID(tx);

            tx.Txid = txid;
            return(tx);
        }