Ejemplo n.º 1
0
 public bool IsContractDeployed(StorageContext storage, string name)
 {
     return(IsContractDeployed(storage, SmartContract.GetAddressForName(name)));
 }
Ejemplo n.º 2
0
        internal bool TransferToken(RuntimeVM runtimeVM, string symbol, Address source, Address destination, BigInteger tokenID)
        {
            if (!TokenExists(symbol))
            {
                return(false);
            }

            var tokenInfo = GetTokenInfo(symbol);

            if (!tokenInfo.Flags.HasFlag(TokenFlags.Transferable))
            {
                throw new Exception("Not transferable");
            }

            if (tokenInfo.Flags.HasFlag(TokenFlags.Fungible))
            {
                throw new Exception("Should be non-fungible");
            }

            if (tokenID <= 0)
            {
                return(false);
            }

            var ownerships = new OwnershipSheet(symbol);

            if (!ownerships.Take(runtimeVM.ChangeSet, source, tokenID))
            {
                return(false);
            }

            if (!ownerships.Give(runtimeVM.ChangeSet, destination, tokenID))
            {
                return(false);
            }

            var tokenTriggerResult = SmartContract.InvokeTrigger(runtimeVM, tokenInfo.Script, TokenContract.TriggerSend, source, tokenID);

            if (!tokenTriggerResult)
            {
                return(false);
            }

            tokenTriggerResult = SmartContract.InvokeTrigger(runtimeVM, tokenInfo.Script, TokenContract.TriggerReceive, destination, tokenID);
            if (!tokenTriggerResult)
            {
                return(false);
            }

            var accountScript        = this.LookUpAddressScript(source);
            var accountTriggerResult = SmartContract.InvokeTrigger(runtimeVM, accountScript, AccountContract.TriggerSend, source, tokenID);

            if (!accountTriggerResult)
            {
                return(false);
            }

            accountScript        = this.LookUpAddressScript(destination);
            accountTriggerResult = SmartContract.InvokeTrigger(runtimeVM, accountScript, AccountContract.TriggerSend, destination, tokenID);
            if (!accountTriggerResult)
            {
                return(false);
            }

            EditNFTLocation(symbol, tokenID, runtimeVM.Chain.Address, destination);
            return(true);
        }
        /// <summary>
        /// Uses reflection to set the state field on the contract object.
        /// </summary>
        private static void SetStateField(SmartContract smartContract, ISmartContractState contractState)
        {
            FieldInfo field = typeof(SmartContract).GetField("state", DefaultBindingFlags);

            field.SetValue(smartContract, contractState);
        }
Ejemplo n.º 4
0
 public void SaveTemplate(SmartContract smartContract)
 {
     Db.SmartContracts.Add(smartContract);
     Db.Save();
 }
Ejemplo n.º 5
0
        private static void DeployOrUpgrade(string[] args, NexusAPI api, BigInteger minFee, bool isUpgrade)
        {
            if (args.Length != 1)
            {
                throw new CommandException("Invalid number of arguments, expected file name");
            }

            DoChecks(api);

            var fileName = args[0];

            if (!File.Exists(fileName))
            {
                throw new CommandException("Provided file does not exist");
            }

            var extension = ScriptModule.ScriptExtension;

            if (!fileName.EndsWith(extension))
            {
                throw new CommandException($"Provided file is not a compiled {extension} script");
            }

            var abiFile = fileName.Replace(extension, ".abi");

            if (!File.Exists(abiFile))
            {
                throw new CommandException($"No ABI file {abiFile} that matches provided script file");
            }

            var contractName = Path.GetFileNameWithoutExtension(fileName);

            var contractScript = File.ReadAllBytes(fileName);
            var abiBytes       = File.ReadAllBytes(abiFile);

            var abi = ContractInterface.FromBytes(abiBytes);

            var sb = new ScriptBuilder();

            bool isToken        = ValidationUtils.IsValidTicker(contractName);
            var  availableFlags = Enum.GetValues(typeof(TokenFlags)).Cast <TokenFlags>().ToArray();

            sb.AllowGas(Keys.Address, Address.Null, minFee, 9999);

            if (isUpgrade)
            {
                // check for modification in flags
                if (isToken)
                {
                    var     symbol    = contractName;
                    var     resultStr = api.Execute("getToken", new[] { symbol, "false" });
                    dynamic apiResult = JsonConvert.DeserializeObject <TokenResult>(resultStr);

                    if (apiResult is TokenResult)
                    {
                        var oldToken = (TokenResult)apiResult;

                        var oldFlags   = TokenFlags.None;
                        var splitFlags = oldToken.flags.Split(',');
                        foreach (var entry in splitFlags)
                        {
                            TokenFlags flag;

                            if (Enum.TryParse <TokenFlags>(entry, true, out flag))
                            {
                                oldFlags |= flag;
                            }
                        }

                        foreach (var flag in availableFlags)
                        {
                            var propName = "is" + flag;
                            if (abi.HasMethod(propName))
                            {
                                var isSet  = ExecuteScript(contractScript, abi, propName).AsBool();
                                var wasSet = oldFlags.HasFlag(flag);
                                if (isSet != wasSet)
                                {
                                    throw new CommandException($"Detected '{flag}' flag change: {wasSet} => {isSet}");
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new CommandException("could not find any deployed token contract for " + symbol);
                    }
                }

                sb.CallInterop("Runtime.UpgradeContract", Keys.Address, contractName, contractScript, abiBytes);
            }
            else
            if (isToken)
            {
                if (!abi.HasMethod("getName"))
                {
                    throw new CommandException("token contract is missing required 'name' property");
                }

                var symbol = contractName;
                var name   = ExecuteScript(contractScript, abi, "getName").AsString();

                if (string.IsNullOrEmpty(name))
                {
                    throw new CommandException("token contract 'name' property is returning an empty value");
                }

                BigInteger maxSupply = abi.HasMethod("getMaxSupply") ? ExecuteScript(contractScript, abi, "getMaxSupply").AsNumber() : 0;
                BigInteger decimals  = abi.HasMethod("getDecimals") ? ExecuteScript(contractScript, abi, "getDecimals").AsNumber() : 0;

                TokenFlags flags = TokenFlags.None;

                foreach (var flag in availableFlags)
                {
                    var propName = "is" + flag;
                    if (abi.HasMethod(propName) && ExecuteScript(contractScript, abi, propName).AsBool())
                    {
                        flags |= flag;
                    }
                }

                sb.CallInterop("Nexus.CreateToken", Keys.Address, symbol, name, maxSupply, decimals, flags, contractScript, abiBytes);

                contractName = symbol;
            }
            else
            {
                sb.CallInterop("Runtime.DeployContract", Keys.Address, contractName, contractScript, abiBytes);
            }

            sb.SpendGas(Keys.Address);
            var script = sb.EndScript();

            if (!isUpgrade)
            {
                var upgradeTrigger = AccountContract.GetTriggerForABI(AccountTrigger.OnUpgrade);
                if (abi.Implements(upgradeTrigger))
                {
                    logger.Message($"{contractName} implements proper triggers, and can be upgraded later.");
                }
                else
                {
                    logger.Warning($"{contractName} does not implements proper triggers, can't be upgraded later.");
                }
            }

            var hash = ExecuteTransaction(api, script, ProofOfWork.Minimal, Keys);

            if (hash != Hash.Null)
            {
                var expectedEvent    = isUpgrade ? EventKind.ContractUpgrade : (isToken ? EventKind.TokenCreate : EventKind.ContractDeploy);
                var expectedEventStr = expectedEvent.ToString();

                var events = GetTransactionEvents(hash);
                if (events.Any(x => x.kind == expectedEventStr))
                {
                    var contractAddress = SmartContract.GetAddressForName(contractName);

                    string action = isUpgrade ? "Upgraded" : "Deployed";

                    logger.Message($"{action} {contractName} at {contractAddress}");
                }
                else
                {
                    throw new CommandException("Transaction was confirmed but deployment event is missing!");
                }
            }
        }
Ejemplo n.º 6
0
 public async Task <Balance> GetContractBalance(SmartContract con)
 {
     return(await GetContractBalance(con.Address.Raw));
 }
Ejemplo n.º 7
0
        public void SpendGas(Address from)
        {
            if (Runtime.IsReadOnlyMode())
            {
                return;
            }

            Runtime.Expect(Runtime.IsWitness(from), "invalid witness");

            Runtime.Expect(_allowanceMap.ContainsKey(from), "no gas allowance found");

            var availableAmount = _allowanceMap.Get <Address, BigInteger>(from);

            var spentGas       = Runtime.UsedGas;
            var requiredAmount = spentGas * Runtime.GasPrice;

            Runtime.Expect(requiredAmount > 0, "gas fee must exist");

            Runtime.Expect(availableAmount >= requiredAmount, "gas allowance is not enough");

            /*var token = this.Runtime.Nexus.FuelToken;
             * Runtime.Expect(token != null, "invalid token");
             * Runtime.Expect(token.Flags.HasFlag(TokenFlags.Fungible), "must be fungible token");
             */

            var leftoverAmount = availableAmount - requiredAmount;

            var        targetAddress = _allowanceTargets.Get <Address, Address>(from);
            BigInteger targetGas;

            Runtime.Notify(EventKind.GasPayment, from, new GasEventData(targetAddress, Runtime.GasPrice, spentGas));

            // return escrowed gas to transaction creator
            Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, this.Address, from, availableAmount);

            Runtime.Expect(spentGas > 1, "gas spent too low");
            var burnGas = spentGas / 2;

            if (burnGas > 0)
            {
                Runtime.BurnTokens(DomainSettings.FuelTokenSymbol, from, burnGas);
                spentGas -= burnGas;
            }

            if (!targetAddress.IsNull)
            {
                targetGas = spentGas / 2; // 50% for dapps
            }
            else
            {
                targetGas = 0;
            }

            if (targetGas > 0)
            {
                var targetPayment = targetGas * Runtime.GasPrice;
                Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, from, targetAddress, targetPayment);
                spentGas -= targetGas;
            }

            if (spentGas > 0)
            {
                var validatorPayment = spentGas * Runtime.GasPrice;
                var validatorAddress = SmartContract.GetAddressForNative(NativeContractKind.Block);
                Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, from, validatorAddress, validatorPayment);
                spentGas = 0;
            }

            _allowanceMap.Remove(from);
            _allowanceTargets.Remove(from);

            Runtime.Notify(EventKind.GasPayment, Address.Null, new GasEventData(targetAddress, Runtime.GasPrice, spentGas));

            if (Runtime.HasGenesis && Runtime.TransactionIndex == 0)
            {
                if (_lastInflation.Value == 0)
                {
                    var genesisTime = Runtime.GetGenesisTime();
                    _lastInflation = genesisTime;
                }
                else
                {
                    var infDiff         = Runtime.Time - _lastInflation;
                    var inflationPeriod = SecondsInDay * 90;
                    if (infDiff >= inflationPeriod)
                    {
                        ApplyInflation();
                    }
                }
            }
        }
Ejemplo n.º 8
0
        public void SpendGas(Address from)
        {
            if (Runtime.IsReadOnlyMode())
            {
                return;
            }

            Runtime.Expect(Runtime.IsWitness(from), "invalid witness");

            Runtime.Expect(_allowanceMap.ContainsKey(from), "no gas allowance found");

            var availableAmount = _allowanceMap.Get <Address, BigInteger>(from);

            var spentGas       = Runtime.UsedGas;
            var requiredAmount = spentGas * Runtime.GasPrice;

            Runtime.Expect(requiredAmount > 0, "gas fee must exist");

            Runtime.Expect(availableAmount >= requiredAmount, "gas allowance is not enough");

            /*var token = this.Runtime.Nexus.FuelToken;
             * Runtime.Expect(token != null, "invalid token");
             * Runtime.Expect(token.Flags.HasFlag(TokenFlags.Fungible), "must be fungible token");
             */

            var leftoverAmount = availableAmount - requiredAmount;

            var        targetAddress = _allowanceTargets.Get <Address, Address>(from);
            BigInteger targetGas;

            // TODO the transfers around here should pass through Nexus.TransferTokens!!
            // return unused gas to transaction creator
            if (leftoverAmount > 0)
            {
                Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, this.Address, from, leftoverAmount), "gas leftover return failed");
            }

            Runtime.Expect(spentGas > 1, "gas spent too low");
            var bombGas = spentGas / 2;

            if (bombGas > 0)
            {
                var bombPayment = bombGas * Runtime.GasPrice;
                var bombAddress = SmartContract.GetAddressForNative(NativeContractKind.Bomb);
                Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, this.Address, bombAddress, bombPayment), "gas bomb payment failed");
                Runtime.Notify(EventKind.GasPayment, bombAddress, new GasEventData()
                {
                    address = from, price = Runtime.GasPrice, amount = bombGas
                });
                spentGas -= bombGas;
            }

            if (!targetAddress.IsNull)
            {
                targetGas = spentGas / 2; // 50% for dapps
            }
            else
            {
                targetGas = 0;
            }

            if (targetGas > 0)
            {
                var targetPayment = targetGas * Runtime.GasPrice;
                Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, this.Address, targetAddress, targetPayment), "gas target payment failed");
                Runtime.Notify(EventKind.GasPayment, targetAddress, new GasEventData()
                {
                    address = from, price = Runtime.GasPrice, amount = targetGas
                });
                spentGas -= targetGas;
            }

            if (spentGas > 0)
            {
                var validatorPayment = spentGas * Runtime.GasPrice;
                var validatorAddress = SmartContract.GetAddressForNative(NativeContractKind.Block);
                Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, this.Address, validatorAddress, validatorPayment), "gas validator payment failed");
                Runtime.Notify(EventKind.GasPayment, validatorAddress, new GasEventData()
                {
                    address = from, price = Runtime.GasPrice, amount = spentGas
                });
                spentGas = 0;
            }

            _allowanceMap.Remove(from);
            _allowanceTargets.Remove(from);

            // check if there is an active lend and it is time to pay it
            if (_loanMap.ContainsKey <Address>(from))
            {
                var loan = _loanMap.Get <Address, GasLoanEntry>(from);

                Runtime.Expect(_lenderMap.ContainsKey <Address>(loan.lender), "missing lender info");
                var gasLender = _lenderMap.Get <Address, GasLender>(loan.lender);

                if (loan.hash == Runtime.Transaction.Hash)
                {
                    var unusedLoanAmount = loan.amount - requiredAmount;
                    Runtime.Expect(unusedLoanAmount >= 0, "loan amount overflow");

                    // here we return the gas to the original pool, not the the payment address, because this is not a payment
                    Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, from, this.Address, unusedLoanAmount), "unspend loan payment failed");

                    gasLender.balance += unusedLoanAmount;
                    _lenderMap.Set <Address, GasLender>(loan.lender, gasLender);

                    Runtime.Notify(EventKind.GasPayment, loan.borrower, new GasEventData()
                    {
                        address = from, price = 1, amount = unusedLoanAmount
                    });

                    loan.amount   = requiredAmount;
                    loan.interest = (requiredAmount * LendReturn) / 100;
                    _loanMap.Set <Address, GasLoanEntry>(from, loan);
                }
                else
                {
                    Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, from, loan.lender, loan.amount), "loan payment failed");
                    Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, from, gasLender.paymentAddress, loan.interest), "loan interest failed");
                    _loanMap.Remove <Address>(from);

                    var list  = _loanList.Get <Address, StorageList>(loan.lender);
                    int index = -1;
                    var count = list.Count();
                    for (int i = 0; i < count; i++)
                    {
                        var temp = list.Get <Address>(i);
                        if (temp == from)
                        {
                            index = i;
                            break;
                        }
                    }

                    Runtime.Expect(index >= 0, "loan missing from list");
                    list.RemoveAt <Address>(index);

                    Runtime.Notify(EventKind.GasPayment, loan.lender, new GasEventData()
                    {
                        address = from, price = 1, amount = loan.amount
                    });
                    Runtime.Notify(EventKind.GasPayment, gasLender.paymentAddress, new GasEventData()
                    {
                        address = from, price = 1, amount = loan.interest
                    });
                }
            }
        }
Ejemplo n.º 9
0
        private static BigInteger _calculateNumericLogicPayment(PbEntity.ConditionalPay _pay, byte[][] _preimages, byte _funcType)
        {
            int        j              = 0;
            BigInteger amount         = 0;
            bool       hasContracCond = false;

            PbEntity.ConditionType        ConditionType        = PbEntity.getConditionType();
            PbEntity.TransferFunctionType TransferFunctionType = PbEntity.getTransferFunctionType();
            PbEntity.Condition[]          conditions           = _pay.conditions;
            for (var i = 0; i < conditions.Length; i++)
            {
                PbEntity.Condition cond = _pay.conditions[i];
                if (cond.conditionType == ConditionType.HASH_LOCK)
                {
                    BasicMethods.assert(SmartContract.Sha256(_preimages[j]) == cond.hashLock, "wrong preimage");
                    j++;
                }
                else if (
                    cond.conditionType == ConditionType.DEPLOYED_CONTRACT ||
                    cond.conditionType == ConditionType.VIRTUAL_CONTRACT
                    )
                {
                    byte[] numericCondHash      = _getCondAddress(cond);
                    DynamicCallContract dyncall = (DynamicCallContract)numericCondHash.ToDelegate();
                    BasicMethods.assert((bool)dyncall("isFinalized", new object[] { cond.argsQueryFinalization }), "Condition is not finalized");

                    BigInteger outcome = (BigInteger)dyncall("getOutcome", new object[] { cond.argsQueryOutcome });

                    if (_funcType == TransferFunctionType.NUMERIC_ADD)
                    {
                        amount = amount + outcome;
                    }
                    else if (_funcType == TransferFunctionType.NUMERIC_MAX)
                    {
                        amount = max(amount, outcome);
                    }
                    else if (_funcType == TransferFunctionType.NUMERIC_MIN)
                    {
                        if (hasContracCond)
                        {
                            amount = min(amount, outcome);
                        }
                        else
                        {
                            amount = outcome;
                        }
                    }
                    else
                    {
                        BasicMethods.assert(false, "error");
                    }
                    hasContracCond = true;
                }
                else
                {
                    BasicMethods.assert(false, "condition type error");
                }
            }
            PbEntity.TransferFunction transferFunction = _pay.transferFunc;
            PbEntity.TokenTransfer    tokenTransfer    = transferFunction.maxTransfer;
            PbEntity.AccountAmtPair   accountAmtPair   = tokenTransfer.receiver;
            if (hasContracCond)
            {
                BasicMethods.assert(amount <= accountAmtPair.amt, "exceed max transfer amount");
                return(amount);
            }
            else
            {
                return(accountAmtPair.amt);
            }
        }
Ejemplo n.º 10
0
 private static byte[] _calculatePayId(byte[] _payHash, byte[] _setter)
 {
     return(SmartContract.Sha256(_payHash.Concat(_setter)));
 }
Ejemplo n.º 11
0
        public async Task <SmartContract> Create(SmartContract smartContract, List <SmartContractFunction> smartContractFunctions)
        {
            SmartContract mutatedSmartContract = null;

            using (SqlConnection conn = new SqlConnection(DbConfiguration.ConnectionString))
            {
                conn.Open();
                var        transaction = conn.BeginTransaction();
                SqlCommand sqlcmd      = new SqlCommand(StoredProcedures.InsertSmartContract, conn);
                sqlcmd.CommandType = System.Data.CommandType.StoredProcedure;
                sqlcmd.Parameters.Add(new SqlParameter()
                {
                    ParameterName = "@name",
                    SqlDbType     = System.Data.SqlDbType.VarChar,
                    Value         = smartContract.Name
                });
                sqlcmd.Parameters.Add(new SqlParameter()
                {
                    ParameterName = "@abi",
                    SqlDbType     = System.Data.SqlDbType.Text,
                    Value         = smartContract.Abi
                });
                sqlcmd.Parameters.Add(new SqlParameter()
                {
                    ParameterName = "@byteCode",
                    SqlDbType     = System.Data.SqlDbType.Text,
                    Value         = smartContract.ByteCode
                });
                sqlcmd.Parameters.Add(new SqlParameter()
                {
                    ParameterName = "@createdByUserLoginId",
                    SqlDbType     = System.Data.SqlDbType.VarChar,
                    Value         = smartContract.CreatedByUserLoginId
                });

                try
                {
                    sqlcmd.Connection  = conn;
                    sqlcmd.Transaction = transaction;
                    var reader = await sqlcmd.ExecuteReaderAsync();

                    var result = reader.Read();
                    if (result)
                    {
                        mutatedSmartContract = new SmartContract();
                        mutatedSmartContract.SmartContractId      = Convert.ToInt32(reader["SmartContractId"].ToString());
                        mutatedSmartContract.Name                 = reader["Name"]?.ToString();
                        mutatedSmartContract.Abi                  = reader["Abi"]?.ToString();
                        mutatedSmartContract.ByteCode             = reader["ByteCode"]?.ToString();
                        mutatedSmartContract.CreatedByUserLoginId = reader["CreatedByUserLoginId"]?.ToString();
                        mutatedSmartContract.CreatedDatetime      = string.IsNullOrEmpty(reader["CreatedDatetime"]?.ToString()) ? DateTime.MinValue : Convert.ToDateTime(reader["CreatedDatetime"]);
                        mutatedSmartContract.UpdatedDatetime      = string.IsNullOrEmpty(reader["UpdatedDatetime"]?.ToString()) ? DateTime.MinValue : Convert.ToDateTime(reader["UpdatedDatetime"]);
                    }
                    reader.Close();

                    foreach (var smartContractFunction in smartContractFunctions)
                    {
                        SqlCommand sqlCmdSmartContractFunction = new SqlCommand(StoredProcedures.InsertSmartContractFunction, conn);
                        sqlCmdSmartContractFunction.CommandType = CommandType.StoredProcedure;
                        sqlCmdSmartContractFunction.Transaction = transaction;

                        sqlCmdSmartContractFunction.Parameters.Add(new SqlParameter()
                        {
                            ParameterName = "@smartContractId",
                            SqlDbType     = System.Data.SqlDbType.Int,
                            Value         = mutatedSmartContract.SmartContractId
                        });

                        sqlCmdSmartContractFunction.Parameters.Add(new SqlParameter()
                        {
                            ParameterName = "@functionName",
                            SqlDbType     = System.Data.SqlDbType.VarChar,
                            Value         = smartContractFunction.FunctionName
                        });

                        sqlCmdSmartContractFunction.Parameters.Add(new SqlParameter()
                        {
                            ParameterName = "@functionType",
                            SqlDbType     = System.Data.SqlDbType.VarChar,
                            Value         = smartContractFunction.FunctionType
                        });

                        sqlCmdSmartContractFunction.Parameters.Add(new SqlParameter()
                        {
                            ParameterName = "@sequence",
                            SqlDbType     = System.Data.SqlDbType.Int,
                            Value         = smartContractFunction.Sequence
                        });
                        var returnValue = await sqlCmdSmartContractFunction.ExecuteNonQueryAsync();
                    }
                    transaction.Commit();
                    conn.Close();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw ex;
                }
            }
            return(mutatedSmartContract);
        }
Ejemplo n.º 12
0
 public LifecycleResult(SmartContract obj)
 {
     this.Success = true;
     this.Object  = obj;
 }
Ejemplo n.º 13
0
        public void Read(TProtocol iprot)
        {
            iprot.IncrementRecursionDepth();
            try
            {
                TField field;
                iprot.ReadStructBegin();
                while (true)
                {
                    field = iprot.ReadFieldBegin();
                    if (field.Type == TType.Stop)
                    {
                        break;
                    }
                    switch (field.ID)
                    {
                    case 1:
                        if (field.Type == TType.Struct)
                        {
                            Status = new APIResponse();
                            Status.Read(iprot);
                        }
                        else
                        {
                            TProtocolUtil.Skip(iprot, field.Type);
                        }
                        break;

                    case 2:
                        if (field.Type == TType.I32)
                        {
                            Count = iprot.ReadI32();
                        }
                        else
                        {
                            TProtocolUtil.Skip(iprot, field.Type);
                        }
                        break;

                    case 3:
                        if (field.Type == TType.List)
                        {
                            {
                                SmartContractsList = new List <SmartContract>();
                                TList _list49 = iprot.ReadListBegin();
                                for (int _i50 = 0; _i50 < _list49.Count; ++_i50)
                                {
                                    SmartContract _elem51;
                                    _elem51 = new SmartContract();
                                    _elem51.Read(iprot);
                                    SmartContractsList.Add(_elem51);
                                }
                                iprot.ReadListEnd();
                            }
                        }
                        else
                        {
                            TProtocolUtil.Skip(iprot, field.Type);
                        }
                        break;

                    default:
                        TProtocolUtil.Skip(iprot, field.Type);
                        break;
                    }
                    iprot.ReadFieldEnd();
                }
                iprot.ReadStructEnd();
            }
            finally
            {
                iprot.DecrementRecursionDepth();
            }
        }
Ejemplo n.º 14
0
        internal bool TransferTokens(RuntimeVM runtimeVM, string symbol, Address source, Address destination, BigInteger amount)
        {
            if (!TokenExists(symbol))
            {
                return(false);
            }

            var tokenInfo = GetTokenInfo(symbol);

            if (!tokenInfo.Flags.HasFlag(TokenFlags.Transferable))
            {
                throw new Exception("Not transferable");
            }

            if (!tokenInfo.Flags.HasFlag(TokenFlags.Fungible))
            {
                throw new Exception("Should be fungible");
            }

            if (amount <= 0)
            {
                return(false);
            }

            var balances = new BalanceSheet(symbol);

            if (!balances.Subtract(runtimeVM.ChangeSet, source, amount))
            {
                return(false);
            }

            if (!balances.Add(runtimeVM.ChangeSet, destination, amount))
            {
                return(false);
            }

            var tokenTriggerResult = SmartContract.InvokeTrigger(runtimeVM, tokenInfo.Script, TokenContract.TriggerSend, source, amount);

            if (!tokenTriggerResult)
            {
                return(false);
            }

            tokenTriggerResult = SmartContract.InvokeTrigger(runtimeVM, tokenInfo.Script, TokenContract.TriggerReceive, destination, amount);
            if (!tokenTriggerResult)
            {
                return(false);
            }

            var accountScript        = this.LookUpAddressScript(source);
            var accountTriggerResult = SmartContract.InvokeTrigger(runtimeVM, accountScript, AccountContract.TriggerSend, source, amount);

            if (!accountTriggerResult)
            {
                return(false);
            }

            accountScript        = this.LookUpAddressScript(destination);
            accountTriggerResult = SmartContract.InvokeTrigger(runtimeVM, accountScript, AccountContract.TriggerSend, destination, amount);
            if (!accountTriggerResult)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 15
0
 private static byte[] HashChildren(byte[] v, byte[] hash)
 {
     byte[] prefix = { 1 };
     return(SmartContract.Sha256(prefix.Concat(v).Concat(hash)));
 }
Ejemplo n.º 16
0
 public static Address GetContractAddress(string symbol)
 {
     return(SmartContract.GetAddressForName(symbol));
 }
Ejemplo n.º 17
0
 private static byte[] HashLeaf(byte[] value)
 {
     byte[] prefix = { 0x00 };
     return(SmartContract.Sha256(prefix.Concat(value)));
 }
Ejemplo n.º 18
0
        public void TestIndexGap()
        {
            var test = CreateAPI();

            var simulator = test.simulator;
            var owner     = test.owner;
            var sender    = PhantasmaKeys.Generate();
            var receiver  = PhantasmaKeys.Generate();
            var node      = PhantasmaKeys.FromWIF(nodeWIF);
            var nexus     = simulator.Nexus;
            var api       = test.api;

            var contractAddress = SmartContract.GetAddressForName("relay");

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, DomainSettings.FuelTokenSymbol, 100000000);
            simulator.EndBlock();

            TopUpChannel(simulator, sender, 1000000);

            var indexGap     = 5;
            var messageCount = 3;
            var messages     = new RelayMessage[messageCount];

            var random = new Random();

            for (int i = 0; i < messageCount; i++)
            {
                var script = new byte[100];
                random.NextBytes(script);

                var message = new RelayMessage
                {
                    nexus     = nexus.Name,
                    index     = i * indexGap,
                    receiver  = receiver.Address, //node.Address,
                    script    = script,
                    sender    = sender.Address,
                    timestamp = Timestamp.Now
                };
                messages[i] = message;

                var    receipt       = RelayReceipt.FromMessage(message, sender);
                string serializedHex = Base16.Encode(receipt.Serialize());

                api.RelaySend(serializedHex);
            }

            var receipts = (ArrayResult)api.RelayReceive(receiver.Address.Text);

            Assert.IsTrue(receipts.values.Length == messageCount);

            for (int i = 0; i < messageCount; i++)
            {
                var obj = receipts.values[i];
                Assert.IsTrue(obj is ReceiptResult);

                var receiptResult = (ReceiptResult)obj;
                Assert.IsTrue(receiptResult.nexus == messages[i].nexus);
                Assert.IsTrue(new BigInteger(receiptResult.index, 10) == messages[i].index);
                //Assert.IsTrue(receiptResult.receiver == messages[i].receiver);
                //Assert.IsTrue(receiptResult.script == messages[i].script);
                //Assert.IsTrue(receiptResult.sender == messages[i].sender);
                Assert.IsTrue(receiptResult.timestamp == messages[i].timestamp);
            }

            var lastMessage = messages[messageCount - 1];
            var lastReceipt = RelayReceipt.FromMessage(lastMessage, sender);

            var fuelToken = simulator.Nexus.GetTokenInfo(simulator.Nexus.RootStorage, DomainSettings.FuelTokenSymbol);

            var senderInitialBalance   = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, sender.Address);
            var chainInitialBalance    = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, contractAddress);
            var receiverInitialBalance = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, node.Address);

            simulator.BeginBlock();
            var tx = simulator.GenerateCustomTransaction(sender, ProofOfWork.None, () =>
                                                         ScriptUtils.BeginScript().AllowGas(sender.Address, Address.Null, 1, 9999)
                                                         .CallContract("relay", nameof(RelayContract.SettleChannel), lastReceipt).
                                                         SpendGas(sender.Address).EndScript());

            simulator.EndBlock();

            var txCost = simulator.Nexus.RootChain.GetTransactionFee(tx);

            var senderFinalBalance   = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, sender.Address);
            var chainFinalBalance    = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, contractAddress);
            var receiverFinalBalance = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, receiver.Address);

            var expectedFee = RelayFeePerMessage * (lastReceipt.message.index + 1);

            Assert.IsTrue(senderFinalBalance == senderInitialBalance - txCost);
            Assert.IsTrue(receiverFinalBalance == receiverInitialBalance + (expectedFee / 2));
            Assert.IsTrue(chainFinalBalance == chainInitialBalance - (expectedFee / 2));    //the sender's balance is escrowed in the chain address, so the chain just sends the other half of the fee away to the receiver
        }
Ejemplo n.º 19
0
        static byte[] nameHashWithSubHash(byte[] roothash, byte[] subhash)
        {
            var domain = subhash.Concat(roothash);

            return(SmartContract.Sha256(domain));
        }
Ejemplo n.º 20
0
 //域名转hash算法
 //aaa.bb.test =>{"test","bb","aa"}
 static byte[] nameHash(string domain)
 {
     return(SmartContract.Sha256(domain.AsByteArray()));
 }
Ejemplo n.º 21
0
 public async Task <string> GetSmartContractCode(SmartContract c)
 {
     return(await GetSmartContractCode(c.Address.Raw));
 }