Exemple #1
0
        public static Hash SendTransfer(JSONRPC_Client rpc, Logger logger, string nexusName, string host, PhantasmaKeys from, Address to, BigInteger amount)
        {
            Throw.IfNull(rpc, nameof(rpc));
            Throw.IfNull(logger, nameof(logger));

            var script = ScriptUtils.BeginScript().AllowGas(from.Address, Address.Null, 1, 9999).TransferTokens("SOUL", from.Address, to, amount).SpendGas(from.Address).EndScript();

            var tx = new Phantasma.Blockchain.Transaction(nexusName, "main", script, Timestamp.Now + TimeSpan.FromMinutes(30));

            tx.Sign(from);

            var bytes = tx.ToByteArray(true);

            //log.Debug("RAW: " + Base16.Encode(bytes));

            var response = rpc.SendRequest(logger, host, "sendRawTransaction", Base16.Encode(bytes));

            if (response == null)
            {
                logger.Error($"Error sending {amount} {DomainSettings.FuelTokenSymbol} from {from.Address} to {to}...");
                return(Hash.Null);
            }

            if (response.HasNode("error"))
            {
                var error = response.GetString("error");
                logger.Error("Error: " + error);
                return(Hash.Null);
            }

            var hash = response.Value;

            return(Hash.Parse(hash));
        }
Exemple #2
0
        protected void OnSetValue(string[] args)
        {
            var chain     = _cli.Nexus.GetChainByName(_cli.Nexus.RootChain.Name);
            var fuelToken = _cli.Nexus.GetTokenInfo(_cli.Nexus.RootStorage, DomainSettings.FuelTokenSymbol);
            var balance   = chain.GetTokenBalance(chain.Storage, fuelToken, _cli.NodeKeys.Address);

            if (balance == 0)
            {
                Console.WriteLine("Node wallet needs gas to create a platform token!");
                return;
            }

            var key = args[0];

            if (string.IsNullOrEmpty(key))
            {
                Console.WriteLine("Key has to be set!");
                return;
            }

            Phantasma.Numerics.BigInteger value;
            try
            {
                value = Phantasma.Numerics.BigInteger.Parse(args[1]);
            }
            catch
            {
                Console.WriteLine("Value has to be set!");
                return;
            }

            var script = ScriptUtils.BeginScript()
                         .AllowGas(_cli.NodeKeys.Address, Address.Null, 100000, 15000)
                         .CallContract("governance", "SetValue", key, value)
                         .SpendGas(_cli.NodeKeys.Address).EndScript();

            var expire = Timestamp.Now + TimeSpan.FromMinutes(2);
            var tx     = new Phantasma.Blockchain.Transaction(_cli.Nexus.Name, _cli.Nexus.RootChain.Name, script, expire, Spook.TxIdentifier);

            tx.Mine((int)ProofOfWork.Minimal);
            tx.Sign(_cli.NodeKeys);

            if (_cli.Mempool != null)
            {
                _cli.Mempool.Submit(tx);
                Console.WriteLine($"Transaction {tx.Hash} submitted to mempool.");
            }
            else
            {
                Console.WriteLine("No mempool available");
                return;
            }

            Console.WriteLine($"SetValue {key}:{value} ts: {tx.Hash}");
        }
Exemple #3
0
        protected void OnPlatformAddressAdd(string[] args)
        {
            var platform        = args[0];
            var externalAddress = args[1];

            Address localAddress;

            switch (platform)
            {
            case NeoWallet.NeoPlatform:
                localAddress = NeoWallet.EncodeAddress(externalAddress);
                break;

            case EthereumWallet.EthereumPlatform:
                localAddress = EthereumWallet.EncodeAddress(externalAddress);
                break;

            case BSCWallet.BSCPlatform:
                localAddress = BSCWallet.EncodeAddress(externalAddress);
                break;

            default:
                throw new Exception("Unknown platform: " + platform);
            }

            var minimumFee = _cli.Settings.Node.MinimumFee;
            var script     = ScriptUtils.BeginScript()
                             .AllowGas(_cli.NodeKeys.Address, Address.Null, minimumFee, 1500)
                             .CallContract("interop", nameof(InteropContract.RegisterAddress), _cli.NodeKeys.Address, platform, localAddress, externalAddress)
                             .SpendGas(_cli.NodeKeys.Address).EndScript();

            var expire = Timestamp.Now + TimeSpan.FromMinutes(2);
            var tx     = new Phantasma.Blockchain.Transaction(_cli.Nexus.Name, _cli.Nexus.RootChain.Name, script, expire, Spook.TxIdentifier);

            tx.Mine((int)ProofOfWork.Minimal);
            tx.Sign(_cli.NodeKeys);

            if (_cli.Mempool != null)
            {
                _cli.Mempool.Submit(tx);
                Console.WriteLine($"Transaction {tx.Hash} submitted to mempool.");
            }
            else
            {
                Console.WriteLine("No mempool available");
                return;
            }
            Console.WriteLine($"Added address {externalAddress} to {platform}");
            Spook.Logger.Message($"Added address {externalAddress} to {platform}");
        }
Exemple #4
0
        protected void OnCreatePlatform(string[] args)
        {
            var platform = args[0];

            if (string.IsNullOrEmpty(platform))
            {
                Console.WriteLine("platform has to be set!");
                return;
            }

            var nativeCurrency = args[1];

            if (string.IsNullOrEmpty(nativeCurrency))
            {
                Console.WriteLine("Native currency has to be set!");
                return;
            }

            var platformKeys    = InteropUtils.GenerateInteropKeys(_cli.NodeKeys, _cli.Nexus.GetGenesisHash(_cli.Nexus.RootStorage), platform);
            var platformText    = Phantasma.Ethereum.EthereumKey.FromWIF(platformKeys.ToWIF()).Address;
            var platformAddress = Phantasma.Pay.Chains.BSCWallet.EncodeAddress(platformText);

            var script = ScriptUtils.BeginScript()
                         .AllowGas(_cli.NodeKeys.Address, Address.Null, 100000, 9999)
                         .CallInterop("Nexus.CreatePlatform", _cli.NodeKeys.Address, platform, platformText, platformAddress, nativeCurrency.ToUpper())
                         .SpendGas(_cli.NodeKeys.Address).EndScript();

            var expire = Timestamp.Now + TimeSpan.FromMinutes(2);
            var tx     = new Phantasma.Blockchain.Transaction(_cli.Nexus.Name, _cli.Nexus.RootChain.Name, script, expire, Spook.TxIdentifier);

            if (tx != null)
            {
                tx.Mine((int)ProofOfWork.Minimal);
                tx.Sign(_cli.NodeKeys);

                if (_cli.Mempool != null)
                {
                    _cli.Mempool.Submit(tx);
                }
                else
                {
                    Console.WriteLine("No mempool available");
                    return;
                }

                Console.WriteLine($"Platform \"{platform}\" created.");
            }
        }
        protected void OnWalletRelayCommand(string[] args)
        {
            var script = Base16.Decode(args[0]);
            var expire = Timestamp.Now + TimeSpan.FromMinutes(2);
            var tx     = new Phantasma.Blockchain.Transaction(_cli.Nexus.Name, _cli.Nexus.RootChain.Name, script, expire, Spook.TxIdentifier);

            tx.Sign(WalletModule.Keys);

            if (_cli.Mempool != null)
            {
                _cli.Mempool.Submit(tx);
            }
            else
            {
                throw new CommandException("no mempool available");
            }
        }
Exemple #6
0
        private Transaction TokenInitTx(KeyPair owner)
        {
            var sb = ScriptUtils.BeginScript();

            sb.CallContract(ScriptBuilderExtensions.TokenContract, "MintTokens", owner.Address, StakingTokenSymbol, UnitConversion.ToBigInteger(8863626, StakingTokenDecimals));
            // requires staking token to be created previously
            // note this is a completly arbitrary number just to be able to generate energy in the genesis, better change it later
            sb.CallContract(ScriptBuilderExtensions.EnergyContract, "Stake", owner.Address, UnitConversion.ToBigInteger(100000, StakingTokenDecimals));
            sb.CallContract(ScriptBuilderExtensions.EnergyContract, "Claim", owner.Address, owner.Address);

            var script = sb.EndScript();

            var tx = new Transaction(Name, RootChainName, script, Timestamp.Now + TimeSpan.FromDays(300));

            tx.Sign(owner);

            return(tx);
        }
        private Transaction TokenCreateTx(Chain chain, KeyPair owner, string symbol, string name, BigInteger totalSupply, int decimals, TokenFlags flags, bool useGas)
        {
            var sb = ScriptUtils.BeginScript();

            if (useGas)
            {
                sb.AllowGas(owner.Address, Address.Null, 1, 9999);
            }

            sb.CallContract(ScriptBuilderExtensions.NexusContract, "CreateToken", owner.Address, symbol, name, totalSupply, decimals, flags);

            if (symbol == StakingTokenSymbol)
            {
                sb.CallContract(ScriptBuilderExtensions.TokenContract, "MintTokens", owner.Address, symbol, UnitConversion.ToBigInteger(8863626, StakingTokenDecimals));
            }
            else
            if (symbol == FuelTokenSymbol)
            {
                // requires staking token to be created previously
                // note this is a completly arbitrary number just to be able to generate energy in the genesis, better change it later
                sb.CallContract(ScriptBuilderExtensions.EnergyContract, "Stake", owner.Address, UnitConversion.ToBigInteger(100000, StakingTokenDecimals));
                sb.CallContract(ScriptBuilderExtensions.EnergyContract, "Claim", owner.Address, owner.Address);
            }

            if (useGas)
            {
                sb.SpendGas(owner.Address);
            }

            var script = sb.EndScript();

            var tx = new Transaction(Name, chain.Name, script, Timestamp.Now + TimeSpan.FromDays(300));

            tx.Sign(owner);

            return(tx);
        }
Exemple #8
0
        // signingKeys should be null if the block should not be modified
        public StorageChangeSetContext ProcessTransactions(Block block, IEnumerable <Transaction> transactions
                                                           , OracleReader oracle, BigInteger minimumFee, out Transaction inflationTx, PhantasmaKeys signingKeys)
        {
            bool allowModify = signingKeys != null;

            if (allowModify)
            {
                block.CleanUp();
            }

            var changeSet = new StorageChangeSetContext(this.Storage);

            transactions = ProcessPendingTasks(block, oracle, minimumFee, changeSet, allowModify).Concat(transactions);

            int txIndex = 0;

            foreach (var tx in transactions)
            {
                VMObject vmResult;
                try
                {
                    using (var m = new ProfileMarker("ExecuteTransaction"))
                    {
                        if (ExecuteTransaction(txIndex, tx, tx.Script, block.Validator, block.Timestamp, changeSet, block.Notify, oracle, ChainTask.Null, minimumFee, out vmResult, allowModify))
                        {
                            if (vmResult != null)
                            {
                                if (allowModify)
                                {
                                    var resultBytes = Serialization.Serialize(vmResult);
                                    block.SetResultForHash(tx.Hash, resultBytes);
                                }
                            }
                        }
                        else
                        {
                            throw new InvalidTransactionException(tx.Hash, "script execution failed");
                        }
                    }
                }
                catch (Exception e)
                {
                    e = e.ExpandInnerExceptions();

                    // log original exception, throwing it again kills the call stack!
                    Log.Error($"Exception while transactions of block {block.Height}: " + e);

                    if (tx == null)
                    {
                        throw new BlockGenerationException(e.Message);
                    }

                    throw new InvalidTransactionException(tx.Hash, e.Message);
                }

                txIndex++;
            }

            inflationTx = null;

            if (this.IsRoot && allowModify)
            {
                var inflationReady = NativeContract.LoadFieldFromStorage <bool>(changeSet, NativeContractKind.Gas, nameof(GasContract._inflationReady));
                if (inflationReady)
                {
                    var script = new ScriptBuilder()
                                 .AllowGas(block.Validator, Address.Null, minimumFee, 999999)
                                 .CallContract(NativeContractKind.Gas, nameof(GasContract.ApplyInflation), block.Validator)
                                 .SpendGas(block.Validator)
                                 .EndScript();

                    var transaction = new Transaction(this.Nexus.Name, this.Name, script, block.Timestamp.Value + 1, "SYSTEM");

                    transaction.Sign(signingKeys);

                    VMObject vmResult;

                    if (!ExecuteTransaction(-1, transaction, transaction.Script, block.Validator, block.Timestamp, changeSet, block.Notify, oracle, ChainTask.Null, minimumFee, out vmResult, allowModify))
                    {
                        throw new ChainException("failed to execute inflation transaction");
                    }

                    inflationTx = transaction;
                    block.AddTransactionHash(transaction.Hash);
                }
            }

            if (block.Protocol > DomainSettings.LatestKnownProtocol)
            {
                throw new BlockGenerationException($"unexpected protocol number {block.Protocol}, maybe software update required?");
            }

            // Only check protocol version if block is created on this node, no need to check if it's a non validator node.
            if (allowModify)
            {
                var expectedProtocol = Nexus.GetGovernanceValue(Nexus.RootStorage, Nexus.NexusProtocolVersionTag);
                if (block.Protocol != expectedProtocol)
                {
                    throw new BlockGenerationException($"invalid protocol number {block.Protocol}, expected protocol {expectedProtocol}");
                }

                using (var m = new ProfileMarker("CloseBlock"))
                {
                    CloseBlock(block, changeSet);
                }
            }

            return(changeSet);
        }