Beispiel #1
0
        public Transaction CallContract(NeoKeys key, UInt160 scriptHash, object[] args, string attachSymbol = null
                                        , IEnumerable <Transaction.Output> attachTargets = null, byte[] nonce = null, Action <string> usedRpc = null)
        {
            var bytes = GenerateScript(scriptHash, args, nonce);

            return(CallContract(key, scriptHash, bytes, attachSymbol, attachTargets, usedRpc));
        }
Beispiel #2
0
        public Transaction Transfer(NeoKeys from_key, byte[] to_address_hash, decimal value)
        {
            BigInteger amount = ConvertToBigInt(value);

            var sender_address_hash = from_key.Address.GetScriptHashFromAddress();
            var response            = api.CallContract(from_key, ScriptHash, "transfer", new object[] { sender_address_hash, to_address_hash, amount });

            return(response);
        }
Beispiel #3
0
        public void WaitForTransaction(BlockIterator iterator, NeoKeys keys, Transaction tx, int maxBlocksToWait = 9999)
        {
            if (tx == null)
            {
                throw new ArgumentNullException();
            }

            WaitForTransaction(iterator, x => x.Hash == tx.Hash, maxBlocksToWait);
            lastTransactions[keys.Address] = tx;
        }
Beispiel #4
0
        public static Transaction MintTokens(NEP5 token, NeoKeys buyer_key, string symbol, decimal amount)
        {
            var attachs = new List <Transaction.Output>();

            attachs.Add(new Transaction.Output()
            {
                assetID = NeoAPI.GetAssetID(symbol), scriptHash = token.ScriptHash, value = amount
            });
            var response = token.api.CallContract(buyer_key, token.ScriptHash, "mintTokens", new object[] { }, symbol, attachs);

            return(response);
        }
Beispiel #5
0
        public Transaction ClaimGas(NeoKeys ownerKey)
        {
            var targetScriptHash = new UInt160(ownerKey.Address.AddressToScriptHash());

            decimal amount;
            var     claimable = GetClaimable(targetScriptHash, out amount);

            var references = new List <Transaction.Input>();

            foreach (var entry in claimable)
            {
                references.Add(new Transaction.Input()
                {
                    prevHash = entry.hash, prevIndex = entry.index
                });
            }

            if (amount <= 0)
            {
                throw new ArgumentException("No GAS to claim at this address");
            }

            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            GenerateInputsOutputs(ownerKey, "GAS", null, out inputs, out outputs);

            outputs.Add(
                new Transaction.Output()
            {
                scriptHash = targetScriptHash,
                assetID    = NeoAPI.GetAssetID("GAS"),
                value      = amount
            });

            Transaction tx = new Transaction()
            {
                type            = TransactionType.ClaimTransaction,
                version         = 0,
                script          = null,
                gas             = -1,
                claimReferences = references.ToArray(),
                inputs          = inputs.ToArray(),
                outputs         = outputs.ToArray(),
            };

            tx.Sign(ownerKey);

            var ok = SendTransaction(tx);

            return(ok ? tx : null);
        }
Beispiel #6
0
        public IEnumerator ClaimGas(UnspentEntries unspent, NeoKeys ownerKey, List <UnspentEntry> claimable, decimal amount, Action <Transaction, string> callback)
        {
            var targetScriptHash = new UInt160(ownerKey.Address.AddressToScriptHash());

            var references = new List <Transaction.Input>();

            foreach (var entry in claimable)
            {
                references.Add(new Transaction.Input()
                {
                    prevHash = entry.hash, prevIndex = entry.index
                });
            }

            if (amount <= 0)
            {
                throw new ArgumentException("No GAS to claim at this address");
            }

            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            GenerateInputsOutputs(unspent, ownerKey, "GAS", null, out inputs, out outputs);

            outputs.Add(
                new Transaction.Output()
            {
                scriptHash = targetScriptHash,
                assetID    = NeoAPI.GetAssetID("GAS"),
                value      = amount
            });

            Transaction tx = new Transaction()
            {
                type            = TransactionType.ClaimTransaction,
                version         = 0,
                script          = null,
                gas             = -1,
                claimReferences = references.ToArray(),
                inputs          = inputs.ToArray(),
                outputs         = outputs.ToArray(),
            };

            tx.Sign(ownerKey);

            return(SendTransaction(tx, (error) =>
            {
                callback(string.IsNullOrEmpty(error) ? tx : null, error);
            }));
        }
Beispiel #7
0
        public Transaction WithdrawAsset(NeoKeys toKey, UInt160 fromScripthash, string symbol, IEnumerable <Transaction.Output> targets, byte[] verificationScript)
        {
            var check = verificationScript.ToScriptHash();

            if (check != fromScripthash)
            {
                throw new ArgumentException("Invalid verification script");
            }

            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            GenerateInputsOutputs(fromScripthash, symbol, targets, out inputs, out outputs);


            List <Transaction.Input>  gas_inputs;
            List <Transaction.Output> gas_outputs;

            GenerateInputsOutputs(toKey, "GAS", null, out gas_inputs, out gas_outputs);

            foreach (var entry in gas_inputs)
            {
                inputs.Add(entry);
            }

            foreach (var entry in gas_outputs)
            {
                outputs.Add(entry);
            }

            Transaction tx = new Transaction()
            {
                type    = TransactionType.ContractTransaction,
                version = 0,
                script  = null,
                gas     = -1,
                inputs  = inputs.ToArray(),
                outputs = outputs.ToArray()
            };

            var witness = new Witness {
                invocationScript = ("0014" + toKey.Address.AddressToScriptHash().ByteToHex()).HexToBytes(), verificationScript = verificationScript
            };

            tx.Sign(toKey, new Witness[] { witness });

            var ok = SendTransaction(tx);

            return(ok ? tx : null);
        }
Beispiel #8
0
        public Transaction WithdrawAsset(NeoKeys toKey, string fromAddress, string symbol, decimal amount, byte[] verificationScript)
        {
            var fromScriptHash = new UInt160(fromAddress.GetScriptHashFromAddress());
            var target         = new Transaction.Output()
            {
                scriptHash = new UInt160(toKey.Address.GetScriptHashFromAddress()), value = amount
            };
            var targets = new List <Transaction.Output>()
            {
                target
            };

            return(WithdrawAsset(toKey, fromScriptHash, symbol, targets, verificationScript));
        }
Beispiel #9
0
        // transfer to multiple addresses
        public Transaction Transfer(NeoKeys from_key, Dictionary <byte[], decimal> transfers)
        {
            if (transfers.Count > max_transfer_count)
            {
                throw new ArgumentException("Max transfers per call = " + max_transfer_count);
            }

            var scripts = new List <byte[]>();

            var sender_address_hash = from_key.Address.GetScriptHashFromAddress();

            int index = 0;

            foreach (var entry in transfers)
            {
                if (entry.Value <= 0)
                {
                    var addr = new UInt160(entry.Key).ToAddress();
                    throw new ArgumentException($"Invalid amount {entry.Value} for address {addr}");
                }

                BigInteger amount = ConvertToBigInt(entry.Value);

                var isLast = index == transfers.Count - 1;
                var args   = new object[] { sender_address_hash, entry.Key, amount };
                var bytes  = NeoAPI.GenerateScript(ScriptHash, new object[] { "transfer", args }, isLast);

                scripts.Add(bytes);
                index++;
            }

            var final_size = scripts.Sum(x => x.Length);

            byte[] final_script = new byte[final_size];

            using (var stream = new MemoryStream(final_script))
            {
                foreach (byte[] bytes in scripts)
                {
                    stream.Write(bytes, 0, bytes.Length);
                }
            }

            var response = api.CallContract(from_key, ScriptHash, final_script);

            return(response);
        }
Beispiel #10
0
        // transfer to multiple addresses
        public Transaction Transfer(NeoKeys from_key, Dictionary <string, decimal> transfers)
        {
            var temp = new Dictionary <byte[], decimal>(new ByteArrayComparer());

            foreach (var entry in transfers)
            {
                if (!entry.Key.IsValidAddress())
                {
                    throw new ArgumentException($"{entry.Key} is not a valid address");
                }

                var hash = entry.Key.AddressToScriptHash();
                temp[hash] = entry.Value;
            }

            return(Transfer(from_key, temp));
        }
Beispiel #11
0
        public Transaction CallContract(NeoKeys key, UInt160 scriptHash, byte[] bytes, string attachSymbol = null
                                        , IEnumerable <Transaction.Output> attachTargets = null, Action <string> usedRpc = null)
        {
            List <Transaction.Input>  inputs  = null;
            List <Transaction.Output> outputs = null;

            if (attachSymbol == null)
            {
                attachSymbol = "GAS";
            }

            if (!string.IsNullOrEmpty(attachSymbol))
            {
                GenerateInputsOutputs(key, attachSymbol, attachTargets, out inputs, out outputs);

                if (inputs.Count == 0)
                {
                    throw new NeoException($"Not enough inputs for transaction");
                }
            }

            var transaction = new Transaction()
            {
                type    = TransactionType.InvocationTransaction,
                version = 0,
                script  = bytes,
                gas     = 0,
                inputs  = inputs != null?inputs.ToArray() : null,
                              outputs = outputs != null?outputs.ToArray() : null,
                                            attributes = inputs == null ? (new TransactionAttribute[] { new TransactionAttribute(TransactionAttributeUsage.Script, key.Address.AddressToScriptHash()) }) : null
            };

            transaction.Sign(key);

            if (SendTransaction(key, transaction, out string rpc))
            {
                if (usedRpc != null)
                {
                    usedRpc.Invoke(rpc);
                }

                return(transaction);
            }

            return(null);
        }
Beispiel #12
0
        public Transaction SendAsset(NeoKeys fromKey, string toAddress, string symbol, decimal amount)
        {
            if (String.Equals(fromKey.Address, toAddress, StringComparison.OrdinalIgnoreCase))
            {
                throw new NeoException("Source and dest addresses are the same");
            }

            var toScriptHash = toAddress.GetScriptHashFromAddress();
            var target       = new Transaction.Output()
            {
                scriptHash = new UInt160(toScriptHash), value = amount
            };
            var targets = new List <Transaction.Output>()
            {
                target
            };

            return(SendAsset(fromKey, symbol, targets));
        }
Beispiel #13
0
        public void GenerateInputsOutputs(UnspentEntries unspent, NeoKeys key, string symbol, IEnumerable <Transaction.Output> targets, out List <Transaction.Input> inputs, out List <Transaction.Output> outputs, decimal system_fee = 0, bool allowSameSourceAndDest = false)
        {
            var from_script_hash = new UInt160(key.signatureHash.ToArray());
            var info             = GetAssetsInfo();
            var targetAssetID    = NeoUtils.ReverseHex(info[symbol]).HexToBytes();

            if (targets != null)
            {
                foreach (var t in targets)
                {
                    if (t.assetID == null)
                    {
                        t.assetID = targetAssetID;
                    }
                }
            }
            //else Console.WriteLine("ASSETID target already existed: " + symbol);
            GenerateInputsOutputs(unspent, from_script_hash, targets, out inputs, out outputs, system_fee, allowSameSourceAndDest);
        }
Beispiel #14
0
        public static NeoKeys FromNEP2(string nep2, string passphrase, int N = 16384, int r = 8, int p = 8)
        {
            Throw.IfNull(nep2, nameof(nep2));
            Throw.IfNull(passphrase, nameof(passphrase));

            byte[] data = nep2.Base58CheckDecode();
            if (data.Length != 39 || data[0] != 0x01 || data[1] != 0x42 || data[2] != 0xe0)
            {
                throw new FormatException();
            }

            byte[] addressHash = new byte[4];
            Buffer.BlockCopy(data, 3, addressHash, 0, 4);
            byte[] datapassphrase = Encoding.UTF8.GetBytes(passphrase);
            byte[] derivedkey     = SCrypt.DeriveKey(datapassphrase, addressHash, N, r, p, 64);
            Array.Clear(datapassphrase, 0, datapassphrase.Length);

            byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
            byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
            Array.Clear(derivedkey, 0, derivedkey.Length);

            byte[] encryptedkey = new byte[32];
            Buffer.BlockCopy(data, 7, encryptedkey, 0, 32);
            Array.Clear(data, 0, data.Length);

            byte[] prikey = XOR(encryptedkey.AES256Decrypt(derivedhalf2), derivedhalf1);
            Array.Clear(derivedhalf1, 0, derivedhalf1.Length);
            Array.Clear(derivedhalf2, 0, derivedhalf2.Length);

            ECPoint pubkey = ECCurve.Secp256r1.G * prikey;
            var     keys   = new NeoKeys(prikey);
            var     temp   = Encoding.ASCII.GetBytes(keys.Address).Sha256().Sha256().Take(4).ToArray();

            if (!temp.SequenceEqual(addressHash))
            {
                throw new FormatException("invalid passphrase when decrypting NEP2");
            }
            return(keys);
        }
Beispiel #15
0
        public Transaction SendAsset(NeoKeys fromKey, string symbol, IEnumerable <Transaction.Output> targets)
        {
            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            GenerateInputsOutputs(fromKey, symbol, targets, out inputs, out outputs);

            Transaction tx = new Transaction()
            {
                type    = TransactionType.ContractTransaction,
                version = 0,
                script  = null,
                gas     = -1,
                inputs  = inputs.ToArray(),
                outputs = outputs.ToArray()
            };

            tx.Sign(fromKey);

            var ok = SendTransaction(tx);

            return(ok ? tx : null);
        }
Beispiel #16
0
        public void GenerateInputsOutputs(UnspentEntries unspent, NeoKeys key, IEnumerable <Transaction.Output> targets, out List <Transaction.Input> inputs, out List <Transaction.Output> outputs, decimal system_fee = 0, bool allowSameSourceAndDest = false)
        {
            var from_script_hash = new UInt160(key.signatureHash.ToArray());

            GenerateInputsOutputs(unspent, from_script_hash, targets, out inputs, out outputs, system_fee);
        }
Beispiel #17
0
        public IEnumerator CallContract(Action <Transaction, string> callback, UnspentEntries unspent, NeoKeys key, UInt160 scriptHash, object[] args, string interop, decimal fee = 0, string attachSymbol = null, IEnumerable <Transaction.Output> attachTargets = null)
        {
            var bytes = GenerateScript(scriptHash, args);

            return(CallContract(callback, unspent, key, scriptHash, bytes, interop, fee, attachSymbol, attachTargets));
        }
Beispiel #18
0
 public Transaction Transfer(NeoKeys from_key, string to_address, decimal value)
 {
     return(Transfer(from_key, to_address.GetScriptHashFromAddress(), value));
 }
Beispiel #19
0
 public decimal BalanceOf(NeoKeys keys)
 {
     return(BalanceOf(keys.Address));
 }
Beispiel #20
0
 public IEnumerator CallContract(Action <Transaction, string> callback, UnspentEntries unspent, NeoKeys key, UInt160 scriptHash, string operation, object[] args, string interop, string attachSymbol = null, IEnumerable <Transaction.Output> attachTargets = null)
 {
     return(CallContract(callback, unspent, key, scriptHash, new object[] { operation, args }, interop, attachSymbol, attachTargets));
 }
Beispiel #21
0
 public Transaction Transfer(NeoKeys from_key, UInt160 to_address_hash, decimal value)
 {
     return(Transfer(from_key, to_address_hash.ToArray(), value));
 }
Beispiel #22
0
        public IEnumerator Transfer(UnspentEntries unspent, NeoKeys from_key, byte[] to_address_hash, BigInteger amount, string interop, Action <Transaction, string> callback)
        {
            var sender_address_hash = from_key.Address.GetScriptHashFromAddress();

            return(api.CallContract(callback, unspent, from_key, ScriptHash, "transfer", new object[] { sender_address_hash, to_address_hash, amount }, interop));
        }
Beispiel #23
0
 public IEnumerator Transfer(UnspentEntries unspent, NeoKeys from_key, UInt160 to_address_hash, BigInteger amount, string interop, Action <Transaction, string> callback)
 {
     return(Transfer(unspent, from_key, to_address_hash.ToArray(), amount, interop, callback));
 }
Beispiel #24
0
        public static Transaction Deploy(NEP5 token, NeoKeys owner_key)
        {
            var response = token.api.CallContract(owner_key, token.ScriptHash, "deploy", new object[] { });

            return(response);
        }
Beispiel #25
0
        public IEnumerator SendAsset(Action <Transaction, string> callback, UnspentEntries unspent, NeoKeys fromKey, string symbol, IEnumerable <Transaction.Output> targets, string interop, decimal fee = 0, bool allowSameSourceAndDest = false)
        {
            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            GenerateInputsOutputs(unspent, fromKey, symbol, targets, out inputs, out outputs, fee, allowSameSourceAndDest);

            Transaction tx = new Transaction()
            {
                type    = TransactionType.ContractTransaction,
                version = 0,
                script  = null,
                gas     = -1,
                inputs  = inputs.ToArray(),
                outputs = outputs.ToArray(),
                interop = interop,
            };

            tx.Sign(fromKey);

            return(SendTransaction(tx, (error) =>
            {
                callback(string.IsNullOrEmpty(error) ? tx : null, error);
            }));
        }
Beispiel #26
0
        public IEnumerator CallContract(Action <Transaction, string> callback, UnspentEntries unspent, NeoKeys key, UInt160 scriptHash, byte[] bytes, string interop, decimal fee = 0, string attachSymbol = null, IEnumerable <Transaction.Output> attachTargets = null)
        {
            List <Transaction.Input>  inputs  = null;
            List <Transaction.Output> outputs = null;

            if (attachSymbol == null)
            {
                attachSymbol = "GAS";
            }

            if (!string.IsNullOrEmpty(attachSymbol))
            {
                GenerateInputsOutputs(unspent, key, attachSymbol, attachTargets, out inputs, out outputs, fee);

                if (inputs.Count == 0)
                {
                    throw new NeoException($"Not enough inputs for transaction");
                }
            }

            var transaction = new Transaction()
            {
                type    = TransactionType.InvocationTransaction,
                version = 0,
                script  = bytes,
                gas     = 0,
                inputs  = inputs != null?inputs.ToArray() : null,
                              outputs = outputs != null?outputs.ToArray() : null,
                                            attributes = inputs == null ? (new TransactionAttribute[] { new TransactionAttribute(TransactionAttributeUsage.Script, key.Address.AddressToScriptHash()) }) : null,
                                            interop    = interop
            };

            transaction.Sign(key);

            return(SendTransaction(transaction, (error) =>
            {
                callback(string.IsNullOrEmpty(error) ? transaction : null, error);
            }));
        }
Beispiel #27
0
        public IEnumerator SendAsset(Action <Transaction, string> callback, UnspentEntries unspent, NeoKeys fromKey, string toAddress, string symbol, decimal amount, string interop, decimal fee = 0, bool allowSameSourceAndDest = false)
        {
            if (!allowSameSourceAndDest && String.Equals(fromKey.Address, toAddress, StringComparison.OrdinalIgnoreCase))
            {
                throw new NeoException("Source and dest addresses are the same");
            }

            var toScriptHash = toAddress.GetScriptHashFromAddress();
            var target       = new Transaction.Output()
            {
                scriptHash = new UInt160(toScriptHash), value = amount
            };
            var targets = new List <Transaction.Output>()
            {
                target
            };

            return(SendAsset(callback, unspent, fromKey, symbol, targets, interop, fee, allowSameSourceAndDest));
        }
Beispiel #28
0
 public IEnumerator BalanceOf(NeoKeys keys, Action <BigInteger> callback)
 {
     return(BalanceOf(keys.Address, callback));
 }
Beispiel #29
0
 public IEnumerator GetAssetBalancesOf(NeoKeys key, Action <Dictionary <string, decimal> > callback)
 {
     return(GetAssetBalancesOf(key.Address, callback));
 }
Beispiel #30
0
 public IEnumerator Transfer(UnspentEntries unspent, NeoKeys from_key, string to_address, BigInteger amount, string interop, Action <Transaction, string> callback)
 {
     return(Transfer(unspent, from_key, to_address.GetScriptHashFromAddress(), amount, interop, callback));
 }