Giter Club home page Giter Club logo

neo-lux's Introduction

ad

NEO Lux

NEO light wallet / blockchain API for C#.

Contents


Description

NEO Lux was developed to provide an easy way to interact with Smart Contracts in the NEO blockchain using C#.

It is not necessary to run a full node, because NEO Lux connects to Neon DB, which is the same API used by the Neon wallet.

Compatibility

Platform Status
.NET framework Working
UWP Working
Mono Working
Xamarin / Mobile Untested
Unity Working

Installation

PM> Install-Package NeoLux

Usage

Import the package:

using Neo.Lux;

For invoking a Smart Contract, e.g.:

	var privKey = "XXXXXXXXXXXXXXXXprivatekeyhereXXXXXXXXXXX".HexToBytes();	 // can be any valid private key
	var myKeys = new KeyPair(privKey);
	var scriptHash = "de1a53be359e8be9f3d11627bcca40548a2d5bc1"; // the scriptHash of the smart contract you want to use	
	// for now, contracts must be in the format Main(string operation, object[] args)
	var api = NeoDB.ForMainNet();
	var result = api.CallContract(myKeys, scriptHash, "registerMailbox", new object[] { "ABCDE", "[email protected]" });

For transfering assets (NEO or GAS), e.g.:

	var privKey = "XXXXXXXXXXXXXXXXprivatekeyhereXXXXXXXXXXX".HexToBytes();	 
	// can be any valid private key in raw format, for WIF use KeyPair.FromWIF
	var myKeys = new KeyPair(privKey);
	// WARNING: For now use test net only, this code is experimental, you could lose real assets if using main net
	var api = NeoDB.ForTestNet();
	var result = api.SendAsset("AanTL6pTTEdnphXpyPMgb7PSE8ifSWpcXU" /*destination address*/, "GAS", 3 /*amount to send */ , myKeys);

For getting the balance of an address:

	var api = NeoDB.ForTestNet();
	var balances = api.GetBalancesOf("AYpY8MKiJ9q5Fpt4EeQQmoYRHxdNHzwWHk");
	foreach (var entry in balances)
	{
		Console.WriteLine(entry.Key + " => " + entry.Value);
	}

NEP5 Token support

Neo-Lux allows to abstract interaction with Neo tokens via the NEP5 C# class.

Here's an example of interaction with a NEP5 token:

	var api = NeoDB.ForMainNet(); 
	var redPulse_token = api.GetToken("RPX");	
	Console.WriteLine($"{redPulse_token.Name} ({redPulse_token.Symbol})");
	Console.WriteLine($"Total Supply: {redPulse_token.TotalSupply} ({redPulse_token.Symbol})");
	
	// you can also request transfers of tokens
	var privKey = "XXXXXXXXXXXXXXXXprivatekeyhereXXXXXXXXXXX".HexToBytes();	 // can be any valid private key
	var myKeys = new KeyPair(privKey);
	redPulse_token.Transfer(myKeys, "AanTL6pTTEdnphXpyPMgb7PSE8ifSWpcXU" /*destination*/, 123 /*amount to send*/); 

You can also instantiate a NEP5 token from a script hash.

Look up the script hashes here or use your own if you're developing your own NEP5 token.

	var api = NeoDB.ForMainNet(); 	
	var redPulse_contractHash = "ecc6b20d3ccac1ee9ef109af5a7cdb85706b1df9";
	var redPulse_token = new NEP5(api, redPulse_contractHash);

Console Demo

A console program is included to demonstrate common features:

  • Loading private keys
  • Obtaining wallet address from private key
  • Query balance from an address
  • Invoking a NEP5 Smart Contract (query symbol and total supply)

Screenshot

Light Wallet Demo

A winforms demo is included to showcase how simple is to create a light wallet.

The light wallet demo is able to login into any wallet by inserting a private key in either raw format or WIF format, and also to transfer funds (NEO or GAS) to any address.

Please beware of using this wallet to transfer funds in Neo main net, as this wallet was created just for demonstration purpose and not exhaustively tested.

City of Zion cannot be responsibilized for loss of funds caused by using this light wallet.

Screenshot

Unity Support

NEOLux can be used together with Unity to make games that interact with the NEO blockchain. A Unity demo showcasing loading a NEO wallet and querying the balance is included.

Use caution, as most NEOLux methods are blocking calls; in Unity the proper way to call them is using Coroutines.

    IEnumerator SyncBalance()
    {
        var balances = NeoAPI.GetBalance(NeoAPI.Net.Test, this.keys.address);
        this.balance = balances["NEO"];
    }
	
	// Then you call the method like this
	StartCoroutine(SyncBalance());

Note: If you get compilation errors in Unity uou will need to go to Settings -> Player and change the Scripting Runtime version to .NET 4.6 equivalent

Using with Unity

In order to get the demo running in Unity, you'll want to open Unity and then open a new project. Open the folder located here.

Next, you'll want to open the Assets menu in your toolbar and import an asset package. This package can be found here.

You should now be able to hit play and see the demo in action!

If you're still receiving errors in the Console window, you'll want to go to Unity's Build Settings > Player Settings > and set the API compatibility level to .NET 4.6.

Inputs Screenshot

Airdrop / Snapshots

Latest versions of NEOLux have support for doing snapshots of the blockchain. This can be useful for example to find every wallet with a certain token balance at a certain date. Running a full local node using neo-cli full synced is extremely recommended when using snapshot features.

The following code extracts all transactions related to a specific NEP5 token.

	var api = new LocalRPCNode(10332, "http://neoscan.io");

	uint startBlock = 2313827;
	uint endBlock = 2320681;

	var token = api.GetToken("SOUL");
	var soul_tx = SnapshotTools.GetTokenTransactions(token, startBlock, endBlock);
	var soul_lines = new List<string>();
	foreach (var tx in soul_tx)
	{
		soul_lines.Add(tx.Hash+","+tx.Serialize().ByteToHex());
	}
	File.AppendAllLines("soul_txs.txt", soul_lines.ToArray());

Transaction Listening

Many applications will need to react to certain transactions once they appear on the chain. The ScriptInspector class can be used for decoding contract calls along with their arguments.

// First declare a BlockIterator
var iterator = new BlockIterator(api);
var targetContractHash = "AY9o94nWrUCEJ29UWhAodaJjQ16byjH852".AddressToScriptHash();
var token = new NEP5(api, targetContractHash);
var targetAddress = "AY9o94nWrUCEJ29UWhAodaJjQ16byjH852";

// You can listen for specific transactions of a specific type
var tx = api.WaitForTransaction(iterator, x => x.type == TransactionType.ContractTransaction);
if (tx != null) {
	Console.WriteLine($"Transaction {tx.Hash} is a asset transfer");
}

// You can listen for specific transactions arriving to a specific address 
var tx = api.WaitForTransaction(iterator, x => x.HasOutput(targetAddress));
if (tx != null) {
	Console.WriteLine($"Transaction {tx.Hash} was sent to {targetAddress}");
}

// You can listen for specific transactions coming from a specific address 
var tx = api.WaitForTransaction(iterator, x => x.HasInput(targetAddress));
if (tx != null) {
	Console.WriteLine($"Transaction {tx.Hash} was sent from {targetAddress}");
}

// You can listen for specific transactions that contain certain contract operations
var tx = api.WaitForTransaction(iterator, x => new ScriptInspector(x.script, targetContractHash).Any(y => y.operation == "transfer"));
if (tx != null) {
	Console.WriteLine($"Transaction {tx.Hash} contains transfer for {token.Name}");
	var inspector = new ScriptInspector(tx.script);
	foreach (var call in inspector.Calls) {
		if (call.operation == "transfer") {
			var from = new UInt160(call.arguments[0]);
			var to = new UInt160(call.arguments[1]);
			var amount = new BigInteger(call.arguments[2]);
			Console.WriteLine($"Transfer of {amount} from {from.ToAddress()} to {to.ToAddress()});
		}
	}
}

// You can listen for specific transactions that contain certain new contract deployments
var tx = api.WaitForTransaction(iterator, x => new ScriptInspector(x.script, targetContractHash).Deployments.Any());
if (tx != null) {
	Console.WriteLine($"Transaction {tx.Hash} deployed a new contract");
}

Advanced operations

NEOLux supports some advanced transaction operations specially useful for those doing an ICO in NEO.

Withdrawing NEO from an ICO contract address

After an ICO finishes, it is necessary to withdraw the received funds outside of the contract address. Now the problem is, for smart contracts the private key is not known, since the smart contract address is derived from the hash of it's own code. NEOLux provides some methods to do withdrawals from smart contracts. Once the funds are moved to a normal address, you have full access to them.

// first read the AVM bytecode from the disk. This AVM must be exactly the same deployed in the main net
var bytes = System.IO.File.ReadAllBytes(@"d:\code\crypto\my_ico\MyICOContract.avm");

// the team keys must match what is written in the contract. Usually only a single address will have withdraw permissions
var team_keys = Neo.Lux.Cryptography.KeyPair.FromWIF("XXXXXXXXXXXXXX");

var ICO_address = "AY9o94nWrUCEJ29UWhAodaJjQ16byjH852"; // this should be the contract address, the one where the sale funds are stored

// finally, execute the withdraw. It is recommended to first try withdrawing a small amount and check if the transaction gets accepted
var amount = 50;
var tx = api.WithdrawAsset(team_keys, ICO_address, "NEO", amount, bytes);
if (tx != null){
	Console.WriteLine("Unconfirmed tx " + tx.Hash);
}
else {
	Console.WriteLine("Sorry, transaction failed");
}

Claiming GAS from an ICO contract address

After an ICO finishes, if the sale received tons of NEO but you don't withdraw it right away, then the address will have a large amount of unclaimed GAS. With NEOLux it is possible to claim it, and later send it to another address using the withdraw method.

// first read the AVM bytecode from the disk. This AVM must be exactly the same deployed in the main net
var bytes = System.IO.File.ReadAllBytes(@"d:\code\crypto\my_ico\MyICOContract.avm");

// the team keys must match what is written in the contract. Usually only a single address will have withdraw permissions
var team_keys = Neo.Lux.Cryptography.KeyPair.FromWIF("XXXXXXXXXXXXXX");

var ICO_address = "AY9o94nWrUCEJ29UWhAodaJjQ16byjH852"; // this should be the contract address, the one where the sale funds are stored

// execute the claim. Note that this operation is quite slow and can take several seconds to execute the transaction
var amount = 50;
var tx = api.ClaimGas(team_keys, ICO_address, bytes);
if (tx != null){
	Console.WriteLine("Unconfirmed tx " + txw.Hash);
}
else {
	Console.WriteLine("Sorry, transaction failed");
}

After the GAS is claimed it is available and you can use api.WithdrawAsset() to move it to other address.

Using with Main net

The recommended way to do it by specifying a list of nodes:

var api = new RemoteRPCNode("http://neoscan.io", "http://seed6.ngd.network:10332", "http://seed.neoeconomy.io:10332");

An update list of active main net nodes can be found here: http://monitor.cityofzion.io/

Credits and License

Created by Sérgio Flores (http://lunarlabs.pt/).

Credits also go to the other devs of City Of Zion(http://cityofzion.io/), as this project started as a port of code from their NEON wallet from Javascript to C#. Of course, credits also go to the NEO team(http://neo.org), as I also used some code from their NEO source.

This project is released under the MIT license, see LICENSE.md for more details.

neo-lux's People

Contributors

gubanotorious avatar jhepkema avatar lock9 avatar meevee98 avatar miguelzf avatar mwherman2000 avatar relfos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

neo-lux's Issues

Update nuget package

I can see from source code that .NET Core standard is added, but I guess it isn't published to nuget.

Are you planning to publish it ?

Support for custom networks

Some users might need to test their dApps in a private test net, Neo-Lux must have a way to support this.

Support for Withdraw()

Should be possible to call a method Withdraw(from_address, to_address) which will create a transaction that requests an asset withdrawal or token withdrawal.

Can't call `public static object Main(string operation, params object[] args)` from `Demo.cs`

I'm playing around with neo-lux tonight. Trying to call my NPCdApp:

Script Hash: 0x7074acf3f06dd3f456e11053ebf61c5b04b07ebc (testnet)

public static object Main(string operation, params object[] args) (link to source)

win-gui parameter type: 0710

I tried to change your Demo.cs in a simple way but I'm just getting a null result back (should get back the string "success"). Here's the 4 lines I added to your Demo.cs:

https://github.com/mwherman2000/neo-lux/blob/master/neo-lux-demo/Demo.cs#L51

var NPCdAppContractHash = "0x7074acf3f06dd3f456e11053ebf61c5b04b07ebc".Replace("0x", "");
var response2 = api.TestInvokeScript(NPCdAppContractHash, "test2", new object[] { new BigInteger(5) } );
var result2 = System.Text.Encoding.ASCII.GetString((byte[])response2.result);
Console.WriteLine("result2" + result2);

Is there a simple fix?

Here's the Main() for my SC: https://github.com/mwherman2000/neo-persistibleclasses/blob/master/NPCdApp/NPCdApp.cs#L96

Cheers,
Michael

Add MyWish to NeoRPC.cs file under ForPrivateNet method

Hi all,

I would like to add MyWish (http://neoscan.mywish.io) to NeoRPC.cs file as PrivateNet.

I have added the following lines, but it does not work.

Could you help me about how to add MyWish as RemoteRPCNode?

Thank you.

public static NeoRPC ForPrivateNet()
        {
            return new RemoteRPCNode(20332, "http://neo.mywish.io", NEONodesKind.MYWISH);
        }

Also, I have added this code structure to NeoRPC.cs file.

 case NEONodesKind.MYWISH:
                    {
                        nodes = new string[4];
                        for (int i = 0; i < nodes.Length; i++)
                        {
                            nodes[i] = $"http://neo.mywish.io:{port}";
                            port = port + 1;
                        }
                        break;
                    }

New fork and clone to my laptop: Demo.cs doesn't build

These are the errors...

Severity	Code	Description	Project	File	Line	Suppression State
Error	CS0117	'NeoRPC' does not contain a definition for 'ForMainNet'	neo-lux-demo	D:\repos\neo-lux\neo-lux-demo\Demo.cs	31	Active
Error	CS0117	'NeoRPC' does not contain a definition for 'ForTestNet'	neo-lux-demo	D:\repos\neo-lux\neo-lux-demo\Demo.cs	11	Active
Error	CS1579	foreach statement cannot operate on variables of type '?' because '?' does not contain a public definition for 'GetEnumerator'	neo-lux-demo	D:\repos\neo-lux\neo-lux-demo\Demo.cs	23	Active
Error	CS0117	'NeoRPC' does not contain a definition for 'ForTestNet'	neo-lux-light-wallet	D:\repos\neo-lux\neo-lux-light-wallet\WalletForm.cs	11	Active
Error	CS0117	'NeoRPC' does not contain a definition for 'ForMainNet'	neo-sender	D:\repos\neo-lux\neo-sender\Sender.cs	36	Active
Error	CS0117	'NeoRPC' does not contain a definition for 'ForTestNet'	neo-sender	D:\repos\neo-lux\neo-sender\Sender.cs	37	Active
Error	CS7036	There is no argument given that corresponds to the required formal parameter 'port' of 'NeoRPC.NeoRPC(string, int)'	neo-sender	D:\repos\neo-lux\neo-sender\Sender.cs	38	Active

Any sample or demo for api.CallContract() ?

How to use api.CallContract?

public Transaction CallContract (KeyPair key, UInt160 scriptHash, string operation, object[] args, string attachSymbol = null, IEnumerable<Transaction.Output> attachTargets = null);

DemoForUnity has lots of error on building.

Thanks for your work.
There are some obvious errors in file "NeoDemo.cs".
eg:
using NeoLux; using Neo; using Neo.Cryptography; using Neo.VM;

Base on your lastest Neo-Lux it should like
using Neo; using Neo.Lux; using Neo.Lux.Core; using Neo.Lux.Utils; using Neo.Lux.Cryptography;

It will be greatly helpfull if you can fix them .
Thanks in advance

Unable to process transaction using api.InvokeScript .. null transaction is returned

I am trying to invoke a smartcontract and make a transaction over a private network but there is some issue that i am unable to resolve. Will be grateful if someone help me solve the issue.

This is my smart contract code:
image

This is how i am trying to invoke the contract from api code:
image

image

Transaction and result are always returned as null as shown below
image

List all demos with descriptions

Since there are already lots of demos, the readme should be updated with a table containing list of demos and descriptions / notes for each

GetStorage method bug

NeoRPC.cs row 58
public override byte[] GetStorage(string scriptHash, byte[] key)
{
var response = QueryRPC("getstorage", new object[] { key.ByteToHex() });
var result = response.GetString("result");
if (string.IsNullOrEmpty(result))
{
return null;
}
return result.HexToBytes();
}
you missed the param of "scriptHash", it should be the first param in new object[]

neo-lux fails to build

Severity	Code	Description	Project	File	Line	Suppression State
Error	CS0103	The name 'NeoDB' does not exist in the current context	Neo.Lux.Demo	D:\repos\neo-lux\Neo.Lux.Demo\Demo.cs	14	Active
Error	CS1579	foreach statement cannot operate on variables of type '?' because '?' does not contain a public definition for 'GetEnumerator'	Neo.Lux.Demo	D:\repos\neo-lux\Neo.Lux.Demo\Demo.cs	26	Active
Error	CS0103	The name 'NeoDB' does not exist in the current context	Neo.Lux.Demo	D:\repos\neo-lux\Neo.Lux.Demo\Demo.cs	34	Active
Error	CS0103	The name 'NeoDB' does not exist in the current context	Neo.Lux.Tests	D:\repos\neo-lux\Neo.Lux.Tests\NEP5.cs	15	Active

ScriptBuilder emitting trimmed hexstring

The ScriptBuilder is emitting a trimmed hexstring for BigInteger representation. Usually, the BigInteger is represented as a 16 character hexstring. Trimming may occur for excess zeroes. However, this trimming is causing an issue as the node seems to be unable to process the trimmed BigInteger.

Take for example, 78a1552b1a4cf1eb04a9cfa4998965603a0beb148a80354f0d2d58ef5aeb58c2 on testnet. The VM script uses a trimmed hexstring for the amount and the user reports that the transaction did not effect a change in tokens.

I had this experience in neon-js too and the solution was to always use 8 bytes to represent a BigInteger.

.net core ?

Hi guys .
Please tell me when your library is coming to .net ?

Bug in `WaitForTransaction`... [includes fix]

The logic in WaitForTransaction was wrong for finding the confirmed block that contained a specific Tx. I've fixed it.
I found this by running my console app side by side with the NEO-GUI transaction log.

CallContract would only succeed after the previous Tx was confirmed in NEO-GUI and WaitForTransaction was returning too quickly ...relative to what I was seeing in NEO-GUI.

Wait times are about 40-50 seconds (FYI).

Fixes:
https://github.com/mwherman2000/neo-lux/blob/master/Neo.Lux/Core/NeoAPI.cs#L1019
https://github.com/mwherman2000/neo-lux/blob/master/Neo.Lux/Core/NeoAPI.cs#L1069

The fix uses a derivative of my "batches of blocks" looping pattern that I first used in the NeoEventMonitor1 class: https://github.com/mwherman2000/neo-lux/blob/master/NEO.mwherman2000.MonitorEvents/NeoEventMonitor1.cs#L81

How to get a DataNode On a CallContract

Thanks for your wonderful work

It's realy helpful on working with unity.
I want to get a datanode object on calling a method from contract.
but now I got a transaction from which nothing usedfull data is included.

Any advice is appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.