/// <summary> /// Get token balance with string parameters /// </summary> /// <param name="tokenHash">token script hash, Example: "0x43cf98eddbe047e198a3e5d57006311442a0ca15"(NEO)</param> /// <param name="account">address, scripthash or public key string /// Example: address ("AV556nYUwyJKNv8Xy7hVMLQnkmKPukw6x5"), scripthash ("0x6a38cd693b615aea24dd00de12a9f5836844da91"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575")</param> /// <returns></returns> public BigInteger GetTokenBalance(string tokenHash, string account) { UInt160 scriptHash = Utility.GetScriptHash(tokenHash); UInt160 accountHash = Utility.GetScriptHash(account); return(nep5API.BalanceOf(scriptHash, accountHash)); }
/// <summary> /// Verify Witness count and add witnesses /// </summary> public TransactionManager Sign() { // Calculate NetworkFee Tx.NetworkFee = CalculateNetworkFee(); var gasBalance = nep5API.BalanceOf(NativeContract.GAS.Hash, sender); if (gasBalance < Tx.SystemFee + Tx.NetworkFee) { throw new InvalidOperationException($"Insufficient GAS in address: {sender.ToAddress()}"); } // Sign with signStore foreach (var item in signStore) { foreach (var key in item.KeyPairs) { byte[] signature = Tx.Sign(key); if (!context.AddSignature(item.Contract, key.PublicKey, signature)) { throw new Exception("AddSignature failed!"); } } } // Verify witness count if (!context.Completed) { throw new Exception($"Please add signature or witness first!"); } Tx.Witnesses = context.GetWitnesses(); return(this); }
/// <summary> /// Create an unsigned Transaction object with given parameters. /// </summary> /// <param name="script">Transaction Script</param> /// <param name="attributes">Transaction Attributes</param> /// <param name="cosigners">Transaction Cosigners</param> /// <param name="networkFee">Transaction NetworkFee, will set to estimate value(with only basic signatures) when networkFee is 0</param> /// <returns></returns> public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] attributes = null, Cosigner[] cosigners = null, long networkFee = 0) { var random = new Random(); uint height = rpcClient.GetBlockCount() - 1; Tx = new Transaction { Version = 0, Nonce = (uint)random.Next(), Script = script, Sender = sender, ValidUntilBlock = height + Transaction.MaxValidUntilBlockIncrement, Attributes = attributes ?? new TransactionAttribute[0], Cosigners = cosigners ?? new Cosigner[0], Witnesses = new Witness[0] }; // Add witness hashes parameter to pass CheckWitness UInt160[] hashes = Tx.GetScriptHashesForVerifying(null); RpcInvokeResult result = rpcClient.InvokeScript(script, hashes); Tx.SystemFee = Math.Max(long.Parse(result.GasConsumed) - ApplicationEngine.GasFree, 0); if (Tx.SystemFee > 0) { long d = (long)NativeContract.GAS.Factor; long remainder = Tx.SystemFee % d; if (remainder > 0) { Tx.SystemFee += d - remainder; } else if (remainder < 0) { Tx.SystemFee -= remainder; } } context = new ContractParametersContext(Tx); // set networkfee to estimate value when networkFee is 0 Tx.NetworkFee = networkFee == 0 ? EstimateNetworkFee() : networkFee; var gasBalance = nep5API.BalanceOf(NativeContract.GAS.Hash, sender); if (gasBalance >= Tx.SystemFee + Tx.NetworkFee) { return(this); } throw new InvalidOperationException($"Insufficient GAS in address: {sender.ToAddress()}"); }