public static void ClaimPreloadGas(NeoSystem system, Neo.Wallets.Wallet wallet, Random random) { void SubmitTransaction(Func <Snapshot, WalletAccount, Transaction?> factory) { using var snapshot = Blockchain.Singleton.GetSnapshot(); var validators = snapshot.GetValidators(); if (validators.Length != 1) { throw new InvalidOperationException("Preload only supported for single-node blockchains"); } var account = wallet.GetAccounts().Single(a => a.Contract.Script.IsMultiSigContract()); var tx = factory(snapshot, account); if (tx == null) { throw new Exception("Attempted to submit null preload transaction"); } var context = new ContractParametersContext(tx); wallet.Sign(context); if (!context.Completed) { throw new InvalidOperationException("could not complete signing of preload transaction"); } var block = CreatePreloadBlock(wallet, random, tx); var result = system.Blockchain.Ask <RelayResultReason>(block).Result; if (result != RelayResultReason.Succeed) { throw new Exception($"Preload {tx.Type} transaction failed {result}"); } } SubmitTransaction((snapshot, account) => NodeUtility.MakeTransferTransaction(snapshot, ImmutableHashSet.Create(account.ScriptHash), account.ScriptHash, Blockchain.GoverningToken.Hash, null)); // There needs to be least one block after the transfer transaction before submitting a GAS claim var block = CreatePreloadBlock(wallet, random); var result = system.Blockchain.Ask <RelayResultReason>(block).Result; if (result != RelayResultReason.Succeed) { throw new Exception($"Preload transfer suffix block failed {result}"); } SubmitTransaction((snapshot, account) => NodeUtility.MakeClaimTransaction(snapshot, account.ScriptHash, Blockchain.GoverningToken.Hash)); }
public JObject OnGetUnspents(JArray @params) { JObject GetBalance(IEnumerable <Coin> coins, UInt256 assetId, string symbol) { var unspents = new JArray(); var total = Fixed8.Zero; foreach (var coin in coins.Where(c => c.Output.AssetId == assetId)) { var unspent = new JObject(); unspent["txid"] = coin.Reference.PrevHash.ToString().Substring(2); unspent["n"] = coin.Reference.PrevIndex; unspent["value"] = (double)(decimal)coin.Output.Value; total += coin.Output.Value; unspents.Add(unspent); } var balance = new JObject(); balance["asset_hash"] = assetId.ToString().Substring(2); balance["asset_symbol"] = balance["asset"] = symbol; balance["amount"] = (double)(decimal)total; balance["unspent"] = unspents; return(balance); } var address = @params[0].AsString().ToScriptHash(); string[] nativeAssetNames = { "GAS", "NEO" }; UInt256[] nativeAssetIds = { Blockchain.UtilityToken.Hash, Blockchain.GoverningToken.Hash }; using (var snapshot = Blockchain.Singleton.GetSnapshot()) { var coins = NodeUtility.GetCoins(snapshot, ImmutableHashSet.Create(address)).Unspent(); var neoCoins = coins.Where(c => c.Output.AssetId == Blockchain.GoverningToken.Hash); var gasCoins = coins.Where(c => c.Output.AssetId == Blockchain.UtilityToken.Hash); JObject json = new JObject(); json["address"] = address.ToAddress(); json["balance"] = new JArray( GetBalance(coins, Blockchain.GoverningToken.Hash, "NEO"), GetBalance(coins, Blockchain.UtilityToken.Hash, "GAS")); return(json); } }
private JObject OnShowCoins(JArray @params) { var address = @params[0].AsString().ToScriptHash(); using (var snapshot = Blockchain.Singleton.GetSnapshot()) { var coins = NodeUtility.GetCoins(snapshot, ImmutableHashSet.Create(address)); return(new JArray(coins.Select(c => { var j = new JObject(); j["state"] = (byte)c.State; j["state-label"] = c.State.ToString(); j["reference"] = c.Reference.ToJson(); j["output"] = c.Output.ToJson(0); return j; }))); } }
private JObject GetClaimable(JArray @params) { var address = @params[0].AsString().ToScriptHash(); using (var snapshot = Blockchain.Singleton.GetSnapshot()) { var coins = NodeUtility.GetCoins(snapshot, ImmutableHashSet.Create(address)); var unclaimedCoins = coins.Unclaimed(Blockchain.GoverningToken.Hash); var totalUnclaimed = Fixed8.Zero; var claimable = new JArray(); foreach (var coin in unclaimedCoins) { var spentCoinState = snapshot.SpentCoins.TryGet(coin.Reference.PrevHash); var startHeight = spentCoinState.TransactionHeight; var endHeight = spentCoinState.Items[coin.Reference.PrevIndex]; var(generated, sysFee) = NodeUtility.CalculateClaimable(snapshot, coin.Output.Value, startHeight, endHeight); var unclaimed = generated + sysFee; totalUnclaimed += unclaimed; var utxo = new JObject(); utxo["txid"] = coin.Reference.PrevHash.ToString().Substring(2); utxo["n"] = coin.Reference.PrevIndex; utxo["start_height"] = startHeight; utxo["end_height"] = endHeight; utxo["generated"] = (double)(decimal)generated; utxo["sys_fee"] = (double)(decimal)sysFee; utxo["unclaimed"] = (double)(decimal)(unclaimed); claimable.Add(utxo); } JObject json = new JObject(); json["claimable"] = claimable; json["address"] = address.ToAddress(); json["unclaimed"] = (double)(decimal)totalUnclaimed; return(json); } }
private JObject GetUnclaimed(JArray @params) { var address = @params[0].AsString().ToScriptHash(); using (var snapshot = Blockchain.Singleton.GetSnapshot()) { var coins = NodeUtility.GetCoins(snapshot, ImmutableHashSet.Create(address)); var unclaimedCoins = coins.Unclaimed(Blockchain.GoverningToken.Hash); var unspentCoins = coins.Unspent(Blockchain.GoverningToken.Hash); var unavailable = snapshot.CalculateBonus( unspentCoins.Select(c => c.Reference), snapshot.Height + 1); var available = snapshot.CalculateBonus(unclaimedCoins.Select(c => c.Reference)); JObject json = new JObject(); json["unavailable"] = (double)(decimal)unavailable; json["available"] = (double)(decimal)available; json["unclaimed"] = (double)(decimal)(available + unavailable); return(json); } }