示例#1
0
        /// <summary>
        /// Adds the master signature into the approved masters of the desired account.
        /// The minimum signatures required to consider an account approved
        /// is defined bythe RequiredAuthorizations method.
        /// </summary>
        /// <param name="args">
        /// args[0] = account to approve,
        /// args[1] = the master account used to approve this request</param>
        /// <returns></returns>
        public static bool ApproveRegularAccount(object[] args)
        {
            Runtime.Log("Approve called");
            if (args.Length != 2)
            {
                Runtime.Log("Invalid parameters for ApproveRegularAccount");
                return(false);
            }

            byte[] newAccount       = (byte[])args[0];
            byte[] masterAccountKey = (byte[])args[1];

            if (newAccount.Length != 20 || masterAccountKey.Length != 20)
            {
                Runtime.Log("Invalid parameters for ApproveRegularAccount");
                return(false);
            }

            byte[] masterAccounts = BankDao.GetMasterAccounts();
            if (masterAccounts.Length == 0)
            {
                Runtime.Log("Master account not found or not approved");
                return(false);
            }

            byte[] account = BankDao.GetRegularAccount(newAccount);
            if (account.Length == 0)
            {
                Runtime.Log("Account not registered");
                return(false);
            }

            Map <byte[], object> masterAccountsObjects = (Map <byte[], object>)masterAccounts.Deserialize();

            if (masterAccountsObjects.HasKey(masterAccountKey))
            {
                Map <string, object> masterAccountMap = (Map <string, object>)masterAccountsObjects[masterAccountKey];

                Map <string, object> accountMap = (Map <string, object>)account.Deserialize();
                //if (Runtime.CheckWitness(masterAccountKey))
                if (true)
                {
                    Map <byte[], BigInteger> accountApprovals = (Map <byte[], BigInteger>)accountMap[ModelMap.ACCOUNT_MASTER_APPROVALS];
                    if (accountApprovals.HasKey(masterAccountKey))
                    {
                        BigInteger approvalStatus = accountApprovals[masterAccountKey];
                        if (approvalStatus != 1)
                        {
                            accountApprovals[masterAccountKey]            = 1;
                            accountMap[ModelMap.ACCOUNT_MASTER_APPROVALS] = accountApprovals;
                            BankDao.PersistRegularAccount(newAccount, accountMap.Serialize());
                            Notifier.NotifyRegularAccountApproved(masterAccountKey, newAccount);
                            return(true);
                        }
                    }
                    else
                    {
                        accountApprovals[masterAccountKey] = 1;
                        BankDao.PersistRegularAccount(newAccount, accountMap.Serialize());
                        Notifier.NotifyRegularAccountApproved(masterAccountKey, newAccount);
                        return(true);
                    }
                }
            }

            return(false);
        }
示例#2
0
        /// <summary>
        /// Creates tokens and tag it to the master that is creating it.
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static bool MintTokens(object[] args)
        {
            if (args.Length != 3)
            {
                Runtime.Log("Invalid parameters for MintTokens");
                return(false);
            }

            byte[] masterAccount = (byte[])args[0];
            if (masterAccount.Length != 20)
            {
                Runtime.Log("Invalid master account");
                return(false);
            }

            byte[] masterAccounts = BankDao.GetMasterAccounts();
            if (masterAccounts.Length == 0)
            {
                Runtime.Log("Mint called before Deploy. Contract not deployed");
                return(false);
            }

            Map <byte[], BigInteger> masterAccountsObjects = (Map <byte[], BigInteger>)masterAccounts.Deserialize();

            if (!masterAccountsObjects.HasKey(masterAccount))
            {
                Runtime.Log("Master Account not found");
                return(false);
            }

            //if (!Runtime.CheckWitness(masterAccount))
            //{
            //    Runtime.Log("Check Witness failed for master account");
            //    return false;
            //}

            byte[] recipient = (byte[])args[1];
            if (recipient.Length != 20)
            {
                Runtime.Log("Invalid recipient to Mint");
                return(false);
            }


            byte[] amountBytes = (byte[])args[2];
            if (amountBytes.Length == 0)
            {
                Runtime.Log("Invalid amount to Mint");
                return(false);
            }

            BigInteger amount = amountBytes.AsBigInteger();

            if (amount > MaxMint)
            {
                Runtime.Log("Amount too large to Mint. ");
                return(false);
            }

            byte[] account = BankDao.GetRegularAccount(recipient);
            if (account.Length == 0)
            {
                Runtime.Log("Account not found");
                return(false);
            }

            Map <string, object> accountMap = (Map <string, object>)account.Deserialize();

            bool accountIsApproved = AccountHasApprovals(accountMap);

            if (!accountIsApproved)
            {
                Runtime.Log("Account not approved");
                return(false);
            }

            Map <byte[], object> unspentTransactions = (Map <byte[], object>)accountMap[ModelMap.ACCOUNT_UNSPENT];

            Transaction invocationTransaction = (Transaction)ExecutionEngine.ScriptContainer;
            uint        currentBlockHeight    = Blockchain.GetHeight();

            object[]             previousTransactions = new object[] { invocationTransaction.Hash };
            Map <string, byte[]> transaction          = CreateTransaction(currentBlockHeight, 1, masterAccount, amount, previousTransactions);

            byte[] serializedTransaction = transaction.Serialize();
            byte[] transactionHash       = Hash256(serializedTransaction);

            if (unspentTransactions.HasKey(transactionHash))
            {
                Runtime.Log("Invalid transaction hash to mint");
                return(false);
            }

            unspentTransactions[transactionHash] = serializedTransaction;
            accountMap[ModelMap.ACCOUNT_UNSPENT] = unspentTransactions;

            BankDao.PersistRegularAccount(recipient, accountMap.Serialize());
            Notifier.NotifyMint(masterAccount, amount, recipient, transactionHash);

            return(true);
        }
示例#3
0
        /// <summary>
        /// Inserts a new account into the database. The account must be inserted prior to being approved.
        /// The account can only be registered by the owner (using the account signature)
        /// </summary>
        /// <param name="args">
        /// Args[0] = Account ScriptHash,
        /// Args[1] = publicKey,
        /// Args[2] = signature,
        /// Args[3] = type (1 for personal 2 for enterprise),
        /// Args[4] = document,
        /// Args[5] = name,
        /// Args[6] = email,
        /// Args[7] = description </param>
        /// <returns></returns>
        public static bool RegisterRegularAccount(object[] args)
        {
            if (args.Length != 8)
            {
                Runtime.Log("Invalid parameters for RegisterRegularAccount");
                return(false);
            }

            byte[] newAccount = (byte[])args[0];

            if (newAccount.Length != 20)
            {
                Runtime.Log("Invalid parameters for ApproveRegularAccount");
                return(false);
            }

            //if (!Runtime.CheckWitness(newAccount))
            //{
            //    Runtime.Log("Invalid signature for account " + newAccount);
            //    return false;
            //}

            byte[] currentAccount = BankDao.GetRegularAccount(newAccount);
            if (currentAccount.Length != 0)
            {
                Runtime.Log("Account already exists " + newAccount);
                return(false);
            }

            byte[] publicKey = (byte[])args[1];
            byte[] signature = (byte[])args[2];

            if (publicKey.Length == 0)
            {
                Runtime.Log("Invalid public key");
                return(false);
            }

            if (signature.Length == 0)
            {
                Runtime.Log("Invalid Signature");
                return(false);
            }

            BigInteger accountType = (BigInteger)args[3];

            if (accountType != 1 && accountType != 2)
            {
                Runtime.Log("Invalid account type");
                return(false);
            }

            string document = (string)args[4];

            if (document.Length < 10 || document.Length > 24)
            {
                Runtime.Log("Invalid document");
                return(false);
            }

            string accountName = (string)args[5];

            if (accountName.Length <= 3)
            {
                Runtime.Log("Invalid account name");
                return(false);
            }

            string email = (string)args[6];

            if (email.Length < 5)
            {
                Runtime.Log("Invalid e-mail");
                return(false);
            }


            string description = (string)args[7];

            if (description.Length > 255)
            {
                Runtime.Log("Remarks too long");
                return(false);
            }

            Map <string, object> accountMap = CreateRegularAccount(publicKey, document, email, accountName, accountType, description);

            BankDao.PersistRegularAccount(newAccount, accountMap.Serialize());
            BankDao.PersistSignature(newAccount, signature);
            Notifier.NotifyNewRegularAccount(newAccount);

            return(true);
        }
示例#4
0
        /// <summary>
        /// Private method used to transfer values from one account to another.
        /// </summary>
        /// <param name="senderScriptHash"></param>
        /// <param name="recipientScriptHash"></param>
        /// <param name="sender"></param>
        /// <param name="recipient"></param>
        /// <param name="amount"></param>
        /// <param name="transactions"></param>
        /// <returns></returns>
        private static object DoTransfer(byte[] senderScriptHash, byte[] recipientScriptHash, Map <string, object> sender, Map <string, object> recipient, BigInteger amount, object[] transactions)
        {
            BigInteger           transactionCount             = transactions.Length;
            BigInteger           totalInTransfers             = 0;
            Map <byte[], object> senderUnspentTransactions    = (Map <byte[], object>)sender[ModelMap.ACCOUNT_UNSPENT];
            Map <byte[], object> spentTransactions            = new Map <byte[], object>();
            Map <byte[], object> recipientUnspentTransactions = (Map <byte[], object>)recipient[ModelMap.ACCOUNT_UNSPENT];

            for (int i = 0; i < transactionCount; i++)
            {
                byte[] transactionHash = (byte[])transactions[i];

                if (!senderUnspentTransactions.HasKey(transactionHash))
                {
                    Runtime.Log("Not the owner");
                    return(false);
                }

                byte[] transactionBytes          = (byte[])senderUnspentTransactions[transactionHash];
                Map <string, object> transaction = (Map <string, object>)transactionBytes.Deserialize();

                byte[] amountInTransactionBytes = (byte[])transaction[ModelMap.TRANSACTION_AMOUNT];
                if (amountInTransactionBytes.Length <= 0)
                {
                    return(false);
                }

                senderUnspentTransactions.Remove(transactionHash);
                spentTransactions[transactionHash] = transaction;

                BigInteger amountInTransaction = amountInTransactionBytes.AsBigInteger();
                totalInTransfers += amountInTransaction;
                if (totalInTransfers >= amount)
                {
                    Runtime.Log("There is enough in the transactions sent.");
                    if (i != transactionCount - 1)
                    {
                        Runtime.Log("Too many transactions");
                        return(false);
                    }

                    BigInteger change             = totalInTransfers - amount;
                    uint       currentBlockHeight = Blockchain.GetHeight();

                    byte[] changeTransactionHash = new byte[0];
                    if (change > 0)
                    {
                        Runtime.Log("Has change!");
                        object[]             previousTransactions = new object[] { transactionHash };
                        Map <string, byte[]> changeTransaction    = CreateTransaction(currentBlockHeight, 0, new byte[0], change, previousTransactions);
                        byte[] serializedChangeTransaction        = changeTransaction.Serialize();
                        changeTransactionHash = Hash256(serializedChangeTransaction);
                        senderUnspentTransactions[changeTransactionHash] = serializedChangeTransaction;
                    }

                    object[] previousTransactionsNewTransaction = new object[spentTransactions.Keys.Length];

                    for (int j = 0; j < spentTransactions.Keys.Length; j++)
                    {
                        byte[] spentTransactionHash = spentTransactions.Keys[j];
                        previousTransactionsNewTransaction[j] = spentTransactionHash;
                    }

                    Map <string, byte[]> sentTransaction = CreateTransaction(currentBlockHeight, 0, new byte[0], amount, previousTransactionsNewTransaction);
                    byte[] serializedSentTransaction     = sentTransaction.Serialize();
                    byte[] sentTransactionHash           = Hash256(serializedSentTransaction);
                    recipientUnspentTransactions[sentTransactionHash] = serializedSentTransaction;

                    BankDao.PersistRegularAccount(senderScriptHash, sender.Serialize());
                    BankDao.PersistRegularAccount(recipientScriptHash, recipient.Serialize());
                    Notifier.NotifyTransfer(senderScriptHash, recipientScriptHash, amount, sentTransactionHash, change, changeTransactionHash);
                    return(true);
                }
            }

            return(false);
        }