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)); }
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}"); }
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}"); }
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"); } }
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); }
// 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); }